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

3 posts, 1 answers
  1. Pascal
    Pascal avatar
    2 posts
    Member since:
    Dec 2012

    Posted 04 Sep 2013 Link to this post

    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. Answer
    Alexander Valchev
    Admin
    Alexander Valchev avatar
    2875 posts

    Posted 06 Sep 2013 Link to this post

    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!
  3. Kendo UI is VS 2017 Ready
  4. Pascal
    Pascal avatar
    2 posts
    Member since:
    Dec 2012

    Posted 11 Sep 2013 Link to this post

    It helped a lot.

    Thank you !
Back to Top