Inserting value into test box with Javascript - javascript

I'm using Greasemonkey to insert a value into a text box, but I cannot for the life of me get it to work. I right click the text box in Firefox and inspect the element. It shows "input#ExtensionExtnum.field_for_edit"
document.getElementsByName("ExtensionExtnum").item(0).value = "test";
document.forms[0].submit();
and I get back:
/*
Exception: document.getElementsByName("ExtensionExtnum").item(0) is null
#Scratchpad:8
*/
I've gotten this sort of code to work on other websites, for inputting usernames and passwords automatically. I don't understand why it won't work here.

var items = document.getElementsByName("ExtensionExtnum");
if(items.length > 0)
items[0].value = "test";

Check if there is such an element first
if(document.getElementById("ExtensionExtnum") != undefined)
{
document.getElementById("ExtensionExtnum").value = "test";
}

In input#ExtensionExtnum.field_for_edit, ExtensionExtnum is the element ID, not its name. Thus you must use:
var elem = document.getElementById("ExtensionExtnum");
if ( elem !== null) elem.value = "test";
If you want to set the value of all the elements of class field_for_edit, use:
var elem = document.getElementsByClassName("field_for_edit");
for (var i = 0; i < elem.length; i++)
{
elem[i].value = "test";
}

Related

Error while selecting allElementsByID and adding a class to them

Hello I'm trying to add a class to all of my elements on a webpage. The overall goal is to grab all the elements on a webpage and add in a class. The class containing a font size will be changed to hide a message.
I'm getting this error
Uncaught TypeError: Cannot set property 'innerHTML' of null
I've tried moving my script outside the body tag of my index.html but its still not working.
Another problem is I can't add a class to all of the IDs I'm selecting. I can add classes manually like
$("#iconLog").addClass("style"); //this works
but when I try to add a class like this
empTwo = "#" + temp; //where empTwo is a string that equals "#iconLog"
$("empTwo").addClass("style") //this does not work
I'll post my entire script below for reference
$(function() {
var hideMsg = "f";
var n = hideMsg.length;
var i;
var j;
var holder;
var hideHolder;
// on button click - hide msg
$('#btnHide').on('click', function() {
//grab all IDS ON WEBPAGE
var allElements = document.getElementsByTagName("*");
var allIds = [];
for (var i = 0, n = allElements.length; i < n; ++i) {
var el = allElements[i];
if (el.id) {
allIds.push(el.id);
}
}
//ERRORS HAPPENING IN THIS LOOP
for(var i = 0; i < allElements.length; ++i)
{
console.log(allIds[i]);
try{
var temp = document.getElementById(allIds[i]).id;
}
catch(err){
document.getElementById("*").innerHTML = err.message;
}
tempTwo = "#" + temp;
console.log(tempTwo);
//$("#iconLog").addClass("style") //this works
$("tempTwo").addClass("style"); //this does not work
}
for(i = 0; i < n; i++) {
//set var holder to first value of the message to hide
holder = hideMsg.charCodeAt(i);
for(j = 7; -1 < j; j--) {
//set hideHolder to holders value
hideHolder = holder;
//mask hideHolder to grab the first bit to hide
hideHolder = hideHolder & (1<<j);
//grab the first element ID
if(hideHolder === 0) {
// embed the bit
// bitwise &=
} else {
//embed the bit
// bitwise ^=
}
}
}
});
});
To add a class to all elements you don't need a for loop. Try this:
$("*").addClass("style");
Same for setting the inner html of all elements. Try this:
$("*").html("Html here");
Remove the double quotes from empTwo .You don't need quotes when you are passing a varible as a selector. The variable itself contains a string so you don't need the quotes.
empTwo = "#" + temp;
$(empTwo).addClass("style") //this will work
Try this:
$(empTwo).addClass("style")
Note: You used string instead of variable:
well,
try this...
You were passing the varibale in the quotos because of that instead of getting value to empTwo it was searching directly for "empTwo".
$(empTwo).addClass("style");
to get all element try this-
var allElements = = document.body.getElementsByTagName("*");
Hoping this will help you :)
empTwo = "#" + temp; //where empTwo is a string that equals "#iconLog"
$("empTwo").addClass("style") //this does not work
You made mistake in the second Line.
The variable empTwo already is in string format.
So all you need to do is
$(empTwo).addClass("style") //this works because empTwo returns "#iconLog"

