Having the following view:
someView = Backbone.View.extend({
events : {
'change #selectID' : 'checkSelect'
},
checkSelect : function(e) {
console.log(e);
}
});
I wonder if possible to the selected option from the select tag, considering this select is rendered with data injected from a collection.
Any help?
You can get the value of the select with $(e.target).val() as in:
var MyView = Backbone.View.extend({
events : {
'change #selectID' : 'checkSelect'
},
checkSelect : function(e) {
var selectValue = $(e.target).val();
console.log(selectValue);
}
});
Check this fiddle
Related
define(["jquery" ,
"underscore" ,
"backbone" ,
"custom",
"wishlist"
],function($ , _ , Backbone, Ice, WishList){
var wishlist1 = new WishList();
var SavedCartView = Backbone.View.extend({
tagName:"div",
initialize : function(){
console.log("hi!");
},
event : {
'click .savedCart' : 'viewEachCart'
},
viewEachCart : function(e){
console.log(1);
},
render : function(){
wishlist1.viewAllSaveCart(106,function(output){
_.each(output,function(row){
$("#webbodycontainer").append('<a class="savedCart" id="'+row.ID+'">'+row.Name + "</a><br>");
});
});
}
});
return SavedCartView;
});
Here is the router :
app_router.on('route:savedCart', function( ){
if(window.currentSection)
window.currentSection.remove();
window.currentSection = new SavedCart({});
$("#webbodycontainer").html(window.currentSection.$el);
window.currentSection.render();
});
console.log(1); didn't work, Any idea what could be causing this. Thanks.
I think this should be events : {
If ".savedCart" is an anchor tag (like this):
Saved Cart
...then you need to have e.preventDefault() in your function so that the link is not activated.
events : {
'click a.savedCart' : 'viewEachCart'
},
viewEachCart : function(e){
e.preventDefault();
console.log(1);
},
In formView inside the newAttributes method i would like to trigger an event that will then show the entry view(both are shown here). In order to do this should I use a controller? It seems no matter how I set the trigger and listenTo commands up I get a different error.
MyApp = new Backbone.Marionette.Application();
MyApp.addRegions({
formBox : '#formBox',
listBox : '#listBox'
});
Entry = Backbone.Model.extend({
defaults: {
DB : 'not specified',
CT : 'not specified',
go : 'not specified'
},
});
EntryList = Backbone.Collection.extend({
model: Entry
});
FormView = Backbone.Marionette.ItemView.extend({
tagName: 'div',
template: '#form-template',
className: 'form',
ui: {
DB: '#DB',
CT: '#CT',
gos: '#gos'
},
events:{
'click #processInput' : 'validateForm'
},
onRender: function(){
console.log("rendering...");
},
validateForm : function(){
var validInput = true;
if(!this.ui.DB.val().trim())
{
validInput = false;
!this.ui.DB.css("background-color","#CC0000");
}
else
{
!this.ui.DB.css("background-color","#ffffff");
}
if(!this.ui.CT.val().trim())
{
validInput = false;
this.ui.CT.css("background-color","#CC0000");
}
else
{
this.ui.CT.css("background-color","#ffffff");
}
if(!this.ui.gos.val().trim())
{
validInput = false;
this.ui.gos.css("background-color","#CC0000");
}
else
{
this.ui.gos.css("background-color","#ffffff");
}
if(validInput)
{
this.hideForm();
this.getEntries(this.ui.DB.val().trim(),
this.ui.CT.val().trim(),this.ui.gos.val().trim());
}
},
newAttributes :function(db,con,gos){
for(go in gos)
{
MyApp.ents.add({DB : db, CT: con, go: gos[go]});
}
//TRIGGER CUSTOM EVENT
},
getEntries : function(db,con,gos){
var gos = gos.split("\n");
for(go in gos)
{
console.log("data bank: " + db + " CT: " + con + " go: |" + gos[go].trim()+"|");
}
this.newAttributes(db,con,gos);
},
hideForm : function(){
this.$el.hide();
}
});
EntryView = Backbone.Marionette.ItemView.extend({
tagName: 'tr',
template: '#entry-template',
className: 'entry',
events: {
'click .delete' : 'destroy'
},
destroy : function(){
this.model.destroy();
}
});
EntriesView = Backbone.Marionette.CompositeView.extend({
tagName: 'table',
template: '#entries-template',
itemView: EntryView,
appendHtml: function(collectionView, itemView){
colleCTionView.$('tbody').append(itemView.el);
}
});
MyApp.addInitializer(function(test){
var entriesView = new EntriesView({
collection: test.DB
});
var formView = new FormView();
//SHOW on load
MyApp.formBox.show(formView);
//SHOW Later with custom event
MyApp.listBox.show(entriesView)
});
$(document).ready(function(){
MyApp.ents = new EntryList([]);
MyApp.start({DB: MyApp.ents});
});
There are 2 ways you can solve your problem.
The cleanest way is to use a controller, and listen for the triggered event on the view instance within the controller. E.g. in your view, have this.trigger("my:event"), then in your controller have myFormViewInstance.on("my:event", function(...){...})
Another option (which wouldn't really be recommended), is to trigger the event at the application level, and listen for it elsewhere also on the application level. I.e. MyApp.trigger("my:event") and MyApp.listen("my:event")
I have the problem that the event "form:selectedForm" is calling the method "showForm" but when sending this to my view I am getting the following error: TypeError: e[t] is not a function.
This is stated in line 128 in the backbone.js script but I have no clue what he is doing there. It looks like that he is looking for a "to" or "on" event on the collection.
What I am doing wrong here?
MyController = Backbone.Marionette.Controller.extend({
initialize: function(options) {
this.options = options;
this.urls = options.urls;
this.mainRegion = options.mainRegion;
this.view = new MyLayout();
this.mainRegion.show(this.view);
this.view.render();
this.showSelectorView(this.view.formHeader);
},
showSelectorView : function(view) {
var forms = new MyForms();
forms = this.urls.loadForms;
var selectorView = new FormSelectorView({
collection: forms
});
forms.fetch();
this.listenTo(selectorView, "form:selectedForm", this.showForm);
view.show(selectorView);
},
showForm : function(models) {
console.log("showForm");
var form = new FormContentView({
collection: models
});
this.view.form.show(form);
}
});
MyLayout = Backbone.Marionette.Layout.extend({
template: Backbone.Marionette.TemplateCache.get('#content'),
regions: {
formHeader: "#selector",
form: "#formContent",
formContent: "#content",
formFooter: "#save",
formTemplates: "#templates"
}
});
FormSelectorView = Backbone.Marionette.ItemView.extend({
template: Backbone.Marionette.TemplateCache.get('form-selector-template'),
events : {
"click option" : "selectForm"
},
initialize : function() {
this.listenTo(this.collection, "sync", this.render, this);
},
selectForm : function(e) {
e.preventDefault();
var id = $(e.currentTarget).attr("name");
var item = this.collection.get(id);
this.trigger("form:selectedForm", item.attributes.fields);
}
});
I think the error is in your showSelector view function, you are overwriting your forms collection in the second line,
i think your intention in that line was to assing the url of the forms collection so my guess is that this will fix it:
showSelectorView : function(view) {
var forms = new MyForms();
forms.url = this.urls.loadForms; /// Im assuming you were trying to pass the url here
var selectorView = new FormSelectorView({
collection: forms
});
forms.fetch();
this.listenTo(selectorView, "form:selectedForm", this.showForm);
view.show(selectorView);
},
I have the following problem. On a user-event (click on .twitterDefault) I call save event with
twitter : {
handle : handle,
ignore : false
}
Then the success function gets called and I set fields on the model (klout, twitter and tester). All fields are set (logging statements all print out appropiate objects.
However, then I call view.render() and here twitter is not set anymore. I have no idea why, there is no sync happening after the save so twitter does not get overwritten (additionally I made sure twitter is also saved on the server before the success method gets called).
Any help greatly appreciated!
Code as follows (stripped to improve readability)
$(function() {
var ContactModel,
ContactModelCollection,
ContactView,
ContactCollectionView,
contacts,
contactCollectionView;
//base model
ContactModel = Backbone.Model.extend({
defaults : {
},
initialize : function() {
}
});
ContactModelCollection = Backbone.Collection.extend({
model : ContactModel,
url : '/api/contacts',
comparator : function(contact) {
return contact.get('strength_of_relationship');
},
initialize : function() {
}
});
ContactView = Backbone.View.extend({
tagName : 'li', //attempting to create a new element
render: function() {
var compiled_tmpl = _.template($('#contact-template').html());
var html = compiled_tmpl(this.model.toJSON());
console.log('model.get("twitter")=('+JSON.stringify(this.model.get('twitter)'))+')');
console.log('model.get("klout")=('+JSON.stringify(this.model.get('klout'))+')');
console.log('model.get("tester")=('+JSON.stringify(this.model.get('tester'))+')');
this.$el.html(html);
console.log('rendered view successfully)');
return this;
},
initialize: function() {
console.log('contactView initalized');
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
},
events: {
'click .twitterDefault' : 'assignDefaultTwitterHandle',
},
assignDefaultTwitterHandle : function(event) {
var handle = $(event.currentTarget).data('twitter');
this.assignTwitterHandle(handle);
},
assignTwitterHandle : function(handle) {
console.log('model assignTwitterHandle. handle='+handle+')');
var view = this,
model = view.model;
model.save({
twitter : {
handle : handle,
ignore : false
},
id : model.get('id')
}, {
error : function() {
console.log('saving twitter handle failed');
},
success : function(model, response) {
console.log('response=('+JSON.stringify(response)+')');
if(response.error) {
console.log('error on server ='+response.error);
}
if(response.twitter) {
console.log('twitter is set');
var twitter = {
handle : handle,
tweet : response.twitter,
age : new Date()
};
console.log('setting twitter to '+JSON.stringify(twitter));
model.set('twitter', twitter);
model.set('tester', 'tester');
console.log('twitter after setting it = '+JSON.stringify(model.get('twitter')));
console.log('view\'s model twitter after setting it = '+JSON.stringify(view.model.get('twitter')));
}
if(response.klout) {
console.log('klout is set');
var klout = {
topics : response.klout
}
console.log('setting klout to '+JSON.stringify(klout));
model.set('klout', klout);
}
if(response.twitter || response.klout) {
console.log('Rerendering view after setting klout/twitter');
view.render();
}
}
});
}
});
contacts = new ContactModelCollection;
ContactCollectionView = Backbone.View.extend({
el : $('#suggestions-list'),
initialize : function(){
contacts.bind('add', this.addOne, this);
contacts.bind('reset', this.addAll, this);
contacts.bind('all', this.render, this);
},
render : function(){
console.log('contactcollectionview render');
},
addOne : function(contact) {
console.log('addOne');
var view = new ContactView({model: contact});
var el = view.render().el;
console.log('el=('+el+')');
$('#suggestions-list').append(el);
},
addAll : function() {
console.log('addAll');
contacts.each(this.addOne);
}
});
contactCollectionView = new ContactCollectionView;
App.contacts = contacts;
App.contactCollectionView = contactCollectionView; });
I guess the problem is the scope of the render function.
Depending from where is called, this takes a different value.
To warranty that always this is pointing to the View scope, add to your initialize:
_.bindAll(this,"render");
Also, it's not good habit to call view.render manually. You should let the events do their work. Model save already triggers some events. Just listen to them to update your View.
I have a small backbone class:
view = Backbone.View.extend({
events: {
"click textarea" : "doSomething"
},
doSomething : function() {
var textarea = $(this.el).find('textarea')
// I would like to just call, this.textarea, or this.elements.textarea
}
});
Ideally I would like to be able to access my textarea through a variable instead of having to search the element every time. Anyone have any idea on how to accomplish this?
maybe i am under thinking it but how bout giving the textarea a class or id and target specifically when needed,
or create a sub view that generates the textarea
var View = Backbone.View.extend({
el: '#main',
initialize: function(){
this.render();
},
render: function() {
var subview = new SubView();
this.$('form').append(subview.el);
this.$('form').show();
},
});
var SubView = Backbone.View.extend({
tagName: 'textarea',
id: 'whateverId',
events: {
"click" : "doSomething"
},
initialize: function(){
this.render();
},
doSomething : function(event) {
var textarea = $(event.target);
// or var textarea = $(this.el);
},
render: function(){
return $(this.el);
}
});
The other answers get you the reference that you need, but if you really need a handle to the textarea, then you can do something like this:
view = Backbone.View.extend({
initialize: function() {
this.myTextareaElement = $(this.el).find('textarea')
}
events: {
"click textarea" : "doSomething"
},
doSomething : function() {
// use this.myTextareaElement ...
}
});
pass the event as the argument and then use the event target
view = Backbone.View.extend({
events: {
"click textarea" : "doSomething"
},
doSomething : function(event) {
var textarea = $(event.target);
}
});