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

  • Work with all your cloud files (Drive, Dropbox, and Slack and Gmail attachments) and documents (Google Docs, Sheets, and Notion) in one place. Try Dokkio (from the makers of PBworks) for free. Now available on the web, Mac, Windows, and as a Chrome extension!



Page history last edited by Jörn Zaefferer 10 years ago

A widget for editing cells. The editing ability can be specified for each column, the editor to use depends on the column type (see 3.1.3 Type). Editing can be cancelled (ie. throwing away all changes), or persisted (ie. synchronizing changes with the data model). Activating inline editing can happen for a single cell or a full row (or even full grid). Activating editing must interact with selection to avoid conflicts, e.g. a selection musn't start editing.


The API for triggering editing events on objects and arrays is encapsulated in Observable.

As for bidirectional bindings (aka data linking), see Editing-Databinding.


Open issues

  • How to handle nested arrays? Could be an array with scalar values (list of strings), or more nested objects. Important for detail view, while grid should be able to display a serialized form.
    • use custom template for rendering the grid cell
    • use template to generate inputs for editing 
  • Do we need row refresh? What should be the API for that? Index-based? How does the user get the index of a data object? Object-identiy? How does the grid map an object to a row? 
    • probably the way to go: grid.refresh(rowIndex)  



  • Add a demo that uses a remote dataview to receive data, then use the result to initialize a local dataview  
  • observable: Update remove implementation to handle duplicate objects in an array.
    •  While doing that, fix the remove event to follow the spec (allow for multiple indicies) 
  • Wade through jqgrid demos and figure out what interactions to integrate on our end. 
  • Make selection compatible with navigator and inline editing, integrate into main editing demo. Extract the code into a gridSelectable widget. 
    • WIP: created separate grid-selectable demo, replacing previous grid-selecting demo and backporting some code from Boris' modified grid demos. Needs refactoring, then integration with the main demo.
  • Review and refactor specifications
  • Add a timestamp-property, and output it using a custom template
    • WIP: Output both date and time in separate columns. Not yet editable, as the edited data isn't converted back to a timestamp.
    • Use datepicker and timepicker? 
  • Refactor todo-app example, giving it a bit more structure, maybe ala the backbone todo example 
    • currently the example is broken, need to adapt to the latest $.observable changes 
  • Add full-row editing 
  • Try generating the edit form for non-grid example to allow editing of nested array 
    • displaying array works, but serializing still needs to handle it 
    • still need to apply to non-grid master/detail demo 
    • deserializing multiple nested properties will fail right now, too 



    • SproutCore 2.0 
      • SC.ArrayProxy acts as the controller in the Todo app demo. Its similar to the observable array, in that it wraps array methods and adds events for each modification. 
      • There are a various methods for selecting and manipulating objects within the array, see also the enumerables guide
        • to set isDone on all items: this.setEach('isDone', value)
        • to check if all items have isDone set to true: this.everyProperty('isDone', true) 
    • Backbone
      • both models and collections
        • have a fetch method to retrieve content from server
        • have a save method to create a new object and update changes
        • all remote operations are handled by a single method, Backbone.sync
          • has some basic customization options, like mapping PUT to POST
          • heavier customizations possible by overriding, its just one method
        • have a toJSON() method - misleading name, but "exports" as object suitable for passing to template 
      • models have
        • a get method to retrieve an attribute, though just maps to model[attribute], no support to retrieve nested properties with a single call
        • a set method to set one or many attributes (as hash), triggers a "change" as well as "change:attribute" events for each one
        • unset removes an attribute, fires "change" event 
        • destroy method to delete on server 
      • collections
        • proxy to underscore.js for iteration methods
        • add/remove method accepts a single object or an array to add/remove to/from collection, triggers "add/remove" event
        • get retrieves object in collection by model id
        • at retrieves by index
        • sort method triggers "refresh" event
        • .pluck("attribute") is short for .map(function(model) { return model.attribute; }) 
      • events can be supressed with additional, optional {silent:true} argument, .add(model, { supress: true })
    • recent Adobe data model work once avaible (via John Brinkman) 
      • working on getting access to code
    • JsViews (and related grid-based demos)
      • JsViews integrates JsRender (new version of jQuery templates which does pure string-based rendering, with no DOM dependency) 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. 





An inline editor widget. Moved to Editable.



A wrapper around the inline editor widget to run inside a grid, to support lazy initialization and configuration via the grid's columns option.

