Reputation: 4482
so I am trying to get the fields in my backbone model being called in the view, editable and validated by the model. How do I go about doing that? I know there is an html way of doing contenteditable="true" but I am looking for a more backbone oriented way or a way to actually make that validate too.
Here is my current code for my main.js file (but I am not trying to .append it I want it to stay in place and also trying to figure out how to get the field to be called specifically depending on which text they clicked on. Ultimately the button should change too (to save changes).
The main.js
App.Models.User = Backbone.Model.extend({
defaults: {
firstName: 'first',
lastName: 'last',
email: 'Email',
phone: '222',
birthday: 'date'
},
validate: function (attrs) {
if (!attrs.firstName) {
return 'You must enter a real first name.';
}
if (!attrs.lastName) {
return 'You must enter a real last name.';
}
if (attrs.email.length < 5) {
return 'You must enter a real email.';
}
if (attrs.phone.length < 10 && attrs.phone === int) {
return 'You must enter a real phone number, if you did please remove the dash and spaces.';
}
if (attrs.city.length < 2) {
return 'You must enter a real city.';
}
}
});
App.Views.UserUpdate = Backbone.View.extend({
model: App.Models.User,
events: {
'click .edit': 'editUserProfile'
},
editUserProfile: function(field) {
var field =
$('#user').append('<input type="text" class="edit" placeholder="' + field+'" /> ' );
},
initialize: function() {
this.model.on('change', function() {
this.render();
}, this);
},
render: function() {
this.$el.html(this.model.get('email'));
}
});
This is the jade file:
extends layout
block content
div.centerContent
script(type="text/javascript", src="/js/main.js")
h4 User goes here with equal before it no space
div(contenteditable="true")
form#user
- var firstName = "John"
- var lastName = "Smith"
label #{firstName} #{lastName}
- var email = "[email protected]"
label.edit #{email}
- var phone = "555-555-5757"
label #{phone}
- var pin = "PIN: LIO20001"
label #{pin}
- var birthday = "07/28/1982"
label #{birthday}
button Post
hr
div.user User
p
button.edit Edit
Upvotes: 3
Views: 3436
Reputation: 4340
I have created a fiddle for this: http://jsfiddle.net/LTGjT/18/
You should assign the contenteditable
and id
for each editable label:
- var firstName = "John"
- var lastName = "Smith"
label #{firstName} #{lastName}
- var email = "[email protected]"
label(contenteditable="true", id="email") #{email}
- var phone = "555-555-5757"
label(contenteditable="true", id="phone") #{phone}
- var birthday = "07/28/1982"
label(contenteditable="true", id="birthday") #{birthday}
The reason is to recognize what label is being edited by getting the event.target
, in your old code the event.target
will always be the parent div
.
Then in backbone
listen to the input
event for the change of the label then update the model:
App.Models.User = Backbone.Model.extend({
defaults: {
firstName: 'first',
lastName: 'last',
email: '[email protected]',
phone: '222',
birthday: '01/01/2001'
},
initialize: function() {
},
validate: function (attrs) {
if (!attrs.firstName) {
return 'You must enter a real first name.';
}
if (!attrs.lastName) {
return 'You must enter a real last name.';
}
if (attrs.email.length < 5) {
return 'You must enter a real email.';
}
if (attrs.phone.length < 10 && attrs.phone === int) {
return 'You must enter a real phone number, if you did please remove the dash and spaces.';
}
if (attrs.city.length < 2) {
return 'You must enter a real city.';
}
}
});
App.Views.UserUpdate = Backbone.View.extend({
model: App.Models.User,
events: {
'click button' : 'saveHandler'
},
initialize: function() {
var self = this;
self.render();
console.log(this.model);
$('[contenteditable=true]').on('input', function(e){
var field = e.target.id;
var value = e.target.innerText;
self.model.set(field, value);
logUser(self.model);
});
self.model.on('change', function(){
$('button').show();
});
},
saveHandler: function(e) {
//Validate & Save logic
//this.model.save()
e.preventDefault();
$(e.target).hide();
},
render: function() {
var template = _.template($('#user-view').html());
this.$el.html(template({user: this.model.toJSON()}));
$('body').prepend(this.$el);
logUser(this.model);
}
});
Upvotes: 4