Trouble with changing the text of an element based off of a text form .val()

My app dynamically creates and deleted new elements based on the + / - buttons.
Inside the dynamically created elements are text forms. I want whatever the user types into the text form to be displayed in another dynamically created element.
$('.LName').keyup(function(event) {
var crazy = {};
for (var x = 1; x < i; x++) {
crazy[x] = function() {
$('#sideChange'+ x).keyup(function(event) {
var value = $(this).val();
$('.sLoan'+ x).text(value);
})
}
}
for (var p = 1; p < i; p++) {
crazy[p]();
}
});
For example, I accomplished this for changing the text in the previous element by including the function in the html onkeyup attribute, but I don't know how to accurately target other elements.
var changeTitle = function() {
var loanTitle = $(this).val();
var code = $("input[type='text'][name='loanName']").keyCode || $("input[type='text'][name='loanName']").which;
var length = loanTitle.length;
console.log(length);
if(length < 1 || code == 8) {
$(this).prev().text('Loan');
}
else {
$(this).prev().text(loanTitle);
}
};
What youll probably want to do is data bind the two elements with some sort of ID you generate. In the fiddle below, I just use an incrementing number. When the keyup happens, I grab that elements data-id and use it to find its "mirrored" input.
$('.mirror[data-id="'+id+'"]').val(text);
Your question was a bit vague but I think this is what you were asking for.
http://jsfiddle.net/swoogie/f8cd4voz/

innerText is undefined in Greasemonkey script

I've made code to query a document for matching strings and make a URL from the strings obtained. It looks through the tag elements looking for matches, makes the URL string, then it appends the link to the designated parentNode object. This code works fine in plain javascript, but it breaks when I stick it in Greasemonkey. I can't figure out why.
Here is a fully working version when I stick it in the chrome console:
//loop through elements by classname and find string matches
regexQueryEmail = "(AccountEmailAddress\\s)(.+?)(\\n)"
regexQueryContact = "(Contact with ID: )(.+?)(\\D)"
var Tags = document.getElementsByClassName('msg-body-div')
for (i = 0; i < Tags.length; i++) {
matchEmail = Tags[i].innerText.match(regexQueryEmail)
matchContact = Tags[i].innerText.match(regexQueryContact)
if (matchEmail != null) {
var emailString = matchEmail[2]
var placeHolder = Tags[i]
}
if (matchContact != null) {
var idString = matchContact[2]
}
}
var urlFirst = "https://cscentral.foo.com/gp/stores/www.foo.com/gp/communications/manager/main/191- 4559276-8054240?ie=UTF8&customerEmailAddress="
var urlSecond = "%3E&initialCommId="
var cscURL = urlFirst + emailString + urlSecond + idString
var cscLink = document.createElement('a')
cscLink.innerText = 'Communication History'
cscLink.href = cscURL
placeHolder.parentNode.appendChild(cscLink)
When I stick it in Greasemonkey, it gives me this error from the Greasemonkey "Edit" screen:
/*
Exception: Tags[i].innerText is undefined
#Scratchpad:18
*/
It has also told me that "placeHolder" is undefined, but I am unable to replicate this right now. I have a feeling that it has something to do with how the variables are scoped. I've added "var Tags;" and "var placeHolder;" to the top of the script and it didn't help.
Firefox uses the element.textContent property.
https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent?redirectlocale=en-US&redirectslug=DOM%2FNode.textContent
The variable placeholder in never declared in the scope you try to use it in. Instead it's declared somewhere in your for loop. Make sure you declare it within the same scope.
E.g.
var Tags = document.getElementsByClassName('msg-body-div')
var placeholder; // declare in same scope
for (var i = 0; i < Tags.length; i++) {
// lookup the tag once
var tag = Tags[i];
// get the text only once
var text = tag.textContent;
matchEmail = text.match(regexQueryEmail)
matchContact = text.match(regexQueryContact)
if (matchEmail != null) {
var emailString = matchEmail[2]
placeHolder = tag // deleted var statement
}
if (matchContact != null) {
var idString = matchContact[2]
}
}
...
// now you can use it.
if (placeHolder) {
placeHolder.parentNode.appendChild(cscLink);
}

