Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
10 posts Page 1 of 1
Hi everybody,

Those that are familiar with the CouchCart documentation and demo site know that we have shown how to enhance the shopping cart experience with a Bootstrap modal window. Another example using Magnific Popup can be found at viewtopic.php?f=4&t=8551. Couch does not impose any restrictions on the front end implementation of your shopping cart. There are obviously other interesting ways (besides modals) to display cart information and handle cart actions without reloading the page. The following template should be useful for all methods.

This is a generic replacement for the documented cart-modal.php file. The template outputs all of the cart data in JSON format, which makes it perfect for use with JavaScript AJAX functions. Nevertheless, you will need to be comfortable with JavaScript to put any of this to use...

Also hosted on GitHub at https://github.com/cheesypoof/CouchCMS-Cart-JSON-Template.
Code: Select all
<?php require_once('couch/cms.php'); ?>

<cms:no_cache/>

<cms:content_type 'application/json'/>

<cms:template hidden='1' title='Cart JSON'/>

{
    "items":                <cms:pp_count_items/>,
    "unique_items":         <cms:pp_count_unique_items/>,
    "shippable_items":      <cms:pp_count_shippable_items/>,
    "sub_total":            <cms:pp_sub_total/>,
    "discount":             <cms:pp_discount/>,
    "sub_total_discounted": <cms:pp_sub_total_discounted/>,
    "taxes":                <cms:pp_taxes/>,
    "shipping":             <cms:pp_shipping/>,
    "total":                <cms:pp_total/>,

    <cms:if "<cms:get_session 'coupon_found'/>">
        "coupon_code":          "<cms:addslashes><cms:get_session 'coupon_code'/></cms:addslashes>",
        "coupon_discount":      <cms:get_session 'coupon_discount'/>,
        "coupon_free_shipping": <cms:if "<cms:get_session 'coupon_free_shipping'/>">true<cms:else/>false</cms:if>,
    </cms:if>

    "cart_items": [
        <cms:pp_cart_items>
            <cms:incr item_count/>
            {
                <cms:hide><!-- Add editable regions --></cms:hide>
                <cms:pages id=id limit='1' masterpage="<cms:pp_config 'tpl_products'/>">
                    "description": "<cms:addslashes><cms:show product_desc/></cms:addslashes>",
                    "image":       "<cms:show product_image/>",
                    "thumbnail":   "<cms:show pp_product_thumb/>",
                </cms:pages>

                "id":                <cms:show id/>,
                "quantity":          <cms:show quantity/>,
                "price":             <cms:show price/>,
                "line_total":        <cms:show line_total/>,
                "requires_shipping": <cms:if requires_shipping>true<cms:else/>false</cms:if>,
                "name":              "<cms:show name/>",
                "title":             "<cms:addslashes><cms:show title/></cms:addslashes>",
                "link":              "<cms:show link/>",
                "remove_item_link":  "<cms:pp_remove_item_link/>",
                "line_id":           "<cms:show line_id/>",

                <cms:if line_discount>
                    "line_discount": <cms:show line_discount/>,
                    "orig_price":    <cms:show orig_price/>,
                </cms:if>

                "options": [
                    <cms:set opt_count = '0'/>
                    <cms:pp_selected_options><cms:incr opt_count/></cms:pp_selected_options>

                    <cms:if opt_count>
                        <cms:pp_selected_options startcount='1'>
                            {
                                "name":  "<cms:addslashes><cms:show option_name/></cms:addslashes>",
                                "value": "<cms:addslashes><cms:show option_value/></cms:addslashes>"
                            }
                            <cms:if opt_count != k_count>,</cms:if>
                        </cms:pp_selected_options>
                    </cms:if>
                ]
            }
            <cms:if item_count != "<cms:pp_count_unique_items/>">,</cms:if>
        </cms:pp_cart_items>
    ]
}

<?php COUCH::invoke(); ?>

Let's say for example, you choose to utilize an off-canvas panel for your shopping cart. When a product is added to the cart, this small panel slides into view (without reloading the page).
cart.png
cart.png (10.98 KiB) Viewed 53973 times

