cannot create object in IE using new Keyword - javascript

var com = {};
var com.Project = function(){
this.display = function(){
alert("hai.....");
}
}
var project_obj = new com.Project();
while creating the project_obj i got an error in IE9 like "Object doesn't support this action"
this code working well in firefox and chrome.
i have given a sample code.
i'm trying to use Classes and package concept in javastript.
i don't know why this error came in IE.

This is illegal in all browsers and raises a syntax error :
var com.Project = function(){
You may do this :
var com = {}; // whatever
com.Project = function(){

The problem is the 1st line, as variable names cannot include ..
If you're trying to namespace, you need to first define com as an Object with Project as one of its properties:
var com = {
Project: function () {
// etc.
}
};

Based on the working link to your javascript code I think you should change this
$.extend(true, window, container[0]);
to
$.extend(true, window, d);

Related

How to reference a function defined inside prototype

I am trying to add a functionality to a web page that uses a jquery library which doesn't seem to have any documentation. (unknown origin) my problem is mainly due to the lack of understanding on jquery plugin model and/or inner workings of javascript.
1. the plugin is initiated as follows
jQuery('div.carousel').scrollGallery({
mask: 'div.mask',
slider: 'div.slideset',
slides: 'div.slide', ............ });
2. the plugin is defined in jquery as follows
;(function($){
function ScrollGallery(options) {
this.options = $.extend({
mask: 'div.mask', ...... }, options);
this.init();
3. in the Object.prototype declaration i see the following function numSlide defined.
ScrollGallery.prototype = {
....................
numSlide: function(c) {
if(this.currentStep != c) {
this.currentStep = c;
this.switchSlide();
}
},
.......... };
Question.
How do i reference numSlide(int) function externally?.
I tried the following methods and it did not work.
myx = jQuery('div.carousel').scrollGallery({ // var myx was added in the global scope
myx.numSlide(1); //error undefined is not a function
i tried adding return this; at the end of myx = jQuery('div.carousel').scrollGallery({ but it still returns the jQuery object.
i also tried
jQuery.scrollGallery().numSlide(2); //error undefined is not a function
jQuery.scrollGallery.numSlide(2); //same error
Do i need to add LIGHT BULB
// jquery plugin
$.fn.scrollGallery = function(opt){
return this.each(function(){
$(this).data('ScrollGallery', new ScrollGallery($.extend(opt,{holder:this})));
});
};
}(jQuery));
ANSWER (I think)
it looks like the ScrollGalary object is stored in a data for the selector. So i believe i can do the following jQuery('selector').data('ScrollGallery').numSlide(2);
I decided to post this anyway in-case if anyone in the future had a similar gullible situation.
One way of doing this will be to initiate ScrollGallery object first and then use it.
var test = new ScrollGallery();
test.numSlide();
if you want to extend jQuery and use the function you can assign it as follows
$.fn.scrollGallery = new ScrollGallery();
and use it
$("window").scrollGallery.numSlide();

Titanium JavaScript: How to pass data/values from one window to another window

In objective c we can pass data between two classes very easily by nextClassname.recievedVariable = passedVariable;
i tried same with titanium, but failed
I tried as follows
in Second Class
$.table.addEventListener('click', function(e) {
var selected = e.row;
alert(e.row.title);
var TodayStatus = Titanium.UI.createWindow({ url:'TodayStatus.js' });
TodayStatus.seletedProj = e.row.title;
// var TodayStatus = new Alloy.createController("TodayStatus");
TodayStatus.getView().open();
});
in the first Calss whic we have to recieve string from another class
var win = Ti.UI.currentWindow;
Ti.API.info(win.seletedProj);
But causes errors like
message = "'undefined' is not an object (evaluating 'win.seletedProj')";
[ERROR] : name = TypeError;
You can pass the data by passing parameter like this.
x.addEVentListener('click', function(e){
var controller = require('controllerPath').createWindow(e.value);
controller.open();
})
And in controller.js
exports.createWindow = function(value)
{
//whatever You like to do with UI
}
If you create a new window by using the 'url' parameter it automatically puts that code into it's own Sub-context and it isn't possible to pass complex objects accross, see here:
http://docs.appcelerator.com/titanium/3.0/#!/api/Titanium.UI.Window
I don't tend to do it this way anymore.
The way i would do it would be to create your todayStatus window as a common js class:
// todayStatus.js
var win = Ti.UI.createWindow({ top:0, left: 0, right: 0, bottom:0, etc... });
//any extra visual building code can go here
win.open();
exports.seletedProj = function(rowTtl){
//this function is available outside the class
}
Then you can reference it from your main class like this:
// main.js
var TodayStatus = require('todayStatus');
TodayStatus.seletedProj(e.row.title);
etc...
Hope that helps
see link here for how to do it in Alloy,
https://github.com/aaronksaunders/alloy_fugitive/blob/master/app/controllers/Fugitives.js#L29
but basic idea is to pass the object as a parameter when creating the new controller.
$.table.addEventListener('click', function(_e) {
var detailController = Alloy.createController('FugitiveDetail', {
parentTab : $.fugitiveTab,
data : fugitiveCollection.get(_e.rowData.model)
});
$.fugitiveTab.open(detailController.getView());
});
The link I provided has a complete solution using Alloy

JavaScript multiple object instances, cannot correctly access properties inside event handler

I have a working version of HTML5 drag & drop file uploader. I was editing the JS code to support multiple file uploads on same page. I came across with a problem by trying to access "instance" properties in methods which are registered as events.
The problem is shown by the code below, in method this.drop.
The reason of existence of the this.$$upload_self property is to access data through this property. For example, I can't use this keyword inside this.drop function, because when event is raised, this not referring my "instance".
I'm not sure that by creating $$upload_self was a good idea.
The new instances area created like this:
var recording_upload = new upload();
recording_upload.init(recording_upload, ...);
Code of Drag & drop file upload:
var upload = function() {
this.$$upload_self = null;
this.$drop = null;
this.$status = null;
this.$progress = null;
this.maxNumberOfFiles = null;
...
this.init = function (self, pUrl, maxNmbOfFiles, dropArea, progress, status) {
$$upload_self = self;
$$upload_self.postUrl = pUrl;
$$upload_self.maxNumberOfFiles = maxNmbOfFiles;
$$upload_self.$drop = $("#" + dropArea);
$$upload_self.$progress = $("#" + progress);
$$upload_self.$status = $("#" + status);
$$upload_self.$drop.bind('dragenter', $$upload_self.enter);
$$upload_self.$drop.bind('dragleave', $$upload_self.leave);
$$upload_self.$drop.bind('drop', $$upload_self.drop);
};
this.enter = function (e) {
$(e.target).addClass('hover');
return false;
};
this.leave = function (e) {
$(e.target).removeClass('hover');
return false;
};
this.drop = function (e, _this) {
$(e.target).removeClass('hover');
var files = e.originalEvent.dataTransfer.files;
if (files.length > $$upload_self.maxNumberOfFiles) { // for example, here $$upload_self references always last instance...
$$upload_self.displayErrorMessage('Error: You can only drop ' + $$upload_self.maxNumberOfFiles + ' file(s) at time.');
return false;
}
...
};
...
}
Is there any workaround to solve this issue? I believe this maybe a common problem, but can't find nothing to solve this problem.
Any help is very much appreciated.
You could ditch the new keyword altogether and use a fresh closure for each instance of upload.
EDIT: Updated to avoid potential clobbering of global this.
var upload = function(pUrl, maxNmbOfFiles, dropArea, progress, status) {
return {
postUrl: pUrl,
...
drop: function(e) {
...
if (files.length > this.maxNumberOfFiles) {
this.displayErrorMessage(...);
}
...
},
...
};
};
...
var someUpload = upload(...);
Try to search for a "scope". As an example see how it implemented in ExtJS.
In a modern browser you can do this:
$$upload_self.$drop.bind('dragleave', $$upload_self.leave.bind($$upload_self));
For older IE versions you can do this:
$$upload_self.$drop.bind('dragleave', function() { $$upload_self.leave(); });
Really the ".bind()" method of all Function objects in new browsers just creates a little intermediate function for you, essentially like the second example. The Mozilla docs page for ".bind()" has a very good block of code you can use as a "polyfill" patch for browsers that don't support ".bind()" natively.

Can't get JavaScript Array to work in OOP style

Hi currently I'm trying to get following snippet of code to work:
function Entry() {
var pauses = new Array();
}
Entry.prototype = {
AddElement: function(aParameter) {
this.pauses.push(aParameter);
}
}
Unfortunately this code fails with following error in Safari if I try to call AddElement("Test");
TypeError: Result of expression 'this.pauses' [undefined] is not an object. Does anybody know why?
In your code, pauses is a local variable within the Entry() function, not a member on the object constructed by it.
You want to replace var pauses = ... with this.pauses = ....
change
var pauses = new Array();
to
this.pauses = new Array();
or, better
this.pauses = [];

Problem with Javascript object and accessing property which exists

I have something like this:
var test = {};
function blah() {
test[2] = 'filled';
}
blah(); // ! Hopefully confusion is now averted..
console.log(test);
//result test -> 2:"filled"
console.log(test[2]);
//result undefined
I don't understand why I'm getting 'undefined' in the second instance when according to the first instance, the property of that object clearly exists!
Does anyone have any ideas?
Thanks
OK, it seems that folk are getting confused as to what context the code exists in, for clarity sake I have now added the call to the blah(). but please refer to the comment under Jeff B's response!
Here is an example of relevant code so to say:
mydb = ..... //gets created here with relevant credentials
var test = {};
mydb.transaction(
function(transaction) {
transaction.executeSql("select * from mytable;", [], function(transaction,result) {
var r = result.rows.item(0);
test[2] = r.title;
}, errorHandler);
});
console.log(test);
//result test -> 2:"the title"
console.log(test[2]);
//result undefined
#Dancrumb
Your mention of the single-threadedness of Javascript gave me an idea, and I tried this:
window.setTimeout(function(){ alert(test[2]); },2000);
and it worked! I got the expected value to alert. Can you suggest how I can get around this without using a 'hack' like that above?
Because you aren't calling blah()?
Also, you want:
var test = [];
or:
var test = new Array();
EDIT
I ran the following code:
mydb = openDatabase('note','','Example',1024);
var test = {};
mydb.transaction(
function(transaction) {
transaction.executeSql("select * from mytable;", [], function(transaction,result) {
var r = result.rows.item(0);
test[2] = r.title;
}, errorHandler);
});
console.log(test);
console.log(test[2]);
in Safari 4.0.5
I got the following:
Object
No Properties
undefined
This is what I would expect to see. The object test does not have any properties assigned to it until the callback from mydb.transaction occurs and, since Javascript is single threaded, this cannot happen before the calls to console.log.
Since you're getting a different outcome, can you outline what browser and what version you are using?
This is pretty clearly an asynchronous issue. The simplest way of getting code to run after you set test[2], is to either put the code right there, or use another callback, and call it after you set test[2].

Categories