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

Unusual Grid use case

2 Answers 171 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Eric
Top achievements
Rank 1
Eric asked on 07 Jan 2013, 08:26 PM
I have a particular use case / pattern for a grid in mind. I would like some input on if it is even possible, the best way to go about it or alternative approaches that might work. I'm asking this even though I know the answer is probably going to be 'No, the grid is not designed for that and can't be adapted to do so'; I'm asking because our back end data service is already set up to provide data and accept inputs in this way.

I have a customer management system which allows multiple profiles per customer. The profiles control the type and amount of products they will recieve as said products come into supply. There are numerous collections of sub-objects managed at the profile level (one-profile to many sub-configurations). The profile management data services already have a lot of logic in place for updating and audit logging - that is to say, every modification to a profile actually copies the whole profile, archives the old one and sets the new one up. This is so that customers and account managers both have visibility on who made what changes and when. Also, not all aspects of the profile are under direct control of the customer: discounts, promotions, advanced settings etc. can only be controlled by our account managers (essentially administrator level users).

So what I would like the grid to do is this:

  1. Display a collection of sub-configurations (this part is trivial and already working)
  2. When adding/creating new additions to the list, do not allow free-form input, only allow the user to select from a pre-approved list of objects. The list also needs to only show options which haven't already been added to the profile. I would prefer this to be displayed in a modal dialog that allows multi-selection. Need some help here.
  3. When finished selecting new additions, display them in the grid without telling the server yet. (This is essentially batch editing and looks to be compatible with existing grid options.)
  4. Some, but not all, fields are editable here. (I think I have this configured correctly via datasource options.)
  5. Entire sub-configuration objects can be removed here. I know how to make this work, but it conflicts with the next requirement.
  6. When saving changes, the entire collection needs to be posted back to the server as a whole. There needs to be only one action for this and it needs to send the entire collection with the most up-to-date entries the user has typed in the UI each time. Need some help here.
Regarding 2:
I can make a Kendo UI pop-up, load its content from an ajax controller with the correct entries in it. I can enable multi-select with a ListView or a Grid, get the selected rows and data items back etc. but I can't make it add the selected items to the current grid listing. Attempts to do so conflict with the datasource only wanting to use data actually from the server. Is there a way to dynamically add items to a datasource without them being part of the server response?

I have also tried to use the built in pop-up editing to add the items to the grid. This bypasses the problems in the previous approach - items that are being edited are displayed in the grid, waiting to be added to the server collection; so they're part of the datasource object without being part of the service call. But there are two other problems with this approach:

1) I can't get the service editor to select a whole object. I can get it to select part of the objects from the approved list using a foreign key setup, but that essentially lets the user mix-and-match pieces from different items on the pre-approved list.

2) I can't get the popup editor to allow multi-selection.

Is there an example I perchance overlooked? Or should I fall back on a single-item editor template (so the user is essentially just selecting the 'ID' of the object they want to add)? Is there multi-add available anywhere?

Regarding 6:
I can get the grid to batch its updates no problem. But I need them done in one call. Currently there is a call to the 'Create' action with just the new items followed by a call to the 'Destroy' action with just the deleted items. Handling these separately would result in two audit log entries being created because there is no way for the server to tie them together. Also, since they are fired one after another asynchronously, handling the on the server would result in a race condition as follows:

Create receives the list of items to add. It has to retrieve the current list, add the new items to the collection, save the collection with the items included which are about to be removed in the destroy call.
Destroy receives the list of items to remove. It retrieves the current list, almost always before the save operation has completed, it removes the items needing removal, saves the collection almost always without the items that were added in the create call.

Is there anyway to put the grid in an all-together batch edit mode? I realize this is bandwidth inefficient, but we gladly trade that off for the auditing and accountability provided by our backend data service.

Any help at all is appreciated.

2 Answers, 1 is accepted

Sort by
0
Eric
Top achievements
Rank 1
answered on 07 Jan 2013, 10:08 PM
I've found a hacky way to add items to the grid, but it's not pretty. For instance, on the batch editing demo page, I typed the following into the javascript console on chrome:

var data = $("#grid").data("kendoGrid").dataSource;
 
data._data.push({Discontinued: true,
    ProductId: null,
    ProductName: "Tomato",
    UnitPrice: 3.5,
    UnitsInStock: 40,
    _events: {
        Change: [ function (e){
            i.trigger(Q,{field:e.field,node:e.node,index:e.index,items:e.items||[this],action:e.node?e.action||"itemchange":"itemchange"})}
         ]
    },
    dirty: true,
    id: null,
    parent: function (){return r}, uid: null })
