• If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

View
 

Grid-Editing-Databinding

Page history last edited by BorisMoore 10 years, 1 month ago

Related to Editing.

 

tbd

 

Other implementations:

 

JsViews 

  • JsViews integrates JsRender (new version of jQuery templates which does pure string-based rendering, with no DOM dependency, and with a non-jQuery-dependent version too) and data linking. By integrating templates and data linking, JsViews provides a consistent approach to mapping data to UI and presentation, with, in particular, a declarative approach to specifying how UI renders against data, and how it updates when the data changes.
  • The following demos show JsViews in action.
  • In addition, the following demos (code here) explore the use of JsViews with the jQuery UI Grid. 
  • Partial review of jsviews:
    • The following comments are from Joern Zaefferer, after looking at the jsviews-grid demos, with replies from Boris Moore and Brad Olenick: 
      • [Joern] How to handle presentation data? In one of the grid examples, a global variable 'adding' is set in order to decide whether to display "Add" instead of "Edit" in the template. There needs to be an alternative for that.
        [Boris] The user has to deal with page presentation data, and the grid with grid presentation data. 
        In this case it is for the detail view, which is part of the user-created page. In reality they would put it on a namespace they own in the page, not as a global. But alternatively they can pass data through with options as in .link( selectedData, "#detail-template", { title: detailTitle }) and have it visible to the template rendering, as ${$options.title}. (I'll change it to this in the demo, though right now there are a couple of related bugs which I am currently fixing)
        • The approach of converting data for presentation was so far countered with the argument that the data can't be touched, as it needs to be sent back to the server. That part could be solved by making the link back to the original model, while using the intermediate representation for output.
        • Whatever the solution, there's plenty of usescases for modifying data for display, e.g. converting a date/time string to a "x [minutes|hours|days|months|years] ago" label.
          [Boris] Yes you often want to format differently for display, but this doesn't mean you have to change the data, or (if you are round-tripping data so cannot change it) clone the data, mapped to the original data - which is expensive and complex. Instead you would just use converter functions for display - such as: ${myConverters.dateFormat(date)} within a template, or data-from="myConverters.dateFormat([date])" for a data-linked value. You can add convert functions to the converters collection as in linkSettings.converters.dateFormat = function() {...} for convenience, so you can then just write data-from="dateFormat([date])", or you can pass them in with options, and then do $options.dateFormat(…)
      • [Joern] The selected-state visualization (.ui-selected) is added using the grid's refresh callback, then iterating through all rows, getting the tmplItem.data, then checking if that is $.inArray in selectedData. That needs to be refactored into a selectable-grid component, along with the custom code for applying selectable to the grid.
        [Boris] Yes, that would be integrated into the grid, and the samples are a progressive step-by-step sequence suggesting just that: how to move selection and observability etc. into the grid. It is only the final sample which attempts to actually get nearer to real integration of that code into the grid itself. That is also indicated in comments in the code: //Selection support - to be integrated into grid// 
        (For review purposes, I had suggested you only need to look at the final step, grid-master-detail.html, as well as looking at grid-edit.html, and skip all the other ones.)
        .
        [Joern] The user should be able to call gridElement.gridSelectable() or something like that, with one or more callbacks that inform about selection-state changes, once they are done. Not so much about jsviews, more a Selecting issue.
        [Boris] By making the grid return a ‘selected’ array you don’t need to invent new callbacks for selection – you can just use the observable collection change events and you are done…
        • [Joern] This relates to the more generic issue of incremental rendering. In the clearSelection-click-handler, the ui-selected class is removed manually, 'for better perf'. The mentioned gridSelectable component should include that optimiziation, if actually necessary. The clear-click-handler should be able to call gridSelectable("clear") and not having to care about anything else.
          [Boris] Yes, it would be part of the built-in selectable implementation. This was just a progressive demo towards that encapsulated version 
        • [Joern] Same for inverting the selection: gridSelectable("invert").
        • Would also be interesting to investigate if that can be pushed up to Selectable
        • There should be a way to retrieve the first and last index of the current selection, to insert a new element before or after the selection. Trivial for single-selection, more involved for multi-selection. 
      • [Joern] Deleting in the readonly and editable demos (first two modified grid demos) happens by splicing the underlying array. In the observer demo, that is replaced by $.observable(array).remove(index) + $.observable(selectedData).remove(selectedIndex). The index is different, once referring to the actual data, once to the seperate selectedData.
        • If the selected-state would be stored on the data itself, this could be done with one call.
        • If the selected-state would be stored as decoration-data, avoiding to clutter the data itself, but keeping it linked to each data object, removing the object should also remove the selected-state. Whatever that structure would actually look like. 
        • If $.observable would offer a .remove(object) method, looking up the index manually could be skipped, while $.observable would have the opportunity to keep a (hash)map of the data for efficient lookup. Which would probably require some kind of unique key, which also isn't present in the examples, yet.

[Boris] Putting it in the data means that a) it round trips to the server, b) it implies selection in one UI view will have side-effects on selection on another, if the same data shows up in more than one place - which it often does, as in the different grids in this demo. Having it as “data decoration” requires some kind of ID definition of data items as keys for maps, or implies storing object references, and again likely implies the side-effect b) above.
More generally (as [Brad] put it in an email) we have to be sure that these scenarios are considered and likely covered:

        • An item of data should be selectable in multiple different views at the same time.
        • We should agree on selection behavior when an item of data is present N>1 times in a given array.  Can I select an individual TR and not find that the other TRs for that data item are selected?
        • We should make sure however selection is presented to the client of a grid that the scheme is reactive/event-driven.
      • [Joern] In the observer example, when adding a new object, $.observable(developers).insert(index, newDeveloper) is called, which makes sense. Afterwards, $.observable(selectedData).refresh(newDeveloper) is called, with the effect of replacing the current selection with that new object. That should be replaced with a combo like .clear().add(newDeveloper). Using refresh to replace the array's content is odd.
        [Boris] As Brad put it in email, the reason this is “refresh” is that there would be a single event here.  With clear+add, you’d get two events and suboptimal repaint of controls.
      • [Joern] Again in the observer example, instead of binding the grid.refresh to the observable's (change) events, grid.refresh() is called manually where ever needed. Only in the grid-edit example (using grid5-editable.js) is that replaced, moving the necessary binding into the grid itself. There's also a lot of other cleanup here, e.g. adding a developer is now a single operation via $.observable(developers).insert(0, newDeveloper). 
        [Boris] Yup – that was the intention: progressive demos towards the encapsulated version.  

Comments (0)

You don't have permission to comment on this page.