jQuery UI Widgets Forums Grid DropDownList in Grid does not update Knockout model properly

This topic contains 1 reply, has 2 voices, and was last updated by  Peter Stoev 13 years, 6 months ago.

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author

  • gfhe
    Member

    Continuing my evaluation of grids I’m trying to get a jqxGrid with a dropdownlist column working against the underlying Knockout viewmodel but I’m missing something.

    I\’m working of the gridkeyvaluecolumn sample.

    There’s two issues.
    1) The drop down list shows only the companies already listed in the grid, not all the companies in the company data source. I’ll get back to that later unless someone have a quick fix for me 🙂

    2) The Knockout view model is not updated properly. The “cellendedit” event fires and shows the proper oldvalue and new value. However, when exiting edit mode for the cell (by tabbing out or clicking outside the cell) the old value is put into the cell again.

    Also, the CompanyID field in the datamodel is set to “0”. I was expecting it to be set to the value of the selected company.

    What part am I missing here?

    My relevant code is below:

    <h3>People sample</h3>
    <div id="jqxGrid"></div>
    <table>
    <thead>
    <tr><th>First name</th><th>Last name</th></tr>
    </thead>
    <tbody data-bind="foreach: people">
    <tr>
    <td data-bind="text: Firstname"></td>
    <td data-bind="text: Lastname"></td>
    <td data-bind="text: Active"></td>
    <td data-bind="text: DateOfBirth"></td>
    <td data-bind="text: Company.Id"></td>
    <td data-bind="text: Company.Name"></td>
    <td data-bind="text: CompanyId"></td>
    <td data-bind="text: CompanyName"></td>
    </tr>
    </tbody>
    </table>
    <div id="eventLog"></div>
    <script type="text/javascript">
    $(function () {
    var people = [{ "Id": 1, "DateOfBirth": "1971-07-08T10:47:08+02:00", "Active": true, "Firstname": "Hadley", "Lastname": "Calhoun", "NumberOfKids": 7, "City": "Shelton", "CompanyName": "Finale", "CompanyId": 6, "Company": { "Id": 6, "Name": "Finale" } }, { "Id": 2, "DateOfBirth": "1965-10-03T15:08:20+02:00", "Active": false, "Firstname": "Emma", "Lastname": "Joyce", "NumberOfKids": 8, "City": "Port Jervis", "CompanyName": "Yahoo", "CompanyId": 13, "Company": { "Id": 13, "Name": "Yahoo" } }, { "Id": 3, "DateOfBirth": "1959-05-04T20:38:06+02:00", "Active": false, "Firstname": "Jerry", "Lastname": "Kerr", "NumberOfKids": 6, "City": "Hoboken", "CompanyName": "Apple Systems", "CompanyId": 2, "Company": { "Id": 2, "Name": "Apple Systems" } }, { "Id": 4, "DateOfBirth": "1976-10-12T11:01:31+02:00", "Active": true, "Firstname": "Nasim", "Lastname": "Shaw", "NumberOfKids": 6, "City": "Kenosha", "CompanyName": "Chami", "CompanyId": 5, "Company": { "Id": 5, "Name": "Chami" } }, { "Id": 5, "DateOfBirth": "1950-03-16T16:40:01+01:00", "Active": false, "Firstname": "Alfonso", "Lastname": "Ruiz", "NumberOfKids": 6, "City": "Orlando", "CompanyName": "Google", "CompanyId": 7, "Company": { "Id": 7, "Name": "Google" } }, { "Id": 6, "DateOfBirth": "1944-01-10T19:58:38+01:00", "Active": true, "Firstname": "Cheyenne", "Lastname": "Townsend", "NumberOfKids": 3, "City": "Port Washington", "CompanyName": "Lavasoft", "CompanyId": 8, "Company": { "Id": 8, "Name": "Lavasoft" } }, { "Id": 7, "DateOfBirth": "1947-07-18T19:39:55+02:00", "Active": true, "Firstname": "Kibo", "Lastname": "Bright", "NumberOfKids": 8, "City": "Port Jervis", "CompanyName": "Yahoo", "CompanyId": 13, "Company": { "Id": 13, "Name": "Yahoo" } }, { "Id": 8, "DateOfBirth": "1975-10-26T04:28:46+01:00", "Active": false, "Firstname": "Len", "Lastname": "Woodard", "NumberOfKids": 9, "City": "Pittsburgh", "CompanyName": "Google", "CompanyId": 7, "Company": { "Id": 7, "Name": "Google" } }];
    var companies = [{ "Id": 0, "Name": "Adobe" }, { "Id": 1, "Name": "Altavista" }, { "Id": 2, "Name": "Apple Systems" }, { "Id": 3, "Name": "Borland" }, { "Id": 4, "Name": "Cakewalk" }, { "Id": 5, "Name": "Chami" }, { "Id": 6, "Name": "Finale" }, { "Id": 7, "Name": "Google" }, { "Id": 8, "Name": "Lavasoft" }, { "Id": 9, "Name": "Lycos" }, { "Id": 10, "Name": "Macromedia" }, { "Id": 11, "Name": "Microsoft" }, { "Id": 12, "Name": "Sibelius" }, { "Id": 13, "Name": "Yahoo" }]
    viewModel = {
    people: ko.observableArray(people),
    companies: ko.observableArray(companies)
    };
    var companySource = {
    datafields: [
    { name: 'Name' }
    ],
    id: 'Id',
    localdata: viewModel.companies,
    datatype: 'observablearray'
    };
    var companyDataAdapter = new $.jqx.dataAdapter(companySource);
    var peopleSource = {
    datafields: [
    { name: 'Id' },
    { name: 'Firstname' },
    { name: 'Lastname' },
    { name: 'CompanyId', map: 'CompanyId', displayname: 'CompanyName', text: 'Name', id: 'Id', source: companyDataAdapter.records },
    { name: 'CompanyId', map: 'CompanyId' },
    { name: 'CompanyName', map: 'CompanyName' },
    ],
    localdata: viewModel.people,
    datatype: 'observablearray'
    };
    var peopleDataAdapter = new $.jqx.dataAdapter(peopleSource);
    $("#jqxGrid").jqxGrid({
    editable: true,
    theme: 'metro',
    source: peopleDataAdapter,
    autoheight: true,
    columns: [
    {
    text: 'Id',
    datafield: 'Id',
    }, {
    text: 'First name',
    datafield: 'Firstname',
    }, {
    text: 'Last name',
    datafield: 'Lastname',
    }, {
    text: 'Company',
    datafield: 'CompanyId',
    displayfield: 'CompanyName',
    columntype: 'dropdownlist',
    width: 150
    }
    ]
    });
    $("#jqxGrid").bind('cellendedit', function (event) {
    var column = $("#jqxGrid").jqxGrid('getcolumn', event.args.datafield);
    if (column.displayfield != column.datafield) {
    $("#eventLog").html("Cell Edited:<br/>Index: " + event.args.rowindex + ", Column: " + column.text + "<br/>Value: " + event.args.value.value + ", Label: " + event.args.value.label
    + "<br/>Old Value: " + event.args.oldvalue.value + ", Old Label: " + event.args.oldvalue.label
    );
    }
    else {
    $("#eventLog").html("Cell Edited:<br/>Row: " + event.args.rowindex + ", Column: " + column.text + "<br/>Value: " + event.args.value
    + "<br/>Old Value: " + event.args.oldvalue
    );
    }
    });
    ko.applyBindings(viewModel);
    });
    </script>

    Peter Stoev
    Keymaster

    Hi gfhe,

    There are issues in the provided code and there is also an issue on our side regarding the Grid’s ‘setcellvalue’ when a column has “datafield and “displayfield” and the Grid is bound to an “observableArray”. We will fix the issue on our side for the next release which will be available on 01-February.

    Here’s the modified code which correctly initializes the companyDataAdapter.

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />
    <script type="text/javascript" src="../../scripts/jquery-1.8.2.min.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxgrid.pager.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxgrid.edit.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxgrid.edit.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxcombobox.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxpanel.js"></script>
    <script type="text/javascript" src="../../scripts/gettheme.js"></script>
    <script type="text/javascript">
    $(document).ready(function () {
    var theme = getTheme();
    var employeesSource =
    {
    datatype: "xml",
    datafields: [
    { name: 'FirstName', type: 'string' },
    { name: 'LastName', type: 'string' }
    ],
    root: "Employees",
    record: "Employee",
    id: 'EmployeeID',
    url: "../sampledata/employees.xml",
    async: false
    };
    var employeesAdapter = new $.jqx.dataAdapter(employeesSource, {
    autoBind: true,
    beforeLoadComplete: function (records) {
    var data = new Array();
    // update the loaded records. Dynamically add EmployeeName field.
    for (var i = 0; i < records.length; i++) {
    var employee = records[i];
    employee.EmployeeName = employee.FirstName + " " + employee.LastName;
    data.push(employee);
    }
    return data;
    }
    });
    // prepare the data
    var ordersSource =
    {
    datatype: "xml",
    datafields: [
    // id - determines the id of a record in the foreign collection(employees.xml) which should match to the record's name in the source collection(orders.xml).
    // text - determines the display field from the foreign collection.
    // source - determines the foreign collection.
    // displayname - the field's name in the adapter's records array.
    // name - the field's name in the data source.
    { name: 'EmployeeID', displayname: 'EmployeeName', map: 'm\\:properties>d\\:EmployeeID', text: 'EmployeeName', id: 'EmployeeID', source: employeesAdapter.records },
    { name: 'EmployeeID', map: 'm\\:properties>d\\:EmployeeID' },
    { name: 'ShippedDate', map: 'm\\:properties>d\\:ShippedDate', type: 'date' },
    { name: 'Freight', map: 'm\\:properties>d\\:Freight', type: 'float' },
    { name: 'ShipName', map: 'm\\:properties>d\\:ShipName' },
    { name: 'ShipAddress', map: 'm\\:properties>d\\:ShipAddress' },
    { name: 'ShipCity', map: 'm\\:properties>d\\:ShipCity' },
    { name: 'ShipCountry', map: 'm\\:properties>d\\:ShipCountry' }
    ],
    root: "entry",
    record: "content",
    id: 'm\\:properties>d\\:OrderID',
    url: "../sampledata/orders.xml",
    pager: function (pagenum, pagesize, oldpagenum) {
    // callback called when a page or page size is changed.
    }
    };
    var ordersAdapter = new $.jqx.dataAdapter(ordersSource);
    $("#jqxgrid").jqxGrid(
    {
    width: 670,
    source: ordersAdapter,
    theme: theme,
    selectionmode: 'singlecell',
    pageable: true,
    autoheight: true,
    editable: true,
    columns: [
    { text: 'Employee Name', datafield: 'EmployeeID', displayfield: 'EmployeeName', columntype: 'dropdownlist', width: 150 },
    { text: 'Ship City', datafield: 'ShipCity', width: 150},
    { text: 'Ship Country', datafield: 'ShipCountry', width: 150 },
    { text: 'Ship Name', datafield: 'ShipName'}
    ]
    });
    $("#jqxgrid").bind('cellselect', function (event) {
    var column = $("#jqxgrid").jqxGrid('getcolumn', event.args.datafield);
    var value = $("#jqxgrid").jqxGrid('getcellvalue', event.args.rowindex, column.datafield);
    var displayValue = $("#jqxgrid").jqxGrid('getcellvalue', event.args.rowindex, column.displayfield);
    $("#eventLog").html("Selected Cell<br/>Row: " + event.args.rowindex + ", Column: " + column.text + ", Value: " + value + ", Label: " + displayValue);
    });
    $("#jqxgrid").bind('cellendedit', function (event) {
    var column = $("#jqxgrid").jqxGrid('getcolumn', event.args.datafield);
    if (column.displayfield != column.datafield) {
    $("#eventLog").html("Cell Edited:<br/>Index: " + event.args.rowindex + ", Column: " + column.text + "<br/>Value: " + event.args.value.value + ", Label: " + event.args.value.label
    + "<br/>Old Value: " + event.args.oldvalue.value + ", Old Label: " + event.args.oldvalue.label
    );
    }
    else {
    $("#eventLog").html("Cell Edited:<br/>Row: " + event.args.rowindex + ", Column: " + column.text + "<br/>Value: " + event.args.value
    + "<br/>Old Value: " + event.args.oldvalue
    );
    }
    });
    });
    </script>
    </head>
    <body class='default'>
    <div id='jqxWidget'>
    <div id="jqxgrid">
    </div>
    <div style="font-size: 13px; "margin-top: 20px; font-family: Verdana, Geneva, 'DejaVu Sans', sans-serif;" id="eventLog"></div>
    </div>
    </body>
    </html>

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.