How to get data from master view to detail view

85 views
Skip to first unread message

Michael Reno

unread,
Jun 14, 2016, 11:25:01 PM6/14/16
to KnockoutJS
I have an image to illustrate my question
I'm using devexpress, html, js(knockout), c#, odata
This is my code : 

order-details.dxview
<div data-options="dxView : { name: 'OrderDetail', title: 'Order' } " >
    <div data-bind="dxCommand: { onExecute: '#OrderEdit/{id}', direction: 'none', id: 'edit', title: 'Edit', icon: 'edit' }"></div>
    <div data-bind="dxCommand: { onExecute: handleDelete, id: 'delete', title: 'Delete', icon: 'remove' }"></div>
    <div  data-options="dxContent : { targetPlaceholder: 'content' } " class="dx-detail-view dx-content-background" data-bind="dxDeferRendering: { showLoadIndicator: true, staggerItemSelector: 'dx-fieldset-header,.dx-field', animation: 'detail-item-rendered', renderWhen: isReady }" >
        <div data-bind="dxScrollView: { }">
            <div class="dx-fieldset">
                <div class="dx-fieldset-header" data-bind="text: order.PhoneNumber"></div>
<div class="dx-field">
<div class="dx-field-label">Order id</div>
<div class="dx-field-value-static" data-bind="text: order.OrderId"></div>
</div>
<div class="dx-field">
<div class="dx-field-label">Phone number</div>
<div class="dx-field-value-static" data-bind="text: order.PhoneNumber"></div>
</div>
                <div class="dx-field">
                    <div class="button-info" data-bind="dxButton: { text: 'Add Item', onClick: '#AddItem/{order.OrderId}', icon: 'add', type: 'success' }"></div>
                    <!-- Item List -->
                    <div data-bind="dxList: { dataSource: dataSource, pullRefreshEnabled: true }">
                        <div data-bind="dxAction: '#OrderDetailDetails/{OrderDetailId}'" data-options="dxTemplate : { name: 'item' } ">
                            <div class="list-item" data-bind="text: Item().ItemName"></div>
                            <div class="list-item" style="float:right;" data-bind="text: Amount"></div>
                        </div>
                    </div>
                </div>
<div class="dx-field">
<div class="dx-field-label">Grand total</div>
<div class="dx-field-value-static" data-bind="text: order.GrandTotal"></div>
</div>
</div>
            <div data-options="dxContentPlaceholder : { name: 'view-footer', animation: 'none' } " ></div>
        </div>
    </div>
</div>


order-details.js
POSApp.OrderDetail = function(params, viewInfo) {
    "use strict";

    var id = params.id,
        order = new POSApp.OrderViewModel(),
        isReady = $.Deferred(),
        // Item List
        shouldReload = false,
        dataSourceObservable = ko.observable(),
        dataSource;

    function handleDelete() {
        DevExpress.ui.dialog.confirm("Are you sure you want to delete this item?", "Delete item").then(function(result) {
            if(result)
                handleConfirmDelete();
        });
    }

    function handleConfirmDelete() {        
        POSApp.db.Orders.remove(id).done(function() {
            if(viewInfo.canBack) {
                POSApp.app.navigate("Orders", { target: "back" });
            }
            else {
                POSApp.app.navigate("Blank", { target: "current" });
            }
        });
    }

    function handleViewShown() {
        POSApp.db.Orders.byKey(id).done(function(data) {
            order.fromJS(data);
            isReady.resolve();
        });

        //Item List
        if (!dataSourceObservable()) {
            dataSourceObservable(dataSource);
            dataSource.load().always(function () {
                isReady.resolve();
            });
        }
        else if (shouldReload) {
            refreshList();
        }
    }

    //Item List

    function handleOrderDetailsModification() {
        shouldReload = true;
    }

    function handleViewDisposing() {
        POSApp.db.OrderDetails.off("modified", handleOrderDetailsModification);
    }

    function refreshList() {
        shouldReload = false;
        dataSource.pageIndex(0);
        dataSource.load();
    }

    dataSource = new DevExpress.data.DataSource({
        store: POSApp.db.OrderDetails,
        map: function (item) {
            return new POSApp.OrderDetailViewModel(item);
        },
        expand: ["Item"],
        sort: { field: "OrderDetailId", desc: false },
        filter: ["OrderId", parseInt(id)]
    });

    POSApp.db.OrderDetails.on("modified", handleOrderDetailsModification);

    //Item List

    return {
        id: id,
        order: order,
        handleDelete: handleDelete,        
        viewShown: handleViewShown,
        isReady: isReady.promise(),
        //Item List
        dataSource: dataSourceObservable,
        refreshList: refreshList,
        viewDisposing: handleViewDisposing,
    };
};





