I'm trying to create a pre-processor that converts some custom markup in a file into attribute names which works with Polymer's data binding $= annotation, however I've come across a stumbling block.
I cannot set attributes using Javascript that contain a dollar sign.
I'm trying to convert
<p stuff="align bottom#md top#lg; offset 2gu#md; "></p>
to
<p align-bottom$="{{globals.abovemd}}" align-top$="{{globals.abovelg}}" offset-2gu$="{{globals.abovemd}}">
I have tried:
.setAttribute("align-bottom$", "{{globals.abovemd}}");
But it won't work because the attribute name cannot contain a dollar sign.
Can any one think of a way I can get around this?
This might do the trick(setting invalid attribute names), although obviously not valid in all cases:
function setDollar(el,name,val){
var attrs = [];
var tagName = el.tagName;
for (var i = 0; i < el.attributes.length; i++) {
var attrib = el.attributes[i];
if (attrib.specified) attrs.push(attrib.name+'="'+attrib.value+'"')
}
el.outerHTML = '<'+tagName+ ' '+name+'$="'+val+'"'+attrs.join(' ')+'>'+ el.innerHTML+'</'+el.tagName+'>';
attrs.forEach((attr)=>el.setAttribute(attr.name, attr.value))
}
setDollar(document.querySelector('#wow'),'foo','bar')
<div id="wow"><p>something</p></div>
Still, needs checking for closing tag etc.
Just exclude the $ anytime you are dealing with that property. The $ is just reflecting the property to the attribute onto that DOM element.
.setAttribute("align-bottom", globals.abovemd);
Pretty sure this gonna work
(you need put align-bottom$="" into your html first, this is just to update the value):
.attributes['align-bottom$'].value = "{{globals.abovemd}}";
Related
I need to change the href of link in a box. I can only use native javaScript. Somehow I have problems traversing through the elements in order to match the correct <a> tag.
Since all the a tags inside this container are identical except for their href value, I need to use this value to get a match.
So far I have tried with this:
var box = document.getElementsByClassName('ic-Login-confirmation__content');
var terms = box.querySelectorAll('a');
if (typeof(box) != 'undefined' && box != null) {
for (var i = 0; i < terms.length; i++) {
if (terms[i].href.toLowerCase() == 'http://www.myweb.net/2/') {
terms[i].setAttribute('href', 'http://newlink.com');
}
}
}
However, I keep getting "Uncaught TypeError: box.querySelectorAll is not a function". What do I need to do in order to make this work?
Jsfiddle here.
The beauty of querySelectorAll is you dont need to traverse like that - just use
var terms = document.querySelectorAll('.ic-Login-confirmation__content a');
And then iterate those. Updated fiddle: https://jsfiddle.net/4y6k8g4g/2/
In fact, this whole thing can be much simpler
var terms = document.querySelectorAll('.ic-Login-confirmation__content a[href="http://www.myweb.net/2/"]');
if(terms.length){
terms[0].setAttribute('href', 'http://newlink.com');
}
Live example: https://jsfiddle.net/4y6k8g4g/4/
Try This:
var box = document.getElementsByClassName('ic-Login-confirmation__content')[0];
Since you are using getElementsByClassName ,it will return an array of elements.
The getElementsByClassName method returns returns a collection of all elements in the document with the specified class name, as a NodeList object.
You need to specify it as follows for this instance:
document.getElementsByClassName('ic-Login-confirmation__content')[0]
This will ensure that you are accessing the correct node in your HTML. If you console.log the box variable in your example you will see an array returned.
you can select by href attr with querySelector,
try this:
document.querySelector('a[href="http://www.myweb.net/2/"]')
instead of defining the exact href attribute you can simplify it even more :
document.querySelector('a[href?="myweb.net/2/"]'
matches only elments with href attribute that end with "myweb.net/2/"
I have a component with an ID that is composed of a first static part and a second dynamic value, like this:
<div id="smallPlacardone">
Where: smallPlacard is static and one is passed using a variable.
Later in my code I want to use the dynamic part of the ID, namely one, but not the first static part smallPlacard, like this:
var clicked = $(this).parent().attr("id");
$("#right"+clicked+"").show();
What's the best way of doing it?
If "smallPlacard" is static, then you can just remove it using the replace method:
var clicked = $(this).parent().attr("id").replace(/smallPlacard/, '');
$("#right" + clicked).show();
I recommend working with delimiter chars and split(). It's easier to read and avoids the regex entirely:
<div id="smallPlacard_one">
and
var clicked = $(this).parent().attr("id").split("_")[1];
$("#right_" + clicked).show();
Alternatively something like this, which is more flexible because it does not rely on hidden conventions:
<div id="smallPlacard_one" data-show="#right_one">
and
var selector = $(this).data("show")
$(selector).show();
Snippet of HTML code I need to retrieve values from:
<div class="elgg-foot">
<input type="hidden" value="41" name="guid">
<input class="elgg-button elgg-button-submit" type="submit" value="Save">
</div>
I need to get the value 41, which is simple enough with:
var x = document.getElementsByTagName("input")[0];
var y = x.attributes[1].value;
However I need to make sure I'm actually retrieving values from inside "elgg-foot", because there are multiple div classes in the HTML code.
I can get the class like this:
var a = document.getElementsByClassName("elgg-foot")[0];
And then I tried to combine it in various ways with var x, but I don't really know the syntax/logic to do it.
For example:
var full = a.getElementsByTagName("input")[0];
So: Retrieve value 41 from inside unique class elg-foot.
I spent hours googling for this, but couldn't find a solution (partly because I don't know exactly what to search for)
Edit: Thanks for the answers everyone, they all seem to work. I almost had it working myself, just forgot a [0] somewhere in my original code. Appreciate the JQuery as well, never used it before :-)
The easiest way is to use jQuery and use CSS selectors:
$(".elgg-foot") will indeed always get you an element with class "elgg-foot", but if you go one step further, you can use descendent selectors:
$(".elgg-foot input[name='guid']").val()
That ensures that you only get the input named guid that is a child of the element labelled with class elgg-foot.
The equivalent in modern browsers is the native querySelectorAll method:
document.querySelectorAll(".elgg-foot input[name='guid']")
or you can do what you have yourself:
var x = document.getElementsByClassName("elgg-foot")
var y = x.getElementsByTagName("input")[0];
Assuming you know it is always the first input within the div
You can combine it like this:
var a = document.getElementsByClassName("elgg-foot")[0];
var b = a.getElementsByTagName("input")[0];
var attribute = b.attributes[1].value;
console.log(attribute); // print 41
Think of the DOM as the tree that it is. You can get elements from elements in the same way you get from the root (the document).
You can use querySelector like
var x = document.querySelector(".elgg-foot input");
var y = x.value;
query the dom by selector https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
var fourty1 = document.querySelector('.elgg-foot input[name=guid]').value;
querySelector will return the first match from the selector. This selector will find the element with class elgg-foot and then look at the input element inside of that for one named guid and then take the value of the selected element.
I think the simplest way would be using JQuery. But using only javascript,
the simplest way would be:
var div = document.getElementsByClassName("elgg-foot")[0];
var input = div.getElementsByTagName("input")[0];
alert(input.value)
Take a look at this JSFiddle here: http://jsfiddle.net/2oa5evro/
Is this the correct format?
var title = new_element.setAttribute('jcarouselindex', "'items+1'");
alert(title);
No need to put the second parameter in quotes.
var title = new_element.setAttribute('jcarouselindex', items+1);
If you want to set a custom attribute then you can use HTML5 data-attributes, something like
var title = new_element.setAttribute('data-jcarouselindex', items+1);
It is syntactically correct JS/DOM, but there is no 'jcarouselindex' attribute in HTML and using setAttribute (as opposed to setting properties that map to attributes) is generally bad practice as it is buggy in MSIE (although not in such a way that will cause a problem in this case).
You might not be intending to have <foo jcarouselindex="'items+1'"> as your end result though.
Using jQuery?
var title = $('#new_element').attr('jcarouselindex', "'items+1'");
alert(title);
You have too many quotes:
var index = items + 1;
new_element.setAttribute('jcarouselindex', index);
Remark: there's no jcarouselindex attribute defined in HTML elements so this is not very clean code.
I'm trying to apply a tooltip to a foreach loop, but I need the javascript to read the attribute "mystickytooltip" with a number at the end.
<div id="mystickytooltip{$smarty.foreach.cart.iteration}" class="stickytooltip">
Will output
<div id="mystickytooltip1" class="stickytooltip">
<div id="mystickytooltip2" class="stickytooltip">
<div id="mystickytooltip3" class="stickytooltip">
And I need the javascript to read "mystickytooltip(ANYVALUE)" is this possible? My JS knowledge sucks.
//stickytooltip.init("targetElementSelector", "tooltipcontainer")
stickytooltip.init("*[data-tooltip]", "mystickytooltip")
Thanks.
In your previous (now deleted) question, it looked like you were using jQuery. If that's the case, you should just be able to use a class selector:
var myToolTips = $("div.mystickytooltip");
Or you could use the Attribute Starts With selector:
var myToolTips = $("div[id^='mystickytooltip']");
The only possible drawback I could forsee with the attr-starts-with selector is if you have any other div elements whose id begins with "mystickytooltip" (ie, "mystickytooltipcontainer"). In that case you could combine the class and attr-starts-with selectors:
var myToolTips = $("div.mystickytooltip[id^='mystickytooltip']");
You can try this :
var i=1; // starting index
while(document.getElementById('mystickytooltip'+i)) {
stickytooltip.init("*[data-tooltip]", "mystickytooltip"+(i++));
}
In english : as long as you can find an element with id 'mysticktooltip'+i (+ is string concatenation in js), call stickytooltip.init with this id as second parameter (and increment i).