having trouble with document.getElementById for dynamic client id

Do you have to do anything special while passing in a dynamically created string as a clientID for document.getElementById?
I have a asp:gridview control that has a textbox column and a checkbox column. I added an onclick event to the checkboxes to set the textbox value of that row to the max value of all checked rows +1. I pass in the IDs of the grid and the controls of the row that was selected. I can getElementByID fine for these controls, but When I dynamically build the IDs of the other controls, I keep getting null, even though I know that the IDs are correct. My code is bellow.
function SetPriority(cbID, tbID, gridID) {
var cb = document.getElementById(cbID);
if (cb.checked) {
var tb = document.getElementById(tbID);
var grid = document.getElementById(gridID);
var maxv = 0;
for (var i = 0; i < grid.rows.length; i++) {
var indexID = 102 + i;
var cbClientID = 'LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ct' + indexID + '_chkGroup';
var tbClientID = 'LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ct' + indexID + '_txtPriority';
console.log("row" + i);
//just for example of how it should be working
console.log(cbID);
var cbx = document.getElementById(cbID);
console.log(cbx);
//get row checkbox
console.log(cbClientID);
var thisCB = document.getElementById(cbClientID);
console.log(thisCB);
//get row textbox
var thisTB = document.getElementById(tbClientID);
console.log(thisTB);
if (thisCB) {
if (thisCB.type == "checkbox") {
if (thisCB.checked) {
if (thisTB.value > maxv)
maxv = thisTB.value;
}
}
}
}
tb.value = parseInt(maxv) + 1;
}
}
Here is how its showing up in the console, where you can see the IDs for the first row are the same
For Those wondering about How I am calling the function, I am adding it on to a checkbox in a .net gridview control on row databind. It renders as follows:
<input id="LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ctl02_chkGroup" type="checkbox" name="LeaveInfo$pnlMain$wgbLeaveSummary$gridSubmitted$ctl02$chkGroup" onclick="javascript:SetPriority('LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ctl02_chkGroup','LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted_ctl02_txtPriority','LeaveInfo_pnlMain_wgbLeaveSummary_gridSubmitted');">
The vb .net code to add the function is this...(on-_RowDataBound)
Dim chk As CheckBox = CType(e.Row.FindControl("chkGroup"), CheckBox)
Dim tb As TextBox = CType(e.Row.FindControl("txtPriority"), TextBox)
chk.Attributes.Add("onclick", String.Format("javascript:SetPriority('{0}','{1}','{2}');", chk.ClientID, tb.ClientID, gridSubmitted.ClientID))
No, you don't have to do anything special when dynamically building a string. A string in javascript is the same string whether it was built dynamically or specified directly in your code. If document.getElementById() is not working, then one of the following is likely the cause:
Your string isn't what you think it is so it doesn't match the target id.
Your DOM id isn't what you think it is.
You have multiple elements with the same id (not likely here because you won't get null)
You are calling getElementById() before the DOM is ready or before the desired elements have been added to the DOM.
In this case, it seems more likely that 1) or 2) are the issues here, but you don't show us any context to know whether 4) could be the problem.
Not 100% sure, but I think it could be a context issue. Try this:
function ( id ) {
var ID = document.getElementById;
this.id = id;
this.newvar = ID.call( document, this.id );
...
}
Also, this question may help you — it has a good explanation on context and assigning a var to getElementById Why can't I directly assign document.getElementById to a different function?
I couldnt figure out why my IDs that seemed identical were not. I will leave this question open for anyone to add insight on how to remedy this. I ended up just getting my elements by cell and not by ID.
function SetPriority(cbID, tbID, gridID) {
var cb = document.getElementById(cbID);
if (cb.checked) {
var tb = document.getElementById(tbID);
var grid = document.getElementById(gridID);
var maxv = 0;
if (grid.rows.length > 0) {
for (row = 1; row < grid.rows.length; row++) {
var thisCB = grid.rows[row].cells[5].childNodes[1];
if (thisCB == cb) {
continue;
}
var thisTB = grid.rows[row].cells[6].childNodes[1];
if (thisCB.type == "checkbox") {
if (thisCB.checked) {
if (thisTB.value > maxv)
maxv = thisTB.value;
}
}
}
}
tb.value = parseInt(maxv) + 1;
}
}

