I'm converting a mootools class to Jquery, but I'm with a problem at the moment.
I've the following code (mootools)
var ListaItens = new Class({
...
...
initialize: function(element){
....
this.btnAdd = this.tabela.getElement('.add_linha button');
if(this.btnAdd){
this.btnAdd.addEvent('click', this.addLinha.bindWithEvent(this));
this.checkAdd();
}
...
},
addLinha: function(){
}
});
Now in Jquery I've this
var ListaItens = function(element, maxLinhas){
...
this.btnAdd = this.tabela.find('.add_linha button')[0];
if(this.btnAdd){
//$(this.btnAdd).proxy('click', this.addLinha);
$(this.btnAdd).on("click", this.addLinha);
this.checkAdd;
}
...
this.addLinha = function(){
}
})
My problem is how to bind the addline function to btnAdd. My code isn't work because the element 'this' change. And I don't know how to convert the function bindWithEvent to jquery.
Any solution?
Thanks in advance
As far as I know, jQuery does not provide a similar concept of classes as mootools does, so one thing you can do is to use the »classic JS approach« to create classes like so:
function ListaItens () {
var that = this;
this.tabela = $(…);
this.btnAdd = this.tabela.find(…);
if (this.btnAdd) {
this.this.btnAdd.on('click', function (e) {
that.addLinha();
})
}
}
ListaItens.prototype.addLinha = function () {
}
var instance = new ListaItens();
So, to answer your question: What you basically need to do is to keep a reference to the »original this«
Related
To demonstrate my issue, here I have small demo Script:
/user.html =
<div id="user-box"></div>
js =
class UserComponent {
constructor({}) {
this.srcFile = "/user.html";
this.parentBox = $("#container-box");
this.childBox = $("#user-box");
};
show(){
this.parentBox.load(this.srcFile, function() {
this.childBox.html("<p>Hello</p>")
}.bind(this));
};
}
The problem is that this line does not work correctly:
this.childBox.html("<p>Hello</p>")
For me the problem seems to be that when this.chilBox is referenced in the constructor, it does not yet exist in the DOM.
When I rewrite my code to:
this.parentBox.load(this.srcFile, function() {
var childBox = $("#user-box");
childBox.html("<p>Hello</p>")
}.bind(this));
Then it works. But I would like to reference the element in the constructor.
How can I reference the element in the constructor and then use it later when it exists?
I tried this.childBox.find().html("<p>Hello</p>") but like this it did not work.
Thanks for your help!
try this
this.childBox.html($("<p>Hello</p>"))
instead of
this.childBox.html("<p>Hello</p>")
I am setting some setInterval values on my widget's controller code as follows:
define(['durandal/widget'],function (widget) {
var count = 0;
var intervals = [],
ctor = function (element, settings) {
this.settings = settings;
};
ctor.prototype.updateCount = function( ){
var interval = setInterval(function () {
count = count + 1;
return count;
}, 1000);
intervals.push(interval);
}
return ctor;
}
The above code is being run inside a forEach loop inside the view like:
<div data-bind="foreach: {data: settings.items}">
<span class="count" data-bind="text:$parent.updateCount()"></span>
</div>
What I would like to do is call the clearInterval method on all the items in the intervals array when the widget is destroyed or essentially removed from the dom. I know I could do this using the deactivate on a viewModel but from a reusability point of view, I would like the widget itself to handle the clearing of interval. Is there any way I could achieve this with the widget module in Durandal.
For anyone else looking into the same issue, there's a knockout way of achieving the same. Have a look at the following links https://github.com/BlueSpire/Durandal/issues/139 and https://groups.google.com/forum/#!topic/durandaljs/NqUkY-9us2g . The suggestion is to use:
ko.utils.domNodeDisposal.addDisposeCallback(element, callback)
As long as the widget is removed with JQuery's "remove" function, adding a custom event handler on this "remove" function should go like this:
var self = this;
var self.count = 0;
var self.intervals = [];
self.ctor = function (element, settings) {
$(element).on("remove", function () {
$.each(self.intervals, function(index, ival) {
clearInterval(ival);
});
});
this.settings = settings;
};
The problem is that if the widget is removed without JQuery, simply by manipulating the DOM, the event will not be fired. You could then implement the code for the DOMNodeRemoved event, but it's not gonna work for IE...
Edit: if you're using JQuery pre-1.9.1, you might want to check out the other answers to this question.
I want to add a function to jQuery UI Dialog. I want to do that without actually downloading .js file with jQuery UI Dialog source code and editing it. Is it possible to do this from separate .js file?
Some further explanation: let's say I want to add custom function that's called e.g. "func1". After I've coded it, I should be able to call it like this:
($"#dialog").dialog("func1");
Is that possible without editing original jQuery Dialog source code?
Ok, I've finally found the answer :D
(function($){
var _init = $.ui.dialog.prototype._init;
//Init
$.ui.dialog.prototype._init = function() {
var self = this;
_init.apply(this, arguments);
//here you can do custom init
};
//Custom Dialog Functions
$.extend($.ui.dialog.prototype, {
func1: function() {
alert("f1");
},
func2: function() {
alert("function 2");
}
});
})(jQuery);
I have figured it out from this post :
http://www.droptoframe.com/?p=35
I have not tested, but I think it should work:
$.fn.dialog = (function() {
var cached_function = $.fn.dialog;
return function() {
if (arguments[0] !== "func1")
cached_function.apply(this, arguments);
else {
// Do what you want here...
}
};
}());
I want to dynamically call the method of a custom class much like the below javascript. Except, the javascript below only calls a function that exists in my code. I want to call (dynamically) the function of a class. So I would remove window{value](target, event, self); and use something else that would call the method of a custom created class such as "mycustomclass.anythingcouldbethismethod(target, event, self);" after it had been instantiated of course.
var functions = [
'ajaxify_overlay',
'ajaxify_overlayCancel',
'ajaxify_overlaySubmit',
'ajaxify_rollout',
'ajaxify_rolloutCancel',
'ajaxify_rolloutSubmit',
'ajaxify_upload',
'ajaxify_contentArea',
'ajaxify_itemToggler',
'ajaxify_closer',
'ajaxify_submit',
'ajaxify_inputActivate',
'ajaxify_executeAndRefresh',
'ajaxify_empty'
];
$(document).bind('ready', function(event) {
$('body').live('click', function (event){
var target = $(event.target);
var self = this;
$.each(functions, function(index, value){
if($(target).hasClass(value)) {
window[value](target, event, self);
}
});
});
});
var myClass = { /* your class definition */ };
var methodName = 'myMethod';
myClass[methodName](p1,p2,...,pN);
You mean like this?
function methodCaller( methodName, target, event, self ) {
mycustomclass[ methodName ](target, event, self);
}
methodCaller( "someMethodName" );
I have an extension going like:
$.fn.crazything = function() {
var self = $(this);
// do some crazy stuff
return self;
}
And when I call it like:
$("div.crazydiv").crazything();
It works, but only on the first matching div. If I have more than one div on the page, I need to do:
$("div.crazydiv").each(function(i) { $(this).crazything (); });
Why is this, and how can I rewrite my extension to work on multiple divs?
Most jQuery plugins use this pattern which handles your crazy stuff:
(function($) {
$.fn.crazything = function() {
// allow setup on jQuery objects that conatin multiple elements:
return this.each(function() {
// this function is called once for each element in the jQuery object
var self = $(this);
// do some crazy stuff
});
};
})(jQuery);