jQuery attr() method to create a data dash attribute - javascript

I'm trying to figure out why when adding a data-attribute to (Let's say an image) requires the attribute name to be put into quotes. I know that it needs to be done, but if a student asked me I wouldn't have the exact answer why. So take the two examples below.
1.) I'm looking for an explanation why the dash is a problem.
2.) Is there a way to escape it so you don't need to put it in quotes?
This Doesn't work:
$("img").attr({
alt: "a picture of my cat",
data-item : "pet",
data-color : "orange",
});
This Does work
$("img").attr({
alt: "a picture of my cat",
'data-item' : "pet",
'data-color' : "orange",
});
3.) The arguments that are passed to the attr() method is an object literal right?
4.) Is this just a rule in object literal syntax that a dash is not allowed?

1.) In object literals, the - symbol is not allowed as an identifier because it is also the minus operator in javascript.
2.) no, you have to use quotes.
3.) yes.
4.) yes, see 1.

I agree with #Ferdi265.
However one additional point I would make is to use jQuery.data().
jQuery.data() doesn't actually update the DOM, it updates a javascript object referencing the element and stores the value there.
It's much better for performance as no DOM manipulation is required.
$("img").attr({
alt: "a picture of my cat"
}).data({
item: "pet",
color: "orange"
});
Obviously this doesn't update your element's attributes, and therefore any future reference to these values will have to be done with jQuery.data();
$("img").data("item");
If you're interested in understanding how this works under-the-hood I wrote an article on it a while back:
http://curtistimson.co.uk/jquery/understanding-jquery-data-storage/

this is how I worked around it:
.attr({ style: "font-size : 50px;background-color : powderblue;font-family:arial" })
as a specific example of how to specify multiple attributes in an element creation statement. This is after the above examples did not work.

Related

om/react: manipulate elements outside the render target element

