title: jqgrid: how send and receive row data keeping edit mode
body: <p>jqGrid has employee name and employee id columns.</p>
  
  <p>If <code>employee name</code> has changed, server validate method should called to validate name. Current row columns should be updated from data returned by this method.</p>
  
  <p>If <code>employee id</code> has changed, server validate method should called to validate id.
  Current row columns should be updated from data returned by this method.</p>
  
  <p>Preferably jqGrid should stay in edit mode so that user has possibility to continue changing, accept or reject changes.</p>
  
  <p>How to implement this in inline and form editing?
  I'm thinking about following possibilites:</p>
  
  <p>Possibility 1.</p>
  
  <p>Use editrules with custom validator like</p>
  
  <pre><code>            editrules = new
              {
                  custom = true,
                  custom_func = function(value, colname) { ??? }
              },
  </code></pre>
  
  <p>Issues: How to get data from all columns, make sync or async call and update columns with this call results.</p>
  
  <p>Possibility 2.</p>
  
  <p>Require user to press Enter key to save row. 
  Issues: how to find which column was changed and pass this column number to server.
  How to update current row data from server response.</p>
  
  <p>Possibility 3.</p>
  
  <p>using blur as described in Oleg great answer in
  <a href="https://stackoverflow.com/questions/5247138/jqgrid-change-cell-value-and-stay-in-edit-mode">jqgrid change cell value and stay in edit mode</a></p>
  
  <p>Issues: blur does not fire if data is entered and enter is pressed immediately. How to apply blur in this case ?</p>
  
  <p>In summary server sice calculation/validation should be dones as follows:</p>
  
  <p>If column in changed and focus moved out or enter is pressed in changed column to save, server side sync or if not possible then async method should be called. Changed column name and current edited row values like in edit method are passed as parameters to this method.</p>
  
  <p>This method returns new values for edited row. current edited row values should be replaced with values returned by that method. </p>
  
  <p><strong>Update</strong></p>
  
  <p>Oleg answer assumes that primary key is modified. This factor is not important. Here is new version of question without primary keys and other updates:</p>
  
  <p>jqGrid has product barcode and product name columns.</p>
  
  <p>If <code>product name</code> has changed, server validate method should called to validate name. Current row columns should be updated from data returned by this method.</p>
  
  <p>If <code>product barcode</code> has changed, server validate method should called to validate product barcode.
  Current row columns should be updated from data returned by this method.</p>
  
  <p>jqGrid should stay in edit mode so that user has possibility to continue changing, accept or reject changes.</p>
  
  <p>How to implement this in inline and form editing?
  I'm thinking about following possibilites:</p>
  
  <p>Possibility 1.</p>
  
  <p>Use editrules with custom validator like</p>
  
  <pre><code>            editrules = new
              {
                  custom = true,
                  custom_func = function(value, colname) { ??? }
              },
  </code></pre>
  
  <p>Issue: custom_func does not fire if input element loses focus. It is called before save for all elements. So it cannot used.</p>
  
  <p>Possibility 2.</p>
  
  <p>Require user to press Enter key to save row. 
  Issues: how to find which column was changed and pass this column number to server.
  Save method should known column (name or barcode change order) and fill different columns. This looks not reasonable.</p>
  
  <p>Possibility 3.</p>
  
  <p>using blur:</p>
  
  <pre><code>colModel: [{"label":"ProductCode","name":"ProductCode","editoptions":{
  "dataEvents":[
  {"type":"focus","fn":function(e) { ischanged=false}},
  {"type":"change","fn":function(e) {ischanged=true}},
  {"type":"keydown","fn":function(e) {ischanged=true }},
  {"type":"blur","fn":function(e) { if(ischanged) validate(e)} }
  ]},
  </code></pre>
  
  <p>To implement validate I found code from Oleg great answer in
  <a href="https://stackoverflow.com/questions/5247138/jqgrid-change-cell-value-and-stay-in-edit-mode">jqgrid change cell value and stay in edit mode</a></p>
  
  <p>Summary of requirement:</p>
  
  <p>If column in changed and focus moved out or enter is pressed in changed column to save, server side sync or if not possible then async method should be called. Changed column name and current edited row values like in edit method are passed as parameters to this method.</p>
  
  <p>This method returns new values for edited row. current edited row values should be replaced with values returned by that method.</p>
  
  <p><strong>Update2</strong></p>
  
  <p>This question is not about concurrency. This is single user and jqGrid issue. Updating means that single user changes product name or barcode and server shoudl provide additonal data (product id and/or name/barcode) is responce of this.</p>
  
  <p><strong>Update 4</strong></p>
  
  <p>I tried code below. 
   If user enters new code and presses Enter without moving to other row, blur does not occur and validation is not called.</p>
  
  <p>How to dedect in jqGrid save method if cell is dirty or other idea how to force this code to run if enter is pressed to end edit without losing focus from changed foreign key cell ?</p>
  
  <pre><code>function validate(elem, column) {
  ischanged = false;
  var i, form, row;
  var postData = { _column: column  };
  var colModel = $("#grid").jqGrid('getGridParam', 'colModel');
  var formEdit = $(elem).is('.FormElement');
  // todo: use jQuery serialize()  ???
  if (formEdit) {
      form = $(elem).closest('form.FormGrid');
      postData._rowid = $("#grid").jqGrid('getGridParam', 'selrow');
      for (i = 0; i &lt; colModel.length; i++)
          eval('postData.' + colModel[i].name + '="' + $('#' + colModel[i].name + '.FormElement', form[0]).val() + '";');
  }
  else {
      row = $(elem).closest('tr.jqgrow');
      postData._rowid = row.attr('id');
      for (i = 1; i &lt; colModel.length; i++)
          eval('postData.' + colModel[i].name + '="' + $('#' + postData._rowid + '_' + colModel[i].name).val() + '";');
  }
  $.ajax('Grid/Validate', {
      data: postData,
      async: false,
      type: 'POST',
      success: function (data, textStatus, jqXHR) {
          for (i = 0; i &lt; data.length; i++) {
              if (formEdit)
                  $('#' + data[i].name + '.FormElement', form[0]).val(data[i].value);
              else
                  $('#' + postData._rowid + '_' + data[i].name).val(data[i].value);
          }
      }
  });
  }
  </code></pre>
  
  <p>colModel is defined as:</p>
  
  <pre><code>{"name":"ProductBarCode",
  "editoptions":    {"dataEvents":  
  [{"type":"focus","fn":function(e) {ischanged=false}
  },
  {"type":"change","fn":function(e) {ischanged=true},
  {"type":"keydown","fn":function(e) {if(realchangekey()) ischanged=true}
  },{"type":"blur","fn":function(e) { if(ischanged) {  validate(       e.target,ProductBarCode')}}
  }]},"editable":true}
  </code></pre>