Why are jQuery set attributes not reflected in .html()? - javascript

I am trying to set some attributes on HTML snippets. The purpose is to repopulate a form with previous inputed values. I set attributes with .attr() but after I do a .html(), I do not see my changed attributes.
I have done a basic example here http://jsfiddle.net/ejanderson4/CSYnU/
My function looks like this:
function setValue(html,value,name){
var element=$(html);
$(element).find("[name='"+name+"']").attr('value',value)
return element.html();
}

It is setting it, but for reasons unknown to me, you can't directly query the value attribute of an input element. You need to call .val() on that element to get it.
Updated your example here

parse the html string using $.parseXML and then set the attr value
var html="<div><label id='el_c5c0f78656138c39c5eb91a9bf1d3bf6'> table input 1 </label><input type='text' value='' name='table_input_1' class='select-mini' id='table_input_1' /></div>";
var value= 'xxxxxxxxxxxxx';
var name='table_input_1';
function setValue(html,value,name){
var xml = html,
xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc ),
$title = $xml.find( "[name='"+name+"']" );
$title.attr("value",value);
//var element=$(html);
//element.find("[name='"+name+"']").attr('value',value)
return $title.attr("value");
}
alert(setValue(html,value,name));
here is the working fiddle http://jsfiddle.net/CSYnU/4/
also this solution requires you to use jquery version 1.5.2 and higher
update
sry for overdoing it in your scenario you have to do
function setValue(html,value,name){
var element=$(html);
$(element).find("[name='"+name+"']").attr('value',value);
return $(element).find("[name='"+name+"']").attr('value');
}
here is the fiddle http://jsfiddle.net/CSYnU/5/
you are wrapping the html in $(html) then there is no need to again wrap the cached html in $
var element = $(html);
element.find ...
see here http://jsfiddle.net/CSYnU/6/

I think the short answer here is that setting an attribute on a DOM object does not necessarily change what the browser returns for innerHTML. If you want to retrieve a particular attribute, then you should just retrieve that attribute directly.
You also have an error in your code (which jQuery might be tolerating). You've already turned element into a jQuery object so you don't need to do that again with $(element).find, you can just use element.find.
function setValue(html,value,name){
var element=$(html);
element.find("[name='"+name+"']").attr('value',value)
return element.html();
}

Depend on your code, the first problem is about element variable. It doesn't denote "table_input_1" element. To get this element, you should replace by :
var element=$(html).find("[name='"+name+"']");
The second problem is in the your return statement. Since you changed the value of input element, you have to get this value by method val() or attr('value') rather than html(). The html() method is used to get the content inside tags of a element, but in this case value is a attribute, not content.
return element.attr('value'); // element.val();
Here is the complete code:
function setValue(html,value,name){
var element=$(html).find("[name='"+name+"']");
element.attr('value',value); // element.val(value);
return element.attr('value'); // element.val();
}

One reason is that the jQuery attr method gets confused between HTML attributes and DOM properties. The imlpementation of setAttribute and getAttribute was (probably still is) buggy in IE, so in general forget about HTML attributes and use DOM properties.
In most browsers, modifying the HTML attribute (say using setAttribute) will modify the related DOM property. But in many browsers, changing the DOM property will not modify the HTML attribute.
Further, some browsers will modify an element's innerHTML based on the current DOM property, others will use the HTML attribute (which might have a different value in most browsers). HTML 5 is the first attempt to standardise the behaviour of innerHTML, note that it is not a W3C standard yet and is not consistently implemented.
The best approach is to be consistent and always set DOM properties to the values you want. Expect that an element's innerHTML may be inconsistent across browsers.

Setting the current value of an input element doesn't change the initial value, which is what the value attribute is.
There is no property to change the initial value, so you can't alter the HTML code that way.
Edit:
If you want to use the elements in the page, then just make the function return a jQuery object containing the elements instead of returning HTML code:
function setValue(html, value, name){
var elements = $(html);
elements.find("[name='"+name+"']").val(value)
return elements;
}
Adding the elements to the page works the same as using a string. Example:
var html = '<div><input type="text" name="city" /></div>';
$('#SomeForm').append(setValue(html, 'York', 'city'));

Related

Select all the elements within an element having an attribute set to a specific value

