Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone.js: how to inline editing on attribute of a model

how would i add inline editing on attributes of a model,

for example, when i have a Player model

var Player = Backbone.Model.extend({
  defaults: {
    id: 0,
    name: '',
    points: 0
  },
  initialize: function(){
    // irrelevant stuff happening here...
  },
  rename: function(newName){
    this.set({ name: newName });
  }
});

and a playerRow view

var PlayerRow = Backbone.View.extend({
  tagName: 'li',
  className: 'player',
  events: { 
    'click span.score':  'score',
    'blur input.name': 'rename',
    'click div.playername': 'renderRename'
  },   
  initialize: function(){
    _.bindAll(this, 'render', 'rename');
    this.model.bind('change', this.render);
  },
  render: function(){
    var template = Tmpl.render("playerRow", { model : this.model });
    $(this.el).html(template);
    return this;
  },
  renderRename: function() {
    // i was thinking of switching the DOM into a textfield here
  },
  rename: function(){
    var inpt = $(this.el).find('input.name');
    var newName = (inpt.val() != '') ? inpt.val() : 'no-name';
    this.model.rename(newName);
  }
});

and my playerRow template

<script type="text/template" id="playerRow-template">
  <% if ( model.get('name') == '' ) { %>
    <div class="state-edit"><input type="text" class="name" name="name"></input></div>
  <% } else { %>    
    <div class="playername"><%= model.get('name') %></div>
  <% } %>
</script>

either i set a certain property of my model that holds the state (default or edit), which triggers a re-render and in my template instead of testing if name == '' i can test on that state property.

or i do it inline like i say in my comment in renderRename i just swap the DOM into an input field but i think this is a bad way to do it. Would this cause troubles with the already bound events? like 'blur input.name': 'rename'

i doubt creating a new view for the edit is the best way, because i want inline editing, for just this one name field, i don't want all the rest of the player template to be duplicate in the player template and the editplayer template.

so, bottomline, my question: what is the best way, to handle inline editing

  1. a separate view
  2. inline just appending an input field (don't know if this works well with the bound events)
  3. having my model hold a state variable for this attribute (would work but sounds weird to have a model hold view related data)
like image 206
Sander Avatar asked Jan 18 '23 16:01

Sander


1 Answers

A different option altogether:

Inline edititing making use of the html EditableContent feature. No need for changing/cluttering the DOM, great user experience if done correctly, supported in all major browsers.

A couple of js-editors make use of this, most notably Aloha Editor (check for browser support), but for attribute editing without needing much else (e.g rich text editing etc) you can easily roll your own.

EDIT: June 2012:

Rolling your own becomes much easier when using the excellent range Library: http://code.google.com/p/rangy/

Hth, Geert-Jan

like image 158
Geert-Jan Avatar answered Jan 31 '23 16:01

Geert-Jan