Those snippes of code that you will check works fine for FF, Chrome, Safari, but seems to be a problem with IE when running jQuery clone function:
My template:
<form method="post" action="/post/add/">
{{ form.management_form }}
<div class='table'>
<table class='no_error'>
<input id="id_mypost_set-0-title" type="text" name="mypost_set-0-title" />
<input id="id_mypost_set-0-content" type="text" name="mypost_set-0-content" />
</table>
</div>
<input type="button" value="Add Other" id="add_more">
<script>
$('#add_more').click(function() {
cloneMore('div.table:last', 'mypost_set');
});
</script>
</form>
In a javascript file:
function cloneMore(selector, type) {
var newElement = $(selector).clone(true);
var total = $('#id_' + type + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function() {
var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
$(this).attr('for', newFor);
});
total++;
$('#id_' + type + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
}
The problem is with the selector: "A clone of the original html piece of code works OK", but, A clone from cloned piece of code marks the selector as "undefined", in other words, the second time that I clone the table the selector doesnt work anymore for those cloned items.
Problem only for IE.
What im missing? Any hint is apreciated :)
This is a known jQuery bug, though they claim it is fixed.
One option here is to use .html(), and clone them manually. This will not clone events and saved .data, which may be an issue for you. .live can help if you have events here.
If the only thing you need is to change the names and id, a better option is to use a regular expression (this clones the events from the first element, mind you):
var name = $(this).attr('name').replace(/-\d+-/,'-' + total + '-');
this will search for -number-, and replace it, so it finds the last number on all browsers, or -0- on IE.
Here's a working demo with alerts: http://jsbin.com/evapu
As a side note - your code is a little messy. jQuery code should be inside $(document).ready (the click), you have a table with no body (no <tr>,<td> - the inputs are thrown out), and the code has some duplications.
Although it didn't help in this case, invalid DOM and not using the ready event can cause problems.
you're missing a hidden input with id 'id_' + type + '-TOTAL_FORMS'
- you're getting your total from this object and using it to modify the name and id of cloned objects.
I tried your code with this:
<input type="hidden" id="id_mypost_set-TOTAL_FORMS" value="1"/>
added right after
<form method="post" action="/post/add/">
and it works correctly, all new inputs have correct ids.
does this really work in FF ??
You code works perfectly on all browsers as stated before
Still if you could replace:
var newElement = $(selector).clone(true);
with:
var newElement = $($(selector).html());
and see if it helps.
Also, re-attach the event handler, like so.
newElement.bind(EVENT, function() {});
Or use the appropriate helper.
perhaps you can use this clone function :
/*
* Clone method
* Prevents reference problem
*/
clone: function( obj ){
if(obj == null || typeof(obj) != 'object')
return obj;
var temp = new obj.constructor();
for(var key in obj)
temp[key] = clone(obj[key]);
return temp;
}
Related
I am trying to get prices from between span tags. I would like to have all prices in an array. I cant seem to get it to work, I am guessing my regex is incorrect.
I am looking for any span tags with the class 'amount', the tag has no other attributes set and only has one class. E.g. <span class="amount">£9.99</span>
var prices = resp.fragments['data'].match(/<span class=\"amount\">(.*?)<\/span>/g)
.map(function(val){
return val;
});
Output
[ '£9.99', '£100.00' ]
I am trying to get prices from between span tags. I would like to have all prices in an array. I cant seem to get it to work, I am guessing my regex is incorrect.
I am looking for any span tags with the class 'amount', the tag has no other attributes set and only has one class. E.g. <span class="amount">£9.99</span>
var prices = resp.fragments['data'].match(/<span class=\"amount\">(.*?)<\/span>/g)
.map(function(val){
return val;
});
Output
[ '£9.99', '£100.00' ]
* UPDATE *
Turns out it was an encoding with the ajax response resp.fragments['data'].
I was using regex as it is something I have not really used before in JS and thought I would have a play. I did look at many examples and after about 45 mins with no success I thought a fresh set of eyes would fix it.
#spaceman
Thanks for the helpful comment. Your one of those people if someone asked "Is there is a doctor in the house?", you would stand up and say "Sweet load there are loads of doctors out there".
While a regular expression could work for this, it might be easier to simply select the <span class='amount'> elements and map their innerHTML content to an array via the map() function:
// This would yield an array containing your values
var amounts = Array.prototype.slice
.call(document.querySelectorAll('span.amount'))
.map(function(a){ return a.innerHTML; });
You can see a working example of this demonstrated here.
Simplest method will be to add this to an invisible DOM object and then traverse it via DOM API
var text = '<span class="amount">£9.99</span><span class="amount">£9.99</span>'
//now append it to an DOM object
var wrapperDiv = "<div style='display:none' id='tmpDiv'>" + text + "</div>";
document.body.innerHTML += wrapperDiv;
var elements = document.querySelectorAll( "#tmpDiv amount" );
var output = Array.prototype.slice.call( elements ).map( function(val){
return val.innerText;
})
Another approach could be split the text by <span class="amount"> and get the value after first index
DEMO
var text = '<span class="amount">£9.99</span><span class="amount">£9.99</span>'
var output = [];
text.split('<span class="amount">').forEach( function(val, index) {
if (index > 0 )
{
output.push( val.replace( "</span>", "" ) );
}
});
document.body.innerHTML += JSON.stringify( output, 0, 4 );
You can use this instead.
var prices = document.getElementsByClassName('amount');
var price_array = [];
for (i= 0; i < prices.length; ++i) {
price_array.push(prices[i].innerHTML);
}
document.write(" | " + price_array);
<span class='amount'>£123</span>
<span class='amount'>£3</span>
<span class='amount'>£5</span>
<span class='amount'>£64</span>
You don't need to use regex or jQuery for this.
I need to write some html with placeholder used for javascript.
ex:
<span><placeholder data-id="42" data-value="abc"/><span>
Later on, a script will access those placeholders and put content in (next to?) them.
<span><placeholder data-id="42" data-value="abc"><div class="Google"><input type="text" value="abc"/></div><span>
But the placeholder tag doesn't exist. What tag can be used? Using < input type="hidden" .../> all over feels wrong.
Creating Custom tag
var xFoo = document.createElement('placeholder');
xFoo.innerHTML = "TEST";
document.body.appendChild(xFoo);
Output:
<placeholder>TEST</placeholder>
DEMO
Note: However creating hidden input fields with unique ID is good practice.
give your span element an id like,
<span id="placeToAddItem"><span>
and then in jQuery,
$('#placeToAddItem').html('<div class="Google"><input type="text" value="abc"/></div>');
or else
var cloneDiv = $('.Google');
$('#placeToAddItem').html(cloneDiv);
Example
The best way to do this, is using <input type='hidden' id="someId" value=""> tags.
Then you can easily access them by using jQuery, and recall the variable or change it.
var value = $("#someId").val(); to get variable or $("#someId").val(value) to change it.
This complete, no jQuery solution allows you to specify the placeholder/replacement html as a string within the element that will be replaced.
EG HTML:
<div data-placeholder="<div class='Google'><input type='text' value='abc'/></div>"></div>
<div data-placeholder="<div class='Boogle'><input type='text' value='def'/></div>"></div>
<div data-placeholder="<div class='Ooogle'><label>with label <input type='text' value='ghi'/></label></div>"></div>
<span data-placeholder="<em>Post JS</em>">Pre JS</span>
<br />
<button id="test">click me</button>
JS:
Use querySelectorAll to select all elements with the attribute 'data-placeholder' (returns a NodeList)
var placeholders = document.querySelectorAll('[data-placeholder]'); //or by ids, classnames, element type etc
Extend the NodeList prototype with a simple 'each' method that allows us to iterate over the list.
NodeList.prototype.each = function(func) {
for (var i = 0; i < this.length; i++) {
func(this[i]);
}
return this;//return self to maintain chainability
};
Extend the Object prototype with a 'replaceWith' method that replaces the element with a new one created from a html string:
Object.prototype.replaceWith = function(htmlString) {
var temp = document.createElement('div');//create a temporary element
temp.innerHTML = htmlString;//set its innerHTML to htmlString
var newChild = temp.childNodes[0];//(or temp.firstChild) get the inner nodes
this.parentNode.replaceChild(newChild, this);//replace old node with new
return this;//return self to maintain chainability
};
Put it all together:
placeholders.each(function(self){
self.replaceWith(self.dataset.placeholder);//the 'data-placeholder' string
});
Another example but here we only replace one specific element with some hard-coded html on click:
document.getElementById("test").addEventListener('click', function() {
this.replaceWith("<strong>i was a button before</strong>");
}, false);
DEMO: http://jsfiddle.net/sjbnn68e/
use the code below :
var x = document.createElement('placeholder');
x.innerHTML = "example";
document.body.appendChild(x);
i am trying to alert id of a button (which is generated using jquery ) but when i alert its value it not coming right. heres the code
function removeimg(name,btn12){
//make request to remove the name
// $("#" + name).closest('li').remove();
// $("#" + btn12).remove();
// document.getElementById(name).style.display = 'none';
// document.getElementById(btn12).style.display = 'none';
var str = "#" + btn12;
alert(str);
alert($(str).val());
}
here is the link
http://shri-ram.lifekloud.com/pilot/step4.php
when you uplaod a image under the tab "add delete photo" the button is generated
i am trying to alert id of a button
val() does not get the id of an element; val returns the value element.
To get the id of an element, use attr
alert($(str).attr('id'));
Just a stab in the dark from your comment well its not even returning value thts the issue. but the id name is getting displayed correctly
If you have
<input type='button' id='b' value='btn' />
then
alert($('#b').val());
will in fact display btn. That said, if you have
<button id='b'>btn</button>
then nothing will be displayed. But like I said that's just a stab in the dark. It's impossible to know better without the html available (and I'm afraid I don't have time to parse through your site)
You have one meta-character . in your id #btnheader-8878374.png, That is the problem.
Just escape like this
$('.#btnheader-8878374\\.png')
and try you will get your concept working.
Full code,
var str = "#" + btn12;
str = str.replace('.','\\\\');
alert($(str).val());
Your problem is most likely that you do not have the value attribute set on your buttons, thus calling val() returns nothing.
If you want the text of the button just call text().
See jsFiddle
HTML
<button id="btn12">Button 12</button>
JQUERY
var str = "#" + "btn12";
alert( str ); // yields #btn12
alert( $(str).val() ); // yields nothing
alert( $(str).text() ); // yields Button 12
html file:
<div id ="main">
</div>
Javascript:
//create a div
var divElem = $('<div class="divText"></div>');
//create input element inside it
var inhtml = "<input type='text' id='12345' />";
//add to page
$(divElem).html(inhtml).appendTo('#main')
Following does not work as it is unable to find input element:
//retrieve input element
$('#12345').val('hello')
Following works:
document.getElementById('12345').value = 'hello'
Following works:
var ipElem = $(inhtml);
$(divElem).append(ipElem).appendTo('#main')
$(ipElem).val('hello')
Can anyone tell why first version of retrieving element does not work in jquery? (just starting with jquery... :) )
Edit:
I think '12345' works but not some weird id like: mytext0.15942923246580176
See here:
http://jsfiddle.net/9PVNb/4/
You're wrapping divElem in jQuery object twice:
var divElem = $('<div class="divText"></div>');
var inhtml = "<input type='text' id='12345' />";
$(divElem).html(inhtml).appendTo('#main') // Nop '$(divElem)' plus missing `;`
divElem.append(inhtml).appendTo('#main'); // Yup
EDIT:
Edit: I think '12345' works but not some weird id like: mytext0.15942923246580176
Your code at http://jsfiddle.net/9PVNb/4/ isn't working because:
// Your `id` has a `.` which you didn't escape
var elemid = 'mytext0.15942923246580176';
You can make it work by doing this:
alert($('#' + elemid).val()); //undefined. DOES NOT WORK
alert($('#' + elemid.replace('.', '\\.')).val()); // hello world IT WORKS!
works here: http://jsfiddle.net/xvKcd/
basic check:
are you using $(document).ready()? your code may be firing up before the element you needed was loaded.
did you load jQuery before anything else?
typos?
I have a variable account_number in which account number is stored. now i want to get the value of the element having id as account_number. How to do it in javascript ?
I tried doing document.getElementById(account_number).value, but it is null.
html looks like this :
<input class='transparent' disabled type='text' name='113114234567_name' id='113114234567_name' value = 'Neeloy' style='border:0px;height:25px;font-size:16px;line-height:25px;' />
and the js is :
function getElement()
{
var acc_list = document.forms.editBeneficiary.elements.bene_account_number_edit;
for(var i=0;i<acc_list.length;i++)
{
if(acc_list[i].checked == true)
{
var account_number = acc_list[i].value.toString();
var ben_name = account_number + "_name";
alert(document.getElementById("'" + ben_name.toString() + "'").value);
}
}
}
here bene_account_number_edit are the radio buttons.
Thanks
Are you storing just an integer as the element's id attribute? If so, browsers tend to behave in strange ways when looking for an element by an integer id. Try passing account_number.toString(), instead.
If that doesn't work, prepend something like "account_" to the beginning of your elements' id attributes and then call document.getElementById('account_' + account_number).value.
Why are you prefixing and post-fixing ' characters to the name string? ben_name is already a string because you've appended '_name' to the value.
I'd recommend doing a console.log of ben_name just to be sure you're getting the value you expect.
the way to use a variable for document.getElementById is the same as for any other function:
document.getElementById(ben_name);
I don't know why you think it would act any differently.
There is no use of converting ben_name to string because it is already the string.
Concatenation of two string will always give you string.
var account_number = acc_list[i].value.toString();
var ben_name = account_number + "_name";
try following code it will work fine
var ben_name=acc_list[i]+ "_name";
here also
alert(document.getElementById("'" + ben_name.toString() + "'").value);
try
alert(document.getElementById(ben_name).value);
I have tested similar type of code which worked correctly. If you are passing variable don't use quotes. What you are doing is passing ben_name.toString() as the value, it will definitely cause an error because it can not find any element with that id viz.(ben_name.toString()). In each function call, you are passing same value i.e. ben_name.toString() which is of course wrong.
I found this page in search for a fix for my issue...
Let's say you have a list of products:
<div class="rel-prod-item">
<img src="assets/product-photos/title-of-the-related-product_thumbnail.jpg" alt="Western Digital 1TB" />
<p class="rel-prod-title">Western Digital 1TB</p>
<p class="rel-prod-price" id="price_format_1">149.95</p>
add to cart
</div>
<div class="rel-prod-item">
<img src="assets/product-photos/title-of-the-related-product_thumbnail.jpg" alt="Western Digital 1TB" />
<p class="rel-prod-title">Western Digital 1TB</p>
<p class="rel-prod-price" id="price_format_2">139.95</p>
add to cart
</div>
<div class="rel-prod-item">
<img src="assets/product-photos/title-of-the-related-product_thumbnail.jpg" alt="Western Digital 1TB" />
<p class="rel-prod-title">Western Digital 1TB</p>
<p class="rel-prod-price" id="price_format_3">49.95</p>
add to cart
</div>
The designer made all the prices have the digits after the . be superscript. So your choice is to either have the cms spit out the price in 2 parts from the backend and put it back together with <sup> tags around it, or just leave it alone and change it via the DOM. That's what I opted for and here's what I came up with:
window.onload = function() {
var pricelist = document.getElementsByClassName("rel-prod-price");
var price_id = "";
for (var b = 1; b <= pricelist.length; b++) {
var price_id = "price_format_" + b;
var price_original = document.getElementById(price_id).innerHTML;
var price_parts = price_original.split(".");
var formatted_price = price_parts[0] + ".<b>" + price_parts[1] + "</b>";
document.getElementById(price_id).innerHTML = formatted_price;
}
}
And here's the CSS I used:
.rel-prod-item p.rel-prod-price b {
font-size: 50%;
position: relative;
top: -4px;
}
I hope this helps someone keep all their hair :-)
Here's a screenshot of the finished product