How to set a text value for document.activeElement? - javascript

Knowing that my document.activeElement is an input field (I don't know exactly the name of the component, but may be the Google's search input field, for example), how can I set a text on it programmatically?
--update
I'm trying it from a xul application, via javascript after the page is loaded. A paste command works fine, so I know the field have the focus. (and I didn't put the Xul tag becouse it's just about the javascript)

See the mozilla reference. This is the same type as document.getElementById()
document.activeElement.value = 'new value';

If you are sure it is a input text field, just set the value:
document.activeElement.value = 'value'

Without seeing your code and the context it is running in, I can only speculate. However, my guess is that you are calling document.activeElement from your XUL app, which means document is the chrome document, not the content page. In this case, the active element is likely to be the browser or iframe element you are using to display the content.

I think there's a little more trouble because I'm in a Xul app. Javascript was supposed to work like in the browsers, but it didn't.
What I did to make it work was (after put the content in the clipboard):
controller.doCommand('cmd_selectAll');
controller.doCommand('cmd_paste');

If you want the focused element wherever it may be relative to the given application window, e.g. it may be inside a <browser> element, use document.commandDispatcher.focusedElement.value which is the same as document.commandDispatcher.focusedWindow.document.activeElement.value. This gives you the element that cmd_paste operates on.

Related

Custom javascript value not updating in Google Tag Manager

I have created a Custom JavaScript variable in GTM to pull out the form title on a popup form.
I am using element visibility and CSS selector to identify the forms.
This is a page with multiple forms so instead of having multiple tags and triggers, I want to do it on one and it to dynamically change.
So the CJS is:
function() {
return document.querySelector ('div._form-title').innerText
}
And it works perfectly when testing in the console, but when I test it in preview mode of Google Tag Manager, the first one works fine, but then if I open any other forms, the previous value shows again in the new tag.
It's like it's unable to fetch the most recent one.
The tag is triggered on element visible and observes DOM changes, so I would have thought the CJS variable would run again for the updated value, but it doesn't.
Any ideas?
Otherwise, in the variables that do come through automatically, when the popup loads, "Click text" comes through as the entire form text.
So an alternative way to do it could be to return the click text, but to shorten it - do you know how to return e.g. just the first 25 characters of the "Click text" variable?
Thanks in advance :)
On a page with multiple forms (or multiple elements that match the selector) this will always return the first match. That is just how document.querySelector works, not something GTM specific (also do not use custom HTML to get DOM nodes, use the built-in DOM variable type - this avoids the use of eval, which is good for security and performance and allows for stricter content security policies if that is an issue for you).
If you say that using click text is a viable alternative you do not need to shorten it (you could do that in a custom Javascript variable that returns a substring of the {{Click Text}} variable, but since you do not have to type out the click text anywhere this seems unnecessary), just use the starts with condition in your trigger filter and match the first 25 characters:

How can I scroll in the background using JS?

I'm building a chrome extension where I have to access the innerText of some span elements. I can safely get them using simple document.querySelector commands.
But for some spans, it returns null because they don't exist yet in the DOM> (For security reasons, I cannot disclose which website this happens with but to make it more clear, LinkedIn does a similar thing where the Experience block is only loaded if you scroll down to it.)
Now, to quote the problem using that example: I want to get the value of a span which is inside that Experience section. If I run the script inside window.onload, it returns null because the span isn't there yet.
One solution is to simply scroll the page, (or even worse, ask the users of the extension to first scroll the page before running the extension.) However, I do not want to do that.
Is there a way in JS to scroll the page in the background without visual feedback to the user so that I can get the value of the HTML elements that are initially hidden?
Assume that the span I want to get has the following class: defense-rc4

Selecting an element with no particular id, class, xpath, etc

I am currently working on writing the test automation for a web application that loads as an SWF file for our end-users, but a fully functioning Javascript version exists for the sole purpose of automation.
I have means to navigate through the application with keyboard shortcuts, but when it comes to executing click commands, I have no luck at all. Upon inspecting with Firebug/Firepath, the only value that I could find was an xpath (no id exists, no class, no anything really).
The next issue is the xpath itself.
It is:
Really brittle.
.//*[#id='flow']/div[1]/div/div[7]/div/div[3]/div[4]/div/div/div/div/div/div/div/div[3]/div[1]/img
This appears to be the xpath to the image that represents the button, not the button itself.
Executing .click() commands on the above type of xpath will do nothing until you manually hover your mouse over the button (regardless of moveToElement commands), where it will "click" the image but no functionality will run.
So I'm wondering after digging around in the actual JavaScript looking for identifiers, is there any way to select an element through any other properties? Or is there any way I can better "identify" a function? Perhaps find the xpath to the button that the image represents?
Using JUnit and Java, if that helps.
Thanks
Apparently, my comments answered the OP's question, so here goes, for reference sake:
If you need "the button itself", as you wrote in your question, use Inspect Element from the browser to find out what the actual element is you need and then simply remove from the right-hand side of your XPath expression enough axis steps until the part that remains selects the ancestor element that is the actual button element.
Now you should be able to send it a click event.
I'm afraid there won't be much we can do about the XPath statement to be "brittle", simply because you do not have an identifier to go on. That means that if the structure of the page changes, you will have to change the XPath (unless some of the ancestor elements have some notable identifiers).

