AppleScript - do JavaScript returns missing value - javascript

The below script is used to click on a button to load a date on our website, then get the value of that date.
It should then return that date value, which will be used in some comparisons later on.
However, when I log doJavaStuff and emptyDate, both come back as "(*missing value *)".
The display dialog for emptyDate also returns "msng".
Why isn't the result of the do JavaScript being returned?
I've looked at multiple articles and sources and tried multiple suggestions, but nothing has worked.
e.g. I tried setting the second line of the do JavaScript to a variable, and returning that variable, but that somehow made the AppleScript variable undefined.
I'm relatively new to AppleScript, so maybe I'm missing something obvious.
global emptyDue, serviceDate, doJavaStuff
set emptyDue to " "
set doJavaStuff to " "
set serviceDate to "2021-11-30"
on isEmptyDue()
tell application "Safari" to tell document 1
set doJavaStuff to do JavaScript
"document.getElementById('trgUseNext').click(); #clicks button to load date.
document.getElementById('inspDate').value;" --gets the value of date
return doJavaStuff
end tell
end isEmptyDue
set emptyDate to isEmptyDue()
display dialog emptyDate
log doJavaStuff
log emptyDate

I was able to duplicate your problem using an element that happens to be on this StackOverFlow page (post-id), using this simplified version of your script:
on isEmptyDue()
tell application "Safari" to tell document 1
set doJavaStuff to do JavaScript
"document.getElementById('post-id').value"
return doJavaStuff
end tell
end isEmptyDue
set emptyDate to isEmptyDue()
display dialog emptyDate
The return value is, as you noted, “msng”.
The problem appears to be that AppleScript is perfectly happy to have nothing but quoted text on its own line, and is also perfectly happy to run do JavaScript with no script. That is, the code as you’ve presented it doesn’t run any JavaScript: it calls do JavaScript with nothing, and then the next line is a string of text that AppleScript ignores.
If I combine the lines so that they are one line instead of two, display dialog emptyDate displays the expected 8-digit value of element post-id on this StackOverFlow page (found by viewing the source).
on isEmptyDue()
tell application "Safari" to tell document 1
set doJavaStuff to do JavaScript "document.getElementById('post-id').value"
return doJavaStuff
end tell
end isEmptyDue
set emptyDate to isEmptyDue()
display dialog emptyDate
That was oddly difficult to track down because neither of the “mistakes” provided an obvious error: do JavaScript without any text is not an error—instead, it returns a cryptic string, “msng”, which I suspect but do not know stands for “missing”—and a string on its own on a line is not an error either. So it looks like it’s doing something and not working, instead of not doing anything and not working.

Related

Loop through list in AppleScript and JavaScript

I’m currently using AppleScript to automate some tasks in Safari. I have below code, which is supposed to set the value of the text box ‘ownerValue’ to the item from the loop. Whenever I execute the code, nothing happens.
set countryList to {"BR", "CN"}
repeat with country in countryList
tell application "Safari"
activate
tell document 1
do JavaScript "document.getElementById('ownerValue').value = country"
end tell
end tell
end repeat
When I replace the country in the loop to the actual country value, e.g. “BR”, it then inserts the text into the text field.
tell application "Safari"
activate
tell document 1
do JavaScript "document.getElementById('ownerValue').value = ‘BR'"
end tell
end tell
It also seems that AppleScript doesn’t recognise country as an item from the loop, since country is not in green.
Any ideas on how I can fix this so I can let AppleScript loop through the values in countryList?
Thanks!
This will resolve the issue of the variable not being treated as a variable:
set countryList to {"BR", "CN"}
repeat with country in countryList
tell application "Safari"
activate
tell document 1
do JavaScript "document.getElementById('ownerValue').value = '" & country & "';"
end tell
end tell
end repeat
However, you may have another issue here, in that you are looping while inputing the value of a new variable into the same input field. In other words the JavaScript command as written is going to first input BR and immediately overwrite it with CN.
Note that the color of country in the code above is not showing as green, however, here is a clipped screenshot from Script Editor and you see it's green.
To address the comment:
Could you please explain why it was previously not treated as a variable but now is?
When mixing two languages, i.e. AppleScript and JavaScript in this use case, and passing an AppleScript variable to JavaScript, you need to build out the JavaScript command using concatenation so the value of the variable is expanded.
In your code it was being treated as a fixed value as JavaScript has no way of knowing it was an AppleScript variable, hence concatenation, i.e. & ... &. In AppleScript, & is the concatenation character.

