Geeks With Blogs

News

Renso Hollhumer

Goal:

As we all know the jqGrid examples in the demo and the Wiki always refer to static values for drop down boxes. This of course is a personal preference but in dynamic design these values should be populated from the database/xml file, etc, ideally JSON formatted.

Can you do this in jqGrid, yes, but with some custom coding which we will briefly show below (refer to some of my other blog entries for a more detailed discussion on this topic).

What you CANNOT do in jqGrid, referring here up and to version 3.8.x, is to load different drop down values for different rows in the jqGrid. Well, not without some trickery, which is what this discussion is about.

Issue:

Of course the issue is that jqGrid has been designed for high performance and thus I have no issue with them loading a  reference to a single drop down values list for every column. This way if you have 500 rows or one, each row only refers to a single list for that particular column. Nice!

SO how easy would it be to simply traverse the grid once loaded on gridComplete or loadComplete and simply load the select tag's options from scratch, via Ajax, from memory variable, hard coded etc? Impossible! Since their is no embedded SELECT tag within each cell containing the drop down values (remember it only has a reference to that list in memory), all you will see when you inspect the cell prior to clicking on it, or even before and on beforeEditCell, is an empty <TD></TD>.

When trying to load that list via a click event on that cell will temporarily load the list but jqGrid's last internal callback event will remove it and replace it with the old one, and you are back to square one.

Solution:

Yes, after spending a few hours on this found a solution to the problem that does not require any updates to jqGrid source code, thank GOD!

Before we get into the coding details, the solution here can of course be customized to suite your specific needs, this one loads the entire drop down list that would be needed across all rows once into global variable. I then parse this object that contains all the properties I need to filter the rows depending on which ones I want the user to see based off of another cell value in that row. This only happens when clicking the cell, so no performance penalty. You may of course to load it via Ajax when the user clicks the cell, but I found it more efficient to load the entire list as part of jqGrid's normal editoptions: { multiple: false, value: listingStatus } colModel options which again keeps only a reference to the single list, no duplication.

