1

I'm solving a problem mentioned here

I was able to do custom format of the grid elements in such a way that few columns with are editable in each row, I make display value one and save the newly changed value in a hidden field using formatOptions. However when it comes to selectbox fields, I read that editoptions is the one to be chosen over formatoptions. So currently my selecbox is as follows

editoptions: {
    dataUrl: '/lists/products', 
    buildSelect: function (data) {
        return "<select><option val='0'></option>" + data + "</select>";
    }
}

Now I need to store the selected value into a hidden field something of this sort <input type="hidden", name="items[item_id]" value="newly selected value">. But some how I'm unable to get this through editoptions. The code that I tried is here.

editable:true, 
edittype:"select",  
editoptions: {
    dataUrl: '/lists/products',
    buildSelect: function (data) {
        return "<select><option val='0'></option>" + data + "</select>";
    },
    dataEvents: [
        {
            type: 'change',
            fn: function(e) {
                console.log(e);
                html = '<input type=text name=product_codes[' + rowObject.item_id +
                    '] value="' + e.currentTarget.options.value + '" />';
                return html;
            }}                              
    ] 
}

This does not work. Any suggestion are welcome.

The whole jqgrid under which this comes is follows

showGrid: function(data){
    var request_data = data[0] ? data[0] :[];
    var data = data[1] ? data[1] :[];
    var items = data.invoice_items;
    var lastsel2;
    var $product_values = {};

    if(data[0].type_code !='xyz'){
      var $this = this;  
      $("#grid").GridUnload();
      $("#grid").jqGrid({
        datatype: 'local',
        colNames:['Item#','Product Group ID', 'Product Group','Product','Origin','Destination','Apps','Mobile','Carrier','Vessels',''],                     
        colModel :[                        
          {name:'item_identifier', index:'item_identifier', width:60},
          {name:'product_group_id', index:'product_group_id', width:60,hidden:true}, 
          {name:'product_group_code', index:'product_group_code', width:60}, 
          {name:'product_code', index:'product_code', width:150, editable:true, edittype:"select", editoptions: { dataUrl: '/lists/products', $.extend({
              custom_element: function (value, editOptions) {
                  var el = $('<input type="hidden" />');
                  el.attr('name', product_codes['+rowObject.invoice_item_id+']);
                  el.attr('value', cellvalue);
                  return el[0];
              }}), buildSelect: function (data) {
                  return "<select><option val='0'></option>" + data + "</select>";
              }}, formatter: function carrierFormatter(cellValue, options, rowObject){
                  html = '<input type=text name=product_codes['+rowObject.invoice_item_id+'] value="'+cellValue+'" />';
                  return html;
              }},
          {name:'origin_branch_code' ,index:'origin_branch_code', width:110},
          {name:'destination_branch_code', index:'destination_branch_code', width:100},
          {name:'term_code', index:'term_code', width:150, editable:true, edittype:"custom", editoptions: { dataUrl: '/lists/incoterms',  buildSelect: function (data) {
                  return "<select><option val='0'></option>" + data + "</select>";
              }}, formatter: function carrierFormatter(cellValue, options, rowObject){
                  html = '<input type=text name=inco_term_code['+rowObject.invoice_item_id+'] value="'+cellValue+'" />';
              return html;
            }},
          {name:'mobile', index:'mobile', width:90, editable:true},  
          {name:'carrier', index:'carrier', width:140, formatter: function carrierFormatter(cellValue, options, rowObject){

              html = '<input type=text name=carrier_code['+rowObject.invoice_item_id+'] value="'+cellValue+'" />&nbsp;<button class="carrier"> ...</button>';
              return html;
          }},
          {name:'vessel', index:'vessel', width:90, formatter: function carrierFormatter(cellValue, options, rowObject){
              html = '<input type=text name=vessel['+options.rowId+'] value="'+cellValue+'"/>&nbsp;<input type=hidden name=item_id['+options.rowId+'] value="'+rowObject.invoice_item_id+'" />';
              return html;
          }},  
          {name:'invoice_item_id', index:'invoice_item_id', hidden:true}
        ],
        loadComplete: function(rowid, status){
              $("#grid > tbody > tr").each(function (rowid){
                    $("#grid").editRow(rowid,true);
                 });
              alert("load Complete")
        },
        onSelectRow: function(rowid, status){
        // This action appends some more grids and sub forms

        },
    }
    else{
      $("#grid").jqGrid({
      datatype: 'local',
        colNames:['Item#','Product Group ID', 'Product Group','Product','Origin','Destination',' Terms','Mobile#','Carrier','Vessel', 'Cancel Item'],                     
        colModel :[                        
          {name:'invoice_item_identifier', index:'invoice_item_identifier', width:60,editable:false},
          {name:'product_group_id', index:'product_group_id', width:60,editable:false, hidden:true}, 
          {name:'product_group_code', index:'product_group_code', width:60,editable:false}, 
          {name:'product_code', index:'product_code', width:150,editable:true,edittype:"select",editoptions:{value: this.callback('getProducts')}},
          {name:'origin_branch_code' ,index:'origin_branch_code', width:110,editable:false},
          {name:'destination_branch_code' ,index:'destination_branch_code', width:100,editable:false},
          {name:'term_code'  ,index:'term_code', width:150,editable:true,edittype:"select",editoptions:{value: this.callback('getIncoterms')}},
          {name:'mbl', index:'mbl', width:90,editable:true,edittype:"text"},  
          {name:'carrier_code', index:'carrier_code', width:90,editable:true,edittype: 'text'},
          {name:'vessel', index:'vessel', width:90,editable:true},
          {
            name:'invoice_item_id',
            index:'invoice_item_id',
            width:90,
            formatter: function (cellvalue, options, rowObject){
              var html_input = "<a href='#invoice_item'>Cancel</a>" ;
              return  html_input;
            }
          }       
        ]
      });
    }        
    if(data){
     /*data gets processed here and mydata array is pushed to grid*/
        mydata.push({
          rowId: x,
          invoiceItem: x,
          item_identifier: d.transaction_type_business_number || 'N/A',
          product_group_id: d.product_group_code.group_id,
          product_group_code: d.product_group_code.product_group.product_group_code || "N/A",
          product_code: d.product_code,
          origin_branch_code: origin_branch_code,
          destination_branch_code: destination_branch_code,
          term_code: inco_term_code,
          Monbile: consolidation_number,
          carrier_code: carrier_code,
          vessel: d.comments,
          invoice_item_id: d.invoice_item_id
        });
        $("#grid").addRowData(d.id, mydata);
      }
    }

    $("#grid").trigger("reloadGrid"); //added for selection of rowids
  }
});