The markup for this panel could resemble the following (I have included a manual 'Update Cart' button for testing purposes):
Code: Select all
<button id="update_cart" type="button">Update Cart</button>

<div id="cart_panel">
    <h3><span id="items"><cms:number_format "<cms:pp_count_items/>" decimal_precision='0'/></span> item(s) - $<span id="total"><cms:number_format "<cms:pp_total/>"/></span></h3>

    <ul id="cart_items">
        <cms:pp_cart_items>
            <li>
                <a href="<cms:show link/>"><img alt="" src="<cms:show product_thumb/>"></a>
                <br>
                <a href="<cms:show link/>"><cms:show title/></a>
                <cms:pp_selected_options>
                    <br>
                    <cms:show option_name/>: <cms:show option_value/>
                </cms:pp_selected_options>
                <br>
                $<cms:number_format price/> &times; <cms:number_format quantity decimal_precision='0'/> &rarr; $<cms:number_format line_total/>
            </li>
        </cms:pp_cart_items>
    </ul>

    <a href="<cms:pp_checkout_link/>">Checkout</a>
</div>

When a cart action (add, remove, update quantity) occurs, you will need to retrieve new cart information. The following example JavaScript (with jQuery) demonstrates how one can use the JSON data to inject cart HTML and update pre-existing text:
Code: Select all
var cart;

function formatNumber( n, money ) {
    var parts = ( money ? n.toFixed( 2 ) : n.toString() ).split( "." );
    return parts[ 0 ].replace( /\B(?=(\d{3})+(?!\d))/g, "," ) + ( parts[ 1 ] ? "." + parts[ 1 ] : "" );
}

function update_cart( callback ) {
    $.ajax({
        dataType: "json",
        url:      "http://mysite.com/json.php" // URL of the above template
    }).done(function( data ) {
        cart = data;

        callback();
    }).fail(function( request ) {
        alert( request.status + ": " + request.statusText );
    });
}

function update_cart_callback() {
    $( "#items" ).text( formatNumber( cart.items ) );
    $( "#total" ).text( formatNumber( cart.total, true ) );

    $( "#cart_items" ).html(function() {
        var html = '';

        for ( var i = 0; i < cart.cart_items.length; i++ ) {
            var item = cart.cart_items[ i ];

            html += '<li>';

            html += '<a href="' + item.link + '"><img alt="" src="' + item.thumbnail + '"></a>';

            html += '<br><a href="' + item.link + '">' + item.title + '</a>';

            for ( var j = 0; j < item.options.length; j++ ) {
                var option = item.options[ j ];

                html += '<br>' + option.name + ': ' + option.value;
            }

            html += '<br>$' + formatNumber( item.price, true ) + ' &times; ' + formatNumber( item.quantity ) + ' &rarr; $' + formatNumber( item.line_total, true );

            html += '</li>';
        }

        return html;
    });
}

$(function() {
    $( "#update_cart" ).on( "click", function() {
        update_cart( update_cart_callback );
    });
});

I hope this is helpful. Let me know if you have any questions.
Thanks @cheesypoof !! Really appreciate the effort you made.

I tried connecting your code with my add to cart button, but it doeesn't work.
I am pretty sure that the URL to the json.php template is correct.