add-item.dxview
<div data-options="dxView : { name: 'AddItem', title: 'Add Item' } " >
    <div data-bind="dxCommand: { onExecute: handleSave, id: 'save', title: 'Save', icon: 'save' } "></div>
    <div data-bind="dxCommand: { onExecute: handleCancel, id: 'cancel', behavior: 'back', title: 'Cancel', icon: 'close' }"></div>
    <div data-options="dxContent : { targetPlaceholder: 'content' } " class="dx-edit-view dx-content-background dx-form-background" data-bind="dxDeferRendering: { showLoadIndicator: true, staggerItemSelector: '.dx-field', animation: 'edit-item-rendered', renderWhen: isReady }">
        <div data-bind="dxScrollView: { }">
            <div class="dx-fieldset">
                <div class="dx-field">
                    <div class="dx-field-label">Order detail id: </div>
                    <div class="dx-field-value" data-bind="dxNumberBox: { value: orderdetail.OrderDetailId, readOnly: true }"></div>
                </div>
                <div class="dx-field">
                    <div class="dx-field-label">Order: </div>
                    <div class="dx-field-value" data-bind="dxLookup: { dataSource: ordersSource, value: orderdetail.Order, displayExpr: 'PhoneNumber', title: 'Orders', placeholder: 'Choose Order' }"></div>
                    <!--<div class="dx-field-value" data-bind="dxNumberBox: { value: orderdetail.Order, placeholder: 'Enter Order Id' }"></div>-->
                </div>
                <div class="dx-field">
                    <div class="dx-field-label">Item: </div>
                    <div class="dx-field-value" data-bind="dxLookup: { dataSource: itemsSource, value: orderdetail.Item, displayExpr: 'ItemName', title: 'Items', placeholder: 'Choose Item' }"></div>
                </div>
                <div class="dx-field">
                    <div class="dx-field-label">Quantity: </div>
                    <div class="dx-field-value" data-bind="dxNumberBox: { value: orderdetail.Quantity, placeholder: 'Enter Quantity' }"></div>
                </div>
                <div class="dx-field">
                    <div class="dx-field-label">Price: </div>
                    <div class="dx-field-value" data-bind="dxNumberBox: { value: orderdetail.Price, placeholder: 'Enter Price' }"></div>
                </div>
                <div class="dx-field">
                    <div class="dx-field-label">Amount: </div>
                    <div class="dx-field-value" data-bind="dxNumberBox: { value: orderdetail.Amount, placeholder: 'Enter Amount' }"></div>
                </div>
            </div>
        </div>
    </div>
</div>

add-item.js
POSApp.AddItem = function (params, viewInfo) {
    "use strict";

    var id = params.id,
        isNew = (id === undefined),
        isSplitLayout = viewInfo.layoutController.name === "split",
        orderdetail = new POSApp.OrderDetailViewModel(),
        isReady = $.Deferred();

    orderdetail.Order(parseInt(id));
    //orderdetail.Order(new POSApp.OrderViewModel(id));
    alert(parseInt(id));

    function load() {
        return POSApp.db.OrderDetails.byKey(id, { expand: ["Item"] }).done(function (data) {
            orderdetail.fromJS(data);
        });
    }

    function insert() {
        // Insert Code
        POSApp.db.OrderDetails.insert(orderdetail.toJS()).done(function (values, newId) {
            //POSApp.app.navigate({ view: "order-details", id: params.id }, { target: "back" });
            POSApp.app.back();
            orderdetail.clear();
        });
    }

    function handleSave() {
        insert()
        //orderdetail.clear();
        //POSApp.app.back();
        // Go back to order-edit and the item that have been chosen will be displayed in the order-edit
        // And so on for the next item
    }

    function handleCancel() {
        orderdetail.clear();
        POSApp.app.back();
    }

    function handleViewShown() {
        isReady.resolve();
    }

    return {
        orderdetail: orderdetail,
        ordersSource: {
            store: POSApp.db.Orders,
            map: function(data) {
                return new POSApp.OrderViewModel(data);
            }
        },
        itemsSource: {
            store: POSApp.db.Items,
            map: function (data) {
                return new POSApp.ItemViewModel(data);
            }
        },
        handleSave: handleSave,
        handleCancel: handleCancel,
        viewShown: handleViewShown,
        isReady: isReady.promise()
    };

};

What I'm asking is how to pass the id of the order to the add item view properly? because with this code, when I save it, in the database the orderid is null, so there's no value inserted. But in the add item view, in the order lookup filed, the id or value was there but it wont be inserted to the database.


Many Thanks & Best Regards
Michael Reno
posapp.jpg

noirabys

unread,
Jun 15, 2016, 3:09:43 AM6/15/16
to KnockoutJS
hi,

there is missing a part in your example (maybe its part of devexpress, which i don't know): 

onClick: '#AddItem/{order.OrderId}

i think the problem is within your custom binding "onClick" which does some magic ...

in case the item needs the orderId why not pass it to the constructor of item ?
or add a function to the order model to add items .. 

kind regards,
  noirabys




Michael Reno

unread,
Jun 15, 2016, 3:48:55 AM6/15/16
to KnockoutJS
I'm new at this
What's wrong with my onClick?
And how to pass to the constructor? Please explain to me

noirabys

unread,
Jun 16, 2016, 3:02:02 AM6/16/16
to KnockoutJS
in knockout you can use:

data-bind="click: methodNameInCurrentContext"

or use an anonymous function:

data-bind="click: function() { $root.addItem(currentOrderId);}"

i don't know the onClick binding, thus i guess its part of devexpress or other framework you use.
Reply all
Reply to author
Forward
0 new messages