Declare public variables in Handlebar JS - javascript

I Would like to declare a global variable in my JS file and i would like to use that variable in different function in the same class .
I have declared a variable in initialize section
initialize: function () {
this.regionid="";
}
selectItems: function ()
{
this.regionid="10";
this.Regions.url = this.Regions.url() + '?requesttype=1';
this.Regions.fetch({ success: this.renderRegion });
}
renderRegion: function () {
var ddlRegionClass = this.Regions.toJSON();
$(this.el).find('[id=cboRegion] option').remove();
$.each(ddlRegionClass.LOCATIONS_Regions, function (j, cc1) {
var data = 'data='+cc1.AreaCode_2;
var selected = '';
if(cc1.AreaCode_3==this.regionid)
selected="selected";
$('[id=cboRegion]').append('<option value="' + cc1.AreaCode_3 + '" ' + data + selected + ' >' + cc1.Area_Name + '</option>');
})
},
While i am checking the value at
if(cc1.AreaCode_3==this.regionid)
i didnt get the value , it is showing 'undefined'

this.regionid="";
initialize: function () {
//some code
}
I think you have to declare like this..then it will work..you can assign values for variable in any function.

this inside the callback of $.each won't be referring to the view (or the object which the js file is containing).
In the initialize you can bind renderRegion with this:
initialize: function() {
this.regionid = "";
_.bindAll(this, "renderRegion");
}
and inside renderRegion:
renderRegion: function() {
// before doing $.each store 'this' reference
var _this = this;
// and inside the callback use if(cc1.AreaCode_3 == _this.regionid)
}
It should work.

Related

Knockout.JS : self.myObservable is not a function, issues with code order

I have page using knockout, which has a searchfield, selectedvalue from a dropdown, and pagenumber..
All these are initialized at set to defaultvalues, especially for first run / page access..
The problem is that i dont understand why i'm getting the following error
"self.selectedTeamId is not a function()"
I know.. this has to be something with the "order of things", so that when it's being used, it has NOT been initialized yet.
Can someone correct my mistake ?
CODE :
$(document).ready(function() {
var ViewModel = function() {
var self = this;
self.photos = ko.observableArray();
self.selectedTeamId = ko.observable(0);
self.searchString = ko.observable('');
self.pageNumber = ko.observable(1);
self.clearFilters = function() {
self.searchString(''); // set default to ''
self.selectedTeamId(0); // set default to 0
self.pageNumber(1); // set default to 1
self.getPhotos();
};
self.getPhotos = function () {
var photoParams = "?teamId=" + self.selectedTeamId() + "&search=" + encodeURIComponent(self.searchString()) + "&pageNumber=" + self.pageNumber();
$.get("api/Photo/GetPhotos" + photoParams,
function(data) {
self.photos(data);
}, "json");
};
};
var photosModel = new ViewModel();
ko.applyBindings(photosModel, document.getElementById("photoarchive"));
// THE NEXT LINE GIVES THE ERROR (self.selectedTeamId())
var photoParams = "?teamId=" + self.selectedTeamId() + "&search=" + encodeURIComponent(self.searchString()) + "&pageNumber=" + self.pageNumber();
$.get("api/Photo/GetPhotos" + photoParams,
function(data) {
photosModel.photos(data);
}, "json");
});
self is a variable which is local to your ViewModel function. It isn't accessible outside of that function.
As you're storing your ViewModel within your photosModel variable, you can instead access the selectedTeamId observable with:
photosModel.selectedTeamId()
You'll need to do the same with self.searchString() and self.pageNumber().
That said, however, you may as well just call photosModel.getPhotos() instead of duplicating the entire function outside of the ViewModel scope.

How to keep object in scope?

