This is a migrated thread and some comments may be shown as answers.

Data binding with the grid not working in the case of XML datasources

2 Answers 167 Views
MultiSelect
This is a migrated thread and some comments may be shown as answers.
Pascal
Top achievements
Rank 1
Pascal asked on 04 Sep 2013, 09:09 AM
Hello,
we want to use the multiselect in this context:
  • Grid bound to an XML datasource
  • Multiselect bound to an XML datasource
  • Data binding between Grid & multiselect for popup or inline editing
But we can't get the data binding between the grid & the multiselect to work in the case of multiple values.

For instance, when the grid data reads either
<record number="3">
    <nid>3</nid>
    <column1>row3col1</column1>
    <column2>BBBtxt,CCCtxt</column2>
    <mval>BBBval,CCCval</mval>
</record>

or
<record number="4">
            <nid>4</nid>
            <column1>row4col1</column1>
            <column2>BBBtxt,CCCtxt</column2>
            <mval>BBBval</mval>
            <mval>CCCval</mval>
        </record>

The multiselect always remains empty in editing mode, no data binding seems to happen between the grid & the multiselect.

But when the grid data reads:
<record number="2">
            <nid>2</nid>
            <column1>row2col1</column1>
            <column2>AAAtxt</column2>
            <mval>AAAval</mval>
        </record>
Binding between grid & multiselect works.

Could it be that there's something wrong in our datasource or multiselect definition or is there something wrong with the multiselect data binding ?

Here's the code we use:
// JavaScript Document
 
jQuery(document).ready(function() {
 
    // grid
    jQuery("#grid").kendoGrid({
        dataSource: gridDataSource,
        columns: [
            {
                field: "column1",
                title: "Column 1",
                width: "300px"
            },
            {
                field: "column2",
                title: "Column 2",
                editor: multiselect_editor,
                width: "300px"
            },
            {
                command: [
                    {name:"edit",text:{update:"Edit",cancel:"Cancel"}},
                ],
                width:"10%"
            }
        ],
        toolbar: [{name:"create",text:"New"}],
        editable: {mode:"popup"},
        sortable: true,
        pageable: true,
        resizable: true
    });
})
 
//grid datasource
var gridDataSource = new kendo.data.DataSource({
    type: "xml",
    transport: {
        read: function (options) {
                jQuery.ajax( {
                    url: "data/griddata.asp",
                    type: "POST",
                    cache: false,
                    success: function(result) { options.success(result); },
                    error: function(e) { alert(e.responseText); },
                    data: {
                        startrow: ((options.data.pageSize*(options.data.page-1))+1),
                        maxrows: 50
                    }
                });
        },
        update: function (options) {
                alert("updated");
        },
        create: function (options) {
                alert("created");
        }
    },
    schema: {
        type: "xml",
        data: "/root/resultset/record/",
        model: {
            id: "nid",
            fields: {
                nid: "nid/text()",
                column1: "column1/text()",
                mval: "mval/text()",
                column2: "column2/text()"
            }
        },
        total: "/root/resultset/@size"
    },
    error: function(e) {
        alert(e.xhr.responseText);
    },
    serverFiltering: true,
    serverPaging: true,
    serverSorting: true,
    pageSize: 50
})
 
// multiselect for popup editor
function multiselect_editor (container, options) {
    jQuery('<select multiple="multiple" id="multiselect_editor" data-text-field="textnode" data-value-field="valuenode" data-bind="value:mval"/>')
    .appendTo(container)
    .kendoMultiSelect ({
        placeholder: "Select...",
        autoBind: true,
        dataTextField: "textnode",
        dataValueField: "valuenode",
        dataSource: {
            type: "xml",
            serverFiltering: true,
            sort: { field: "textnode", dir: "asc" },
            transport: {
                read: { type: "POST", cache: false, url:"data/multiselectdata.asp"},
            },
            schema: {
                type: "xml",
                data: "/root/resultset/record",
                model: {
                    fields: {
                        textnode: "textnode/text()",
                        valuenode: "valuenode/text()"
                    }
                }
            }
            ,error: function(e) {
                alert(e.xhr.responseText);
            }
        }
    });
}

And the data samples:
  • Grid data