I have the followings defined :
var excludedFiltersPanel = $("#excludedFiltersPanel");
var includedfiltersPanel = $("#includedfiltersPanel");
where *Panel is just a div.
in excludedFiltersPanel there are some div's with attribute data-iscorefilter="true" e.g. :
<div id="filterPanel-LastName" class="filterPanel" data-iscorefilter="true">
<Some Stuff here!>
</div>
I am trying to get them and move them to includedfiltersPanel:
It seems neither of these is a correct syntax:
excludedFiltersPanel.('[data-iscorefilter="true"]')
excludedFiltersPanel.$('[data-iscorefilter="true"]')
1.What is the correct syntax?
2.How do I append them to includedfiltersPanel? (I know how to append a single item, but not sure what is the common good practice here, e.g. using for loop or some JQuery magic)
Since excludedFiltersPanel there are some div's with attribute data-iscorefilter="true"
Use .find()
Description: Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
It would look like :
excludedFiltersPanel.find('[data-iscorefilter="true"]')

How to get the value of inner attribute of an li using jquery?

I have following code in Java script from which i have to need get the value on an inner attribute of <li>.
<li class="selected" data-val="1">
I have get the tag using
var a = document.getElementsByClassName('selected');
it is providing me <li> whole tag that is fine. But i have to need get the value of data-val attribute (which is within the <li>) that is 1.
How can i get the value of data-val using variable a that is defined.
Please explain..
Here a is a collection object so you need to get the element reference using index then use .getAttribute() to get the attribute value()
var a = document.getElementsByClassName('selected');
var val = a? a[0].getAttribute('data-val') : '';
//another option for modern browsers
// val = a[0].dataset.val
Since you have jQuery, you can use jQuery to select the element and then use data api like
var val = $('.selected').data('val')
With jQuery you can use $(a).attr("data-val").
Without jQuery you can use a.getAttribute("data-val")
Try this approach
var dataValValue = $(".selected").attr("data-val");
It will get data-val attribute from first li from all li with class .selected
There are two ways, using jQuery and the first returned element in a:
$.data(a[0],"val");
$(a[0]).data("val");
Both are equivalent. Sorry, they're not equivalent, since the first one is lower level, and does not process data-* attributes by itself.
There's no need to use .attr() since data-* attributes are processed automatically in the case of the second one.

Insert javascript (jquery) variable in html input field (textbox)

With span and div this works
jQuery
$('#exchange_rate1').html(data[0].FinalCurrencyRate);
HTML
<span id="exchange_rate1"></span>
But if the HTML is an input element such as <input type='text' name='exchange_rate1' id='exchange_rate1' value='<?php echo $post_exchange_rate; ?>> then nothing happens.
Removed php code from value the same nothing.
I also tried document.getElementById("exchange_rate1").html(data[0].FinalCurrencyRate); but I also see nothing.
Now clear, that need to use val. I just searched google for how to insert jquery variable in input field. Could not find.
Use jQueryObject.val(some_value) to set the value of an input, not html().
To be more specific:
// store the value you're looking to assign
var data = [
{ FinalCurrencyRate: <?= $post_echange_rate; ?> }
];
the jQuery way:
$('#exchange_rate1') // grab the <input>
.val(data[0].FinalCurrencyRate); // and assign it from the variable
the straight js way:
// normal JS version:
document.getElementById('exchange_rate1') // grab the <input>
.value = data[0].FinalCurrencyRate; // assign it
Any kind of form fields (<input>,<select>,<textarea>) use .val() to get/set since they don't contain child elements. .html() should be used for structural elements.
In case of text use as
$("#exchange_rate1").val('Hello');
This is because you aren't supposed to be setting the innerHTML of the input element, but the value.
In jQuery you use the .val() method:
$('#exchange_rate1').val(data[0].FinalCurrencyRate);
Or with plain JavaScript, you're changing the value property of the HTMLInputElement object:
document.getElementById('exchange_rate1').value = data[0].FinalCurrencyRate;
For textual input boxes, use .val(), for textareas, use .text(), and for non-input type elements, use .html().
All you need is
$("#exchange_rate1").val('Hello');

Disable a text area by it's class (not id)