Where I copied the _events and parent function from an existing entry in the _data array. The entry appeared on the grid immediately (at the end - which is expected, because that was its order in the array and there appears to be no sorting on this example) and when I hit  the 'save' button, I got a successful AJAX GET call like this:

  1. Request Headersview source
    1. Accept:
      text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01
    2. Accept-Charset:
      ISO-8859-1,utf-8;q=0.7,*;q=0.3
    3. Accept-Encoding:
      gzip,deflate,sdch
    4. Accept-Language:
      en-US,en;q=0.8
    5. Connection:
      keep-alive
    6. Cookie:
      ASP.NET_SessionId=dzbhq421thgdowjj034jvlf5; __utma=2786159.1118610132.1355152115.1357579584.1357590382.56; __utmb=2786159.34.9.1357592536380; __utmc=2786159; __utmz=2786159.1356631027.37.10.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
    7. Host:
      demos.kendoui.com
    8. Referer:
      http://demos.kendoui.com/web/grid/editing.html
    9. User-Agent:
      Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11
    10. X-Requested-With:
      XMLHttpRequest
  2. Query String Parametersview URL encoded
    1. callback:
      jQuery18204577877796255052_1357585947459
    2. models:
      [{"Discontinued":true,"ProductId":null,"ProductName":"Tomato","UnitPrice":3.5,"UnitsInStock":40}]
    3. _:
      1357595401915

I can apparently also do this:
for(var i = 0; i < data._data.length; i++)
    data._data[i].dirty = true;
And flag all the data as needing to be sent with the update. This resulted in the 'save changes' button sending a call to the /Update action with all 79 (counting my new programmatically added entries) included in the '_models' param. It did not successfully save, however, because your server returned a run time error, the exact nature of which is not visible to me :-)

<span><H1>Server Error in '/service' Application.<hr width=100% size=1 color=silver></H1>

<h2> <i>Runtime Error</i> </h2></span>

<font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

<b> Description: </b>An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.

However, this at least implies that these hacks together could work. I could use a custom command to manually delete items from the grid, or a special 'deleted' column on my model, or even an empty destroy action.

I would still like some advice on a cleaner, more supported way to accomplish this.
    1. Accept:
      text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01
    2. Accept-Charset:
      ISO-8859-1,utf-8;q=0.7,*;q=0.3
    3. Accept-Encoding:
      gzip,deflate,sdch
    4. Accept-Language:
      en-US,en;q=0.8
    5. Connection:
      keep-alive
    6. Cookie:
      ASP.NET_SessionId=dzbhq421thgdowjj034jvlf5; __utma=2786159.1118610132.1355152115.1357579584.1357590382.56; __utmb=2786159.34.9.1357592536380; __utmc=2786159; __utmz=2786159.1356631027.37.10.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
    7. Host:
      demos.kendoui.com
    8. Referer:
      http://demos.kendoui.com/web/grid/editing.html
    9. User-Agent:
      Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11
    10. X-Requested-With:
      XMLHttpRequest
  1. Query String Parametersview URL encoded
    1. callback:
      jQuery18204577877796255052_1357585947459
    2. models:
      [{"Discontinued":true,"ProductId":null,"ProductName":"Tomato","UnitPrice":3.5,"UnitsInStock":40}]
    3. _:
      1357595401915
0
Alexander Valchev
Telerik team
answered on 09 Jan 2013, 06:25 PM
Hello Eric,

You can add items to the grid through the API. Please do not try to modify directly the internal _data array as this approach is error prone and will not work.

To add a new record for editing you may use the addRow method of the Grid. The add and insert methods will allow you to add records directly in the DataSource (the grid will automatically refresh to display the changes). In the console you may try the following:
$("#grid").data("kendoGrid")
    .dataSource
    .insert(0, {
        ProductID: null,
        ProductName: "Another Product",
        UnitPrice: 33,
        UnitsInStock: 5,
        Discontinued: true
    });

On pressing the "save changes" button the record will be submitted.

There is no point to modify the dirty flag as it does not determine whether a given field has been changed or not. If you seed to change the value of a specific field please use the set method - in this way the DataSource will automatically track the changes. Through the dataItem method you can retrieve the corresponding model.

To allow the user to edit with a pre-approved list of objects you may use custom DropDownList editor (demo). Currently we do not provide a multi-select widget, however such will be added in the Q1 2013 release.

Regarding 6th point, I am afraid that such functionality is not supported out of the box. By default the DataSource submits the changes via separate Ajax requests (e.g. one for created items, another for destroyed and etc.)

I hope this information will help. In case you have further questions, please post them in separate topics.
In this way it is much easier to follow and concentrate on the exact issue which usually leads to its faster resolving. Also by following this practice you can be sure that your question will reach the corresponding staff member in time.
Thank you in advance for the understanding.

Regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
Grid
Asked by
Eric
Top achievements
Rank 1
Answers by
Eric
Top achievements
Rank 1
Alexander Valchev
Telerik team
Share this question
or