Get the html of the javascript-rendered page (after interacting with it)

I would like to be able to save the state of the html page after I've interacted with it.
Say I click a checkbox, or the javascript set the values of various elements.
How can I save the "javascript-rendered" page?
Thanks.
In Chrome (and apparently Firefox), there is a special copy() method that will copy the rendered content to the clipboard. Then you can do whatever you want by pasting it to your preferred text editor.
https://developers.google.com/chrome-developer-tools/docs/commandline-api#copyobject
Console Example:
copy(document.body.innerHTML);
Note: I noticed Chrome reports undefined after the method is run, however, it seems to execute correctly and the right content is in the clipboard.
That should do and will grab the ALL page not just the body
console.log(document.getElementsByTagName('html')[0].innerHTML);
document.body.innerHTML will get you the HTML representation of the current document body.
That will not necessarily include all internal state of DOM objects because the HTML contains the initial default state of objects, not necessarily the state that they may have been changed to. The only way to guarantee you get all that state is to make a list of what state you want to save and actually programmatically get that state.
To answer the part of your question about saving it, you'll have to describe more about what problem you're really trying to solve.
To get the equivalent of view source with javascript rendered, including doctype and html tags, copy the command into the chrome console:
console.log(new XMLSerializer().serializeToString(document.doctype) + document.getElementsByTagName('html')[0].outerHTML);
In the chrome console, hover at the end of the output and click on the copy link to copy to the pasteboard.

Jquery (input/textarea).val(): how is it adding content without changing the DOM?

take a look at the JsFiddle here:
http://jsfiddle.net/ru2Fg/2/
Essentially, it starts with two textareas: one empty, one with stuff inside, and an input type=text. I was under the impression that to put stuff in an input you change it's value, and to put stuff in a textarea you add the text as a child to the node.
I perform a $(...).val(...) to change their contents. And their contents do change.
However, the DOM looks exactly the same! I'm printing out the 3 elements with console.log(); they seem unchanged. I look at them with chrome's inspect element: they seem unchanged.
I've looked at jQuery's val() method change doesn't seem to change the DOM, but that question concludes it's something funny with firebug not refreshing the HTML it displays. In this case, i'm quite sure inspect element displays the current html that exists on the page: i've seen the left attribute changing furiously when things are scrolling, for example. I'm also checking it using the console, which tells me the same thing: nothing changed.
My eyes, though, tell me something has changed, as I'm seeing "10, omg, moo" instead of "blank, hello world, 2000". What's going on?
EDIT: I posted the wrong jsFiddle. This should be the correct one now
There is a difference between the value attribute and the value property. When you type in the input box, you are changing the property, not the attribute. The attribute stays the same as when the document was loaded. Among other things, this means you can reset an input box to its default value with elem.value = elem.getAttribute('value');.
Similarly, if you have a drop-down <select> with one of the options having the selected attribute set, even if you choose a different option that attribute will still be there even though the selected property is now false.
The same applies to checkboxes and the checked attribute. The same also applies for the disabled attribute, and several other things too.
It is in-fact changing the DOM, other ways the 10 woulnd't have showed up in the text area anyway. The problem is in the firebug itself(at list the old one), I am not sure if it is still available in the new ones.
To verify, you can use the web console of firefox or console of chrome.
The DOM is completely loaded before anything jQuery happens, so technically the data inserted in the DOM isn't seen by debuggers. The debugging tools see only what is rendered so you won't be able to manipulate the "after the fact" data that arrives via jQuery. You could consider it "out of band" or fudging the DOM in a way. The same happens with AJAX. If you add in data or page content with AJAX methods like .load() you won't see it in the DOM.
An input box in jQuery has the val() method -- which is the value attribute, in the textarea, it is usually the html() method, what the textarea contains.

Categories