We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Multi-select DropDownList in Grid

Hi,

I have been following https://www.syncfusion.com/kb/4809/how-to-set-the-multi-select-dropdown-as-edit-type-for-a-column to get a multi-select drop down list inside a grid.  (the grid is of type "batch").

I have it working as described in the article and I even get a list of the text back for the multi select items in the batch update method in the controller.

However, I would like it to display the text in the grid but I would like to pass back the values (number(s), not the text) back to the controller.  It would be a lot easier if I had the numbers in the controller for updating my child table.  (I could get it to work the way it is but then I would have to find the Id value for each item and what if the text in the options had duplicates...)

Is this doable?  How could you do it?

Thanks,
Chris

5 Replies

VN Vignesh Natarajan Syncfusion Team November 29, 2018 06:37 PM UTC

Hi Chris, 
 
Thanks for using Syncfusion products. 
 
Query: “I would like it to display the text in the grid but I would like to pass back the values (number(s), not the text) back to the controller” 
 
From your query, we understand that you need to render multiselect dropdownlist with text and value pair.  We have achieved your requirement using query-cell-info event and edit-template feature of ejGrid. 
 
Refer the below code example 
 
<ej-grid id="FlatGrid" allow-paging="true" datasource="ViewBag.DataSource" query-cell-info="cellinfo" > 
    <e-edit-settings allow-adding="true" allow-editing="true" allow-deleting="true"></e-edit-settings> 
    <e-toolbar-settings show-toolbar="true" toolbar-items='@new List<string> {"add","edit","update","cancel"}' /> 
    <e-columns> 
        <e-column field="OrderID" is-primary-key="true" header-text="Order ID"></e-column> 
        <e-column field="CustomerID" header-text="CustomerID"></e-column>        
        <e-column field="EmployeeID" datasource="ViewBag.DDl" header-text="Freight"> 
            <e-edit-template create="create" read="read" write="write">    </e-edit-template> 
        </e-column> 
 
 
    </e-columns> 
</ej-grid> 
<script type="text/javascript"> 
    var dropData = @Html.Raw(Json.Serialize(ViewBag.DDl));  // to retrieve the data from server 
    function cellinfo(args) {  
        var data = []; 
        if (args.column.field == "EmployeeID") { 
            for (i = 0; i < args.rowData.EmployeeID.length; i++) 
                for (j = 0; j < dropData.length; j++) { 
                    if (args.rowData.EmployeeID[i] == dropData[j].EmployeeID) { 
                        data.push(dropData[j].CustomerID); 
                        break; 
                    } 
                } 
            args.cell.innerHTML = data.join(","); //assign the value to cell  
        } 
    }    
    function create(args) { 
        return "<input>"; 
    } 
    function read(args) { 
        var selvalue = []; 
        var selected = args.ejDropDownList("getSelectedValue").split(","); 
        for (i = 0; i < selected.length; i++) 
            for (j = 0; j < dropData.length; j++) { 
                if (selected[i] == dropData[j].CustomerID) { 
                    selvalue.push(dropData[j].EmployeeID); 
                    break; 
                } 
            } 
        return selvalue; 
    } 
    function write(args) { 
        var selIndex = []; 
        if (args.rowdata != undefined) 
        { 
            for (i = 0; i < args.rowdata["EmployeeID"].length; i++) 
            for (j = 0; j < dropData.length; j++){ 
                if (args.rowdata["EmployeeID"][i] == dropData[j].EmployeeID) { 
                    selIndex.push(j); 
                    break; 
                } 
            } 
        } 
        args.element.ejDropDownList({ width: "100%", dataSource: dropData, fields: { id: "EmployeeID", text: "CustomerID", value: "value" }, showCheckbox: true, allowMultiSelection: true, selectedItems: args.rowdata !== undefined ? selIndex : "" }); 
    } 
</script> 
 
 
 
Refer the below screenshots for output 
 
1. While editing 
 
 
 
2. While saving the saving the data 
 
 
 
 
For your convenience we have prepared a sample which can be downloaded from below link 
 
