Trouble with Jquery widget - javascript

I have a widget like this
$.widget("ui.myWidget", {
//default options
options: {
myOptions: "test"
},
_create: function () {
this.self = $(this.element[0]);
this.self.find("thead th").click(function () {
this.self._headerClick(); //how do I do this!!!
});
this.self._somethingElse();
},
_headerClick: function (){
},
_somethingElse: function (){
},
.
.
.
The line this.self._headerClick(); throws an error. This is because in that context this is the th element that was clicked. How do I get a reference to the _headerClick function?

Store the scope of desired this within a variable.
$.widget("ui.myWidget", {
//default options
options: {
myOptions: "test"
},
_create: function () {
var that = this; // that will be accessible to .click(...
this.self = $(this.element[0]);
this.self.find("thead th").click(function () {
that._headerClick(); //how do I do this!!!
});
this.self._somethingElse();
},
_headerClick: function (){
},
_somethingElse: function (){
},

Untested, but maybe something like this:
_create: function () {
var self = this,
$elem = $(self.element[0]);
$elem.find("thead th").click(function() {
self._headerClick();
});
self._somethingElse();
},

Related

Calling a private/nested javascript function from an outer scope

I have my javascript code like this . Inside that I have an init() function and in that function I have an options JSON object and in that object I have a function defined as objectselected(). How I call that function in a button click event
I have tried like this WorkFlow.init().options.Objectselected() but it is not working,
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
elementId: "playAreaContainer",
TextStoreList: ['One', 'Two', 'Three'],
LinkTextStoreList: $('#drpLinkType option').map(function () {
return this.text;
}).get(),
shapeList: ['RoundedRectangle', 'Circle', 'Rectangle', 'Ellipse', 'Square', 'Diamond', 'Card', 'Database'],
diagramUpdate: function (e) {
},
objectSelected: function (e) {
},
linkUpdate: function (e) {
},
initialize: function () {
}
myGraph = new Graph(options);
options.initialize();
},
}
How to call that function.
One way around is you can return options and than call it.
init: function () {
var options = {
...your code..}
return options;
},
and call it than
var options = WorkFlow.init();
options.Objectselected();
As it stands, you have no access to options because it's a local variable - that is, local to its scope.
To access its contents, you'll need to return it from init().
Think about it:
WorkFlow.init()
Currently this returns undefined, because your init() returns nothing. You're trying to chain like in jQuery, but that relies on the API always returning the instance. Your path finds a dead-end at init().
To fix this, have init() return options - or at least the part of it you want to access from outside - an "export".
So (basic example)
init: function() {
var options {
my_func: function() { }, //<-- we want outside access to this
private: 'blah' //<-- this can stay private - leave it out of the export
}
//return an export, exposing only what we need to
return {
my_func: options.my_func
}
}
You need to return options as it is inside init function's scope
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
elementId: "playAreaContainer",
TextStoreList: ['One', 'Two', 'Three'],
LinkTextStoreList: $('#drpLinkType option').map(function () {
return this.text;
}).get(),
shapeList: ['RoundedRectangle', 'Circle', 'Rectangle', 'Ellipse', 'Square', 'Diamond', 'Card', 'Database'],
diagramUpdate: function (e) {
},
objectSelected: function (e) {
},
linkUpdate: function (e) {
},
initialize: function () {
}
myGraph = new Graph(options);
options.initialize();
return options;
},
}
And call it as WorkFlow.init().objectSelected();
Building on Patrick's comment, you'd need to return options from the init function:
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
...
options.initialize();
return options;
},
}

Starting with module pattern

