I am trying to pass a variable in javascript. I create a link in the following manner and everything seems to be working.
label.innerHTML = ' link';
However when I create the link in the following way where the link would also pass an associated object I get the following error from firebug -> "missing ] after element list"
label.innerHTML = ' link';
Is this an acceptable way to pass an object to a function. The problem is that I am creating this link within a function. The function creates links like this based upon an object that is passed to it. Therefore I cannot have this "object" as a global scope.
You are building the script by mashing together strings, as such you can only work with strings and object will be automatically stringified.
Use DOM instead.
var link = document.createElement('a');
link.href = "#"; // Have a more sensible fall back for status bar readers and middle clickers
link.appendChild(document.createTextNode(' link');
link.addEventListener('click',function () { show_box(this, object); },false);
label.appendChild(link);
… but use a library that abstracts away the non-standard event models that some browsers have.
What you're trying to do is pass the contents of object to output. Since it's an object, the string representation will be something like [object Object]. The output HTML would look like:
link
which is invalid. Don't try to concatenate the object, just pass it along as another argument to the function, like this. Or, better yet, use jQuery:
<!-- somewhere in the head, or at least after the object is defined -->
<script type="text/javascript">
$(function() {
$('#thelink').click(function() { show_box(this, object); });
});
</script>
...
link
If your object is simple variable like numeric or string variable than it will be Ok but if you are passing html object it will not work because it will be something like below.
link
Related
I have a Jquery element that I want to store in the DOM in the following way:
var html = '<button data-element="' + $('.some-selector') + '">Some action</button>';
$(html).appendTo('body');
console.log($('button').data('element'));
This yields a reference like jQuery331040235755567121182. Is there any way to convert that back into a normal Jquery object?
PS: I do not want to store it after adding the button (such as $('button').data('element', $('.some-selector')))
You have a few problems here. In your first line, $('.some-selector']) returns a jQuery Object. By adding it to a string, the objects are converted to something like "[object Object]". I THINK what you want is something like:
var html = $('<button>Some action</button>').data('element', $('.some-selector'));
$(html).appendTo('body');
console.log($(html).data('element'));
The first line creates the button object, and adds the jQuery objects in data 'element' - not sure why you would avoid this. The second adds it to the body. The third line prints out the jQuery object. One (of the many) advantages of using jQuery's .data is that it will avoid circular references - a plus if you are storing DOM objects within DOM objects.
I have a bunch of CSS properties stored in a MySQL database accessed via PHP. I need to make these properties available to JavaScript after the page has finished loading.
So what I did is foreach row, put the values in a Javascript object like so:
foreach ($cellcontent as $cellproperty) {
echo 'var '.$cellproperty->cell_id.' = {cellwidth:"'.$cellproperty->cell_width.'"};';
}
(For simplicity's sake I've only included one object property here but in reality there are many more.)
My problem is that at runtime, via JavaScript I get the cell_id reference which is somewhere in the html page like so:
var dacell = $(this).closest("div");
var cellid = dacell.attr("id");
So at this point, cellid is equal to the name of my var from the php output.
But when I try to get the property of my object (cellwidth) via JavaScript it doesn't work. Says its undefined when I try to see the value in an alert:
alert(cellid.cellwidth);
I think I'm just not referencing the actual object at this point and just trying to get a property of what has now become a string.
Is there a way to get back the reference to the object itself?
var cellid = dacell.attr("id");
The variable cellid is a string. Your hopes would be that the variable your are looking is in the global namespace which you can access via the following:
window[cellid].cellwidth
It's an awfull practice to pollute the global namespace with so much stuff.
Fetch all the values you need to inject into the JS, create an associative Array and inject it as a single JSON into the Page.
Nevermind everyone. The eval() javascript function fixed it all.
Instead of doing:
alert(cellid.cellwidth);
I did:
alert(eval(cellid).cellwidth);
and everything worked.
Thanks for all your time.
Cheers,
Erick P.
My original problem is specific to Apps Script, but I posted an answer that may be helpful in a more generic way.
I've tested HTML and code that works in regular HTML, but doesn't work with the Apps Script HTML Service. It seems that Apps Script won't accept a FILE object from the browser, but with accept a FORM object from the browser. I can't verify this, but it seems that when a FORM object is sent to the server side .gs code with google.script.run., that the code will extract the file from the object correctly, but if I send an INPUT object, it won't extract the file. I might be wrong, so if anyone can definitively tell me what is going on for the sake of anyone else reading this it would be good.
I'm uploading an image file with a file picker:
<form class='frmUpload'>
<input name="picOneUpload" onchange="picUpload(this.parentNode)" type="file">
</form>
As soon as the file is choosen, the onchange event runs the JavaScript picUpload function in a <script> tag.
<script>
window.picUpload = function(frmData) {
console.log("picUpload ran: " + frmData);
google.script.run.withFailureHandler(onFailure)
.uploadPic(frmData)
};
</script>
The console.log shows the form data as [domado object HTMLFormElement FORM].
Then the statement .uploadPic(frmData) calls a server side .gs function, passing the variable frmData. The .gs code receives the object into the arg argBlobInput:
function uploadPic(argBlobInput) {
Logger.log('argBlobInput: ' + argBlobInput);
Logger.log('Keys: ' + Object.keys(argBlobInput));
};
The Logger.log shows the passed in data as [object Object], not [domado object HTMLFormElement FORM]. If I use Object.keys(argBlobInput) I get a return value of the name of the input field: "picOneUpload". So, Object.keys() works in the .gs code. But, if I use Object.keys(frmData) in the front end code, no key value gets returned. I don't understand why Object.keys() will work on an object passed to the back end code, but it will NOT work on the object in the front end code? Maybe something do do with Caja, since this is a Google Apps Script and the HTML is sanitized with Caja? I don't know? But if that is true, why will it successfully pass the object to the back end code, and it works there fine? This makes no sense to me.
How can I get the key values out of the object [domado object HTMLFormElement FORM] in the front end? Even if I explicitly use the input name picOneUpload, (which shows up as a key to the object in the back end code) frmData["picOneUpload"], it returns nothing.
What I want to accomplish, is setting the height and width of the image in the front end, before it gets passed to the back end. But if I can't work with the [domado object HTMLFormElement FORM] object, I don't know how I'm going to do that?
If is use JSONstingify on that object:
console.log("picUpload data: " + JSON.stringify(frmData));
All I get in the console is: {}
I'm guessing that the object is empty except for the image blob. I guess I'll try putting the file picker in a regular HTML file that doesn't get sanitized by Caja and see what happens.
Okay, I ran the same web page and code without using Google Apps Script, and I get the same issue. It seems that there is an object, it must have an image file in it, but there are no keys in the object? I don't understand this. The image gets passed to the server, then the server uploads a picture to my drive, all without showing that there is anything in the FORM object?
In firefox the object is named: [object HTMLFormElement]
Do I need to access a HTMLFormElement different than a regular object?
Well, I don't think this has anything to do with Apps Script. I've found another method of retrieving the file from the file picker, which returns a file object: [object File].
And I can get the name and size of that object.
var fileInput = document.getElementById('picOneUpload');
var file = fileInput.files[0];
console.log("file: " + file.name + "_file size: " + file.size);
Oh, I just figured out how to get the FILE object out of the FORM Object.
console.log("picUpload FILE object: " + frmData.files[0]);
So, the [domado object HTMLFormElement FORM] has yet another object inside of it, the [object File] object, but the [domado object HTMLFormElement FORM] object has no keys in it I guess? I might be on my way to solving this problem.
I changed the arg getting passed from this.parentNode to just this,
<input name="picOneUpload" onchange="picUpload(this)">
which I prefer because I don't need info from all the elements. Now, instead of getting the FORM object, I get an INPUT object, which I still need to get the FILE object out of.
So there is:
[domado object HTMLFormElement FORM] - Google
[object HTMLFormElement] - Firefox
[object HTMLInputElement]
[object File]
[object Object]
And I'm guessing that there is a label object, since I have a label in the form. I'm assuming the the FORM object has the most data in it.
Using Firebug, and the DOM tab, files has a list of properties I guess.
lastModifiedDate
mozFullPath
name
path
size
type
So, I guess that is one way to find out what the property names are in the object.
Passing this instead of this.parentNode doesn't work with Google Apps Script HTML Service. If I just pass this with the input Object, I get an error that the zero property is null, or something like that. And it looks like the image becomes part of the FileUpload class.
I found this documentation that shows a file upload:
HTML Service Forms File Upload
Yes, there is a difference. In the browser, the this keyword will create an object filled with information about the element from the reference point of this. And there can be objects inside of objects. For example, a FILE object inside of an INPUT object, inside of a FORM object.
[object HTMLFormElement]
[object HTMLInputElement]
[object File]
To get the INPUT object out of the FORM object, you can use the name attribute in the INPUT tag.
//picOneUpload is the name attribute of the FILE input element
console.log("Input Object: " + frmData.picOneUpload);
Then to get the FILE object out of the INPUT object, you can uses the files property.
var file = frmData.picOneUpload.files[0];
console.log("file: " + file);
Browsers seem to add a descriptive name to the object to help understand where the object originated from, and what might be in there.
It seems that when there is an object inside of another object, there might not be any key names at all. So trying to enumerate key names to try to find out how to access the info in that object might not help you. I just happened to see an example at some website that used the files property name to get the file blob out of the FILE object from a file upload picker. So, I tried it, and I discovered that there was data in an object that I otherwise might have though was empty.
One way to figure out what might be in the object, is to inspect the element that the object came from with something like Firebug, and look for properties in the DOM. For example, there is files and under files there is: Size, Type, Name, etc.
I can get all the property names out of the object. I had thought that maybe Caja was doing something to prevent the user from getting data out of an object created with this. I just need to loop with a FOR LOOP.
for (var theProperties in frmData) {
console.log('theProperties: ' + theProperties);
console.log('loop content: ' + frmData[theProperties]);
};
I should have done this to begin with. I can get the ELEMENT object out of the FORM object by just using the element property.
console.log("elements: " + frmData.elements);
I am using code lines like the following in order to fetch data from an intranet website:
util.setProp(obj, "firstNameOld", $(msg).find('#fname_a').text());
Now I have another function in the same file where I want to use the above again, resp. the value of that object - currently I am hard-coding this ('Test') for test purposes:
util.setProp(obj, "firstNameNew", 'Test');
How can I pass the value from the firstNameOld object in one function to the firstNameNew object in another function ? If a solution with global variables is better here than this would work as well.
Many thanks for any help with this, Tim.
I've never used the framework that includes util But I imagine that if there is a setProp() then there has to be a getProp() or something similar.
If so, you could do something like
util.setProp(obj, "firstNameNew", util.getProp(obj, "firstNameOld"));
This also relies on the assumption that you want to copy from two properties in the same object.
If not, then pass the desired source object in the getProp() call.
My guess is that functions (or properties) are called "firstNameOld" and "firstNameNew", so the first time you get it from selector, second time you want to do the same.
Try to use the local variable like that:
var text = $(msg).find('#fname_a').text();
//
util.setProp(obj, "firstNameOld", text);
//
util.setProp(obj, "firstNameNew", text);
I am working with an ActiveX control in Internet Explorer 8 that is to display a save file dialog which let's the user choose a file name and file type (jpg, gif, etc). These values get passed to code and then are used in a different method to save the file. Unfortunately the method that invokes the dialog has no return value, and the file name and file type are passed in as out parameters.
The signature of the method (expressed in Visual Basic) looks like this:
Public Sub SaveFileDialog( _
ByVal bstrDialogType As Variant, _
ByRef pbstrFileName As String, _
ByRef out_pvType As Long _
)
The two ByRef parameters are the out parameters.
I have written the following JavaScript code:
try
{
var saveFileName, saveFileType; // out variables
gxVideoPlayBack.SaveFileDialog("image", saveFileName, saveFileType);
alert(saveFileName); // displays "undefined"
alert(saveFileType); // displays "undefined"
}
catch(error)
{
if(!error.number === -2147221484) // User clicked cancel.
{
alert(error.message);
}
}
The code works in that the ActiveX control produces its dialog, and I can handle error conditions, but I can't seem to figure out how to capture the values of the out parameters.
In the code gxVideoPlayBack is a reference to the ActiveX control embedded in the DOM via an HTML element.
If JavaScript will not work for this, can it be done in VBScript?
As an alternative I can just implement my own dialog, but would rather use the one provided.
Edit: It seems that it's not possible to have "out" parameters in JavaScript/JScript.
Original:
Perhaps the approach described in this article will work:
var saveFileName={}, saveFileType={}; // Empty "output" objects.
gxVideoPlayBack.SaveFileDialog("image", saveFileName, saveFileType);
alert(saveFileName.value); // The "value" attribute is assigned ...
alert(saveFileType.value); // ... by the "SaveFileDialog" method?
I suppose the idea is that the WSH wrapper for this native call will attempt to assign the "value" property of the given output parameters, so you can either override the value setter or just give it an object with a built-in value setter.
All function arguments in JavaScript are passed by value (even if the value being passed is a reference to an object (which it is)). There is no pass-by-reference.
If SaveFileDialog modifies the objects referenced by saveFileName and saveFileType then you have access to those changes through your existing variables.
Unfortunately, out/ByRef parameters will only work in JScript for objects; not for any other type (numbers, strings).
In this case, you’ll have to use VBScript, which does support ByRef arguments, or like maerics says, write a VB/VBScript wrapper for the SaveFileDialog method, which could return an object containing both file name and type.