Backbone js - change model attributes - javascript

I have a backbone model:
App.Models.Education = Backbone.Model.extend({
schema: {
university: {
type: 'Text',
validators: ['required'],
editorAttrs: {placeholder: 'Test placeholder'}
},
info: {type: 'Text'},
desc: {type: 'Text'}
})
and extend it:
App.Models.HighSchool = App.Models.Education.extend({
initialize: function () {
//code to change placeholder
this.set({education_type: init_parameters.school});
}
});
How to change the placeholder text in "university" field of HighSchool?

I wouldn't recommend setting up your models that way. You should try to avoid nesting attributes because of the exact same issue you're having. It becomes hard to change one particular field.
Instead, can you do something like:
App.Models.Education = Backbone.Model.extend({
defaults: { // backbone keyword to have default model attributes
type: 'Text',
validators: ['required'],
editorAttrs: {placeholder: 'Test placeholder'
}
});
App.Models.HighSchool = App.Models.Education.extend({
initialize: function () {
//code to change placeholder
this.set('editorAttrs', {placeholder: 'new placeholder'});
this.set('education_type', init_parameters.school);
}
});

Related

Issues with dynamic routing using meteor-autoform and iron:router

What I am trying to do is create a form with meteor-autoform that will redirect the user to a newly generated route on submit. My thought process is that I can take the submissions _id and use it for an iron:router parameter. What I have so far looks as followed:
Creation of Form
Submits = new Meteor.Collection('Submits');
Submits.allow({
insert: function(username, doc){
return !!username;
}
});
SubmitSchema = new SimpleSchema({
title: {
type: String,
label: "Title"
},
subject:{
type: String,
label: "Subject"
},
summary:{
type: String,
label: "Summary"
},
author:{
type: String,
label: "Author",
autoValue: function() {
return this.userId
},
autoform: {
type: "hidden"
}
},
createdAt: {
type: Date,
label: "Created At",
autoValue: function(){
return new Date()
},
autoform: {
type: "hidden"
}
}
});
Submits.attachSchema( SubmitSchema );
Routing
Router.route('/submit', {
layoutTemplate: 'submitLayout',
waitOn: function() { return Meteor.subscribe("Submits"); },
loadingTemplate: 'loading'
});
Router.route('/submit/:_id', {
name: 'formDisplay',
data: function() {
return Submits.findOne({this.params._id});
}
});
And then I just have the average publish and find calls. My issues are I'm not sure how to perform the redirect on submit, and I am not sure how to display the form results on the newly generated route.
Any help would be appreciated.
I was able to do it by adding an autoform.hook and changing my routing a bit.
Autoform hook:
AutoForm.addHooks('insertSubmit', {
onSuccess: function(doc) {
Router.go('formDisplay',{_id: this.docId});
}
})
Routing:
Router.route('/submit/:_id', {
name: 'submitLayout',
data: function() { return Products.findOne(this.params._id);}
});
I got this information from this post:
Route to the new data submitted by Meteor autoform using iron router?

How to remove nested collection when destroying model?

I'm initializing nested collection like te following:
var post = {
id: 123,
title: 'Sterling Archer',
comments: [
{text: 'Comment text', tags: ['tag1', 'tag2', 'tag3']},
{text: 'Comment test', tags: ['tag2', 'tag5']}
]
};
var PostModel = Backbone.Model.extend({
parse: function (response) {
if (response.comments) {
response.comments = new Backbone.Collection(response.comments);
}
return response;
}
});
var post = new PostModel(post, {parse: true});
How should I remove nested 'comments' collection when removing model?
post.destroy();
You can override destroy method of your PostModel instead of sync (which will not be called in case of a new model without id attribute):
destroy: function(options) {
this.get('comments').each(function(mdl) {
mdl.destroy();
});
Backbone.Model.prototype.destroy.call(this, options)
}
This something can be use to delete comments.
sync : function(method,model,options){
if(method=='delete'){
this.comments.destroy();
}
Backbone.sync(method,model,options);
}

BackboneForms different key than display possible?

I have a very simple form:
var UserForm = Backbone.Form.extend({
template: _.template($('#formTemplate').html()),
schema: {
venue: { validators: ['required'] },
},
model: this.model
});
This create a label with name Venue and puts a textfield beside it. But what if I want to name the label VenueName and keep the key it assigns to model venue. Is this possible? Thanks!
From the documentation yes, this is very easy:
var UserForm = Backbone.Form.extend({
template: _.template($('#formTemplate').html()),
schema: {
venue: {
validators: ['required'],
title: 'Venue Name'
},
},
model: this.model
});

How to add function on table fields - Backbone.js

I have this code in a Backbone application that I need to debug. (rough idea)
window.TableView = Backbone.View.extend({
initialize: function() {...
..
..
...
});
},
selectRow: function() {
...
...
..
},
render: function() { // this renders my models fields in a table
var editableColumns = [
//{ name: "display", type: "combobox", combobox: comboboxOptions, validate: validateText },
{ name: "display" },
{ name: "submitDate", type: "datepicker", datepicker: datepickerOptions },
{ name: "displayDate", type: "datepicker", datepicker: datepickerOptions },
{ name: "name"},
...
...
Now my problem is, how can I add a function to this field: { name: "display" }
like onclick, or after focus function, etc.? For example can I have,
{ name: "display", onclick: setMyText(); } or something like this? Also is this part of backbone.js or one of its components? Where can I read more about this?
In Backbone you have events hash for a View where you can specify the events for respective View. Events are specified in following format:
{"event selector": "callback"}
So in your case for all the editableColumns you also need a selector for each one or may you can specify by using the name property. Try specifying the events hash like this :
events: {
'click .columnSelector[name="display"]' : "setMyText"
}
where .columnSelector is the class applied to element that is to be edited.
For more details on events check this.

Backbone Collection Can't Remove Items

I've got a Backbone Model called Delivery. I then create a collection of Deliveries called DeliveryList backed by LocalStorage. In my Marionette.ItemView for displaying items in the collection, I have a method to remove items:
removeDeliveryOption: function() {
Deliveries.remove(this.model.get("id"));
}
For some reason, this removes the item from the Marionette.CompositeView when I click the remove button, but when I reload the page the same number of items always reappear.
It's worth noting that when I delete the item, it always reappears with the default optionName "Free Delivery". I'm using both defaults and a schema in the model because I'm using the Backbone-forms plugin (https://github.com/powmedia/backbone-forms).
Any help is greatly appreciated!
var Delivery = Backbone.Model.extend({
defaults: function () {
return {
order: Deliveries.nextOrder(),
optionName: "Free Delivery",
shipToState: "Hawaii",
zipCodes: "96813",
perOrderFee: "0.00",
perItemFee: "0.00"
};
},
schema: {
optionName: { type: 'Text', validators: ['required'] },
shipToState: { type: 'Select', options: getStateNames(), validators: ['required'] },
zipCodes: { type: 'Text', validators: ['required'] },
perOrderFee: { type: 'Text', validators: ['required'] },
perItemFee: { type: 'Text', validators: ['required'] },
}
});
var DeliveryList = Backbone.Collection.extend({
model: Delivery,
localStorage: new Backbone.LocalStorage("deliverylist-backbone"),
nextOrder: function () {
if (!this.length) return 1;
return this.last().get('order') + 1;
},
comparator: 'order'
});
var Deliveries = new DeliveryList;
var deliveryView = Marionette.ItemView.extend({
//tagName: "li",
template: "#delivery-item-template",
events: {
"click #removeThis": "removeDeliveryOption",
},
removeDeliveryOption: function() {
Deliveries.remove(this.model.get("id"));
}
});
var DeliveriesView = Marionette.CompositeView.extend({
initialize: function() {
Deliveries.fetch();
},
template: '#deliveries-view-template',
itemView: deliveryView,
events: {
"click #addShipping": "addDeliveryOption",
},
addDeliveryOption: function() {
var editDeliveryForm = new Backbone.Form({
template: _.template($("#editDeliveryTemplate").html()),
model: Deliveries.create()
}).render();
this.$el.append(editDeliveryForm.el);
$("#triggerEditDelivery").fancybox({
'afterClose': function () {
commitForm(editDeliveryForm);
//Wait do display the inlineModel until here
// Once we've bound the form to the model, put the saving logic with the collection
//Deliveries.last().save();
}
}).trigger('click');
},
// Specify a jQuery selector to put the itemView instances in to
itemViewContainer: "#deliveries",
});
EDIT
Thanks to #ejosafat! Had to destroy the model instead of just removing from collection.
removeDeliveryOption: function() {
this.model.destroy();
}
The remove method only affects the collection loaded in the browser, not in the permanent storage (local or server). That's why it dissappears from the view but when you reload the page it appears again.
If you want to get rid of that model in the storage too, use its destroy method.
(btw, it's a common convention in Javascript to use initial capital letter only for constructor functions, as clue that it should be used with the new operator, or be extended to create a derived constructor/class, so it's a bad idea to use Deliveries as a collection var name)

Categories

Resources