This is what I did:
Code: Select all
 $( document ).on( "submit", ".cart-form", function( event ) {
        event.preventDefault();
   update_cart( update_cart_callback );


After adding the product, I get the alert dialog that says 200:0K.

Is your code supposed to work out of the box, or one must adjust some things ?
The template should work out of the box. If you visit json.php directly, what does it generate?

I debated whether to even include the HTML and JavaScript. The JS just updates the cart HTML when that button is clicked. It really was only meant to help people understand the role of the template. The JS will need to be heavily modified for each implementation.

With that said, the JS you posted will exhibit unwanted behavior. When the cart form is submitted, we initially prevent the default action. We still must submit the form though (with AJAX), otherwise Couch never receives the add to cart request. Replace update_cart( update_cart_callback ); with the following:
Code: Select all
$.ajax({
    type: "post",
    url: $( this ).attr( "action" ),
    data: $( this ).serialize()
}).done(function() {
    update_cart( update_cart_callback );
}).fail(function( request ) {
    alert( request.status + ": " + request.statusText );
});
When visiting json.php in the browser, I get all the data displayed from the JSON object, it functions as expected, I suppose.

But I still get the 200:OK alert error, even with the modified code you provided :(

Any thoughts ?
The fail callback is being executed after the AJAX request is made. There may be an issue with the JSON validating successfully. If your site is online, please pm me the URL. Also, please post the full JS and generated JSON.
Here is the generated JSON(please note that I have no product options for my products).

Code: Select all
{
    "items":                8,
    "unique_items":         2,
    "shippable_items":      8,
    "sub_total":            0,
    "discount":             0,
    "sub_total_discounted": 0,
    "taxes":                0,
    "shipping":             0,
    "total":                0,

    "cart_items": [
       
             {
                  "id":                31,
                "quantity":          7,
                "price":             0,
                "line_total":        0,
                "requires_shipping": true,
                "name":              "fourth-test-lamp",
                "title":             "Fourth test lamp",
                "link":              "http://mysite.com/table-lamps.php?p=31",
                "remove_item_link":  "http://mysite.com/cart.php?kcart_action=3&amp;line_id=d3ea3fd3c14dcbf0fdfd98c8694019ba",
                "line_id":           "d3ea3fd3c14dcbf0fdfd98c8694019ba",

               

                "options": [
                    ]
            }
            ,
       
           
            {
               
                 "id":                6,
                "quantity":          1,
                "price":             0,
                "line_total":        0,
                "requires_shipping": true,
                "name":              "metal-table-lamp-ime130012s",
                "title":             "Metal Table Lamp IME130012S",
                "link":              "http://mysite.com/table-lamps.php?p=6",
                "remove_item_link":  "http://mysite.com/cart.php?kcart_action=3&amp;line_id=457e16e445c1ec2853127fb15ad58463",
                "line_id":           "457e16e445c1ec2853127fb15ad58463",

               

                "options": [
                   
                   

                   
                ]
            }
           
       
    ]
}


<!-- Page generated by CouchCMS - Simple Open-Source Content Management -->


JavaScript is exactly like the one you posted, because I first wanted to make sure that your example works.
I had not thought about this, but it should be a case of the appended Couch comment resulting in malformed JSON.
Code: Select all
<!-- Page generated by CouchCMS - Simple Open-Source Content Management -->

There are two solutions -
1. Purchase a Couch license and set K_PAID_LICENSE to 1 in your config.php.
2. Modify the JavaScript; we must change the expected dataType from json to text and remove the comment, before manually parsing the JSON string:
Code: Select all
function update_cart( callback ) {
    $.ajax({
        dataType: "text",
        url:      "http://mysite.com/json.php" // URL of the above template
    }).done(function( data ) {
        cart = $.parseJSON( data.replace( "<!-- Page generated by CouchCMS - Simple Open-Source Content Management -->", "" ) );

        callback();
    }).fail(function( request ) {
        alert( request.status + ": " + request.statusText );
    });
}
Thanks!! I have the licence for this particular website, I will change that option in the config file.
I'll let you know how it turned out.

edit: works great now!!! :)
Hi,

Looks perfect for what i need. safe to assume, we do not need the boostrap or other files related to the previous AJAX method as described in the couch how to's?

Is there a demo working example? github just has the json
Sounds AJAX Cart great code was doing an error

Solved by replacing

Code: Select all
  "cart_items": [

       <cms:pp_cart_items>

       <cms:incr item_count/>

           {

               <cms:hide><!-- Add editable regions --></cms:hide>


by

Code: Select all
  "cart_items": [

       <cms:set item_count='0' />

       <cms:pp_cart_items>

       <cms:incr item_count/>
10 posts Page 1 of 1