title: ExtJS grid store - writing information to MySQL on "Save"/"Update" via CodeIgniter
body: <p>I have a page containing a ExtJS 4.2.2 dataStore and gridPanel showing items created using information from various tables in a MySQL database.</p>
  
  <p>The purpose of the generated grid is to provide a "confirmation" to the user before any information is actually generated in the database in a table separate to those that originated the initial information, as some items can be flagged to be imported; unflagged items are not imported. The page uses HTML, PHP (with CodeIgniter MVC framework) and ExtJS (which implies Javascript and JQuery).</p>
  
  <p>With my current understanding of ExtJS, I would perform the necessary database insert or update by:</p>
  
  <ol>
  <li>Saving all the changes in the grid to the store</li>
  <li>Packaging the store's data into a multidimensional array, which is then assigned into a POST variable in some similar manner to a form</li>
  <li>Perform a POST to the same page, picking up the POST variable</li>
  <li>Loop through the POST information, passing each row's data to the model to perform the SQL query and INSERT/UPDATE as necessary.</li>
  </ol>
  
  <p>I'm thinking this is a long-winded and most likely inefficient method for doing this;  having previously worked with Kendo UI, I would have thought there is some form of "save" action on the store that simply calls a controller/model function that would act on the data in fewer steps.</p>
  
  <p>Having looked at Ext.data.Store's numerous potential candidates (the commitChanges method, update event, the write event, store.sync etc.), I have to say I'm completely bewildered by how I could perform the kind of action I'm thinking of; I need to write the information to a table separate from those that generated the initial information, and none of the above seem to do that.</p>
  
  <p>I would appreciate a "simple words" play-by-play of how to get the "dirty" data from the grid saved to the store, then the store data being passed to a MVC Controller-then-Model function that allows for update/insert to the DB (if that is the best way to do this) - I also appreciate that I will have to modify aspects of my ExtJS code, but what about my current setup isn't helping, if anything?</p>
  
  <p>ExtJS code below renders the grid with data, and not much else:</p>
  
  <pre><code>Ext.Loader.setConfig({
      enabled: true
  });
  Ext.Loader.setPath('Ext.ux', '../ux');
  
  Ext.require([
      'Ext.ux.CheckColumn'
  ]);
  
  Ext.onReady(function(){
      Ext.define('ConfirmationModel', {
          extend: 'Ext.data.Model',
          fields: [
              'GroupName', // generated if not a member of a group, will eventually be retrieved if already existing in group by checking import table for JobNo, ItemNo and ItemTypeId
              'ItemType',
              'ItemTypeId',
              'JobNo',
              'ItemNo',
              'ThicknessDepth',
              'Cutter',
              'CutterId',
              'Source',
              'Qty',
              'Material',
              'MaterialId',
              'Type',
              'TypeId',
              'Work',
              'WorkId',
              'PaintInternal',
              'PaintExternal',
              'Notes',
              'Documented',
              'ImportDate', // fetched by checking import table for jobNo, itemNo and itemTypeId
              'ImportCheck' // usually automatically checked if not yet imported
          ]
      });
  
      confirmationStore = Ext.create('Ext.data.Store',{
          model: 'ConfirmationModel',
          autoLoad: true,
          proxy: {
              // load using HTTP
              type: 'ajax',
              url: '&lt;?= $site_url ?&gt;Production/ConfirmationJSON/&lt;?php echo $job_no ?&gt;', // currently pulls all the information from three separate tables, pushes to object arrays then converts to and returns as JSON; will also check import table for existing entries as further work
              pageParam: false, //to remove param "page"
              startParam: false, //to remove param "start"
              limitParam: false, //to remove param "limit"
              noCache: false, //to remove param "_dc"
              reader: {
                  type: 'json',
                  model: 'ConfirmationModel'
              }
          },
          groupField: 'GroupName'
      });
  
      confirmationGrid = Ext.create('Ext.grid.Panel', {
          width: 1200,
          store: confirmationStore,
          title: 'Import Confirmation',
          tbar: [
              {
                  xtype: 'button',
                  text: 'Update',
                  handler: function(){
                      // function to handle the save/update of information goes here?
                      document.location.href = '&lt;?php echo site_url() ?&gt;Production/Schedule'; // redirect to next page in steps
                  }
              },
              {
                  xtype: 'button',
                  text: 'Cancel',
                  handler: function(){
                      window.history.back();
                  }
              }
          ],
          columns: [
              { text: 'Item&lt;br /&gt;No.', width:50, dataIndex: 'ItemNo' },
              { text: 'Job&lt;br /&gt;No.', width: 65, dataIndex: 'JobNo' },
              { text: 'Item Type', width: 70, dataIndex: 'ItemType' },
              { text: 'Thickness&lt;br /&gt;Depth', width: 65, dataIndex: 'ThicknessDepth' },
              { text: 'Cutter', width: 65, dataIndex: 'Cutter' },
              { text: 'Source', width: 65, dataIndex: 'Source' },
              { text: 'Qty', width: 40, dataIndex: 'Qty' },
              { text: 'Material', flex: 1, dataIndex: 'Material' },
              { text: 'Type', flex: 2, dataIndex: 'Type' },
              { text: 'Work', flex: 2, dataIndex: 'Work' },
              { text: 'Paint - Internal', flex: 2, dataIndex: 'PaintInternal' },
              { text: 'Paint - External', flex: 2, dataIndex: 'PaintExternal' },
              { text: 'Notes', flex: 2, dataIndex: 'Notes' },
              { text: 'Documented?', width: 75, dataIndex: 'Documented' },
              { text: 'Import&lt;br /&gt;Date', width: 60, dataIndex: 'ImportDate' },
              {
                  xtype: 'checkcolumn',
                  sortable: false,
                  header: 'Import?',
                  width: 50,
                  dataIndex:'ImportCheck'
              }
          ],
          features: [{
              id: 'group',
              ftype: 'groupingsummary',
              groupHeaderTpl: '{name}',
              enableGroupingMenu: false
          }],
          renderTo: Ext.get('sencha_confirmation')
      });
  });
  </code></pre>