Thank You Sai Krishna

Community
  • 1
  • 1
J Bourne
  • 1,411
  • 2
  • 14
  • 33
  • Could you include more full definition of your jqGrid and describe more exactly where you save the modified values? Do you have all editable columns twice in the grid? Why you need to hold the data in the grid as HTML? You can just have an object which could set/get by the rowid the modified column items. It seems me more clear and simple. – Oleg Nov 11 '11 at 08:54
  • @Oleg, I pasted the code there, but I think it will be very less useful. In simple words I can say this. A page loads a grid and all its rows are editable mode excepting few fields. Now these fields have some text boxes and select boxes. On Selecting each row, below there would be some more forms and grids will be populated, which after editing when they hit save button, all these changes are supposed to be jsonified and sent to server. This is what I'm trying to achieve. However getting text element value into hidden form, I was successful, but not for the selectbox. These where I'm stuck. – J Bourne Nov 11 '11 at 10:05
  • @Oleg,@CraigStuntz, any suggestions? or am I not still clear in explaining my problem – J Bourne Nov 14 '11 at 22:22
  • I am sure that the usage of hidden fields to save modified data is not the best way. You can do the same **without custom formatter and custom edition (`custom_element`)**. You can save additional data directly in JavaScript variable (object or array of objects). You can post the data directly with respect of `$.ajax`. You current question mostly about *the code which you posted and not about the original problem which you need to solve*. I think that if you describes the original problem more clear one can write very simple code which do all what you need. – Oleg Nov 19 '11 at 11:40
  • Okay, Let me be more clear. I'm doing an invoice correction.Think about a logistics company, which transports various things under one invoice. Which will have its. Under one invoice there will be several item. And Each item has its own dimensions, parameters, consignees, brokers at various stages before it reaches. Now user comes with an invoice id for correction. I fetch all items and show them in an editable format, and that too only fields which are editable. – J Bourne Nov 21 '11 at 09:39
  • Now on click of each row, I need to get each parameters (which also will be editable), and parties, which will be a grid(editable). Similarly there are some references grid which is also editable. Now I need edit one selecting of each item and its parameters. Also you need to remember that is the first grid loads in editable format with some editable fields And some of these fields are select boxes, which I'm unable to do a custom format...! – J Bourne Nov 21 '11 at 09:43

