How to create a html obejct with javascript in a jsp page - javascript

all, I want to create a html obejct with javascript in a jsp
page, but 'alert(GameObject1.loginurl);' will alert 'undefined'.
Do I get some misstakes in the code below?
It seems that 'obj.appendChild' has failed.But Why?
var obj;
try {
obj = document.createElement("object");
obj.id = "GameObject1";
obj.name = "JavaGameObject1";
obj.setAttribute("classid", "clsid:72E6F181-D1B0-4C22-B0D7-4A0740EEAEF5");
obj.width = 640;
obj.height = 526;
var loginurl = document.createElement("param");
loginurl.setAttribute("name", "loginurl");
loginurl.setAttribute("value", "xx.xx.xx.xx:8080");
obj.appendChild(loginurl);
document.body.appendChild(obj);
alert(GameObject1.loginurl);
} catch (e) {
alert("Exception:" + e.message);
}

Based on your code, GameObject1 is never defined. I think you are wanting to use obj instead as that is the HTML object for the ID GameObject1.
I will note however that even obj.loginurl will still be undefined as you created the child HTML object param called loginurl, not a property to the HTML object obj. (ie. You would have needed to do obj.loginurl = "xx.xx.xx.xx:8080" to access it the way you seem to want)
To get the child element param's value, you would want something like obj.children[0].value which will return the value you set on your loginurl object. Alternatively, in your current scope you could just call loginurl.value.
When accessing child elements via obj.children[#], it is best to do checks to see if the element at that position exists so you don't throw exceptions everywhere.

To access the loginurl, you could use
alert(obj.getElementsByTagName("param")[0]);
alert(obj.getElementsByTagName("param")[0].name);
alert(obj.getElementsByTagName("param")[0].value);
Accessing like the way you mentioned is proper way of getting the attributes and not the child element.
GameObject1 // Will look for Object variable not the object with id "GameObject1" - You should use document.getElementById("GameObject1")
GameObject1.loginurl // will look for attribute and not the child element

Related

Trying to pass event data to function

I am trying to pass some data to a function but I'm facing an issue with the code below. I can't seem to make it work when i try to use $(this).data("id") if I just use ABC as a value it works.
$(".printLabel").click({
recordId: $(this).data("id")
}, printLabel);
function printLabel(event){
var data = event.data;
console.log(data.recordId);
}
Within the object you provide this is a reference to the window, not the clicked element, hence the data attribute you're looking for is undefined.
Assuming that the data attribute is on the .printLabel element itself, you can retrieve it within the event handler directly without sending any event arguments. Try this:
$(".printLabel").click(function() {
var recordId = $(this).data("id")
console.log(recordId);
});
Why is it a problem calling the function in a more understandable manner? Also if you insist on passing an object, you need to use the object passed - var data = event.data; would not work either. Here is my suggestion using an object too:
$(".printLabel").on("click",function() {
printLabel( {recordId: $(this).data("id")});
});
function printLabel(passedObject){
console.log(passedObject.recordId);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="printLabel" data-id="ID1">This is id1</div>

Can you access an object-defined property in a private method in JavaScript?

I am building out a library that is roughly laid out as follows. There are a couple of variables, an event handler and a method which results in the related event firing. Finally I extend the deal with a property. It goes like this (I've added some ///... where I've clipped out other code):
$.collidR = function (options) {
/// ...
var hubName = 'CollidRHub';
var hubProxy = connection.createHubProxy(hubName);
/// ...
hubProxy.on('registrationComplete', function (username, hasChanges) {
$(window).triggerHandler(events.onRegistrationComplete, { username: username, hasChanges: hasChanges });
log(username + " has successfully registered for this entity.");
// capture current user
this._currentUser = username;
// hook for catching up when user joins after edits
if (hasChanges) {
log("There are outstanding changes for this entity...");
}
});
/// ...
this.registerClient = function () {
/// does some stuff that makes registrationComplete fire
/// ...
};
};
Object.defineProperty($.collidR.prototype, "currentUser", {
get: function () {
return this._currentUser ? this._currentUser : "";
}
});
Note that above the this._currentUser = username bit does not seem to work. I think it's a problem with encapsulation, which is what this question is building towards.
In a separate but related library I create an instance of collidR, and I need to respond to an event. I've got the handler for that set up as follows:
$(window).on(collidR.events.onEditorsUpdated, function (e, data) {
/// ...
users.forEach(function (user) {
var currentUser = collidR.currentUser;
// here, currentUser is always default of ""
if (user != currentUser) {
/// ...
}
});
});
Here is what I am seeing:
My registrationComplete event fires and the handler is called successfully
From a debugger, this._currentUser is undefined before the value is set
The line this._currentUser = username is executed and the value is set
When the onEditorsUpdated event fires, collidR.currentUser is always the default value (an empty string) in my handler
What feels out-of-order is where I define the property -- after the rest of the object. It's as though I'm altering the prototype of the object after I define a method which tries to reference the property...this can't be right.
I've also tried this.currentUser (in the internal method), but had the same result.
I had assumed that if the prototype was extended before the internal method was invoked that when I did var currentUser = collidR.currentUser; that I would get the value from the property, but it's always an empty string.
Is there a way to register the property earlier?
Is there a correct way to set the value so that I will be able to access it later via the exposed property?
Because this in this._currentUser = username; isn't what you think it is. The value of this in JavaScript depends on how the function was called. I assume that inside the handler, it's now referring to hubProxy or some other object other than collidR.
Assuming that your entire plugin's this refers to collidR (which I highly suspect isn't, explained in the section after this), what you can do is save the context of that scope into another variable outside the handler. That way, you can refer to the outer scope's context via that variable:
// Saving this scope's context
var that = this;
hubProxy.on('registrationComplete', function (username, hasChanges) {
// access _currentUser via the saved context
that._currentUser = username;
});
However, I should warn you about using this. Assuming you are creating a plugin, you'd be calling it like $.collidR({..}). In this case, the this inside the function will refer to $ (which I assume is jQuery) and you are attaching some property to the library. It's risky to attach plugin-specific values to a global library as collisions might occur.
I suggest you store it inside a local variable/object instead.

object *name* has no method *method name*

I have two objects: command and topic.
topic has a method actions that is called from command.
When topic.actions() is called, there are no errors.
When I use the object property command.taxonomy whose value is the string 'topic' to call topic.actions(), an exception is thrown: "Object topic has no method actions".
Why would the console report topic has no method actions when it is right there?
command = {
/*this is set when an html element is clicked by another function:
for this example, it equals the string 'topic'*/
taxonomy : '',
//this is called when the same html element is clicked as above
taxonomy_actions: function(){
this.taxonomy.actions();
}
}
topic = {
actions:function(){
//returns an array of valid commands for topic
this.commands.push('shortcuts');
this.commands.push('action_list');
this.commands['shortcuts'] = new Array();
this.commands['action_list'] = new Array();
for(x in this.aliases){
this.commands.action_list.push(this.aliases[x]);
this.commands.shortcuts.push(x);
}
return this.commands;
}
}
It's actually mostly there in your question:
whose value is the string 'topic' to call ...
What you want is to access the 'topic' property of the Object that contains the topic{} object.
Therefore you want:
taxonomy_actions: function(){
containing_object[this.taxonomy].actions();
}
The containing object (if you didn't attach topic to something) would be window in browser environments or global in NodeJS.

Can't access page-wide javascript variable

I'm fetching a JSON response and with that response, I have two values:
Air shipment cost.
Land shipment cost.
I want to save those two values somewhere in the client so that when a user chooses either 1 radio button or the other, I add that value to another element on the page.
Here's what I'm doing:
<script type="text/javascript">
$(document).ready(function () {
var landCost;
var airCost;
$("#ddlCiudad").change(function () {
var idCity = $("#ddlCiudad").val();
$.getJSON("/ProductCheckout/GetPriceForLocation", { cityId: idCity, productId: idProduct, type: "land" },
function (cityData) {
console.log("Recieved json data."); //This part works. It outputs.
var data = $.parseJSON(cityData);
console.log("Parse JSON response."); //This part works. It outputs.
landCost = data.LandCost;
console.log("Assigned value of LandCost"); //FAILS HERE. nothing is shown. not even an error.
airCost = data.AirCost;
console.log("Assigned value of AirCost");
alert(landCost);
console.log("Alerted land!");
alert(airCost);
console.log("Alerted air!");
}
);
});
So what do you suggest? I need to have the values of this JSON response, available for usage on that page, if I declare the variable inside the change() event, it'll be out of scope.
{"DaysToShip":" TER = 48 Hrs / AER = 24 Hrs","LandCost":"25,00","AirCost":""}
try
landCost = cityData.LandCost;
If you really must use global variables, you can attach them directly to the window object.
window.airCost = cityData.AirCost;
Really though you want to have the json request and the 'radio button' handling in the same scope, so that you're not polluting the global namespace at all.
Your call to $.parseJSON() is returning null because the data passed to your callback has already been parsed to JSON.
var json = {LandCost:3, AirCost:5},
results = $.parseJSON(json);
console.log(results); // results == null
IF you want to globally declare your variables, either put them outside the jQuery closure ($(document).ready(function () {...});), or don't use var to declare them. If you don't use the var keyword the variable will default to a global.
Here is a jsfiddle of setting global variables without using the var keyword: http://jsfiddle.net/jasper/JWtbV/
Have you considered using jQuery's $.data() function to attached the values directly to the body element in the DOM and accessing it from there?
// Set Values
$('body').data('landCost', data.LandCost);
$('body').data('airCost', data.AirCost);
// Retrieve Values //
console.log($('body').data('landCost');
console.log($('body').data('airCost');
Hope it helps.

Nested Objects With YUI and Javascript

I am working on a Javascript object that contains some YUI objects. The key thing is, my object needs to contain it's own set of YUI tabs so that I can display multiple instances of my object on the same page and have the tabs control their own object instance.
I set it up as follows:
var Scheduler = function(divid,startDate,mode){
this.tabView = null;
...
this.init = function(){
this.tabView.appendTo(this.calendar_cell);
this.tabView.addTab( new YAHOO.widget.Tab({
label: 'Day',
content:'<div id="'+ this.calendar_day_div +'" style="width:100%; height:auto;"></div>'
}));
var tab0 = this.tabView.getTab(0);
tab0.addListener('click', this.showWeek);
}
this.showWeek(){
alert(this);
}
});
Here's the problem. I would expect the alert(this); in this.showWeek to alert the instance of scheduler. Instead, it's giving me the tab li. I tried alerting this.parent and am given 'undefined' as an answer.
How should I set this up to do what I need to do?
The addListenter method takes a scope argument. So you can change your call to the following to solve your problem (since you are using YUI):
tab0.addListener('click', this.showWeek, undefined, this);
When you attach a function to an event of an object (in this case the object held by tab0) then its usually that object that becomes the this context of the function when it executes.
Adjust your code like this:-
var self = this;
this.showWeek(){
alert(self);
}

Categories