Jsgrid: Dependency Dropdown

Created on 28 Jul 2015  路  28Comments  路  Source: tabalinas/jsgrid

I have many data such as department, team, and group that i would need to filter them using dropdown.

I was able to populate the department dropdownlist with json, however, i wasnt able to retrieve the select department at the first column and use it as a key to filter the team value in the 2nd column and so on.

Any idea or help?

help wanted

Most helpful comment

Ok, that what I meant by comment "In more general case we could grep team from entire list of teams (if we would use id, not the team name)."

Just modify itemTemplate picking up item by id:

itemTemplate: function(teamId) {
    return $.grep(teams, function(team) {
        return team.id === teamId;
    }[0].name;
},

here teams is an array of all teams (not filtered by department)

All 28 comments

Check out this issue and my answer to it https://github.com/tabalinas/jsgrid/issues/46

capture

Its not about filtering of the records.

For instance, there is
department = [{department: "a", department: "b"}];, and
team = [{department: "a", team: "x"}, {department: "a", team: "y"}, {department: "b", team: "z"}]

The dropdown for insert and edit feature at 'team' should only show "x" and "y" when department "a" is selected, likewise, for department "b", only team"z" will be shown.

Thanks for the reply!

I see, you can extend this sample to editTemplate and insertTemplate too.

How do i access the dropdown value of the previous column within the insertTemplate function?

What if you implement it just the way it's implemented for filterTemplate in this fiddle http://jsfiddle.net/tabalinas/n982uvx1/?

I have tried however, I was experienceing some issues.

capture

I manage to filter out the teamField, however, whenever I tried to select on a single element in the team column, the insertControl onchange at department is still executing.

insertcss: "department-filter", 
insertTemplate: function() {
                var teamField = this._grid.fields[2];
                var $insertControl = jsGrid.fields.select.prototype.insertTemplate.call(this);

                $insertControl.on("change", function() {
                    var selectedDepartment = $(this).val();
                    var departmentTeam = $.grep(team_list, function(team) {
                        return team.department === selectedDepartment;
                    });

                    alert("fe" + JSON.stringify(departmentTeam));
                    teamField.items = departmentTeam;
                    teamField.textField = "team";
                    teamField.valueField = "team";
                    $(".team-filter").empty().append(teamField.insertTemplate());
                });

                return $insertControl;
            },

Could you modify the fiddle http://jsfiddle.net/tabalinas/n982uvx1/ to demonstrate the problem?

Sorry for the late reply, this is the fiddle with the problem demonstrated, http://jsfiddle.net/n982uvx1/12/. As shown, the team does not show the list of team in the "team_list" despite having both valueField and textField set to "team".

I have tried setting teamField.valueField = "team"; and teamField.textField = "team"; at the onchange function. However, as select upon the "team" dropdown list, the onchange function should trigger again and thus making it empty as a result.

Thanks for your help!

Everything looks correct, the only line with an error is:

// the team field index is not 2 but 3
var teamField = this._grid.fields[3];

Here is the fiddle: http://jsfiddle.net/tabalinas/n982uvx1/13/

I see! Thanks alot!

You are welcome!

Sorry to bother again, for the fiddle as shown: http://jsfiddle.net/n982uvx1/14/ .
How to I set the cell value back to the dropdownlist inside the editTemplate?
Right now, once the edit function is trigger, the dropdown value are as of the first item on the data list and not as according to the row value.

Thanks!

You should pass the argument of editTemplate. In your case it's a selected value.

editTemplate: function(value) {
    var teamField = this._grid.fields[3];
    var $editControl = jsGrid.fields.select.prototype.editTemplate.call(this, value);

Also for your scenario it would be better to set change handler to the select and call it immediately, like following:

var changeDepartment = function() {
    var selectedDepartment = $editControl.val();
    var departmentTeam = $.grep(team_list, function(team) {
        return team.department === selectedDepartment;
    });

    teamField.items = departmentTeam;
    $(".team-edit").empty().append(teamField.editTemplate());
};

$editControl.on("change", changeDepartment);
changeDepartment();

You updated fiddle http://jsfiddle.net/tabalinas/n982uvx1/16/

var changeDepartment = function() {
    var selectedType = $(".type-edit select").val();
    var selectedDepartment = $editControl.val();
    var departmentTeam = $.grep(team_list, function(team) {
        return (team.department === selectedDepartment) && (team.type === selectedType);
    });

    teamField.items = departmentTeam;
    $(".team-edit").empty().append(teamField.editTemplate());
};

Thanks alot for the help, however how do i access other access columns from the editTemplate?

You can get the field from the grid by index and get it's edit control (grid.fields[0]._editControl.val()) or just find it by selector with jquery.

Hi tabalinas,
First of all thanks for your help. And sorry about my English.
I need the same select with dependency dropdown, its works but some time when you insert new data, or edit or filter some data, you don't see some cell data but when you refresh o change another thing then fix it.
If you try your example http://jsfiddle.net/tabalinas/n982uvx1/16/ it happens sometime.
It is always with select data.
I capture an image where you can see it.
no-data
thanks

The problem is when you have an item with team that is filtered by department, it cannot be found and rendered as empty.
To fix the issue redefine itemTemplate of team field:

itemTemplate: function(team) {
    return team;
},

Here is the fixed issue http://jsfiddle.net/n982uvx1/19/

In more general case we could grep team from entire list of teams (if we would use id, not the team name).

Hi tabalinas,
Thank you for answering so quickly.
In my case the valueField: "id" and the textField: "name", I do what do you say and then when you insert new items then you see the id not the name.

Here is the sample with valueField: "id" http://jsfiddle.net/n982uvx1/20/

valuefieldid

Thank you

Ok, that what I meant by comment "In more general case we could grep team from entire list of teams (if we would use id, not the team name)."

Just modify itemTemplate picking up item by id:

itemTemplate: function(teamId) {
    return $.grep(teams, function(team) {
        return team.id === teamId;
    }[0].name;
},

here teams is an array of all teams (not filtered by department)

Hi tabalinas,
Thank you for answering so quickly.
I do that and there is an error in the console.log: Uncaught TypeError: Cannot read property 'team' of undefined.
You can see here: http://jsfiddle.net/n982uvx1/22/

It's because in the team field you have not id but the name. That's why team just cannot be found.
So whether you should grep by name or store id (not team name)

Ok, now you can see the grid but when you try to edit or insert items there is the same error: Uncaught TypeError: Cannot read property 'team' of undefined. :S
http://jsfiddle.net/n982uvx1/23/

Thank you very much tabalinas!!!

Ok, I fix it. On item "team" I put valueField:"Id" and when you edit or insert items take the id and when load the grid take the team...

Thank you so much!!!

Glad you found the solution. You are welcome!

Hello Tabalinas,
I want to use filtering in this case and I don't know why it's not working with selects.

http://jsfiddle.net/n982uvx1/24/

Thank you

It doesn't work because filtering is not implemented in the loadData of the grid controller. Checkout this answer https://github.com/tabalinas/jsgrid/issues/32

Ok, thanks!!!

I have tried this example to populate States from selected Country dropdown. For some reason on insert, first record gets inserted correctly but second record onwards itemTemplate always receives 1 as function parameter resulting in incorrect state showing up on grid. Edit work fine though as on edit, itemTemplate is getting called only once.

Below is my code;

$("#lodgingJsGrid").jsGrid({
width: "100%",
autosize: true,
inserting: true,
editing: true,
sorting: true,
paging: true,

        data: model.LodgingList,

        fields: [
            { name: "LodgingName", title: "Preferred Hotel", type: "text", width: 100 },
            { name: "CheckInDate", title: "Check-in Date", id: "checkInDate", type: "myDateField", width: 120 },
            { name: "CheckOutDate", title: "Check-out Date", id: "checkOutDate", type: "myDateField", width: 120 },
            {
                name: "CountryId", title: "Country", id:"CountryId", type: "select", items: model.Countries, valueField: "Id", textField: "Name",
                insertTemplate: function() {
                    var stateField = this._grid.fields[4];
                    var $insertControl = jsGrid.fields.select.prototype.insertTemplate.call(this);

                    $insertControl.on("change", function() {
                        var selectedCountryId = $(this).val();
                            $.ajax({
                                type: 'POST',
                                url: "/Main/TravelRequest/GetAllStates",
                                dataType: 'json',
                                data: { countryId: selectedCountryId },
                                success: function (json) {
                                    stateField.items = json;
                                    $(".state-insert").empty().append(stateField.insertTemplate());
                                }
                            });                            
                    });
                    return $insertControl;
                },
                editTemplate: function (value) {
                    var stateField = this._grid.fields[4];
                    var $editControl = jsGrid.fields.select.prototype.editTemplate.call(this, value);

                    var changeCountry = function() {
                        var selectedCountryId = $editControl.val();
                        $.ajax({
                            type: 'POST',
                            url: "/Main/TravelRequest/GetAllStates",
                            dataType: 'json',
                            data: { countryId: selectedCountryId },
                            success: function (json) {
                                stateField.items = json;
                                $(".state-edit").empty().append(stateField.editTemplate());
                            }
                        });                            
                    };

                    $editControl.on("change", changeCountry);
                    changeCountry();

                    return $editControl;
                },
                align: "center"
            },
            {
                name: "StateId", title: "State", type: "select", items: model.States, valueField: "Id", textField: "Name",
                insertcss: "state-insert", editcss: "state-edit",
                itemTemplate: function (StateId) {
                    return $.grep(model.States, function (state) { return state.Id === StateId; })[0].Name
                }
            },
            { name: "CityId", title: "City", type: "select", items: model.Cities, valueField: "Id", textField: "Name" },
            { name: "DailyRate", title: "Per Diem Lodging Rate", type: "text", width: 100 },
            { name: "Meals", title: "Actual Daily Lodging", type: "text", width: 100 },
            { name: "IsExceedPerDiem", title: "Exceed per diem?", type: "checkbox", width: 50, sorting: false },
            { type: "control" }
        ]
    });
Was this page helpful?
0 / 5 - 0 ratings