How to capture the iCheck change event in backbone view.
I am unable to find any reference and using normal change event is not working.
My solution for events backbone.js is
events: {
'ifChanged #myIdCheckbox': 'changed'
},
First of all, you should try to search on the Internet almost all plugins have a web page, this one for example: http://icheck.fronteed.com/
But anyway, to listen to click event Ichecks, you must use ifChanged or check
$('input').on('ifChanged', function (e) {
var value = $(this).val();
....
});
You can also use an ID to select a checkbox just by typing: $('#Id').....
Related
Question is why isn't the Backbone view executing the jQuery custom event handler?
I'm trying to listen for the enter key on an text box and when the enter key is pressed, and only the enter key, I want to execute a function. I'm using require.js 2.1.15, jquery 1.11.1, backbone 1.1.2 and underscore 1.7.
The idea is to register the "enter.js" plugin with jquery.
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module depending on jQuery.
console.log("require.js registered");
define(['jquery'], factory);
} else {
// No AMD. Register plugin with global jQuery object.
console.log("no amd registered");
factory(jQuery);
}
}(function ($) {
console.log('registered event listener for input on the enter key');
$('input').keyup(function(e) {
console.log("key input");
if(e.keyCode == 13){
console.log("enter key assessed");
$(this).trigger('enter');
}
})
}));
This executes and registers with no errors in the console.
require.js registered enter.js:12
registered event listener for input on the enter key Problem.js:4
Now the backbone code:
define(function (require) {
"use strict";
console.log("start of ArithmeticView.js");
var
$ = require('jquery'),
enter = require('../../$plugins/enter'),
_ = require('underscore'),
Backbone = require('backbone'),
tpl = require('text!tpls/ArithmeticView.html'),
ProblemModels = require('../models/Problem'),
template = _.template(tpl);
return Backbone.View.extend( {
el: 'body',
events: {
"enter .answer": "solve",
},
initialize: function(){
this.render();
this.displayProblem();
},
render: function() {
console.log("render ArithmeticView");
return this.$el.html(template());
},
solve: function() {
console.log("solving ProblemModels.Problem");
var givenAnswer = $(".answer").val();
if(givenAnswer == this.problem.get("answer")) {
return this.displayProblem();
}
return this;
},
displayProblem: function() {
this.problem = new ProblemModels.Problem;
$('.problemArea').text(this.problem.get("question"));
return this;
}
});
});
When I debug in Chrome console I can see the enter listener attached to the textarea with the class answer attached to it. I don't see anywhere in the console the actual function code as coded in the jQuery plugin enter.
Updated:
I totally understand your specifications, in fact I personally like the way you're handling the 'enter' event. Except that the way you're implementing it, it will never work with dynamically loading HTML (think templates).
The reason your view isn't listening to the 'enter' event is because it's not there
Yea, I know, I know. The enter.js plugin is binding to all <input> elements. All of them that are there at the time it's doing the binding. From the jQuery docs (emphasis theirs):
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on()
When you populate and attach template code, _.template returns all new DOM elements. Even bindings to all elements of a type like $('input').on will not protectively bind to new <input> elements.
Workaround
In my opinion, your best bet is to rebind your plugin after you render the view.
(Normally you'd want to use delegation to get around this problem, and read the jQuery.event.target property in your plugin to see if the keypress came from an <input> element, but you can't use that in your view events hash because Backbone can't detect delegation.)
Alternative workaround
Handle the enter keypress in each method that you need to listen for.
Just replace
"enter .answer": "solve"
with
"keypress .answer": "solve"
and add the following in your solve method
solve: function(event) {
event.stopPropagation();
if (event.keyCode == 13) {
console.log("solving ProblemModels.Problem");
var givenAnswer = $(".answer").val();
if(givenAnswer == this.problem.get("answer")) {
return this.displayProblem();
}
return this;
}
}
Backbone will always send a jQuery event object to the callback of a view event. jQuery packages the keyCode property in the event object which saves the key detected on the keypress event. In your case (and if you look at your plugin) all we do is test whether the key pressed was the enter key, with a key code of 13.
The above reproduces your desired effect without the complexity of registering and then loading the plugin into scope with Require. I know it's not as neatly encapsulated as using the enter.js plugin but it makes the code more straightforward and it may possibly run leaner without the plugin overhead.
I can't get event tracking to work for a submit button press on a site.
The relevant code is
button class="btn-submit validate contact-btn " type="submit" onclick="_gaq.push(['_trackEvent', 'ClutchEnquiry', 'Submit']);" >SUBMIT
Is this syntax correct?
https://developers.google.com/analytics/devguides/collection/analyticsjs/sending-hits
// Gets a reference to the form element, assuming
// it contains the id attribute "signup-form".
var form = document.getElementById('signup-form');
// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {
// Prevents the browser from submiting the form
// and thus unloading the current page.
event.preventDefault();
// Sends the event to Google Analytics and
// resubmits the form once the hit is done.
ga('send', 'event', 'Signup Form', 'submit', {
hitCallback: function() {
form.submit();
}
});
});
Are you using the correct analytics object (ie. _gaq or ga)? It would depend on whether you are using Universal Analytics (analytics.js) or classic Google Analytics (ga.js) in your snippet. From you onclick handler, it looks like you may be using classic, but I've seen situations where the user mixes up the _gaq and the ga objects. Syntax-wise, it looks correct.
More information on the event push syntax can be found here https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide.
Hope this helps.
Nyuen is correct. You most likely are using Universal analytics so the JS object you want to use is below:
New syntax:
ga('send', 'event', 'button', 'click', 'ClutchEnquiry')
Old Syntax:
_gaq.push['_trackEvent', 'ClutchEnquiry', 'Submit'])
in my project i am not able to trigger click event registered in one backbone view from another backbone view. its actually i am having a file type input placed hidden from the user and i need to trigger the file type input.
var FileView = Backbone.View.extend({
....
events : {
"click .delete-image" : "deleteFile",
}
....
});
var FilesView = Backbone.View.extend({
....
events : {
"click #attach" : "attachFile",
},
attachFile : function() {
this.fileView.trigger("click .delete-image");
}
....
});
but i tried like this the event is not get triggered. how is it possible.
the events hash attaches itself to the jquery element that represents the view, not the backbone view itself. So you would most likely have to do something like this:
attachFile : function() {
$('.delete-image', this.fileView.$el).trigger("click");
}
but I would discourage this kind of non-pattern and instead work towards using something we call an Event Aggregation pattern. You can find a collection of really good SO solutions next:
fire an event from one view to another in backbone
Backbone.js global events
Multiple view on same page with backbone.js
I am using Extjs 4.1. I need to identify event on grid when data renderred and arrived.
I checked ''afterrender' event. But it fires to early
grid.on('afterrender', function () {
alert(333);
});
Please advice
You're correct grid rendered event would fire after grid was rendered not after the data is displayed. What about subscribing to the store load event?
store.on('load', function() {
...
})
If you simply need to know when the grid has first loaded data, use the Ext.grid.Panel viewready event, it fires when the data has been loaded in and the grid rows have been rendered.
Example:
this.control({
'mygridpanel': {
// select the first record
viewready: function(grid) {
var store = grid.getStore(),
view = grid.getView(),
selModel = grid.getSelectionModel();
if (store.getAt(0)) {
view.focus();
selModel.select(0);
}
},
},
});
This example is configured in the init function of a controller using the MVC pattern, I'm not sure if you are using MVC pattern? The snippet in your comment should work fine either way though.
Also this event passes the Ext.grid.Panel object that fired it as the first argument, as you can see from the example above, you can use that to get a reference to your grid and perform whatever logic you need to do on it in your handler.
Say I have a View that displays a search box with a submit button.
When I click on the submit button how do i pass the value of the search box to another view ?
I tried:
In view 1, inside the submit callback : this.trigger('abc', $('#searchBox').val())
In view 2, in the initialize function: this.bind('abc', function(data){ console.log(data); })
but that does not seem to work: the custom event is fired but View 2 does not see it.
Here's a great article by Derick Bailley # LosTechies.com:
References, Routing, And The Event Aggregator: Coordinating Views In Backbone.js
This article discusses a simple solution using PubSub that is built in Backbone.JS. I agree with Derick when he mentions that views should be decoupled.
Unfortunately you can't bind this way - you will need to share a reference to view1 in view2:
var View2 = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'foo');
this.view1.bind('abc', this.foo);
},
foo: function(data) {
console.log(data);
}
});
This also means that at some point you need to set view1 on your instance of View2 so that you can bind against it.
If you don't want to pass the references around, simply bind the two views together in whatever container you are holding them in (i.e. another view or a controller):
var view1 = new View1();
var view2 = new View2();
view1.bind('abc', view2.foo);
I suggest using a PubSub framework in addition to backbone. MinPubSub is a popular choice. I use the jquery pubsub extension extracted from https://github.com/phiggins42/bloody-jquery-plugins.
Then, View 2 doesn't need a reference to View 1. To modify Andrew Hare's example, you would do:
var View2 = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'foo');
$.subscribe('abc', this.foo);
},
foo: function(data) {
console.log(data);
}
});
Then in View 1:
$.publish('abc', $('#searchBox').val());
Of course, with a pubsub system, you will probably want to use something better than "abc", perhaps instead choosing "searchBox:submit" as the topic.