Akaime aka Akaime aka - 3 months ago 49
AppleScript Question

document.getElementById().value using dialog answer

Im trying to use the Dialog answer to enter value on a website using Applescript.

display dialog "Enter In-Shift" default answer ""
set x_answer to text returned of result
tell application "Safari"
do JavaScript "document.getElementsByClassName('in_shift1')[0].value = 'x_answer' ;" in document 1

end tell

Answer

There are two issues you’re running into. One is that you’ll need to concatenate the desired answer to the JavaScript string. Concatenation in AppleScript uses the ampersand.

set longerVariable to variable1 & " " & variable2

The second is that you’ll need to properly quote the x_answer variable so that characters with special meaning in JavaScript do not cause the resulting JavaScript to fail. For example, if the text entered contains a single quote, this will obviously cause problems with the boundaries of the text assigned to the desired element

The latter problem is the more difficult one, as there is no built-in escape mechanism in AppleScript that conforms to the needs of JavaScript. Using “quoted form of” almost works, but it quotes for AppleScript and shell scripts, not for JavaScript, and so uses triple quotes and a slash to escape contained single quotes, rather than backslashes.

he replied 'nothing' to me

becomes

’he replied '\''nothing'\'' to me'

when it should be

’he replied \'nothing\' to me'

Whenever I run into this problem, I look for a built-in way to solve it, and it doesn’t exist; the problem is exacerbated by AppleScript’s inability to easily replace text within a string. What ends up being necessary is a custom handler for replacing text; the standard way of replacing text in AppleScript is by manipulating text item delimiters: changing the delimiter to the text to be replaced, breaking the string into its text items, changing the delimiter to the text to be replaced with, and putting the parts back together into a string.

It’s not pretty, but there it is.

I’ve changed your example to use the answer box on Stack Overflow (class: wmd-input) for easy testing.

display dialog "Enter In-Shift" default answer ""
set x_answer to text returned of result


set x_answer to escaped from x_answer

tell application "Safari"
    do JavaScript "document.getElementsByClassName('wmd-input')[0].value = " & x_answer & " ;" in document 1
end tell

--escape text for use in JavaScript
on escaped from raw
    set oldDelimiters to text item delimiters
    set text item delimiters to "'"
    set parts to text items of raw
    set text item delimiters to "\\'"
    set escapedText to parts as text
    set text item delimiters to oldDelimiters
    return "'" & escapedText & "'"
end escaped

Note that your code uses getElementsByClassName, but your title asks about getElementById. In general, it will be safer to use getElementById if it’s feasible, because there can be only one.