I'm using om as a clojurescript react interface.
One question, which I guess relates to both om and react:
Inside my html body I have a div of the id "app", which is used for om/react as a render target.
What would be a prefered way to change attributes outside of this element. more concretely I need to set some stylesheets to the body.
Now, more clojure specific:
How do you set multiple key-value pairs to a javascript object. (e.g. document.body.style)
I'm using this:
(doseq [[k v] {"backgroundColor" "red" "overflow" "hidden" ...}]
(aset js/document.body.style k v))
There was a nice way to do so with underscore.js:
_.extend(document.body.style, {"backgroundColor": "red" "overflow": "hidden"})
Well, but this was the question here. Maybe it's not really needed because there is a special om/react way to go.
A nicer way to do this is simply set the body style with a javascript object containing all key-value pairs:
(set! (.. js/document -body -style) #js {:backgroundColor "red" :overflow "hidden"})
The solution provided by Naomi is great, but it uses the bad practice of inline css. Instead of setting the actual css styles in code, I would set a class to the desired html object, and in the styles sheets define the css properties of that class.
For example:
(set! (.. js/document -body -className) "my-class")

How to get value from a div with no ID using Selenium

I am using the Selenium WebDriver Java API on a Java/HTML5 web project. We do not use many IDs, so I am using xPath to isolate values. In the following HTML snippet, when I use my normal method to grab values, the label and the value text are returned.
<div class="gf-item col-sm-4"><label>First Name</label>Emma</div>
Is there an elegant way to grab just the value ("Emma") using Selenium?
Thanks!
I believe the XPath would be
//div[#class="gf-item col-sm-4"]/label/following-sibling::text()
There may be a prettier approach to this. I would create two selectors. One that returns only what you want to exclude and one that returns what you want and what you don't. Then use some Java to compare and remove what you don't want. I don't do xpath so this is all css selectors.
First, the 'big' selector - returns 'First NameEmma'
$$("div.gf-item")
Then the 'trim' selector to define what we don't want - returns 'First Name"
$$("div.gf-item>label")
Then some Java to compare and remove the 'extra' stuff. This removes 'First Name' and leaves only 'Emma'.
String big = getText(big);
String trim = getTextText(trim);
String desiredText = big.replaceAll(trim, "");

Loop though DOM with jQuery to get some data- attribute value

This seems like a simple thing, but I keep getting "undefined"
I am trying out the "data-" HTML5 attribute and I am looping through a bunch of div tags that look like this:
<div id="myEvent"
data-scheduledOn="1399985100000"
data-eventStatus="3">
And I am looping through a bunch of these like this:
$('[id="myEvent"]').each(function(index, divItem) {
alert($(divItem).data("scheduledOn"));
}
But I keep getting "undefined" If I do this (get the attribute) it works fine:
alert($(divItem).attr("data-scheduledOn"));
So What am I missing?
http://api.jquery.com/data/
"The .data() method allows us to attach data of any type to DOM elements in a way that is safe from circular references and therefore from memory leaks."
At least at this point in time, to use the .data function you have to attach the data using the function before you can read it back using the .data function.
If you need to read pre-existing data use the .attr or .prop functions.
It seems as though It is a naming problem as Hamza Kubba suggested, but just a bit different...
if I changed the name of the data attribute to "data-scheduled-on" I can retrieve it by .data("scheduledOn") OR using data-scheduledon and .data("scheduledon") also works.
So don't use CAPS for data- names is the moral of this story!
Please note that per HTML 5 specs, the attribute name should not contain any uppercase letters and some browsers such as FF & Chrome will change any uppercase letter to lowercase. That's why the following demo works if you access the data attributes with lowercase names:
http://jsfiddle.net/fiddleyetu/5LdQd/
$('div.myEvent').each(function(index, divItem) {
console.log($(divItem).data("scheduledon"));
console.log( $(divItem).data("eventstatus") );
});
Ans since you cannot have more than one element on a page with the same ID, I have used a class selector for the demo.
MORAL: Do not use UPPERcase; your browsers may not always be that 'understanding'.

getelementbyid innerHTML to bbcode?

Anyway to convert innerHTML to bbcode?
Something like that
document.getelementbyid.('div').bbcode
or a way to replace %0A to [br] in the current link of the page?
I've tried this with no luck
window.location.replace('%0A', '[br]');
.bbcode is not a valid function (or property how you've written it), unless of course you are including some kind of external library that you haven't told us about?
With regards to the window.location.replace you are not assigning it to anything so where would you expect to see the change? Though you should also use
window.location.href.replace(needle,haystack);
see http://jsfiddle.net/9LGRP/1/ for a quick example or replace working to replace the word "show" with "foo"
Please note the syntax is slightly different for global replacements e.g
window.location.href.replace(/foo/g, 'bar')
would replace all instances of foo. You can also add the modifier 'i' after the 'g' to ignore case https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
Perhaps you need to elaborate more on your question and show more context if this doesn't address your needs.

When I'm trying to append data-id; I got an error

Check this out:
here's a simple code that works fine
html
<select></select>
<button id="btn1">click me</button>
js
$('#btn1').on('click',function(){
var select = $('select');
select.append($('<option>').val('v2').text('text2'));
});
When I'm trying to append data-id I got an error. Any help?
select.append($('<option>').val('v2').text('text2').data-id('id1'));
http://jsfiddle.net/omarmakled/QQ44U/
You can do this 2 ways
select.append($('<option>').val('v2').text('text2').attr('data-id','id1'));
or
select.append($('<option>').val('v2').text('text2').data('id', 'id1'));
http://api.jquery.com/data/
http://api.jquery.com/attr/
First, data-id string is illegal identifier in JS (as it contains hyphen), therefore even if it were available as a jQuery object method, you should have called it like that...
someObj['data-id'](someId);
Apparently, that's too messy for such a simple operation. In fact, there's no such method defined in jQuery.prototype - which instead expects you to employ either attr() (to set any attribute explicitly), or data() (dataset API specific one).
As a sidenote, you don't have to make that many calls: this...
select.append($('<option>', {
value: 'v2',
text: 'text2',
'data-id': 'id1'
}));
... is both more readable AND efficient. Note the quotation marks around 'data-id': object properties can be non-quoted only if they are proper JS identifiers.
JSFiddle.
The correct method to use is data():
select.append($('<option>').val('v2').text('text2').data('id','id1'));
Or if you want an actual attribute you can use attr():
select.append($('<option>').val('v2').text('text2').attr('data-id','id1'));

Categories

Resources