This is my other post about simple usage of ExtJS with CodeIgniter, this time I want to create a simple drag and drop shopping cart, I have learn about how to use the cart class in CodeIgniter that I have posted in the previous post, i’m using MySQL for the storing the product data. I prepared the mockup it something like this

Let just get started to the code:
1. Prepare The Database
Create table named “ci_extjs_cart” or with other name that you desired, next create the table and here the sql code
CREATE TABLE IF NOT EXISTS `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(64) DEFAULT NULL, `price` varchar(32) DEFAULT NULL, `image` varchar(128) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
And this are the sample data (I already included the sample image on the code that you can download)
INSERT INTO `products` (`id`, `name`, `price`, `image`) VALUES (1, 'HP - 20 Inch Widescreen Flat-Panel LCD Monitor', '169', 'hp.jpg'), (2, 'Gateway - 20 Inch Widescreen Flat-Panel LCD Monitor', '159', 'gateway.jpg'), (3, 'Apple - 30 Flat-Panel TFT-LCD Monitor', '1799', 'apple.jpg'), (4, 'Acer - 24 Inch Flat-Panel LED-LCD Monitor', '299', 'acer.jpg'), (5, 'Asus - 24 Inch Widescreen Flat-Panel LCD Monitor', '249', 'asus.jpg');
2. Setting Up CodeIgniter
First time to get hand dirty with a framework is to set all the config file (in folder: “application/config/”). The four files that we have to configure are:
config.php
$config['base_url'] = "http://localhost/ci_extjs_cart/";
database.php
$db['default']['hostname'] = "localhost"; $db['default']['username'] = "root"; $db['default']['password'] = "admin"; $db['default']['database'] = "ci_extjs_cart"; $db['default']['dbdriver'] = "mysql";
routes.php
$route['default_controller'] = "product";
The default controller is set to product controller, in this step we have not create the controller yet, but it will be.
autoload.php
$autoload['libraries'] = array('database', 'session');
$autoload['helper'] = array('url');
4. Setting Up ExtJS on CodeIgniter
Like always I always included ExtJS file on separate folder from Codeigniter
5. Create a Controller and a View
The Controller, create file product.php inside the controllers folder, the very usual method on the controller is the contrustion and the index method, in the construction method the codeigniter cart class loaded.
<?php
class Product extends Controller {
public function __construct()
{
parent::Controller();
$this->load->library('cart');
}
public function index()
{
$this->load->view('product/index');
}
}
The View, create the view file inside views folder “index.php”, the first step to preparing the view is to preparing the HTML layout, include the ExtJS file, and create a basic layout style in CSS.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>assets/js/ext/resources/css/ext-all.css"/>
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/ext/ext-all.js"></script>
<!-- product data view style -->
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>assets/js/ext/ux/data-view.css"/>
<script type="text/javascript">
var BASE_URL = '<?php echo site_url(); ?>/';
Ext.onReady(function() {
});
</script>
<title>Extjs Image Gallery Using DataView</title>
<style type="text/css">
body {
padding: 20px;
margin: 0 auto;
}
#container {
padding: 10px;
background: #e3e3e3;
border: 1px solid #d3d3d3;
margin: 0 auto;
text-align: left;
width: 630px;
}
#top {
}
#bottom {
margin-top: 10px;
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div id="container">
<div id="top"></div>
<div id="bottom"></div>
</div>
</body>
</html>
The Ext.ready function is still empty, inside this function all the ExtJS component will be placed, and I always using BASE_URL value that have value of site_url(); function, to make it easier when accessing a url.
6. Get Product List
The Controller, this is the method the get all the product data, and sending the data as json format.
public function ext_get_all()
{
$query = $this->db->get('products');
$product_arr = array();
foreach($query->result() as $key => $data)
{
$product_arr[] = array(
'id' => $data->id,
'name' => $data->name,
'price' => $data->price,
'image' => $data->image
);
}
echo json_encode(array('products' => $product_arr));
}
The View, this is the code for creating the product list in dataview, and a function to make the dataview draggable.
var proxyProduct = new Ext.data.HttpProxy({
url: BASE_URL + 'product/ext_get_all', method: 'POST'
});
var strProduct = new Ext.data.JsonStore({
proxy: proxyProduct,
root: 'products',
fields: [
'id', 'name', 'price', 'image'
]
});
strProduct.load();
var tplProduct = new Ext.XTemplate(
'<tpl for=".">',
'<div class="thumb-wrap" id="{name}">',
'<div class="thumb"><img src="http://localhost/ci_extjs_cart/assets/img/{image}" title="{name}"></div>',
'<span class="name">{name}</span>',
'<div class="price">$ {price}</div></div>',
'</tpl>',
'<div class="x-clear"></div>'
);
var dvProduct = new Ext.DataView({
autoScroll: true, store: strProduct, tpl: tplProduct,
autoHeight: false, height: 200, multiSelect: false,
overClass: 'x-view-over', itemSelector: 'div.thumb-wrap',
emptyText: 'No product to display',
style: 'border:1px solid #99BBE8;',
listeners: {
render: initializeItemDragZone
}
});
function initializeItemDragZone(v) {
v.dragZone = new Ext.dd.DragZone(v.getEl(), {
getDragData: function(e) {
var sourceEl = e.getTarget(v.itemSelector, 10);
if (sourceEl) {
d = sourceEl.cloneNode(true);
d.id = Ext.id();
return v.dragData = {
sourceEl: sourceEl,
repairXY: Ext.fly(sourceEl).getXY(),
ddel: d,
itemData: v.getRecord(sourceEl).data
}
}
},
getRepairXY: function() {
return this.dragData.repairXY;
}
});
}
var panelProduct = new Ext.Panel({
id: 'images-view',
frame: true,
width: 620,
autoHeight: true,
title: 'Product DataView',
style: 'margin:0 auto;',
items: [dvProduct]
});
panelProduct.render('top');
7. Create The Cart (Using EditorGridPanel)
The Controller, we will create some basic function to manipulating the cart I try to explain them in the separate way, but still in the same controller
7.1 Get All Cart
public function ext_get_cart()
{
if ($this->cart->total_items() != 0)
{
foreach($this->cart->contents() as $product)
{
$cart_arr[] = array(
'rowid' => $product['rowid'],
'id' => $product['id'],
'qty' => $product['qty'],
'name' => $product['name'],
'price' => $product['price'],
'subtotal' => $product['subtotal']
);
}
$cart_arr[] = array(
'rowid' => '',
'id' => '',
'qty' => '',
'name' => '',
'price' => '<b>Total:</b>',
'subtotal' => '<b>'.$this->cart->total().'</b>'
);
echo json_encode(array('cart' => $cart_arr));
}
else
{
$cart_arr[] = array();
echo json_encode(array('cart' => $cart_arr));
}
}
This function is to getting all the available product in the cart in the session, if the cart is not empty then just loop through the cart function “$this->cart->contents()” and put this to array. I add another array to showing the total value from the cart, this will be treated different in the ExtJS grid, and send it as json format
7.2 Add a Product to Cart
public function ext_add_cart()
{
if ($_POST['rowid'] == '')
{
$data = array(
'id' => $_POST['id'],
'qty' => 1,
'price' => $_POST['price'],
'name' => $_POST['name']
);
$this->cart->insert($data);
}
else
{
$data = array(
'rowid' => $_POST['rowid'],
'qty' => intval($_POST['qty']) + 1
);
$this->cart->update($data);
}
echo '{success:true, total: "'.$this->cart->total().'"}';
}
You must be can see in the add cart function there are conditional statement that updating the cart instead insert a new data to cart, well this is to handle if a user adding the product that already available on the cart, so the cart must be updating only the quantity.
7.3 Update a Product Quantity
public function ext_update_cart()
{
$data = array(
'rowid' => $_POST['rowid'],
'qty' => $_POST['qty']
);
$this->cart->update($data);
echo '{success:true}';
}
This function is to updating a product quantity on the cart, I make the quantity editable on the grid so the user can easy put the number of a product that he desired, and to deleting a product from cart the user have to put zero value on the quantity editable grid.
7.4 Clear Cart
public function ext_clear_cart()
{
$this->cart->destroy();
echo '{success:true}';
}
Well nothing really hard in this function, using “$this->cart->destroy()” all the cart clear.
7.5 The Cart
var strCart = new Ext.data.JsonStore({
root: 'cart',
fields: [
'rowid', 'id', 'qty', 'name', 'price', 'subtotal'
],
proxy: new Ext.data.HttpProxy({
url: BASE_URL + 'product/ext_get_cart', method: 'POST'
})
});
strCart.load();
var cb_select = new Ext.grid.CheckboxSelectionModel();
function showDollar(val) {
if (val == '' || val == '<b>Total:</b>') {
return val;
}
else {
return '$ ' + val;
}
}
var panelCart = new Ext.grid.EditorGridPanel({
frame: true, border: true, stripeRows: true,
store: strCart, loadMask: true, title: 'Your Cart (Drag Here)',
style: 'margin:0 auto;font-size:13px;',
height: 220, width: 500, sm: cb_select,
columns: [{
header: 'rowid',
dataIndex: 'rowid',
hidden: true,
hideable: false
}, {
header: 'id',
dataIndex: 'id',
hidden: true,
hideable: false
}, {
header: "Product Name",
dataIndex: 'name',
sortable: true,
width: 280
}, {
header: "Qty",
align: 'center',
width: 40,
dataIndex: 'qty',
menuDisabled: true,
editor: new Ext.form.TextField({
allowBlank: false,
vtype: 'alphanum',
id: 'qtyField'
})
}, {
header: "Price",
dataIndex: 'price',
sortable: true,
align: 'right',
renderer: showDollar,
width: 80
}, {
header: "Subtotal",
sortable: true,
align: 'right',
width: 80,
renderer: showDollar
}],
listeners: {
'afteredit': function() {
var sm = panelCart.getSelectionModel().getSelections();
panelCart.getSelectionModel().clearSelections();
Ext.Ajax.request({
method: 'POST',
url: BASE_URL + 'product/ext_update_cart',
params: {
rowid: sm[0].get('rowid'),
qty: Ext.getCmp('qtyField').getValue()
},
success: function() {
strCart.load();
}
});
}
},
buttons: [{
text: 'Clear Cart',
handler: function() {
Ext.Ajax.request({
url: BASE_URL + 'product/ext_clear_cart',
method: 'POST',
success: function() {
strCart.load();
}
});
}
}, {
text: 'Check Out',
handler: function() {
}
}]
});
panelCart.render('bottom');
var formPanelDropTargetEl = panelCart.getView().scroller.dom;
var formPanelDropTarget = new Ext.dd.DropTarget(formPanelDropTargetEl, {
notifyDrop : function(ddSource, e, data){
panelCart.getSelectionModel().selectAll();
var sm = panelCart.getSelectionModel().getSelections();
panelCart.getSelectionModel().clearSelections();
data.itemData.rowid = '';
for (i=0; i<=sm.length-1; i++) {
if (sm[i].get('id') == data.itemData.id) {
data.itemData.rowid = sm[i].get('rowid');
data.itemData.qty = sm[i].get('qty');
// so can out from loop
i = sm.length;
}
}
Ext.Ajax.request({
url: BASE_URL + 'product/ext_add_cart',
method: 'POST',
params: {
'id': data.itemData.id,
'price': data.itemData.price,
'name': data.itemData.name,
'rowid': data.itemData.rowid,
'qty': data.itemData.qty
},
success: function() {
strCart.load();
}
});
return(true);
}
});
That’s all for the Cart features, there is CheckboxSelectionModel component, this component is to check whether the product is already on the cart, you can see it used on notifyDrop inside the dropTarget you have to add, the expected result is something like this.






Hello,
thanks a lot for the example. I tried to reproduce this example but when i’m trying to access to the scroller object of the GridView, i’m getting an error :
var formPanelDropTargetEl = test.getView().scroller.dom;
When i m using console.log of test.getView(), the scroller attribute is displayed and i can explore this object but there is no way to access to the scroller object.
Am i doing something wrong ?
Thanks for any suggestion.
P.s : Using ExtJS 3.2.1
the example using Ext.grid.EditorGridPanel component,
what component are you using in “test” variable ?
The ‘test’ variable is an Ext.grid.EditorGridPanel like in your example.
Ok i found the problem :
panelCart.render(‘bottom’);
This line was missing
oks nice found
Bisa kasih contoh :
Edit Grid Extjs, dimana kita bisa ADD, DELETE Baris, dan
baris paling bawah dari grid adalah BARIS TOTAL / SUMMARY. DARI KOLOM NILAI misalnya… dan baris total ini tidak bisa di select
thx
Hi . nice tutorial ..
i need to know how to make the check out to work ? and also how to make the shopping cart separate for different clients .
thank you and i hope to get an anwser
Great stuff! I find myself coming back to your site almost daily!
I’m trying to get this demo into a viewport. I’d like to have a tree in the west, your panelProduct in the center and panelCart in the south, but I was getting errors related to the scroll.dom
Just wondering if you think I can put this in a viewport without much effort in changing the code. I don’t want to break anything!
How to create category on the cart