I am implementing the following functionality. The majority of the page is created once in my entryPage.php file. The "Stage" table is created through an AJAX call to stageArea.php. My issue is that my data object is created in a $(document).ready(function() {...} which cannot be accessed by my other functions outside of the $(document).ready(function() {...}.
entryPage.php
...HTML...
<script>
$(document).ready(function() {
var dataObject = new DataEntryObj(); // create the data object
$.post("../stageArea.php", {array : dataObject.dataArray}, function(data){
$('#stageArea').html(data);
});
}
var DataEntryObj = function(){
this.dataArray = [[0,0,0,0,0,0,0,3,0]];
....
}
function updateData(value, row, index){
alert("update:" + row + " " + index + " " + value); //values come in OK
alert(dataObject.dataArray[row][index]); // but the data Object isn't here
dataObject.dataArray[row][index] = value; // so this cannot be assigned
$.post("../stageArea.php", {array : dataObject.dataArray}, function(data){
$('#stageArea').html(data);
});
}
</script>
What is a good solution to keep the object in the same scope as the other functions?
Just declare the var outside of $(document).ready and then assign it's value without using var
var dataObject ;
$(document).ready(function() {
dataObject = new DataEntryObj(); // create the data object
......
});
This will now be equivalent to window.dataObject
You can define a global variable, but you should make sure that updateData tries to access dataObject after DOM becomes accessible
var dataObject, DataEntryObj;
DataEntryObj = function(){
this.dataArray = [[0,0,0,0,0,0,0,3,0]];
}
$(document).ready(function() {
dataObject = new DataEntryObj();
$.post("../stageArea.php", {array : dataObject.dataArray}, function(data){
$('#stageArea').html(data);
});
}
function updateData(value, row, index) {
// will have ref to dataObject changed by $(document)
}
You can not access dataObject varailable. Because you setted in function. You should create a global object variable and you can access everywhere.
var dataObject = { data: null };
$(document).ready(function() {
dataObject.data = new DataEntryObj(); // create the data object
$.post("../stageArea.php", {array : dataObject.data.dataArray}, function(data){
$('#stageArea').html(data);
});
}
var DataEntryObj = function(){
this.dataArray = [[0,0,0,0,0,0,0,3,0]];
}
function updateData(value, row, index){
alert("update:" + row + " " + index + " " + value);
alert(dataObject.data.dataArray[row][index]);
dataObject.data.dataArray[row][index] = value;
$.post("../stageArea.php", {array : dataObject.data.dataArray}, function(data){
$('#stageArea').html(data);
});
}

backbone marionette pass variable to view method

I have simple situation and can't understand why variable that I pass to function always undefined.
var ProjectItemView = Backbone.Marionette.ItemView.extend({
template: "#ProjectItemTemplate",
initialize: function () {
var id = this.model.get('project_id');
$.getJSON('service/api.php/projects/' + id + '/progress').done(function (data) {
this.renderProgress('4'); //<== pass here
});
},
renderProgress: function (why) {
alert(why); //<== undefined
...
},
...
});
I expect that it equals '4'. In next step I want to pass "data" but now I realize that I can't pass anything.
Since you're invoking renderProgress on the return of $.getJSON you can simply provide the function reference to the done()method of the returned jQuery Promise. Your code would look like this:
var ProjectItemView = Backbone.Marionette.ItemView.extend({
template: "#ProjectItemTemplate",
initialize: function () {
var id = this.model.get('project_id');
$.getJSON('service/api.php/projects/' + id + '/progress')
.done(this.renderProgress);
},
renderProgress: function (data) {
alert(data);
...
},
...
});
If you'll need the view context inside renderProgress (like, for example, to refer to a view property), then provide done() a version of renderProgress that's bound to the view context:
$.getJSON('service/api.php/projects/' + id + '/progress')
.done(_.bind(this.renderProgress, this));
where _.bind is an UnderscoreJS function. Read more about it here.
You loose the context in $.getJSON done callback. Try this:
var ProjectItemView = Backbone.Marionette.ItemView.extend({
template: "#ProjectItemTemplate",
initialize: function () {
var id = this.model.get('project_id');
var _this = this;
$.getJSON('service/api.php/projects/' + id + '/progress').done(function (data) {
_this.renderProgress('4'); //<== pass here
});
},
renderProgress: function (why) {
alert(why); //<== undefined
...
},
...
});
You don't have access to this inside " $.getJSON( " assign this to any variable and then call "renderProgress" method.
var currentObj = this;
$.getJSON('service/api.php/projects/' + id + '/progress').done(function (data) {
currentObj .renderProgress('4'); //<== pass here
});
because in your case this points to current object of that function and not to view object.

Variables inside jQuery .on() not updating

Ok so I have a jQuery .on() function that looks like this....
$("#grid").on('rowdoubleclick', function(event) {
var appData = $("#grid").jqxGrid('getrowdata', event.args.rowindex);
var appID = appData.application_id
var cellClassTitle = function(row, column, value) {
alert("VALUE: " + value + " appData.title: " + appData.title);
if (value == appData.title)
{
return "yellowCell"
}
}});
My problem is that the appData.title variable inside the cellClassTitle function only gets evaluated once, on the first doubleclick. the appData variable outside the cellClassTitle function evaluates each time a row is doubleclicked but the appData.title value inside remains the same. How can I get it to update each time the .on('rowdoubleclick') function executes?
Define the function outside the scope of the rowdoubleclick handler, e.g.
var appData = appData || {title:""};
var cellClassTitle = function(row, column, value) {
alert("VALUE: " + value + " appData.title: " + appData.title);
if (value == appData.title)
{
return "yellowCell"
}
}
$("#grid").on('rowdoubleclick', function(event) {
appData = $("#grid").jqxGrid('getrowdata', event.args.rowindex);
var appID = appData.application_id
});
Disclaimer: this is nasty, take care not to pollute the global scope! http://www.yuiblog.com/blog/2006/06/01/global-domination/

javascript function does not get called

I am writing javascript code with revealing prototype pattern for the first time. I am having problems. When I call add function when user clicks add button then it shows me this error in the console.
Uncaught TypeError: Cannot call method 'add' of undefined
How can I solve this problem?
here is my script.js code
$(function () {
var todo = Todo('contents');
$('.addBtn').on('click', function() {
var name = $(this).parent().find('input[type="text"]').val();
todo.add(name);
});
$('.contents').on('click', '.remove', function() {
var el = $(this).parent();
todo.remove(el);
});
$('.contents').on('click', '.update', function() {
var dom = $(this);
todo.addUpdateField(dom);
});
$('.contents').on('click', '.updateBtn', function() {
var el = $(this);
todo.update(el);
});
});
here is my todo.js code
var Todo = function(c) {
this.contents = $('.' + c);
};
Todo.prototype = function() {
var showel = function (d) {
this.contents.prepend(d);
},
add = function (name) {
if(name != "") {
var div = $('<div class="names"></div>')
.append('<span>' + name + '</span>')
.append("<button class='update' class='update'>Edit</button>")
.append("<button class='remove' name='remove'>Remove</button>");
}
return showel(div);
},
addUpdateField = function (dom) {
var name = dom.parent().find('span').text(),
field = $('<input type="text" value="' + name + '" />'),
update = $('<button class="updateBtn">Update</button>');
dom.parent().html('').append(field).append(update);
return;
},
update = function(el) {
var val = el.parent().find('input').val();
el.parent().html('<span>' + val + '</span>')
.append('<button class="update" class="update">Edit</button>')
.append('<button class="remove" class="remove">Remove</button>');
return;
},
remove = function (el) {
return el.remove();
};
return {
add : add,
update : update,
remove : remove,
addUpdateField : addUpdateField
};
}();
Update
After changing
var todo = Todo('contents');
to
var todo = new Todo('contents');
I get this error
Object [object Object] has no method 'add'
update 2
here is my on jsfiddle
You're not properly constructing your object, so it does not have any of the prototypes:
var todo = Todo('contents');
should be:
var todo = new Todo('contents');
Here is an SO question explaining what is happening when you forget the new.
Edit: the way you are defining your prototype functions is messing up the context (what this points to). Try a pattern like this instead:
Todo.prototype = {
method1: function () { ... },
method2: function () { ... }
};
fixed fiddle: http://jsfiddle.net/BagmY/3/
You're trying to assign Todo's prototype to a self-calling function. However, the prototype is just getting assigned to a function and not the expected return object.
Here's your working fiddle. I assigned the prototype directly to an object with your methods.
Also, JS parses from top to bottom. Therefore, define your new instance of Todo after you declare what Todo is.
This is what a self-calling function should look like:
Todo.prototype = (function() {
// ...
return {
add: add,
update: update,
remove: remove,
addUpdateField: addUpdateField
};
})();​

Categories