jQuery .attr() and value - javascript

I want to make the following use .attr();
selectbox.options[selectbox.selectedIndex].value
sadly,
selectbox.options[selectbox.selectedIndex].attr("value")
is not the same, and seems to defeat the purpose of the .attr altogether. My main question is: How should one use nested .attr()s?

To get the value of any type of input element (including <textarea> and <select>) use .val():
var value = $(selectbox).val();
The .attr() translation would roughly be:
$(selectBox).find(":selected").attr("value");
....but just use .val() :)
The basic problem is that .attr() is a jQuery method. It's on jQuery objects, not on DOM elements directly, the same goes for almost all jQuery methods and plugins.

When using attr(), you have to be working with a jQuery object. So first select the relevant select box, then call attr() (or val() in this case, when you need the value of an input element).
var value = $(selectbox).val();

If you would like to retrieve the selected box's value using your current code simply pass it into the jquery object like so.
$(selectbox.options[selectbox.selectedIndex]).attr('value');

The reason they are not the same is because attr('value') gets the value of the value attribute directly from the original HTML code, it is not updated with the DOM, meaning if the value of value is changed after the page has loaded, either by user input (typing into an <input> element, or via manipulation with JavaScript, these changes will not be reflected in the returned value of .attr().
A better way is to use the .val() method of the jQuery object.
Edit
To get the attribute of the value from a DOM Element (i.e. not returned by the $() or jQuery() function) use the element.getAttribute() method, which is native, you would use it like this:
selectbox.options[selectbox.selectedIndex].getAttribute("value");

Related

applying html method of jquery on jquery object

I am trying to change inner html of an element. If we use this:
$('.best-photos-button')[0].innerHTML="Add More Photos";
it works fine. But if instead of ".innerHTML" i.e. JavaScript if we use .html() like this :
$('.best-photos-button').html("Add More Photos");
then it's not working. Why so?
When I am running $('.best-photos-button').innerHTML on console it's giving undefined.
$('.best-photos-button') is a jQuery object. When you use $('.best-photos-button')[0] it will return the raw DOM element, which does not have a .html() method, only .innerHtml.
So you either need to use
$('.best-photos-button').html("Add More Photos");
or use .innerHtml
Edit:
Note that if you use .html() it will affect all the elements with best-photos-button class. So depending on your use case you might need to use a different selector or filter the selection to get the specific object you need.

jQuery .find() not working correctly

I'm trying to allow some text of <p> (the comment) to be editable when the user clicks on 'Edit'.
function editComment(commentid,replyid){
$('#comment'+commentid).find('.comment-text').attr("contenteditable='true'");
}
However this is giving me an error (undefined) and I'm not sure why, as .comment-text is a child of #comment88? I'm probably missing something really simple
Your HTML DOM and jQuery looks fine and legit, however the attr function would cause a trouble. I would suggest that you apply the style using this,
$('#comment'+commentid).find('.comment-text').attr("contenteditable", true);
This will apply the attribute to your element.
Description: When you use attr() function to add or update the attribute value, you pass two parameters. One as a key and second as the value for that attribute (key). If you pass only one, it will return that attribute's value. This is the problem that gets raised in your case, the find function is working, but in the final function, instead of applying that attribute it returns the value (false IMO).

jQuery .val change doesn't change input value

I have an HTML input with a link in the value.
<input type = 'text' value = 'http://www.link.com' id = 'link' />
I am using jQuery to change the value on a certain event.
$('#link').val('new value');
The above code changes the value of the text box but doesn't change the value in the code (value = 'http://www.link.com' stays unchanged). I need the value = '' to change as well.
Use attr instead.
$('#link').attr('value', 'new value');
demo
Changing the value property does not change the defaultValue. In the code (retrieved with .html() or innerHTML) the value attribute will contain the defaultValue, not the value property.
to expand a bit on Ricardo's answer: https://stackoverflow.com/a/11873775/7672426
http://api.jquery.com/val/#val2
about val()
Setting values using this method (or using the native value property) does not cause the dispatch of the change event. For this reason, the relevant event handlers will not be executed. If you want to execute them, you should call .trigger( "change" ) after setting the value.
$('#link').prop('value', 'new value');
Explanation:
Attr will work on jQuery 1.6 but as of jQuery 1.6.1 things have changed. In the majority of cases, prop() does what attr() used to do. Replacing calls to attr() with prop() in your code will generally work. Attr will give you the value of element as it was defined in the html on page load and prop gives the updated values of elements which are modified via jQuery.
This is just a possible scenario which happened to me. Well if it helps someone then great: I wrote a complicated app which somewhere along the code I used a function to clear all textboxes values before showing them. Sometime later I tried to set a textbox value using jquery val('value') but I did'nt notice that right after that I invoked the ClearAllInputs method.. so, this could also happen.
For me the problem was that changing the value for this field didn`t work:
$('#cardNumber').val(maskNumber);
None of the solutions above worked for me so I investigated further and found:
According to DOM Level 2 Event Specification:
The change event occurs when a control loses the input focus and its value has been modified since gaining focus.
That means that change event is designed to fire on change by user interaction. Programmatic changes do not cause this event to be fired.
The solution was to add the trigger function and cause it to trigger change event like this:
$('#cardNumber').val(maskNumber).trigger('change');
My similar issue was caused by having special characters (e.g. periods) in the selector.
The fix was to escape the special characters:
$("#dots\\.er\\.bad").val("mmmk");
Note that the browser parses the HTML tag element and creates a corresponding DOM node object.
"Initial/starting/default value" of input:
Equals:
ONLY the initial value of value attribute of input's HTML tag element.
defaultValue property of input's DOM node object.
Is set in jQuery via:
$(input).attr("value", "42")
"Current value" of input:
Equals:
value attribute of input's HTML tag element
value property of input's DOM node object.
Is set in jQuery via:
$(input).val("42")
$(input).prop("value", "42")
See also: What is the difference between properties and attributes in HTML?
<script src="//code.jquery.com/jquery.min.js"></script>
<script>
function changes() {
$('#link').val('new value');
}
</script>
<button onclick="changes()">a</button>
<input type='text' value='http://www.link.com' id='link'>

What is the difference between removeProp and removeAttr in JQuery 1.6?

If you removeProp on something you should have used removeAttr() on will it silently fail? Will it work? Will it actually remove the entire attribute or just the value inside it?
If checked is added using removeProp(), can it be removed with removeAttr()?
Many questions!
The official jQuery blog provides a very clear explanation:
In the 1.6 release we’ve split apart
the handling of DOM attributes and DOM
properties into separate methods. The
new .prop() method sets or gets
properties on DOM elements, and
.removeProp() removes properties. In
the past, jQuery has not drawn a clear
line between properties and
attributes. Generally, DOM attributes
represent the state of DOM information
as retrieved from the document, such
as the value attribute in the markup
. DOM
properties represent the dynamic state
of the document; for example if the
user clicks in the input element above
and types def the .prop("value") is
abcdef but the .attr("value") remains
abc.
In most cases, the browser treats the
attribute value as the starting value
for the property, but Boolean
attributes such as checked or disabled
have unusual semantics.
For example, consider the markup
<input type="checkbox" checked>. The
presence of the checked attribute
means that the DOM .checked property
is true, even though the attribute
does not have a value. In the code
above, the checked attribute value is
an empty string (or undefined if no
attribute was specified) but the
checked property value is true.
Before jQuery 1.6, .attr("checked")
returned the Boolean property value
(true) but as of jQuery 1.6 it returns
the actual value of the attribute (an
empty string), which doesn’t change
when the user clicks the checkbox to
change its state.
There are several alternatives for
checking the currently-checked state
of a checkbox. The best and most
performant is to use the DOM property
directly, as in this.checked inside an
event handler when this references the
element that was clicked. In code that
uses jQuery 1.6 or newer, the new
method $(this).prop("checked")
retrieves the same value as
this.checked and is relatively fast.
Finally, the expression
$(this).is(":checked") works for all
versions of jQuery.
An attribute of an element is something like 'class'. Whereas its property would be 'className'.
This is the reason for adding jQuery.prop and jQuery.propHooks into version 1.6, to make it easier working with both.
So if the the property had the same name as the attribute you could use both removeProp or removeAttr.
I asked a similar question on jQuery forum, got this answer:
Yes, attr is meant for html attributes
as they are strictly defined. prop is
for properties. So for instance, say
you have a node elem with class
"something" (raw element not jQuery
object). elem.className is the
property, but is where the
attribute resides. Changing the class
attribute also changes the property
automatically and vise versa.
Currently, attr is jumbled and
confusing because it has tried to the
job of both functions and there are
many bugs because of that. The
introduction of jQuery.fn.prop will
solve several blockers, separate code
as it should have been separated from
the beginning, and give developers
faster functions to do what they
expect them to do. Let me make up a
percentage for a sec and say that from
my experience in the support IRC and
reading other's code, 95% of the use
cases for attr will not have to switch
to prop.
EDIT
It may be best to stick to using either jQuery.attr or jQuery.prop. Theres seems to be some strange behaviour when setting and removing the checked attribute using both.
See here for an example: http://jsfiddle.net/tomgrohl/uTCJF/
There is a bug in 1.6 to do with selected: http://bugs.jquery.com/ticket/9079
Using jQuery 1.6, I was was trying to clone a menu item which had several id attributes, and so I did this:
$('ul.menu').clone().filter('*').removeProp('id').appendTo('.sidebar');
When I inspected the elements in Firebug I had a lot of id="undefined" - not what I wanted. So now I am using removeAttr and it seems to work much better.
$('ul.menu').clone().filter('*').removeAttr('id').appendTo('.sidebar');

jquery changing innerhtml of a P isn't working

I have what I thought was a simple select with jQuery to change some text on a paragraph. It works perfect the traditional way i.e.
document.getElementById('message_text').innerHTML = "hello";
But with jQuery it doesn't. I have checked the values of $('#message_text') and sure enough I see the items.
$('#message_text').innerHTML = "hello";
Am I doing something wrong?
Anyone have any ideas?
When you do something like $('#message_text') what you have there is not a regular DOM object, but a jQuery wrapped set (even though in this case it'd only be one element.) If you wanted to access a particular DOM property, you could do this:
$('#message_text')[0].innerHTML = 'whatever';
$('#message_text').get(0).innerHTML = 'whatever';
However, this isn't necessary in this case as jQuery has two functions to do what you want:
html():
$('#message_text').html('whatever');
text():
$('#message_text').text('whatever');
The difference between the two is that html() will allow HTML while text() will escape any HTML tags you pass to it. Use the one you need over manually manipulating the HTML with innerHTML.
The jQuery function $() is not returning a HTMLElement object like getElementById() does but a jQuery object. And there you just have the html() method as equivalent to innerHTML. So:
$('#message_text').html('hello');
$('#message_text').html('hello')
jQuery selector returns an array, not a DOM Element node.

Categories

Resources