Why are edit in place forms rendered together with the display version instead of being rendered on the fly?

1k views Asked by At

Is there a specific reason that most everyone implements edit-in-place as a shown 'display' div and a hidden 'edit' div that are toggled on and off when somebody clicks on the associated 'edit' button like so?

<div id="title">
  <div class="display">
    <h1>
      My Title
    </h1>
  </div>
  <div class="edit">
    <input type="text" value="My Title" />
    <span class="save_edit_button"></span>
    <a href="#" class="cancel_edit">Cancel</a>
  </div>
</div>

Everywhere I look, I see edit-in-place basically handled like this. This approach certainly makes sense when you are rendering all views on the server side and delivering them to the client. However, with pure AJAX apps and frameworks like backbone.js, it seems that we could make our code much more DRY by rendering edit-in-place form elements on the fly as necessary, possibly even making a factory method that determines which form element to render. e.g.

  • an H1 element with class "title" is replaced by <input type="text" />
  • a span with class "year_founded" is replaced by <input type="number" min="1900" max="2050" />
  • a span with class "price" is replaced by an input with the appropriate mask to only allow prices to be input.

Is this practice of rendering all edit-in-place form elements a historical legacy leftover from when pages were rendered on the server-side?

Given the flexibility and power we have with client-side MVC frameworks like Backbone.js, is there a reason for not creating and inserting the form elements on the fly when necessary using a factory method? Something like this:

HTML

<div id="description">
  Lorem ipsum dolar set amit...
</div>
<span class="edit_button"></span>

Backbone.js View

events: {
  "click .edit_button": "renderEditInPlaceForm",
},

renderEditInPlaceForm: function:(e) {
  var el = $(e.currentTarget).previous();
  var id = el.attr('id');
  var value = el.text();
  var tagName = el.tagName();
  var view  = new editInPlaceForm({   
    id: id,
    type: tagName,
    value: value
  });
  $("#id").html(view.render().el)
},

Where editInPlaceForm is a factory that returns the appropriate edit-in-place form element type based on tagName. This factory view also controls all its own logic for saving an edit, canceling an edit, making requests to the server and rerendering the appropriate original element that was replaced with the .html() function?

It seems to me that if we use this approach then we could also render the <span class="edit_button"></span> buttons on the fly based on a user's editing rights like so:

<h1 id="title">
  <%= document.get("title") %>
</h1>
<% if (user.allowedToEdit( document, title )) { %>
  <span class="edit_glyph"></span>  
<% } %>

where the allowedToEdit function on the user model accepts a model and attribute as its arguments.

2

There are 2 answers

0
Igor Alekseev On

After 5 Backbone apps I came to same thoughts.

When things are complicated you have forms to show relations between user data, but in simple cases you just need input, select, checkbox over h1, div or span

Now I am searching for jQuery plugin to make simple in place editing without ajax. jQuery but not Backbone becuase I don't want to be tight coupled with Backbone for such small thing.

Likely to wright my own jQuery + Synapse plugin http://bruth.github.com/synapse/docs/.

Synapse for binding with model and jQuery for input placing

0
graphicdivine On

It's an interesting idea. The devil is in the detail.

While your simple example is easily rendered as an editable form on the fly, things quickly get trickier when dealing with other data types.

For example - suppose my edit form requires the user to choose a value from a select list. On the display form I can simply display the user's choice, but for the edit form I am going to need those other available choices. Where do I hide them on the display? Similar issues exist for checkboxes, radio lists...

So, perhaps we should consider rendering the edit form, and then deriving our display-view from that?