jQuery UI Widgets Forums Grid Update data using grid + dropdownlist + knockoutjs

This topic contains 4 replies, has 2 voices, and was last updated by  gustavohenrique 11 years, 9 months ago.

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
  • Hi!
    How to update a grid that data has an object?
    I have a Transaction object that contains a Category that has an id and name attributes.

    var allTransactions = {
        "fields": [
            {"category": {"id": 1, "name": "Books"}, "amount": "-15.8", "transaction_date": "2012-08-07", "description": "Clean code", "id": 1},
            {"category": {"id": 1, "name": "Books"}, "amount": "-22.2", "transaction_date": "2012-08-12", "description": "vim tips and tricks", "id": 2}
        ],
        "total": 2
    };
    
    var allCategories = {
        "fields": [
            {"id": 1, "name": "Books"},
            {"id": 2, "name": "Internet"},
            {"id": 3, "name": "Clothes"}
        ],
        "total": 4
    };
    
    var model = new GridModel(allTransactions.fields);
    ko.applyBindings(model);
    
    var source = {
        localdata: model.items,
        datatype: 'local',
        updaterow: function (rowid, rowdata) {
            console.log('updating transaction...');
            console.log(rowdata);
        }
    };
    
    var renderer = function(row, column, value) {
        return 'name' in value ? '' + value.name + '' : value;
    };
    
    $("#jqxgrid").jqxGrid({
        source: source,
        editable: true,
        autoheight: true,
        theme: '',
        selectionmode: 'singlecell',
        editmode: 'click',
        columns: [
            { text: 'Date', datafield: 'transaction_date', columntype: 'datetimeinput', width: 90, cellsalign: 'right', cellsformat: 'd' },
            { text: 'Description', datafield: 'description', columntype: 'textbox' },
            { text: 'Amount', datafield: 'amount', width: 65, cellsalign: 'right', cellsformat: 'c2', columntype: 'numberinput' },
            { text: 'Category', columntype: 'dropdownlist', datafield: 'category', width: 177, cellsrenderer: renderer,
                initeditor: function (row, cellvalue, editor) {
                    editor.jqxDropDownList({ valueMember: 'id', displayMember: 'name', source: allCategories.fields });
                }
            },
        ]
    });
    

    So, when I change the category in dropdownlist, I’d like that Transaction as:

    {"category": {"id": 2, "name": "Internet"}, "amount": "-15.8", "transaction_date": "2012-08-07", "description": "Clean code", "id": 1}

    but is:

    {"category": String { 0="I", 1="n", 2="t", 3="e", 4="r", 5="n", 6="e", 7="t"}, "amount": "-15.8", "transaction_date": "2012-08-07", "description": "Clean code", "id": 1}

    Anyone may help me?

    Thanks!


    Peter Stoev
    Keymaster

    Hi gustavohenrique,

    The “category” is a String object. That’s the reason it is displayed in that way.

    Here’s a sample based on your code:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />
    <link rel="stylesheet" href="../../jqwidgets/styles/jqx.classic.css" type="text/css" />
    <script type="text/javascript" src="../../scripts/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="../../scripts/knockout-2.1.0.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/jqxradiobutton.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxgrid.edit.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script>
    <script type="text/javascript" src="../../jqwidgets/jqxdatetimeinput.js"></script>
    <script type="text/javascript" src="../../jqwidgets/globalization/jquery.global.js"></script>
    <script type="text/javascript" src="../../scripts/gettheme.js"></script>
    <script type="text/javascript" src="generatedata.js"></script>
    <script type="text/javascript">
    $(document).ready(function () {
    var allTransactions = {
    "fields": [
    { "category": { "id": 1, "name": "Books" }, "amount": "-15.8", "transaction_date": "2012-08-07", "description": "Clean code", "id": 1 },
    { "category": { "id": 1, "name": "Books" }, "amount": "-22.2", "transaction_date": "2012-08-12", "description": "vim tips and tricks", "id": 2 }
    ],
    "total": 2
    };
    var allCategories = {
    "fields": [
    { "id": 1, "name": "Books" },
    { "id": 2, "name": "Internet" },
    { "id": 3, "name": "Clothes" }
    ],
    "total": 4
    };
    var GridModel = function (items) {
    this.items = ko.observableArray(items);
    this.addItem = function () {
    // add a new item.
    if (this.items().length < 20) {
    this.items.push({ name: "New item", sales: Math.round(Math.random() * 100), price: Math.round(Math.random() * 100) });
    }
    };
    this.removeItem = function () {
    // remove the last item.
    this.items.pop();
    };
    this.updateItem = function () {
    // update the first item.
    var item = {};
    item.name = initialData[Math.floor(Math.random() * initialData.length)].name;
    item.sales = Math.floor(Math.random() * 500);
    item.price = Math.floor(Math.random() * 200);
    this.items.replace(this.items()[0], item);
    };
    };
    var model = new GridModel(allTransactions.fields);
    ko.applyBindings(model);
    var source = {
    localdata: model.items,
    datatype: 'local',
    updaterow: function (rowid, rowdata) {
    var category = rowdata.category.toString();
    console.log(category);
    }
    };
    var renderer = function (row, column, value) {
    return 'name' in value ? '' + value.name + '' : value;
    };
    $("#jqxgrid").jqxGrid({
    source: source,
    editable: true,
    autoheight: true,
    theme: '',
    selectionmode: 'singlecell',
    editmode: 'click',
    columns: [
    { text: 'Date', datafield: 'transaction_date', columntype: 'datetimeinput', width: 90, cellsalign: 'right', cellsformat: 'd' },
    { text: 'Description', datafield: 'description', columntype: 'textbox' },
    { text: 'Amount', datafield: 'amount', width: 65, cellsalign: 'right', cellsformat: 'c2', columntype: 'numberinput' },
    { text: 'Category', columntype: 'dropdownlist', datafield: 'category', width: 177, cellsrenderer: renderer,
    initeditor: function (row, cellvalue, editor) {
    editor.jqxDropDownList({ valueMember: 'id', displayMember: 'name', source: allCategories.fields });
    }
    },
    ]
    });
    });
    </script>
    </head>
    <body class='default'>
    <div id="jqxgrid">
    </div>
    </body>
    </html>

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com

    In this case, the category is a string but I’d like an object. Object {id: 2, name: ‘Internet’} Instead of String “Internet”.

    Hi again!

    I modified the grid:

    $("#jqxgrid").jqxGrid({
            source: source,
            editable: true,
            autoheight: true,
            theme: '',
            selectionmode: 'singlecell',
            editmode: 'click',
            columns: [
                { text: 'Date', datafield: 'transaction_date', columntype: 'datetimeinput', width: 90, cellsalign: 'right', cellsformat: 'd' },
                { text: 'Description', datafield: 'description', columntype: 'textbox' },
                { text: 'Amount', datafield: 'amount', width: 65, cellsalign: 'right', cellsformat: 'c2', columntype: 'numberinput' },
                { text: 'Category', columntype: 'dropdownlist', datafield: 'category', width: 177, cellsrenderer: renderer,
                    initeditor: function (row, cellvalue, editor) {
                        var index = editor.jqxDropDownList('getSelectedIndex');
                        editor.jqxDropDownList({ valueMember: 'id', displayMember: 'name', source: allCategories.fields, selectedIndex: index });
                        editor.bind('change', function (event) {
                             selectedId = editor.jqxDropDownList('getSelectedItem').value;
                             for (var i = 0; i < allCategories.fields.length; i++) {
                                var category = allCategories.fields[i];
                                if (selectedId == category.id) {
                                    $("#jqxgrid").jqxGrid('source').localdata[row].category = category;
                                }
                             }
                        });
                    }
                },
            ]
        });
    

    But no success yet!
    What function is called after initeditor and before the source.updaterow?

    Thanks!

    Hi, Perter!

    I modified the jqxgrid.edit.js, line 870, the _geteditorvalue function:

    _geteditorvalue: function (d) {
        ...
        case "dropdownlist":
            if (this.editcell.editor.jqxDropDownList) {
                var b = this.editcell.editor.jqxDropDownList("selectedIndex");
                var e = this.editcell.editor.jqxDropDownList("getItem", b);
                if (e) {
                    f = e.originalItem instanceof Object ? e.originalItem : new String(e.label); // I change this line
                } else {
                    f = ""
                }
                if (f == null) {
                    f = ""
                }
            }
            break;
        ...
    

    Perhaps the next version may have this change.

    Thanks!

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

You must be logged in to reply to this topic.