I have 2 text area's that are generated automatically, and I need to use JavaScript to disable both when the page has loaded. The catch is because they are generated automatically I can't give them an ID because they would both have the ID - a big no.
Attempted Javascript:
document.getElementByClassName('option_window-size').disabled=true;
I know this works because if I change getElementbyClassName to ID then it will work if I give the text areas the ID as well. But as I say it needs to work off class. Also it can't work of the Name attribute because that is automatically generated per product and per page...
I have tried this but it just doesn't work and I can't figure out why not because it should as the only thing I have changed is from ID to CLASS
Text Areas
<textarea name="willbeautogenerated" class="option_window-size" cols="40" rows="5">willbeautogenerated</textarea>
Additional note: I have tried to count and assign them different IDs using PHP but it gets far to complex. Also it is only these two that need disabling, thus I can't just disable all text area's on the page.
I know this works because if I change getElementByClassName to ID then it will work if I give the text areas the ID as well. But as I say it needs to work off class.
getElementsByClassName returns a NodeList rather than a Node itself. You'll have to loop over the list, or if you expect just 1 item, choose index 0.
var nodes = document.getElementsByClassName("option_window-size"),
i = 0, e;
while (e = nodes[i++]) e.disabled = true;
jQuery makes this pretty simple:
$(".selector").prop("disabled", true);
ALTHOUGH! It should be noted that this note appears on the man pages for $.prop() and $.attr():
Note: Attempting to change the type property (or attribute) of an input element created via HTML or already in an HTML document will result in an error being thrown by Internet Explorer 6, 7, or 8.
This doesn't apply directly to your question, but you are changing prop/attrs on an input element, so be aware.
But it's still possible with plain old JS:
var els = document.getElementsByClassName("selector"); // note: Elements, not Element
for(var e = 0; e < els.length; e++)
{
els[e].disabled = true;
}
getElementsByClassName returns an NodeList, you just have to iterate over each element within.
You can use class selector,
$('.option_window').attr('disabled', true);
OR
$('.option_window')[0].disabled = true;
With Jquery you can do:
//make sure to use .prop() and not .attr() when setting properties of an element
$('.option_window').prop('disabled', true);
Disable textarea using jQuery:
$('.option_window-size').attr('disabled', true);
your missing a s in elements and the index where the element is like [0], for the first element.
document.getElementsByClassName('option_window-size')[0].disabled=true;
or
document.getElementsByName('willbeautogenerated')[0].disabled=true;
Disabel texarea using .prop() methode in jquery...
$('.option_window-size').prop('disabled', true);
You can use CSS:
.option_window-size{display:none;}

jQuery $.data(): Possible misuse?

Perhaps I'm using $.data incorrectly.
Assigning the data:
var course_li = sprintf('<li class="draggable course">%s</li>', course["fields"]["name"]);
$(course_li).data('pk', course['pk']);
alert(course['pk']); // shows a correct value
alert($(course_li).data('pk')); // shows null. curious...
course_li is later appended to the DOM.
Moving the li to a different ul:
function moveToTerm(item, term) {
item.fadeOut(function() {
item.appendTo(term).fadeIn();
});
}
Trying to access the data later:
$.each($(term).children(".course"), function(index, course) {
var pk = $(course).data('pk');
// pk is undefined
courses.push(pk);
});
What am I doing wrong? I have confirmed that the course li on which I am setting the data is the same as the one on which I am looking for it. (Unless I'm messing that up by calling appendTo() on it?)
When you store the data:
$(course_li).data('pk', course['pk']);
you're creating an element but not saving it, so it's lost. Your alert test test the wrong value; it should be:
$(course_li).data('pk', course['pk']);
alert($(course_li).data('pk'));
which is null. Consider:
$(course_li);
$(course_li);
This creates two different elements with source equal to course_li, which are then promptly lost. What you need to do is create the element first, then work with that single element (i.e. don't call $(course_li) more than once). For example,
var course_li = $(sprintf('<li class="draggable course">%s</li>',
course["fields"]["name"]));
course_li.data('pk', course['pk']);
parent.append(course_li);
Note that course_li now holds an element, rather than a string.
try checking to see if the element being created by this call:
$(course_li)
is a single 'li' element, or a div. From the doco:
When the HTML is more complex than a single tag without attributes, as it is in the above example... snip ...Specifically, jQuery creates a new <div> element and sets the innerHTML property of the element to the HTML snippet that was passed in
So it's probably creating a div that you are assigning the data to, so when you select the 'li' itself, you are getting a child of the actual element that you set the data on.

Categories