How to select this text using pure javascript, no jquery?

I need to select some text using javascript (no jquery), and Im not sure how to do it. I need to select the text ('Hello World') in myClass element before the first child element. Here are two examples, sometimes it will be an <img> tag as the first element and sometimes it will be a <br> tag. I also need to select the text between the <br> tags.
<p class="myClass" style="padding: 5px;">
Hello World
<img src="http://xyz.com/image.gif">
<br>
30-12-2011 19:45
<br>
Testing
<br>
</p>
<p class="myClass" style="padding: 5px;">
Hello World
<br>
30-12-2011 19:45
<br>
Testing
<br>
</p>
Edit note: I also need to select the other text nodes in myClass. And note that sometimes there will be an <img> as one of the child elements and sometimes there won't.
So I would like to end up with
var a = 'Hello World'
var b = '30-12-2011 19:45'
var c = 'Testing'
Anyone able to do this?
Not really sure what you want. If you want to get all the text, then use:
var text = element.innerText || element.textContent;
If you want to get the text in several pieces, then you have to iterate over all child nodes and extract the text nodes:
var texts = [],
children = element.childNodes;
for(var i = 0, len = children.length; i < len; i++) {
var node = children[i];
if(node.nodeType === 3) {
var text = node.nodeValue.replace(/^\s+|\s+$/g, '');
if(text.length > 0) {
texts.push(text);
}
}
}
This would not concatenate consecutive text nodes though, which can occur if you inserted new text nodes or split text nodes with JavaScript. In this case, you could do this:
var texts = [''],
children = element.childNodes,
new_bucket = false,
bucket = 0;
for(var i = 0, len = children.length; i < len; i++) {
var node = children[i];
if(node.nodeType === 1 && new_bucket) {
new_bucket = false;
texts[++bucket] = '';
}
else if(node.nodeType === 3) {
var text = node.nodeValue.replace(/^\s+|\s+$/g, '');
if(text.length > 0) {
new_bucket = true;
texts[bucket] += text
}
}
}
var elem = document.getElementsByClassname("myClass")[0],
txtNode = elem.childNodes[0],
txtNodeValue = txtNode.nodeValue;
console.log(txtNodeValue);
Example.
We select the element by its class ([0] just tells it to select the first element in the matched set) and then look for its first child node. In your case this would be the text node, so all we have to do from there is get the nodeValue.
This will get the first element with the class myClass and the first text node of that element:
document.getElementsByClassName("myClass")[0].childNodes[0].nodeValue
Here is a great article explaining.
You will most likely want to trim the string as well to remove white-space. You can add the following to give you trim functionality:
if(typeof String.prototype.trim !== 'function') {
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
}
}
...and use it as such:
var trimmedString = document.getElementsByClassName("myClass")[0].childNodes[0].nodeValue.trim();
http://jsfiddle.net/kgdnR/1/
var abc = [].filter.call((document.getElementsByClassName("myClass")[0].childNodes), function(node) {
if (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim().length) {
return true;
}
return false;
}).map(function(node) {
return node.nodeValue.trim();
});
var a = abc[0],
b = abc[1],
c = abc[2];
console.log(a, b, c);
Can be made work in IE but if you wanted that you might as well use jQuery.
I dont know how regular your example is but you can use the document object to interact with the DOM.
select the myClass elements
var elements = document.getElementsByClassName('myClass');
then take the first index , its childNodes and the first index of that which is a text node
var nodes = elements[0].childNodes;
for (var i = 0; i < nodes.length; i++)
{
var node = nodes[i],
text;
// loop over the nodes and see if its as textnode. Then trim and skip empty strings
if(node.nodeType === 3) {
text = node.textContent.trim();
if(text) {
alert(text);
}
}
}
first of all, you can use
document.getElementsByClassName('test')
to select the elements using the class name.
select the element you want (it returns an array), and then use
nodeValue
which will return the text.
With using XPath expression:
var contextNode = document.body;
var node, textNodes = [];
var search = document.evaluate('.//text()', contextNode, null, XPathResult.ANY_TYPE);
while(node = search.iterateNext()) textNodes.push(node);
Selecting text as asked by the OP:
var my_class = document.getElementsByClassName('myClass')[0];
window.getSelection().selectAllChildren(my_class);

Categories

Resources