JavaScript runtime error: '[MethodName]' is undefined

I'm trying to use jQuery and AJAX to validate that users entered a number in a particular field and that they didn't leave it blank and I'm a little confused as to why I can seem to do one, but not the other.
I'm doing this in a jQuery change() function so any time they change the value in that field, it updates it in the database without refreshing the whole page and it works fine until I try to use isNull() to validate.
I'm saving their input to a variable called UserInput and first checking to make sure it's a number with this:
if (!isNaN(UserInput))
which works perfectly. I'm also trying to check and make sure it isn't empty by using this:
if (isNull(UserInput))
Intellisense completes isNull() for me just like it did for isNaN() and all appears well in Visual Studio, it compiles without error. I've also tried isNullOrUndefined() here with a similar result, intellisense completes it for me and all seems well. Right up until I change the value in the field, at which point it promptly gives me this error:
JavaScript runtime error: 'isNull' is undefined.
I'm not sure why it's undefined (especially since intellisense is completing it for me) or how to go about defining it.
I also tried this because it seemed like it covered all the bases, not just isNull():
https://stackoverflow.com/a/5515349/8767826
and I put an alert() inside the if and I didn't get an error, but my alert didn't fire either.
The end goal is to get it to change to a zero on the client side if they leave do leave it blank.
Anyway I'm kind of stumped and I appreciate any help anyone can offer.
Thanks
There's no need for an isNull function; you can check
if (UserInput === null)
isNaN exists because NaN, unlike every other value in JavaScript, is not equal to itself.
But null doesn't mean the field is blank! If the field is blank, its value will be the empty string. Check for that instead:
if (UserInput === '')

Meaning of JavaScript form validation code?

I have to explain how a specific Javascript code validates a web form, but I am stuck with what some of the features do, most specifically this section of the code. I understand that the first line defines that the rest of the section should only run if the field Field1 of the form ExampleForm is left empty, but I do not know what purpose the rest of the code serves. All I know is that msg is a variable created earlier in the document with an empty default value, and that result is another variable with a default value of true. Can anyone help me out by explaining what each line does?
if (document.ExampleForm.Field1.value=="") {
msg+="You must enter your name \n";
document.ExampleForm.name.focus();
document.getElementById('Field1').style.color="red";
result = false;
}
In plain english:
If the document form field value is equal to an empty string, set the error message to msg, then focus on the element, and give is a red color so the user knows it's an error, and set the result to false, for whatever you're going to use that for later in your code/function.
So this would in part depend on what other code is on the page. For example document.ExampleForm is not part of the DOM and seems to be something someone kludged onto your page.
Overall I would say this is pretty bad code that makes a ton of assumptions that won't necessarily hold up written by someone who doesn't understand in-browser javascript very well, but let's go with it
//if the value in this variable is falsy (false, empty, or 0)
if (document.ExampleForm.Field1.value=="") {
//Append this to the msg string. Note \n is usually used
//to indicate "new line" but wont' do anything on the web since that's not how line breaks
//work on the web
msg+=”You must enter your name \n”;
//Invoke the `focus` field on this variable. From the context I assume this is
//a DOM node so you are basically focusing it in the browser
document.ExampleForm.name.focus();
//Set the font color of '#Field1' to red
document.getElementById('Field1').style.color=”red”;
//Presumably result is something that tells you true/false did the validation succeed.
//set it to false to indicate failure.
result = false;
}
My guess about what document.ExampleForm is that it depends on some undocumented behavior of an old browser to add anything with id=ExampleForm to the document element. But really I have no idea. Maybe you have some code elsewhere that creates that variable. Either way its a horrible idea and should get someone yelled at.