Refer our help documentation for your reference 
 
 
 
Query2: “I could get it to work the way it is but then I would have to find the Id value for each item and what if the text in the options had duplicates...)” 
 
From your query, we understand that you need to know what will happen when dropdownlist has multiple text related to single value. Dropdownlist cannot have duplicate value while having text and value pair dataSource. Because only text is visible to user, he will not able to see the value. So single value cannot have multiple text.   
 
If we misunderstood your query, please get back to us with more details. 
 
 
Regards, 
Vignesh Natarajan 



CH Chris November 29, 2018 09:20 PM UTC

Hi,

Thanks for the reply.  My grid is in "Batch" mode.  QueryCellInfo doesn't fire after selecting items in the drop down. My edit settings look like:

<e-edit-settings allow-editing="true" allow-adding="true" allow-deleting="true" edit-mode="@(EditMode.Batch)" show-confirm-dialog="false" show-delete-confirm-dialog="true" />

If you add edit-mode="@(EditMode.Batch)" to edit settings in the sample you sent me you can see what I mean.  On the initial load it looks good but if you change the selected items in one of the drop downs it displays the numerical values.

How would I do it when it is in batch mode?

Don't worry about Query 2.

Thanks,
Chris


VN Vignesh Natarajan Syncfusion Team November 30, 2018 10:39 AM UTC

Hi Chris, 
 
Sorry for the inconvenience caused. 
 
From your query we understand that you need to render the multiselect dropdown list with text and value in ejGrid while using batch editing. We have modified the previously provided solution by using cellSave, beforeBatchSave  event and setCellValue method of ejGrid. refer the below code example 
 
<ej-grid id="FlatGrid" allow-paging="true" datasource="ViewBag.DataSource" query-cell-info="cellinfo" cell-save="onSave" before-batch-save="beforeSave" > 
    <e-edit-settings allow-adding="true" allow-editing="true" allow-deleting="true" edit-mode="Batch"></e-edit-settings> 
    <e-toolbar-settings show-toolbar="true" toolbar-items='@new List<string> {"add","edit","update","cancel"}' /> 
    <e-columns> 
        <e-column field="OrderID" is-primary-key="true" header-text="Order ID"></e-column> 
        <e-column field="CustomerID" header-text="CustomerID"></e-column>        
        <e-column field="EmployeeID" datasource="ViewBag.DDl" header-text="Freight"> 
            <e-edit-template create="create" read="read" write="write">    </e-edit-template> 
        </e-column> 
 
 
    </e-columns> 
