Templates for nested attributes with Backbone
Asked Answered
H

2

1

I have an Appointment model, each instance of which has a Client. Here's my template for editing an appointment:

<form id="edit-appointment" name="appointment" class="mobile_friendly">
  <div class="field">
    <input type="text" name="start_time_ymd" id="start_time_ymd" value="<%= start_time_ymd %>" placeholder="Start Date">
    <input type="text" name="start_time_time" id="start_time_time" value="<%= start_time_time %>" placeholder="Start Time">
  </div>

  <div class="field">
    <input type="text" name="client_name" id="client_name" value="<%= client.name %>" placeholder="Client">
    <input type="hidden" name="client_id" id="client_id" value="<%= client.id %>" placeholder="Client ID">
  </div>

  <div class="field">
    <input type="text" name="client_phone" id="client_phone" value="<%= client.phone %>" placeholder="Phone">
  </div>

  <div class="field">
    <input type="text" name="notes" id="notes" value="<%= notes %>" placeholder="Notes">
  </div>

  <div class="actions">
    <input type="submit" value="Update Appointment" />
  </div>

</form>

<a href="#/index/<%= stylist_id %>">Back</a>

My problem is that my Client attributes aren't being passed to the server correctly. The JSON object that gets passed to the server on save looks something like the following. Let's pretend I have a client with phone number 555-555-5555 but I change it to 555-555-1234 and then submit the form:

{"appointment":
  {"start_time_ymd":"1/1/2000",
   "client_phone":"555-555-1234",
   "client":{"phone":"555-555-5555"}}

I've omitted a lot of irrelevant fields, but hopefully you see what I mean. I've changed client_phone from 555-555-5555 to 555-555-1234, but the client object in the JSON object has its phone number unchanged. I need to somehow change that phone number.

How do I make these fields - like the phone number field - actually "take" so they get passed to the server as part of the client object under appointment and not directly under appointment? I'm using Backbone-relational, if that makes a difference.

Hereinbefore answered 10/7, 2012 at 13:22 Comment(0)
H
1

I was able to get it to work like this:

class Snip.Views.Appointments.EditView extends Backbone.View
  template : JST["backbone/templates/appointments/edit"]

  events :
    "submit #edit-appointment" : "update"

  update : (e) ->
    e.preventDefault()
    e.stopPropagation()

    # THE ONLY CHANGE I MADE WAS TO ADD THIS LINE
    @model.attributes.client.phone = $("#client_phone").val()

    @model.save(null,
      success : (appointment) =>
        @model = appointment
        window.location.hash = "/#index/" + @model.attributes.stylist_id
    )   
Hereinbefore answered 19/7, 2012 at 17:28 Comment(0)
N
2

if after you change the form text your model is not being updated then you need to update the data explicitly

SampleView = Backbone.View.extend({
el: '#formEl',
events : {
    "change input" :"changed",
    "change select" :"changed"
},

initialize: function () {
    _.bindAll(this, "changed");
},
changed:function(evt) {
   var changed = evt.currentTarget;
   var value = $("#"+changed.id).val();
   var obj = "{\""+changed.id +"\":\""+value+"\"";

   // Add Logic to change the client phone
   if (changed.id === 'client_phone') {
          obj = obj + "client\":{\"phone\":\""+value+"\""};
   }
   obj = obj + "}";
   var objInst = JSON.parse(obj);
   this.model.set(objInst);            
}
});

Reference : Can I bind form inputs to models in Backbone.js without manually tracking blur events?

You can also bind to model change event

    model.on('change:client_phone', 
       function () { 
           //Set client value here  
       });
Neodarwinism answered 11/7, 2012 at 5:27 Comment(0)
H
1

I was able to get it to work like this:

class Snip.Views.Appointments.EditView extends Backbone.View
  template : JST["backbone/templates/appointments/edit"]

  events :
    "submit #edit-appointment" : "update"

  update : (e) ->
    e.preventDefault()
    e.stopPropagation()

    # THE ONLY CHANGE I MADE WAS TO ADD THIS LINE
    @model.attributes.client.phone = $("#client_phone").val()

    @model.save(null,
      success : (appointment) =>
        @model = appointment
        window.location.hash = "/#index/" + @model.attributes.stylist_id
    )   
Hereinbefore answered 19/7, 2012 at 17:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.