Javascript indexOf not finding text in a variable

I am sure there is something simple that I am missing but I am stumped here.
The issue is that I am looping through an array of strings and using the string value to search for a part of that string using indexOf. The first time around the loop the index of is finding what I am looking for but the second time it is not.
Here is a fiddle - http://jsfiddle.net/jeremywrags/uSwjG/1/
the line that seems to be not working is this
var aliasIndex = fromclause.indexOf(" " + tableAlias + " " );
I am trying to build a SQL parser for a cloud app and the use case here is that when a table is aliased I need to get the original table name so that I can look up the table columns. The first time around the loop index of returns the index and then the table name. The second time around the index of is -1 and the table name is not retrieved.
If I need to provide more context please let me know.
thanks
It's not matching because on the second pass, tableAlias is the string " b" (note the space). So then you search for " b " (note two leading spaces), which isn't there.
Rather than using alert, use the debugger built into your browser. You can set breakpoints in the code, step through line by line, inspect variables, etc., etc. Doing that with this would have shown you, when looking at the variable tableAlias, that it had a leading space, hopefully helping you find the solution.
Here's what that looks like in Chrome's debugger, for instance:
(If you look at the jsFiddle source above the actual debugger's version, you'll see a debugger; statement in the code — normally you don't need that statement, you can just open your page, use the "Sources" tab to find your JavaScript file, navigate to the line, and click the margin to the left of it to set a breakpoint. But sometimes [for instance, when using jsFiddle], the debugger; statement is handy. What it does is, if the debugger is open, halts execution of the code at that point like a breakpoint does.)

Is there a way to change variable values while debugging JavaScript?

I have a breakpoint on this piece of code (using Firebug):
if (validator.formValidate([dom.forumid]))
How can I skip this validation part and get into the if clause even if my dom.forumid is not valid, i.e. the call to formValidate() returns false? So how can I make it return true?
I was thinking about modifying the JavaScript, but I don't know how that's done.
As of today (Chrome 67) you can just double-click any variable on the right hand side under the "Scope" section and edit it in real-time.
In Firebug I do this by entering an assignment into the watch input field
to assign a new value
to assign a new function that returns the value I expect
This also works in Chrome ~33 (just tested) execpt: one has to enter the assignment into the console (which actually works in Firefox too, but using the watch panel is faster :).
In Firebug, you have to edit and re-save the assignment typed into the input on each break.
Of course, replacing the function will prevent the code from functioning normally on further runs. To avoid this one might save the original value to window._savedFnX or so and then do the assingment again assigning the saved function/value. But I think this is a workaround from saving one stepping through the code again and again to reach the point of interest. I often realize that there's a bad condition and then I want to continue (while the code would not) to test the rest of the code.
Take a look at these screenshots:
Code background
In the screenshot photo is an instance with this code:
{
...
_loaded: false, // set to true on some condition
...
isLoaded: function(){
return this._loaded;
},
...
}
The method isLoaded() will be replaced in the example to always return true. :)
Firebug
(Applies to Firebug ~1.12)
Stop at breakpoint
Go to the console
Assign function that returns the value you want to the variable in scope (or being reachable) [ORANGE]
The [BLUE] box highlights the the value that would be returned by isLoaded() and the value that is being returned by the replaced function.
Chrome
(Applies to Chrome ~34.0)
Note: in Chrome you can also edit the source code and re-run the modified version.
Stop at breakpoint
Go to the console
Assign function that returns the value you want to the variable in scope (or being reachable) [ORANGE]
(Refresh to see the result) [GREEN]
The [BLUE] box highlights the the value that would be returned by isLoaded() and the value that is being returned by the replaced function.

Categories

Resources