<?xml version="1.0" encoding="utf-8"?>
<root>
    <resultset date="03/09/2013" size="3" time="10:13:50">
        <record number="1">
            <nid>1</nid>
            <column1>row1col1</column1>
            <column2></column2>
            <mval></mval>
        </record>
        <record number="2">
            <nid>2</nid>
            <column1>row2col1</column1>
            <column2>AAAtxt</column2>
            <mval>AAAval</mval><!-- Works for multi select data binding (to set 1 selected item in the multiselect in the editor) -->
        </record>
        <record number="3">
            <nid>3</nid>
            <column1>row3col1</column1>
            <column2>BBBtxt,CCCtxt</column2>
            <mval>BBBval,CCCval</mval><!-- Does not work for multiselect data binding (to set 2 selected items in the multiselect in the editor) -->
        </record>
        <record number="4">
            <nid>4</nid>
            <column1>row4col1</column1>
            <column2>BBBtxt,CCCtxt</column2>
            <mval>BBBval</mval><!-- Does not work for multiselect data binding (to set 2 selected items in the multiselect in the editor) -->
            <mval>CCCval</mval>
        </record>
    </resultset>
</root>

  • Multiselect data
<?xml version="1.0" encoding="utf-8"?>
<root>
    <resultset date="03/09/2013" size="5" time="10:13:50">
        <record number="1">
            <nid>1</nid>
            <valuenode>AAAval</valuenode>
            <textnode>AAAtxt</textnode>
        </record>
        <record number="2">
            <nid>2</nid>
            <valuenode>BBBval</valuenode>
            <textnode>BBBtxt</textnode>
        </record>
        <record number="3">
            <nid>3</nid>
            <valuenode>CCCval</valuenode>
            <textnode>CCCtxt</textnode>
        </record>
        <record number="4">
            <nid>4</nid>
            <valuenode>DDDval</valuenode>
            <textnode>DDDtxt</textnode>
        </record>
    </resultset>
</root>


2 Answers, 1 is accepted

Sort by
0
Accepted
Alexander Valchev
Telerik team
answered on 06 Sep 2013, 11:23 AM
Hello Pascal,

Your current implementation does not work due to a few reasons:

1. Multiselect should be bound to array of values. In your current case, column2 contains a string which is not automatically parsed into array. In other words instead of having coulmn2: "BBBtxt,CCCtxt" in the DataSource, you should have column2: ["BBBtxt", "CCCtxt"].

Here's how you could do the transformation:
fields: {
    nid: "nid/text()",
    column1: "column1/text()",
    mval: "mval/text()",
    column2: {
        field: "column2/text()", //define the XML field
        parse: function(data) { //define a custom parse function
            if(data) { return data.split(","); } //split the data into array of strings
        }
    }
}


2. The multiselect should be bound to the field which contains values array. In our case that is column2.
jQuery('<select multiple="multiple" id="multiselect_editor" data-text-field="textnode" data-value-field="valuenode" data-bind="value:column2"/>')

(As a general information) The following data structure is not supported:
<record number="4">
    <nid>4</nid>
    <column1>row4col1</column1>
    <column2>BBBtxt,CCCtxt</column2>
    <mval>BBBval</mval>
    <mval>CCCval</mval>
</record>


3. The values in column2 array should correspond to the multiselect's value field (in your current implementation they correspond to the dataTextField). For the purpose of this sample I just switched the fields configuration:
jQuery('<select multiple="multiple" id="multiselect_editor" data-text-field="valuenode" data-value-field="textnode" data-bind="value:column2"/>')


4. Since by default the DataSource works with key-value pairs you will have to use column template to display column2 value in the Grid.
template: "#= column2 ? column2.toJSON() : ' ' #",

Note the usage of toJSON() method - as soon as the data is loaded in the Grid, columns2 will be transformed into ObservableArray, so the standard toString() method will not work.
The ternary operator is used to avoid JavaScript errors which occurs in case column2 has no value. In our case, that is when the 1st row is being rendered.

I hope this information will help.

Regards,
Alexander Valchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Pascal
Top achievements
Rank 1
answered on 11 Sep 2013, 12:19 PM
It helped a lot.

Thank you !
Tags
MultiSelect
Asked by
Pascal
Top achievements
Rank 1
Answers by
Alexander Valchev
Telerik team
Pascal
Top achievements
Rank 1
Share this question
or