Uses $.observable to make the actual object changes, instead of triggering custom events.


  • editor (Function(cell, grid), default: returns the editor property of the columns option for that cell)
    • Callback to retrieve editor-option (see Editor) for a given cell and grid 
  • editorOptions  (Function(cell, grid), default: returns the editorOptions property of the columns option for that cell)
    • Callback to retrieve editorOptions-option (see Editor) for a given cell and grid 
  • items (Selector, default: "td")
    • Selector to match what cells should be editable.
    • Override to exclude certains cells, e.g. action buttons.


  • n/a


  • n/a



A navigation component to navigate cells in a grid using the cursor keys, and Enter to start editing. Works with the Grid-Editor.

Sets tabIndex=0 to the table, then manages focus within the grid. Enter is translated to trigger a dblclick event on the focussed cell.


  • n/a


  • TODO: Are there any that need to be exposed? Current impl has most public.


  • n/a



See Editing-API and Editing-Events


Grid Editing demo


Applies a custom inline editor widget to each cell after rendering the current page, writes the result back to the datasource and calls a (custom) save method. The editor supports text and number types (for now), via Spinner (the random column is a customized spinner editor, with a random step-option). The country column is a text input with autocomplete attached.

Initializing the inline editor is done using an additional wrapper widget (currently called gridEditor) to enable lazy init - intializing the editor widget for all cells on grid refresh is way too slow.

The grid can be navigated, when focussed, using the cursor keys. Enter activates the inline editor on the active cell. Doubleclicking a cell has the same effect.


Selectable Grid Editing demo


Basically the demo above, but with selectable applied, and using $.observable to manage the selection. Items can be inserted relative to the selection. Selected items can be edited (currently only the first one) and removed.


Non-Grid Editing demo, master/detail


Renders a list of movies. Click on any of them to edit in a seperate form. Changes are reflected in the view and stored.

Todo app


The popular Todo app example. Currently only using basic jQuery methods and the button widget, along with a small helper for storing data in localStorage (also used in the other two demos). Works on mobile devices (tested on iOS 4.x and Android 2.3.x.)


Early design notes


   - Can make column  editable="false"


    .dataStore("edit"[, ID[, column]]) // How do we specify true or "date"?

   .dataStore("cancelEdit"[,  ID]) // remove dom nodes from editing, call refresh

    // All of these are  stored on the data store view

   editing = {

     "ID1": true,

     "ID2": "date"


   editing = true;

   editing = "date";

   // Wipe out state on  refresh

    editing: {}


   Check editing state on  pagination


   .dataStore("update", ID,  dataObj?)

    Need to specify how frequently to update



       - Row-level blur event  (focusenter, focusleave)

     - Enter says done with row editing, moves to next row -  go to first column

     - Tab says done with cell editing, moves to next cell

     - Click on cell - turns  on editing for whole row (or just cell, if only that cell is on)

     - Make sure not to  conflate selection with triggering editing - use checkboxes for  selection when doing editing as well


   - Inline Edit Row

     - Generate 


   - Click to Edit Cell

   - Entire Table Editing

   - Column Editing



   - Add New Item POST

     - Dialog for adding in  an item?

      - Will return data item in format we're using (must contain ID)

     - Update the items with  the new IDs

    - Delete Row POST

     - Works like update (success / error / timeout)

     - On success, remove  and refresh

    - Reorder Row // Useful, will not work on at first

     - Communicate an  insertBefore event?


   - Event for when column  is changed, event for when entire row is done being edited

   - Ways of triggering  those events (columnchange and rowdone?)

   - Do we have a submit  button - if not handle enter key


   - Inputs, selects can be used in the page to trigger PE  editing

   -  Depends upon l10n plugin

    - Theming

      - Active Row / Active Cell / Editing Row/Cell / Error  Row/Cell


Default: <tr>{{each  columns}}<td>{{field this}}</td>{{/each}}</tr>



  <legend>${firstname}  ${lastname}</legend>

  <label>First name: </label>{{field "firstname"}}  {{editing "firstname"}}Uppercase!{{/editing}}

  <label>Last name:  </label>{{field "lastname"}}


// Note: Names must be exact  matches from header names




name -> StringFilter -> "John"

city -> StringFilter ->  "Boston"

date  -> StringFilterEdit -> <input type="text" ....>


Need template methods:

  - field

  - editing

  - editable


Comments (0)

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