</ej-grid> 
<script type="text/javascript"> 
    var dropData = @Html.Raw(Json.Serialize(ViewBag.DDl));  // to retrieve the data from server 
    var editedData; 
    function onSave(args) { // to display the value after selecting the value. 
        if (args.columnName == "EmployeeID") { 
            var data = []; 
            for (i = 0; i < args.value.length; i++) 
                for (j = 0; j < dropData.length; j++) { 
                    if (args.value[i] == dropData[j].EmployeeID) { 
                        data.push(dropData[j].CustomerID); 
                        break; 
                    } 
                } 
            editedData = data.join(",");  
            setTimeout(function () { 
                var grid = $("#FlatGrid").ejGrid("instance");               
                grid.setCellValue(grid.getSelectedRows().index(),"EmployeeID",editedData); // to display the text instead of value after saving the value  
            },0) 
        } 
    } 
    function beforeSave(args) {       // to change the value from text to interger while saving the changes in dataSource. 
        if (args.batchChanges.changed.length) { 
            for (var k = 0; k < args.batchChanges.changed.length; k++) { 
                if (!(typeof args.batchChanges.changed[k].EmployeeID[0] == "number")) { 
                    var data = []; 
                    for (i = 0; i < args.batchChanges.changed[k].EmployeeID.split(",").length; i++) 
                        for (j = 0; j < dropData.length; j++) { 
                            if (args.batchChanges.changed[k].EmployeeID.split(",")[i] == dropData[j].CustomerID) { 
                                data.push(dropData[j].EmployeeID); 
                                break; 
                            } 
                        } 
                    args.batchChanges.changed[k].EmployeeID = data.join(",") 
                } 
 
            } 
 
        } 
 
    } 
    // to modify the value during intial rendering 
    function cellinfo(args) {  
        var data = []; 
        if (args.column.field == "EmployeeID") { 
            for (i = 0; i < args.rowData.EmployeeID.length; i++) 
                for (j = 0; j < dropData.length; j++) { 
                    if (args.rowData.EmployeeID[i] == dropData[j].EmployeeID) { 
                        data.push(dropData[j].CustomerID); 
                        break; 
                    } 
                } 
            args.cell.innerHTML = data.join(","); // return the selected value from dropdownlist  
        } 
    }    
    function create(args) { 
        return "<input>"; 
    } 
    function read(args) { 
        var selvalue = []; 
        var selected = args.ejDropDownList("getSelectedValue").split(","); 
        for (i = 0; i < selected.length; i++) 
            for (j = 0; j < dropData.length; j++) { 
                if (selected[i] == dropData[j].CustomerID) { 
                    selvalue.push(dropData[j].EmployeeID); 
                    break; 
                } 
            } 
        return selvalue; 
    } 
    function write(args) { 
        var selIndex = []; 
        if (args.rowdata != undefined && typeof args.rowdata.EmployeeID[0] == "number") {   
            for (i = 0; i < args.rowdata["EmployeeID"].length; i++) 
                for (j = 0; j < dropData.length; j++) { 
                    if (args.rowdata["EmployeeID"][i] == dropData[j].EmployeeID) { 
                        selIndex.push(j); 
                        break; 
                    } 
                } 
        } 
        else if (typeof args.rowdata.EmployeeID.split(",")[0] == "string") { // for second time editng changes without saving it. 
            for (i = 0; i < args.rowdata["EmployeeID"].length; i++) 
                for (j = 0; j < dropData.length; j++) { 
                    if (args.rowdata["EmployeeID"].split(",")[i] == dropData[j].CustomerID) { 
                        selIndex.push(j); 
                        break; 
                    } 
                } 
        } 
        args.element.ejDropDownList({ width: "100%", dataSource: dropData, fields: { id: "EmployeeID", text: "CustomerID", value: "value" }, showCheckbox: true, allowMultiSelection: true, selectedItems: args.rowdata !== undefined ? selIndex : "" }); 
    } 
</script> 
 
Refer the below link for the modified sample.  
 
 
Refer our help documentation for your reference 
 
 
 
 
 
Please get back to us if you have further queries. 
    
 
Regards, 
Vignesh Natarajan 



CH Chris November 30, 2018 05:10 PM UTC

Thanks for you help.  I just got handed a new urgent project, so I will have to leave this alone until January.

I did get to work on it a little this morning and I think it will work.  I'm not fully finished but it looks like I found a way to simplify it a bit.  I figured out a way to display it the text yet have the actual numerical data get sent to the controller.

Here is what I came up with for the read and cellsave methods:

    function read(args) {

        var selValues = args.ejDropDownList("getSelectedValue").split(",");
        if (selValues.length == 1) {
            if (selValues[0] == "") {
                selValues = null;
            }
        }

        return selValues;
    }

    function onCellSave(args) {
        if (args.columnName == "thecolumnname") {
            var ddl = $("#Gridnamethecolumnname").data("ejDropDownList");
            var textVal = ddl.getValue();

            setTimeout(function () {
                // this doesn't change the actual values of the cell, just the text
                args.cell[0].innerText = textVal;
            }, 0)

        }
    }

Thanks for your help!
Chris


VN Vignesh Natarajan Syncfusion Team December 3, 2018 11:38 AM UTC

Hi Chris, 

Thank for the update. 

We will wait till your project get over and will be happy to assist you. 

Regards, 
Vignesh Natarajan 


Loader.
Live Chat Icon For mobile
Up arrow icon