Lets get into the meat and potatoes of it.

        var acctId = $('#Id').val();

        var data = $.ajax({ url: $('#ajaxGetAllMaterialsTrackingLookupDataUrl').val(), data: { accountId: acctId }, dataType: 'json', async: false, success: function(data, result) { if (!result) alert('Failure to retrieve the Alert related lookup data.'); } }).responseText;
        var lookupData = eval('(' + data + ')');

        var listingCategory = lookupData.ListingCategory;

        var catList = '{';
        $(lookupData.ListingCategory).each(function() {
            catList += this.Id + ':"' + this.Name + '",';
        });
        catList += '}';



        var lastsel;
        var ignoreAlert = true;
        $(item)
        .jqGrid({
            url: listURL,
            postData: '',
            datatype: "local",
            colNames: ['Id', 'Name', 'Commission<br />Rep', 'Business<br />Group', 'Order<br />Date', 'Edit', 'TBD', 'Month', 'Year', 'Week', 'Product', 'Product<br />Type', 'Online/<br />Magazine', 'Materials', 'Special<br />Placement', 'Logo', 'Image', 'Text', 'Contact<br />Info', 'Everthing<br />In', 'Category', 'Status'],
            colModel: [
                { name: 'Id', index: 'Id', hidden: true, hidedlg: true },
                { name: 'AccountName', index: 'AccountName', align: "left", resizable: true, search: true, width: 100 },
                { name: 'OnlineName', index: 'OnlineName', align: 'left', sortable: false, width: 80 },
                { name: 'ListingCategoryName', index: 'ListingCategoryName', width: 85, editable: true, hidden: false, edittype: "select", editoptions: { multiple: false, value: eval('(' + catList + ')') }, editrules: { required: false }, formatoptions: { disabled: false} }

            ],
            jsonReader: {
                root: "List",
                page: "CurrentPage",
                total: "TotalPages",
                records: "TotalRecords",
                userdata: "Errors",
                repeatitems: false,
                id: "0"
            },
            rowNum: $rows,
            rowList: [10, 20, 50, 200, 500, 1000, 2000],
            imgpath: jQueryImageRoot,
            pager: $(item + 'Pager'),
            shrinkToFit: true,
            width: 1455,
            recordtext: 'Traffic lines',
            sortname: 'OrderDate',
            viewrecords: true,
            sortorder: "asc",
            altRows: true,
            cellEdit: true,
            cellsubmit: "remote",
            cellurl: editURL + '?rows=' + $rows + '&page=1',
            loadComplete: function() {
 
            },
            gridComplete: function() {

            },
            loadError: function(xhr, st, err) {

            },
            afterEditCell: function(rowid, cellname, value, iRow, iCol) {
                var select = $(item).find('td.edit-cell select');
                $(item).find('td.edit-cell select option').each(function() {
                    var option = $(this);
                    var optionId = $(this).val();
                    $(lookupData.ListingCategory).each(function() {
                        if (this.Id == optionId) {                          
                            if (this.OnlineName != $(item).getCell(rowid, 'OnlineName')) {
                                option.remove();
                                return false;
                            }
                        }
                    });
                });
            },

            search: true,
            searchdata: {},
            caption: "List of all Traffic lines",
            editurl: editURL + '?rows=' + $rows + '&page=1',
            hiddengrid: hideGrid

 

Here is the JSON data returned via the Ajax call during the jqGrid function call above (NOTE it must be { async: false}:

{"ListingCategory":[{"Id":29,"Name":"Document Imaging","OnlineName":"RF Globalnet"}   

,{"Id"
:1,"Name":"Ancillary Department","OnlineName":"Healthcare Technology Online"} ,{"Id":2,"Name":"Asset Tracking","OnlineName":"Healthcare Technology Online"}
,{"Id":3,"Name":"Asset Tracking","OnlineName"
:"RF Globalnet"}

,{"Id":4,"Name":"Asset Tracking","OnlineName":"ISMR
"}
,{"Id":5,"Name":"Document Imaging","OnlineName":"Healthcare Technology Online"
}
,{"Id":6,"Name":"Document Imaging","OnlineName":"
RF Globalnet"}

,{"Id":7
,"Name":"EMR/EHR Software","OnlineName":"Healthcare Technology Online"}]}

I only need the Id and Name for the drop down list, but the third column in the JSON object is important, it is the only that I match up with the OnlineName in the jqGrid column, and then in the loop during afterEditCell simply remove the ones I don't want the user to see. That's it!

Posted on Wednesday, February 9, 2011 5:24 PM | Back to top


Comments on this post: jqGrid - dynamically load different drop down values for different rows depending on another column value

# re: jqGrid - dynamically load different drop down values for different rows depending on another column value
Requesting Gravatar...
I am attempting to emulate your code, but I keep getting ajax is not a function on

var data = $.Ajax({ url: $('#ajaxGetAllMaterialsTrackingLookupDataUrl').val(), data: { accountId: acctId }, dataType: 'json', async: false, success: function(data, result) { if (!result) alert('Failure to retrieve the Alert related lookup data.'); } }).responseText;

do you happen to know exactly why?

I am fairly new to JQuery.
Left by Joshua on Feb 10, 2011 2:01 PM

# re: jqGrid - dynamically load different drop down values for different rows depending on another column value
Requesting Gravatar...
Josh, seems when I pasted the code it capped the $.Ajax, do $.ajax all lowercase, let me if this resolves your issue so I can update the blog.
Left by Renso on Feb 11, 2011 9:13 AM

# jqgrid
Requesting Gravatar...
how to retrive 10 records out of 100 from xml and show in "jqgrid" on click and then show next 10 records when click again?
Left by vasant on May 14, 2012 10:56 AM

# re: jqGrid - dynamically load different drop down values for different rows depending on another column value
Requesting Gravatar...
I am trying to update a column values in a grid for all rows. Is that possible without looping through each row? We might have 1000's of rows and it might become a problem when looping through, so i am trying to see if there is any other options.
Left by Mohan on Nov 06, 2012 2:09 PM

# re: jqGrid - dynamically load different drop down values for different rows depending on another column value
Requesting Gravatar...
Mohan, are you wanting different values for each row?
Left by renso on Nov 06, 2012 5:18 PM

# re: jqGrid - dynamically load different drop down values for different rows depending on another column value
Requesting Gravatar...
Thank you for the code. we same scenario where we want to paint the selections based on a readonly column.
Your code helps but i also tried another approach where we extend the jqgrid and overload/overrider the createEl.
Would you see any problems using this?

(function($){
"use strict";
// Store the Original Crete El
gridSuperCreateEl = $.jgrid.createEl;
$.extend($.jgrid,{
createEl : function(eltype,options,vl,autowidth, ajaxso) {
var optionsToUse = options;

if ( eltype && eltype === 'select' ) { // Check if the Element is Select
if ( $.isFunction(optionsToUse.deriveRowValue) ) { // Check if custom function is written for the option
if ( options.name && options.id ) {
var originalOptionsValue = optionsToUse.value;
var lenOfField=options.name.length;
var rowId = options.id.substr(0,options.id.length - lenOfField - 1);
optionsToUse.value = optionsToUse.deriveRowValue(rowId);
if ( ! optionsToUse.value ) {
optionsToUse.value = originalOptionsValue;
}
}
}
}
return gridSuperCreateEl(eltype,optionsToUse,vl,autowidth, ajaxso);
}
})
})(jQuery);

Left by FTP on Jan 29, 2014 8:36 AM

# re: jqGrid - dynamically load different drop down values for different rows depending on another column value
Requesting Gravatar...
Is there a working copy of this somewhere (like jsfiddle)?
Left by Duane Rinehart on Apr 22, 2014 11:04 PM

# re: jqGrid - dynamically load different drop down values for different rows depending on another column value
Requesting Gravatar...
Hi,

I am trying to use your code for the same purpose. I am not getting the success on the code. I have retrieved the JSON of the select dropdown.
But, var lookupData = eval('(' + data + ')');
The above line is showing me the empty objects. What does this line of code do? I am getting the JSON into the "data" variable but when it uses "eval" function on data variable the value is object and it contains null then.
JSON format is correct. If I can get the values in the "lookupData" then I can work further to remove the unwanted option values from the select dropdown.

Can you please tell me what is wrong with this as soon as possible.?

Thanks in advance
Left by Tej on May 26, 2014 11:32 AM

# re: jqGrid - dynamically load different drop down values for different rows depending on another column value
Requesting Gravatar...
Could you please explain bit on
$('#ajaxGetAllMaterialsTrackingLookupDataUrl')

where to get this URL
Left by Harshil on Jun 11, 2014 9:28 AM

Your comment:
 (will show your gravatar)


Copyright © Renso | Powered by: GeeksWithBlogs.net | Join free