I am having issues with a getElementsByClassName function I am using in Google Tag Manager.
I will need to capture an input field value in my client's form and I am isolating the class name and using it in my custom JS however I am only getting Undefined back.
The JS I am using is the below and I've also created a gtm.formsubmit event but I reckon that the event is firing before it has time to listen to the user input, it that even possible?
function() {
var inputField = document.getElementsByClassName("wpcf7-form");
return inputField.value || "";
}
Thanks!
Even if there is just a single element with the class wpcf7-form a call to getElementsByClassName will return an array of elements (in that case a single element). Since an array has no "value" attribute you get an "undefined".
If you are resonably sure there is only one element with the class you can do
...
var inputField = document.getElementsByClassName("wpcf7-form");
return inputField[0].value || "";
...
since a single element will always be at index 0. In that case it would be easier to use a DOM type variable in Google Tag Manager and set the selection method to "CSS selector". This will return the first element with your class (or undefined if not present).
Related
I have a form that is split into 5 stages. The form has the same ID for each stage.
I want to be able to track the clicks for the next buttons on each stage, but they have no unique identifiers other than the input name:
How can I identify the name in the trigger? I have tried several of the built-in variables but to no avail.
Any help would be greatly appreciated!
Thank you.
The built in "Click Element" variable returns the actual DOM object that has been clicked with all its properties.
So you could do a custom javascript variable with
function() {
var clicked = {{Click Element}};
clickedName = clicked.getAttribute('name');
if(clickedName == null) {
return false;
}
return clickedName;
}
You need to activate Click Element first. The function will return the name of the clicked element or "false" if there is no name attribute.
I'm developing a WordPress plugin that adds a button to TinyMCE, which lets you add an id attribute to the selected element. I have the button displaying, and when it is clicked it runs my function, which I'll call "idFunc" for this demo and it looks like this:
function idFunc() {
// Make sure editor has focus.
editor.focus();
// Get currently selected node
var selectednode = editor.selection.getNode();
// Set the id attribute on the node
selectednode.attr("id","newid");
}
With idFunc() written as above, nothing happens when I click my button. If I change the last line to an alert like this:
function idFunc() {
editor.focus();
var selectednode = editor.selection.getNode();
// Alert with the selected node
alert(selectednode);
}
I get an alert as expected, which says:
The page at mytestingdomain.com says: [object HTMLParagraphElement]
If I have my caret in a div instead of a p element, it says:
The page at mytestingdomain.com says: [object HTMLDivElement]
So I know I'm close, but the attr() function isn't adding any attributes to any elements in the TinyMCE editor.
What am I doing wrong?
The solution to this is easy.
editor.selection.getNode() gives you the common ancestor node (not a jQuery object).
To set the id attribute on the node you may call one of the following commands:
selectednode.setAttribute("id","newid");
or
selectednode.id = "newid";
or using jQuery
$(selectednode).attr("id","newid");
So, in my example below, "InputDate'" is an input type=text, "DateColumn" is a TD within a table with a class of "DateColumn".
Read the value of a discreet texbox:
var inputVal = $('#InputDate').val();
Read the value of a div within a table....
This works:
$('#theTable .DateColumn').each(function() {
var rowDate = Date.parse($(this)[0].innerHTML);
});
This doesn't:
$('#theTable .DateColumn').each(function() {
var rowDate = Date.parse($(this)[0].innerHTML());
});
The difference is the "()" after innerHTML. This behavior seems syntactically inconsistent between how you read a value from a textbox and how you read it from a div. I'm ok with sometimes, depending on the type of control, having to read .val vs .innerHTML vs.whateverElseDependingOnTheTypeOfControl...but this example leads me to believe I now must also memorize whether I need trailing brackets or not on each property/method.
So for a person like me who is relatively new to jQuery/Javascript....I seem to have figured out this particular anomaly, in this instance, but is there a convention I am missing out on, or does a person have to literally have to memorize whether each method does or does not need brackets?
innerHTML is javascript, and is a property of an element. If you'd like to stick with the jQuery version of doing things, use html():
$('#theTable .DateColumn').each(function() {
var rowDate = Date.parse($(this).html() );
});
edit: a bit more clarification about your concerns. jQuery is pretty consistent in it's syntax. Basically, most of the methods you find allow read/write access by adjusting the parameters passed to the method.
var css = $('#element').css('color'); // read the color of the element
$('#element').css('color', 'red'); // set the color to "red"
var contents = $('#element').html(); // grab the innerHTML of the element
$('#element').html('Hello World'); // set the innerHTML of this element
.innerHTML is a property of the element not a method.
Property reference Example: object.MyProperty
Method Example: object.SomeFunction();
I have sort of a table with a radio-button column. I managed to make radio-button column work dynamically inserting into a cell (div if matter). But, on postback innerHtml hasn't been updated with "checked" attribute.
Could you give me an idea how can I find out (on the server) if radio-button has been checked?
More info: This is on user control inside update panel.
This would be good post on my topic, still doesn't help
Any reason you cannot use a standard asp:RadioButton and use javascript to ensure it is mutually exclusive. I have done this before by adding a custom attribute to the radiobutton and then using a js function to uncheck all items with that attribute and then check the selected one. This works around the IE issue which prevents the groupname attribute from working on radioboxes that are in different containers.
radioButton.InputAttributes.Add("ClientGroupName", "grpRadioList");
radioButton.InputAttributes.Add("onclick",
string.Format(
"javascript:radiobuttonToggle('{0}','ClientGroupName','grpRadioList');"
,radioButton.ClientID));
and use the following JS to uncheck all radios and then check the one you want.
Note i used InputAttributes instead of Attributes as the radiobutton is wrapped inside a span tag so InputAttributes is for items added to the actual input control rather than the span.
function radiobuttonToggle(selectedRB, attribName, attribValue)
{
var objRadio = document.getElementById(selectedRB);
for(i = 0; i < document.forms[0].elements.length; i++)
{
elm = document.forms[0].elements[i];
if (elm.type == 'radio')
{
if(elm.getAttribute(attribName) == attribValue)
elm.checked = false;
}
}
objRadio.checked = true;
}
You can then expose radioButton.Checked as a property in your CS file and reuse this as a control.
Check Form.Request("radio-name") != null
You only get a non-null value when it's been checked.
Make sure your page elements are being rebuilt correctly on postback. Any binding process that inserted the radio buttons the first time around will have to be re-run before you can access them the second time.
Here is a working example, first I add radios to my webform by the method you linked :
function addRadio()
{
try{
rdo = document.createElement('<input type="radio" name="fldID" />');
}catch(err){
rdo = document.createElement('input');
}
rdo.setAttribute('type','radio');
rdo.setAttribute('name','fldID');
document.getElementById('container').appendChild(rdo);
}
Then at code behind I used only the code below to get the radio's value :
string value = Request["fldID"];
So, be sure you're trying to get the name of the radio buttons at server side. You should use name attribute at server side, not id.
I'm trying to grab the Web.UI.WebControls.HyperLink object itself via javascript so that I can modify its ImageUrl.
Here I'm setting the hyperlink's NavigateUrl to the my javascript function call:
lnkShowHide.NavigateUrl = String.Format(
"javascript:ShowHideElement('{0}');", lnkShowHide.ClientID
)
Here's my javascript function:
function ShowHideElement(img) {
var ele = document.getElementById(img);
if(ele != null) {
// Not sure if this will change the hyperlink's ImageUrl property???
img.src = 'smallPlus.gif';
}
}
However, if I check the value of 'ele' after calling getElementById it prints "String.Format("javascript:ShowHideElement....." and doesn't actually get the hyperlink object itself.
Any ideas would be greatly appreciated!
Why does document.getElementById() return the value of the hyperlink's href attribute?
It doesn't. But when you “alert(element)”, alert() calls toString() on the element, and HTMLLinkElement.toString() returns the contents of the href attribute, so “alert(link)” spits out the same results as “alert(link.href)”.
(Which is a bit weird and confusing, but that's how JavaScript 1.0 worked so there's not much can be done about it now.)
I check the value of 'ele' after calling getElementById it prints "String.Format("javascript:ShowHideElement....."
That shouldn't happen with the exact example you've given... there's no way the server-side “String.Format...” code should make its way through to the client side unless you accidentally enclosed it in quotes, eg.:
lnkShowHide.NavigateUrl = "String.Format(...)";
Other problems that spring to mind are that the function changes name (ShowHideElement/ShowHideImage), and you appear to be trying to set ‘.src’ on the link element (<a>). Links don't have .src, only images do.
Anyhow, you probably don't want to do a show/hide widget like this. javascript: URLs are always the wrong thing, and your example involves a lot of nested strings inside each other which is always fragile. You could try an ‘unobtrusive scripting’ approach, generating markup like:
<div class="showhide"> blah blah blah </div>
With JavaScript to add the open/close functionality at the client side (so non-JavaScript UAs and search engines will see the whole page without hiding bits). eg.:
function ShowHider(element) {
var img= document.createElement('img');
element.parentNode.insertBefore(img, element);
function toggle() {
var show= element.style.display=='none';
element.style.display= show? 'block' : 'none';
img.src= '/images/showhide/'+(show? 'open' : 'closed')+'.gif';
img.alt= show? '-' : '+';
img.title= 'Click to '+(show? 'close' : 'open');
}
img.onclick= toggle;
toggle();
}
// Apply ShowHider to all divs with className showhide
//
var divs= document.getElementsByTagName('div');
for (var i= divs.length; i-->0;)
if (divs[i].className=='showhide')
ShowHider(divs[i]);