Select correct element in DDL while using virtual

0 Answers 64 Views
DropDownList
Sterling
Top achievements
Rank 2
Iron
Sterling asked on 28 Nov 2022, 01:14 PM | edited on 30 Nov 2022, 05:31 AM

Hi,

 

I have a DDL that gets its first value from a grid ("myValue"), a simple string that will be written to the DDL (same JSON format that the DDL is expecting

{

field1: "myValue",

field2: ""

}

). When the DDL is opened, the value I entered ("myValue") should be searched in the data source of the DDL and this value should be put into focus. In the end the JSON looks like this:

{

field1: "myValue",

field2: "describtion of myValue"

}

The DDL datasource has to compare the value from field1 ("myValue), if it matches it has to select it,

As long as I don't use virtual this works, but as soon as I use virtual it doesn't work anymore.
How can I achieve that the value from the grid is written into the DDL and the DDL then sets the correct data set into the focus?

Thanks in advance.

Neli
Telerik team
commented on 01 Dec 2022, 12:18 PM

Hi Sterling,

Could you please provide a little bit more details about the implementation on your side?

In the Dojo linked here, there is a virtualized DropDownList in the Grid column. However, if I try to search for an item (even if the item is not on the first page), the item gets correctly focused.

Please let me know if I am missing something.

Regards,

Neli

Sterling
Top achievements
Rank 2
Iron
commented on 02 Dec 2022, 11:49 AM


<div id="example">
        <div id="grid"></div>
    </div>
    <br>
    <br>
    <br>
  <div id="container">
    <input id="dropdownlist" style="width:300px" />
  </div>


  <script id="templateDDL" type="text/x-kendo-template">
    <span>
      <table>
        <tr class="combo-tr">
            <td class="combo-td">${band}</td>
            <td class="combo-td">${song}</td>
        </tr>
    </table>
    </span>
  </script>


<script>
    var dataForGrid = [
        { id: 1, band: "Iron Maiden", song: "Wasted Years", album: "Ed Hunter", members: "Bruce Dickinson, Steve Harris and more" },
		{ id: 2, band: "Metallica", song: "Enter Sandman", album: "Metallica", members: "James Headfield, Lars Ulrich and more" },
		{ id: 3, band: "Mr. Big", song: "Seven Impossible Days", album: "Japandemonium", members: "Eric Martin, Paul Gilber and more" },
		{ id: 4, band: "Rammstein", song: "Zick Zack", album: "Zeit", members: "Till Lindemann, Paul Landers and more" },
        { id: 5, band: "Motörhead", song: "Ace of Spades", album: "Ace of Spades", members: "Lemy Kilmister, Eddie Clark and more" },
		{ id: 6, band: "Mötley Crüe", song: "Kickstart my Heart", album: "Dr. Feelgood", members: "Tommy Lee, Nikki Sixx and more" },
		{ id: 7, band: "AC/DC", song: "Highway to Hell", album: "Highway to Hell", members: "Angus Young, Dave Evans and more" },
		{ id: 8, band: "Led Zeppelin", song: "Stairway to Heaven", album: "Led Zeppelin IV", members: "Robert Plant, Jimmy Page and more" },
        { id: 9, band: "Black Sabbath", song: "Paranoid", album: "Paranoid", members: "Ozzy Osbourne, Ronnie James and more" },
		{ id: 10, band: "Guns n' Roses", song: "Knockin' on Heaven's Door", album: "Use your Illusion", members: "Axel Rose, Slash and more" },
    ];

    var dataForDDL = [
		{ id: 1, band: "Iron Maiden", song: "Wasted Years" },
		{ id: 2, band: "Metallica", song: "Enter Sandman" },
		{ id: 3, band: "Mr. Big", song: "Seven Impossible Days" },
		{ id: 4, band: "Rammstein", song: "Zick Zack" },
        { id: 5, band: "Motörhead", song: "Ace of Spades" },
		{ id: 6, band: "Mötley Crüe", song: "Kickstart my Heart" },
		{ id: 7, band: "AC/DC", song: "Highway to Hell" },
		{ id: 8, band: "Led Zeppelin", song: "Stairway to Heaven" },
        { id: 9, band: "Black Sabbath", song: "Paranoid" },
		{ id: 10, band: "Guns n' Roses", song: "Knockin' on Heaven's Door" },
	];
    
    $(document).ready(function(){
        $("#grid").kendoGrid({
            dataSource: {
                data: dataForGrid,
                schema: {
                    model: {
                        fields: {
                            band: { type: "string" },
                            song: { type: "string" },
                            album: { type: "string" },
                            members: { type: "string" }
                        }
                    }
                },
                pageSize: 5
            },
            height: 300,
            sortable: true,
            filterable: true,
            selectable: true,
            pageable: {
                previousNext:   true,    
                numeric:        true,
                buttonCount: 3,
            },
            columns: [
                { field: "band", title: "Band", width: "130px" },
                { field: "song", title: "Song", width: "130px" },
                { field: "album", title: "Album", width: "130px" },
                { field: "members", title: "Members", width: "130px" }
            ],
            filterable: false,
            scrollable: {
                virtual: false
            },
            change:function(e) {
                const selectedRows = this.select(),
                    dataItem = this.dataItem(selectedRows[0]);
                    grid_dataItem = dataItem;
                    e.sender._selectedIds = {};
                    e.sender._selectedIds[dataItem.song] = true;                    
            },
            dataBound: function(e) {
                this.select("tr:eq(0)");
                this.content.scrollTop(0);
            }
        });

        $("#dropdownlist").kendoDropDownList({
            optionLabel: "-- Please select something --",
            width:300,
            size:"small",
            dataSource: dataForDDL,
            dataTextField: "band",
            dataValueField: "id", 
            headerTemplate: `<table>
                                <tr class="combo-tr">
                                <td class="combo-hd-td">Band</td>
                                <td class="combo-hd-td">Song</td>
                                </tr>
                            </table>`,
            template: kendo.template($("#templateDDL").html()), 
            virtual: {
                itemHeight: 50,
                valueMapper: function(options) {
                    $.ajax({
                        dataSource: dataForDDL,
                        type: "GET",
                        dataType: "json",
                        data: convertValues(options.value),
                        success: function (data) {
                            options.success(data);
                        }
                    })
                }
            },
            change: function(e) {
                const value = this.value(); 
                console.log("value:", value);
                e.sender.select(function(dataItem){
                   // I have called change from SetDdlValue()
                   // You can see the value when you open the DDL and at the console
                   // How can I achieve that the value is displayed in the DDL?
                   // How can I achieve that the value is found, when I open the DDL, and gets selected?
                   // The DDL has to be updated when I select a new element at the grid 
                })
            }
        }).data('kendoDropDownList');

        function convertValues(value) {
            let data = {};
            value = $.isArray(value) ? value : [value];

            for (let idx = 0; idx < value.length; idx++) {
                data["values[" + idx + "]"] = value[idx];
            }
            return data;
        }    

        const grid = $("#grid").data("kendoGrid");
        const selectedItem = grid.dataItem(grid.select());
            
        const ddl_element = $("#dropdownlist").data("kendoDropDownList"); 
        SetDdlValue(ddl_element, false, 2, selectedItem.band, "");
        

        function SetDdlValue(ddl_element, ddl_loaded, ddl_spalten, ddl_value, ddl_besch) {
            if (ddl_value == "") {
                ddl_value = ddl_element.optionLabel[0].innerText;
            }
            if (ddl_loaded == true) {
                ddl_element.value(ddl_value);
                ddl_element.trigger("change");
            }
            else{       
                let TempDDS = [];
                let TempJson = {"band":ddl_value,"song":ddl_besch};
                TempDDS.push(TempJson);
                ddl_element.setDataSource(TempDDS);
                ddl_element.value(ddl_value);
                ddl_element.trigger("change");
            }
        }
    });
</script>


<style>
	 
  .combo-td{
    width:150px;
  }
   
  .combo-hd-td{
    width:150px;
    font-weight: bold;
    color: #f00;
  } 
</style>

Hi Neli, thanks for the dojo.

In my code you can see where my problem is. When I call "change", in the DDL, from SetDdLValue() it is unclear to me how I can display the value in the DDL and it will be searched and selected when I open the DDL (do I have to implement open and get a new DataSource?). Furthermore, the DDL must also always update itself when selecting a new element in the grid. 

Hope this explains my problem better and thank you for your help.

Sterling

Neli
Telerik team
commented on 07 Dec 2022, 11:09 AM

Hi Sterling,

Thank you for providing a runnable example.

The value in the DropDownList has not being set as you were trying to use a string 'Iron Maiden' in the value method. As in the DropDownList configuration the dataValueField has been configured to use the 'id' field, you need to use the respective id in the value method.

I changed the implementation a little bit:

- as far as I see the ddl_spalten is not used, so I removed it from the parameteres.

- I modified the TempJson as follows:

let TempJson = {"band":ddl_besch,"song":ddl_besch, 'id': ddl_value};

In the example above the ddl_value is set to the id field, and the ddl_besch that contains the text is used for the 'band'

Linked here you will find a Dojo example based on the provided infromation where the DropDownList is populated as expected.

I hope you will find it helpful.

Regards,

Neli

Sterling
Top achievements
Rank 2
Iron
commented on 09 Dec 2022, 11:41 AM | edited

Hi Neli,

thanks for the updated Dojo, I appreciate it. Just figured out what my mistake was. Here's the code if someone else has the same problem.

 


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kendo UI Snippet</title>

    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2022.3.1109/styles/kendo.default-ocean-blue.min.css">
    
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="https://kendo.cdn.telerik.com/2022.3.1109/js/jszip.min.js"></script>
    <script src="https://kendo.cdn.telerik.com/2022.3.1109/js/kendo.all.min.js"></script>
</head>
<body>

    <div id="example">
        <div id="grid"></div>
    </div>
    <br>
    <br>
    <br>
  <div id="container">
    <input id="dropdownlist" style="width:300px" />
  </div>


  <script id="templateDDL" type="text/x-kendo-template">
    <span>
      <table>
        <tr class="combo-tr">
            <td class="combo-td">${band}</td>
            <td class="combo-td">${song}</td>
        </tr>
    </table>
    </span>
  </script>


<script>
    var dataForGrid = [
        { id: 1, band: "Iron Maiden", song: "Wasted Years", album: "Ed Hunter", members: "Bruce Dickinson, Steve Harris and more" },
{ id: 2, band: "Metallica", song: "Enter Sandman", album: "Metallica", members: "James Headfield, Lars Ulrich and more" },
{ id: 3, band: "Mr. Big", song: "Seven Impossible Days", album: "Japandemonium", members: "Eric Martin, Paul Gilber and more" },
{ id: 4, band: "Rammstein", song: "Zick Zack", album: "Zeit", members: "Till Lindemann, Paul Landers and more" },
        { id: 5, band: "Motörhead", song: "Ace of Spades", album: "Ace of Spades", members: "Lemy Kilmister, Eddie Clark and more" },
{ id: 6, band: "Mötley Crüe", song: "Kickstart my Heart", album: "Dr. Feelgood", members: "Tommy Lee, Nikki Sixx and more" },
{ id: 7, band: "AC/DC", song: "Highway to Hell", album: "Highway to Hell", members: "Angus Young, Dave Evans and more" },
{ id: 8, band: "Led Zeppelin", song: "Stairway to Heaven", album: "Led Zeppelin IV", members: "Robert Plant, Jimmy Page and more" },
        { id: 9, band: "Black Sabbath", song: "Paranoid", album: "Paranoid", members: "Ozzy Osbourne, Ronnie James and more" },
{ id: 10, band: "Guns n' Roses", song: "Knockin' on Heaven's Door", album: "Use your Illusion", members: "Axel Rose, Slash and more" },
    ];

    var dataForDDL = [
{ id: 1, band: "Iron Maiden", song: "Wasted Years" },
{ id: 2, band: "Metallica", song: "Enter Sandman" },
{ id: 3, band: "Mr. Big", song: "Seven Impossible Days" },
{ id: 4, band: "Rammstein", song: "Zick Zack" },
        { id: 5, band: "Motörhead", song: "Ace of Spades" },
{ id: 6, band: "Mötley Crüe", song: "Kickstart my Heart" },
{ id: 7, band: "AC/DC", song: "Highway to Hell" },
{ id: 8, band: "Led Zeppelin", song: "Stairway to Heaven" },
        { id: 9, band: "Black Sabbath", song: "Paranoid" },
{ id: 10, band: "Guns n' Roses", song: "Knockin' on Heaven's Door" },
];

    $(document).ready(function(){
        $("#grid").kendoGrid({
            dataSource: {
                data: dataForGrid,
                schema: {
                    model: {
                        fields: {
                            id: {type: "integer"},
                            band: { type: "string" },
                            song: { type: "string" },
                            album: { type: "string" },
                            members: { type: "string" }
                        }
                    }
                },
                pageSize: 25,
                serverPaging: true,
            },
            height: 600,
            sortable: true,
            filterable: true,
            selectable: true,
            pageable: {
                previousNext:   true,    
                numeric:        true,
                buttonCount: 3,
            },
            columns: [
                { field: "id", title: "ID", width: "130px" },    
                { field: "band", title: "Band", width: "130px" },
                { field: "song", title: "Song", width: "130px" },
                { field: "album", title: "Album", width: "130px" },
                { field: "members", title: "Members", width: "130px" }
            ],
            filterable: false,
            scrollable: {
                virtual: false
            },
            change: function(e) {
                const selectedRows = this.select(),
                    dataItem = this.dataItem(selectedRows[0]);
                    grid_dataItem = dataItem;
                    e.sender._selectedIds = {};
                    e.sender._selectedIds[dataItem.song] = true;  
                    changeDdl();                  
            },
            dataBound: function(e) {
                this.select("tr:eq(0)");
                this.content.scrollTop(0);
            }
        });

        $("#dropdownlist").kendoDropDownList({
            optionLabel: "-- Please select something --",
            width:300,
            size:"small",
            dataSource: dataForDDL,
            dataTextField: "band",
            dataValueField: "band",
            template: kendo.template($("#templateDDL").html()), 
            virtual: {
                itemHeight: 50,
                valueMapper: function(options) {
                    $.ajax({
                        dataSource: dataForDDL,
                        type: "GET",
                        dataType: "json",
                        data: convertValues(options.value),
                        success: function (data) {
                            options.success(data);
                        }
                    })
                }
            },
            open: function(e){
                const ddl_element = $("#dropdownlist").data("kendoDropDownList");
                // read the current value of ddl (startValue), comes from SetDdlValue
                let startValue = ddl_element.text();

                // load a new dataSource
                const ds = new kendo.data.DataSource({                                
                    data: dataForDDL
                });
                    
                ddl_element.setDataSource(ds);

                // looking for startValue in ddl-dataSource
                let itemEqualToStartValue = ddl_element.dataSource.view().find(x=>x.band === startValue);
                console.log(itemEqualToStartValue.band);
                
                // select item of ddl-dataSource, that is equal to the startValue
                ddl_element.select(itemEqualToStartValue);
                ddl_element.trigger("change");
            }
        }).data('kendoDropDownList');

        
        // set the initial DDL value 
        const grid = $("#grid").data("kendoGrid");
        const selectedItem = grid.dataItem(grid.select());
        
        const ddl_element = $("#dropdownlist").data("kendoDropDownList"); 
        SetDdlValue(ddl_element, false, 2, selectedItem.band, "");
        
        function convertValues(value) {
            let data = {};
            value = $.isArray(value) ? value : [value];

            for (let idx = 0; idx < value.length; idx++) {
                data["values[" + idx + "]"] = value[idx];
            }
            return data;
        }
          
        // gets called if change in grid is called
        function changeDdl(){
            const grid = $("#grid").data("kendoGrid");
            const selectedItem = grid.dataItem(grid.select());
            
            const ddl_element = $("#dropdownlist").data("kendoDropDownList"); 
            SetDdlValue(ddl_element, false, 2, selectedItem.band, "");
        }        

        function SetDdlValue(ddl_element, ddl_loaded, ddl_value, ddl_besch) {
            if (ddl_value == "") {
                ddl_value = ddl_element.optionLabel[0].innerText;
            }
            if (ddl_loaded == true) {
                ddl_element.value(ddl_value);
                ddl_element.trigger("change");
            }
            else{       
                let TempDDS = [];
                let TempJson = {"id": ddl_value, "band":ddl_besch, "song":ddl_besch};
                TempDDS.push(TempJson);
                ddl_element.setDataSource(TempDDS);
                ddl_element.value(ddl_besch);
                ddl_element.trigger("change");
            }
        }
    });
</script>

<style>  
  .combo-td{
    width:150px;
  }
   
  .combo-hd-td{
    width:150px;
    font-weight: bold;
    color: #f00;
  } 
</style>

</body>
</html>

Neli
Telerik team
commented on 13 Dec 2022, 02:13 PM

Hi Sterling, 

Thank you very much for posting the solution in your scenario. I am sure that the provided code will be helpful for the other users in the Forum.

Regards,

Neli

No answers yet. Maybe you can help?

Tags
DropDownList
Asked by
Sterling
Top achievements
Rank 2
Iron
Share this question
or