2 Answers2

1

You don't posted any test data which you use to fill the grid (mydata). It seems to me that the value from the column invoice_item_id can be good used as the rowid. To simplify the code to get unique id which represent the item of the invoice I will suppose that the value d.id is the same as d.invoice_item_id. If you use another value you can change the code below including additional call of getCell method.

I don't see needs to use any additional hidden input fields either in the custom formatter or in the custom editing (custom_element). Instead of that I suggest do the following simple construction.

You defines a variable (an object) which will represent the changes in the fields which the user do in the invoice. You can just define a variable like.

var invoiceCorrections = {};

and reset it to the empty object {} every time when you clear the grid (about the code $("#grid").GridUnload();).

You can save the changes of invoices in invoiceCorrections object in the following form: The invoiceCorrections can has the values of invoice_item_id as the properties of the changed items of the invoice. If the value of some editable column like 'product_code', 'mbl' (??? 'mbl' or 'mobile' ??? you use both), 'term_code', 'carrier' or 'vessel' are changed you can save in invoiceCorrections the new modified values. For example,

{
    'invoice_item_id123': { // - invoice_item_id123 it's the id of one item
        product_code: 'new product id 1', // 'product_code' was changed 
        carrier: 'new carrier 1'          // 'carrier' was also changed
    },
    'invoice_item_id456': { // - invoice_item_id456it's the id of another item
        product_code: 'new product id 2',
        term_code: 'term code 2'
    },
}

To fill the invoiceCorrections in the described above form you can use dataEvents:

dataEvents: [
    {
        type: 'change',
        fn: function(e) {
            var $input = $(e.target), $tr = $input.closest('tr.jqgrow'),
                rowid, changedItem, inputColumnName = 'product_code';
            if ($tr.length > 0) {
                rowid = $tr[0].id; // if can be invoice_item_id
                // if you use other rowid you can get the value of any non-editable
                // with respect of `getCell`: 
                //     var invoice_item_id = $("#grid").jqGrid('getCell',
                //             rowid, 'invoice_item_id');
                if (rowid in invoiceCorrections) { // the same as
                                // typeof(invoiceCorrections[rowid]) !== "undefined"
                    changedItem = invoiceCorrections[rowid];
                } else {
                    changedItem = {};
                    invoiceCorrections[rowid] = changedItem;
                }
                changedItem = invoiceCorrections[inputColumnName];
                changedItem[inputColumnName] = $input.val();
            }
        }}                              
]

I used inputColumnName = 'product_code' in the above code to make you easier to move the code to the function which you can share in the code of dataEvents for different columns of grid. In case of the usage select elements you can replace $input.val() to $input.find('option:selected').val() or $input.find('option:selected').text().

In the way described above you will collect the full information which you need to post to the server in the invoiceCorrections object. So you can send invoiceCorrections to the server just per $.ajax or $.post. You should fill the data parameter of $.ajax depend on the implementation of your server part. It can be just data: invoiceCorrections or data: JSON.stringify(invoiceCorrections) or data: {invoiceChanged: JSON.stringify(invoiceCorrections)}.

Oleg
  • 219,533
  • 32
  • 395
  • 775
  • Thank you for the effort you kept in solving the problem. Definitely this looks like the cracker that I needed. – J Bourne Nov 22 '11 at 09:39
  • 1
    @SaiKrishna: You are welcome! You can any time ask me additional questions which specifying some aspects of implementation of my suggestion. – Oleg Nov 22 '11 at 09:52
0

Try $("select#id of selectbox[generated by jqgrid]").val();

The query should work.

Makoto
  • 100,191
  • 27
  • 181
  • 221
Rohan
  • 1,594
  • 6
  • 16
  • 37