Search code examples
jqgridfree-jqgrid

Jqgrid cascading dropdown


Using jqgrid free latest version 4.15.2 I am trying to make cascading drop down from db.

I tried the sample as posted by @Oleg jqgrid incorrect select drop down option values in edit box

But this is for older version of jqgrid and does not work fully while using latest version of jqgrid.

var countries = { "UsId": "US", "UkId": "UK" },
            statesOfUS = { "AlabamaId": "Alabama", "CaliforniaId": "California", "FloridaId": "Florida", "HawaiiId": "Hawaii" },
            statesOfUK = { "LondonId": "London", "OxfordId": "Oxford" },
            states = $.extend({}, statesOfUS, statesOfUK),
            allCountries = $.extend({"": "All"}, countries),
            allStates = $.extend({"": "All"}, states),
            // the next maps provide the states by ids to the contries
            statesOfCountry = {
                "": states,
                "UsId": statesOfUS,
                "UkId": statesOfUK
            },

The entire code can be seen in fiddle below

https://jsfiddle.net/svnL4Lsv/

The issue is during the add form the second dropwdown shows all states instead of showing as per country Secondly during the edit the second dropdown again shows all states and not as per the row value

Its just when I change the first dropdown does the second dropdown filters and works.

----------Updated

  editoptions: {
       // value: countries,
       dataInit: dataInitApp,
       dataEvents: dataEventsApp,
       dataUrl: '@Url.Action("GetData", "Home")',
       }

Controller code:

 public enum Countries
 {
    USA = 1,
    UK  = 2               
 }

  public enum State
  {
    Alabama  = 1,           
    Florida  = 2
    London = 3
  }

  public JsonResult GetData()
  {
    var type = typeof(Helpers.UsersEnum.Countries);
    var jsonData = Enum.GetNames(type)
            .Select(name => new
            {
                Id = (int)Enum.Parse(type, name),
                Name = name
            })
                .ToArray();

             return Json(jsonData);
         }

I call the above to populate my dropdown. Also below is the json that is returned back:

[0]: {Id=1, Name="USA"}
[1]: {Id=2, Name="UK"}


[0]: {Id=1, Name="Alabama  "}
[1]: {Id=2, Name="Florida"}
[2]: {Id=3, Name="London"}

Solution

  • In case of usage free jqGrid you can use a little simplified code

    $(function () {
        "use strict";
        var countries = "usId:US;ukId:UK",
            allStates = "alabamaId:Alabama;californiaId:California;floridaId:Florida;hawaiiId:Hawaii;londonId:London;oxfordId:Oxford",
            // the next maps provide the states by ids to the countries
            statesOfCountry = {
                "": allStates,
                usId: "alabamaId:Alabama;californiaId:California;floridaId:Florida;hawaiiId:Hawaii",
                ukId: "londonId:London;oxfordId:Oxford"
            },
            mydata = [
                { id: "10", country: "usId", state: "alabamaId", name: "Louise Fletcher" },
                { id: "20", country: "usId", state: "floridaId", name: "Jim Morrison" },
                { id: "30", country: "ukId", state: "londonId",  name: "Sherlock Holmes" },
                { id: "40", country: "ukId", state: "oxfordId",  name: "Oscar Wilde" }
            ],
            $grid = $("#list"),
            changeStateSelect = function (countryId, countryElem) {
                // build "state" options based on the selected "country" value
                var $select, selectedValues,
                    $countryElem = $(countryElem),
                    isInSearchToolbar = $countryElem.parent().parent().parent().parent().hasClass("ui-search-table");
    
                // populate the subset of countries
                if (isInSearchToolbar) {
                    // searching toolbar
                    $select = $countryElem.closest("tr.ui-search-toolbar")
                            .find(">th.ui-th-column select#gs_list_state");
                } else if ($countryElem.is(".FormElement")) {
                    // form editing
                    $select = $countryElem.closest("form.FormGrid")
                            .find("select#state.FormElement");
                } else {
                    // inline editing
                    $select = $("select#" + $.jgrid.jqID($countryElem.closest("tr.jqgrow").attr("id")) + "_state");
                }
    
                if ($select.length > 0) {
                    selectedValues = $select.val();
                    if (isInSearchToolbar) {
                        $select.html("<option value=\"\">All</option>");
                    } else {
                        $select.empty();
                    }
                    $.jgrid.fillSelectOptions($select[0], statesOfCountry[countryId], ":", ";", false, selectedValues);
                }
            },
            dataInitCountry = function (elem) {
                setTimeout(function () {
                    $(elem).change();
                }, 0);
            },
            dataEventsCountry = [
                { type: "change", fn: function (e) { changeStateSelect($(e.target).val(), e.target); } },
                { type: "keyup", fn: function (e) { $(e.target).trigger("change"); } }
            ],
            cancelInlineEditingOfOtherRows = function (rowid) {
                var $self = $(this), savedRows = $self.jqGrid("getGridParam", "savedRow");
                if (savedRows.length > 0 && rowid !== savedRows[0].id) {
                    $self.jqGrid("restoreRow", savedRows[0].id);
                }
            };
    
        $grid.jqGrid({
            data: mydata,
            datatype: "local",
            colNames: [ "Name", "Country", "State" ],
            colModel: [
                { name: "name", width: 180 },
                { name: "country", formatter: "select", stype: "select", edittype: "select",
                    searchoptions: {
                        noFilterText: "Any",
                        dataInit: dataInitCountry,
                        dataEvents: dataEventsCountry
                    },
                    editoptions: {
                        value: countries,
                        dataInit: dataInitCountry,
                        dataEvents: dataEventsCountry
                    }},
                { name: "state", formatter: "select", stype: "select", edittype: "select",
                    editoptions: { value: allStates }, searchoptions: { noFilterText: "Any" } }
            ],
            cmTemplate: { width: 100, editable: true },
            onSelectRow: cancelInlineEditingOfOtherRows,
            ondblClickRow: function (rowid) {
                cancelInlineEditingOfOtherRows.call(this, rowid);
                $(this).jqGrid("editRow", rowid);
            },
            inlineEditing: {
                keys: true
            },
            formEditing: {
                onclickPgButtons: function (whichButton, $form, rowid) {
                    var $self = $(this), $row = $($self.jqGrid("getGridRowById", rowid)), countryId;
                    if (whichButton === "next") {
                        $row = $row.next();
                    } else if (whichButton === "prev") {
                        $row = $row.prev();
                    }
                    if ($row.length > 0) {
                        countryId = $self.jqGrid("getCell", $row.attr("id"), "country");
                        changeStateSelect(countryId, $form.find("#country")[0]);
                    }
                },
                closeOnEscape: true
            },
            searching: {
                searchOnEnter: true,
                defaultSearch: "cn"
            },
            navOptions: {
                del: false,
                search: false
            },
            iconSet: "fontAwesome",
            sortname: "name",
            sortorder: "desc",
            viewrecords: true,
            rownumbers: true,
            pager: true,
            pagerRightWidth: 85, // fix wrapping or right part of the pager
            caption: "Demonstrate dependent selects (inline editing on double-click)"
        })
        .jqGrid("navGrid")
        .jqGrid("filterToolbar");
    });
    

    see https://jsfiddle.net/OlegKi/svnL4Lsv/3/