title: How to make jqGrid dynamically populate options list based on row data
body: <p>I am using jQrid version 3.8.1 with inline editing and each row in the grid has several dropdown lists to populate. When the user edits the row, I need to do an AJAX query to get the values for each of these lists. I've seen <a href="https://stackoverflow.com/questions/7413905/jqgrid-populate-select-control-on-row-edit">this post</a> regarding how to do that. It appears that the <code>dataUrl</code> and <code>buildSelect</code> features are the standard answer here. There are a few issues I can't figure out though:</p>
  
  <ol>
  <li><p>The row the user is editing has a value that must be passed into the <code>dataUrl</code> value. For example, say each row contains a field called "SpecialValue" and that for row 1, SpecialValue = 100. The <code>dataUrl</code> field for row 1 would be "<a href="http://my.services.com?SpecialValue=100" rel="nofollow noreferrer">http://my.services.com?SpecialValue=100</a>". How do I do that?</p></li>
  <li><p>Each row in the grid has about 10 select boxes that need to be populated. For efficiency reasons, I don't want to make 10 separate AJAX calls. It would be much better to make one call to get all the data, split it up, and fill each select box accordingly. Is that possible? I tried doing this inside <code>onSelectRow</code> but the grid ended up ignoring the values I put in there (I'm guessing do the ordering of the events that fire when you edit a row).</p></li>
  </ol>
  
  <h2>Edit:</h2>
  
  <p>After reading Oleg's answers and working on it more, it's clear to me that using <code>dataUrl</code> and <code>buildSelect</code> are not going to work well for me. The version of jqGrid I'm using doesn't support using <code>dataUrl</code> the way I would need. And even if it did I don't want to send multiple separate requests for each dropdown list.</p>
  
  <p>I've decided to do one request when <code>gridComplete</code> fires to pull all the data needed for all dropdown lists into a single JSON structure. Then when the user selects a row to do inline editing, I will populate each list in the row from that JSON structure (the code below uses the getSelectValuesFromJSON() function for that--I don't give its definition but you can imaging it looks through the structure and gets an appropriate list of values to but in the list box).</p>
  
  <p>I have a few candidate solutions but I'm not 100% happy with either one.</p>
  
  <p><strong>Solution 1</strong>:</p>
  
  <p>Inside <code>onSelectRow</code>, I call <code>editRow</code> overriding the on <code>oneditfunc</code> to get the data out of the grid that I need. Assume that the value in <code>Field1</code> is required to get the values to be put into the list in <code>Field2</code>.</p>
  
  <pre class="lang-js prettyprint-override"><code>onSelectRow: function (index, status, e) {
      jQuery('#my_grid').jqGrid('editRow', index, true, function(rowId) {
          var f1Val = $('#my_grid').jqGrid('getCell', index, 'Field1');
          var selectVals = getSelectValuesFromJSON(f1Val); //gets data out of previously loaded JSON structure
          var select = $('#my_grid').find('tr[id="' + index + '"] td[aria-describedby="my_grid_Field2"] select');
          _.each(selectVals, function(selectVal) {
              $(select).append($("&lt;option&gt;&lt;/option&gt;").attr("value", selectVal).text(selectVal));
          });
      });
  }
  </code></pre>
  
  <p>This works but I'm hesitant about the line</p>
  
  <pre class="lang-js prettyprint-override"><code>var select = $('#my_grid').find('tr[id="' + index + '"] td[aria-describedby="my_grid_Field2"] select');
  </code></pre>
  
  <p>which relies on this <code>aria-describedby</code> attribute that I don't know much about. Seems hacky and brittle.</p>
  
  <p><strong>Solution 2</strong>:</p>
  
  <p>Make use of <code>beforeSelectRow</code> to dynamically change the model of the Field2 column when the user selects a row.</p>
  
  <pre class="lang-js prettyprint-override"><code>beforeSelectRow: function(index, e) {
      var f1Val = getGridCellValue('#my_grid', index, 'Field1');
      var values = getSelectValuesFromJSON(f1Val); //gets data out of previously loaded JSON structure
      var valStr = "";
      _.each(values, function(value) {
          valStr += value + ":" + value + ";"
      });
      jQuery('#grid_pipes').setColProp('Field2', { editoptions: { value: valStr } });
      return true;
  }
  </code></pre>
  
  <p>This also works but I'm not sure about whether or not this is really a good idea. Is it valid to dynamically change the model of a column like that? What if the user has several rows selected at the same time? Isn't there only one model for a column? What would that mean?</p>
  
  <p>To answer some of Oleg's questions, the <code>dataType</code> has been set to a function that uses $.ajax to post data to the server. I think I read that's not the recommended approach anymore. I inherited this code so I'm not sure why it was done that way but it probably won't change unless there is a really compelling reason.</p>
  
  <p>The <code>loadonce</code> boolean is not specified so I guess that means it defaults to <code>false</code>.</p>
  
  <p>Here is an abbreviated version of the column model (nothing terribly out of the ordinary):</p>
  
  <pre class="lang-js prettyprint-override"><code>colModel: [
      { name: 'PK', index: 'PK', hidden: true, editable: true, sortable: true, search: true },
      { name: 'Field1', index: 'Field1', hidden: true, editable: true, sortable: true, search: true },
      { name: 'Field2', index: 'Field2', sortable: false, editable: true, search: false, edittype: "select", editoptions: {} },
      { name: 'Field3', index: 'Field3', sortable: false, editable: true, search: false, edittype: "select", editoptions: {} },
      ...
  ]
  </code></pre>