I'm trying to start using moddule pattern in my JS code from the beginning but I have problems to understand how to perform this kind of code design.
This is a simple event:
$('#docTable').on('dblclick', 'tbody tr.line', function (event) {
$('#modal1').modal({ keyboard: false, backdrop: "static", dismiss: "modal" });
$('#modal1').modal('show');
});
I've created a couple of JS files. View.js:
var task = window.task || {};
task.View = (function () {
function View(rootElement) {
var dom = {
table: $('#docTable'),
},
callbacks = {
onsubmit: undefined
};
return {
};
}
return View;
}());
and Controller.js:
$(document).on('ready', function () {
var View = task.View(document);
});
but I have no idea how to continue and catch the dblclick event.
Could anybody please help me?
Thanks in advance.
You can create 'class' View and add event binding to its prototype. After that you can use it on multiple tables. If you want to have access to element in table you can add classes to them and find them in defineDOM method:
View.js
var task = window.task || {};
task.View = function (table) {
this.$table = $(table);
this.init();
};
task.View.prototype ={
init: function () {
this.defineDOM();
this.bindEvents();
},
defineDOM: function() {
// Search for DOM elements in context of table element
this.$button = $('.docButton', this.$table);
this.$links = $('.docLinks', this.$table);
},
bindEvents: function () {
this.$table.on('dblclick', 'tbody tr.line', this.onDblClick.bind(this))
},
onDblClick: function () {
$('#modal1').modal({ keyboard: false, backdrop: "static", dismiss: "modal" });
$('#modal1').modal('show');
}
}
Usage
$(document).on('ready', function () {
new task.View('#docTable');
});

JS scope: call parent function using namespace

How do I call a parent namespace function from within a function?
var myNamespace = {
funcOne : function () {
//do something
},
funcTwo : function () {
setTimeout ( function () {
myNamespace.funcOne(); //how do I call funcOne?
}, 2000);
}
}
The usual way would be to use the this keyword inside the literal
var myNamespace = {
funcOne : function () {
//do something
},
funcTwo : function () {
var self = this;
setTimeout ( function () {
self.funcOne();
}, 2000);
}
}
But what you're doing should work just fine as well -> FIDDLE

Javascript variable scope

Is it possible for me to call selectCompanyJump(this) internally without calling it from App.site.profile?
Instead of doing App.site.profile.selectStateJump(this); can I do like parent.selectStateJump(this); without reassigning this outside of the .change() call?
$(document).ready(function () {
App.site = function () {
return {
init: function () {
this.profile.init();
},
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
$('select[name="company_id"]', profile).change(function () {
App.site.profile.selectCompanyJump(this);
});
$('select[name="state_id"]', profile).change(function () {
App.site.profile.selectStateJump(this);
});
},
selectCompanyJump: function (select) {
$(select.parent()).submit();
},
selectStateJump: function (select) {
$(select.parent()).submit();
}
}
}()
}
}();
App.site.init();
});
You can reference the "this" scope you want as another variable outside change() function definitions:
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
var self = this;
$('select[name="company_id"]', profile).change(function () {
self.selectCompanyJump(this);
});
$('select[name="state_id"]', profile).change(function () {
self.selectStateJump(this);
});
},
selectCompanyJump: function (select) {
$(select.parent()).submit();
},
selectStateJump: function (select) {
$(select.parent()).submit();
}
}
}()
Assuming that you are just using the select argument of your functions to reference the element that triggered the event you could just pass a pointer to the event binder and then use the this keyword.
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
$('name="state_id"', profile).change(this.selectStateJump);
},
selectStateJump: function () {
$(this).parent().submit();
}
}
you can do the following
$(document).ready(function () {
App.site = function () {
var me = this;
me.selectStateJump = function selectStateJump (select) {
$(select.parent()).submit();
}
return {
....
selectStateJump: selectStateJump
}
and you'll be able to call just me.selectStateJump()
EDIT:
actually below would be enough
$(document).ready(function () {
App.site = function () {
function selectStateJump (select) {
$(select.parent()).submit();
}
return {
method : function(select) {
selectStateJump(select);
}
selectStateJump: selectStateJump
}

Variable Scope: cross-class function call

I have a vehicle and a product object and I need vehicle to call a function within product.... I can't seem to figure it out, what should I do here?
var vehicle = function () {
return {
init: function () {
var that = this;
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
that.remove(jQuery(e.currentTarget).parents('.vehicle-year-profile'));
});
jQuery('.vehicle-year-profile .options .edit').bind('click', function (e) {
e.preventDefault();
that.edit(jQuery(e.currentTarget).parents('.vehicle-year-profile').attr('id'));
});
jQuery('#association-detail .save').bind('click', function (e) {
e.preventDefault();
that.save();
});
},
edit: function (id) {},
save: function () {},
remove: function (el) {},
reset: function () {}
}
}();
var product = function () {
return {
refreshHistory: function () {}
};
}();
Have you tried
product.refreshHistory();
?? The variable "product" is global (or at least relatively global), so code inside the "vehicle" object can refer to it directly.

Categories