I have a HTML structure like this:
<div class="votes">
<b>5</b> Votes
<a id="vote-' + element_id +'" href="#" class="vote-btn"></a>
</div>
I have manage to get the text after 5 i.e. votes using:
var voteTextNode = $(this).parent('div').contents().filter(function() {
return this.nodeType == 3;
});
var voteText = voteTextNode.text();
now i want to change this text to vote which is respective number of votes . I have tried this:
voteNewText = ( newCount == '1' ) ? 'Vote' : 'Votes';
voteTextNode.text(voteNewText);
but it does not work for me. I have also tried the code from this link:
How can I get, manipulate and replace a text node using jQuery?
but it also wont work for me tell me where i am doing wrong
As you have seen, jQuery is not really made for handling text nodes. Your var voteTextNode will be a jQuery instance, holding a set of text nodes. You can hardly manipulate them using .text(), which would add some new TextNodes into them.
Yet, this should work:
$(this).parent('div').contents().each(function() {
// iterate over all child nodes
if (this.nodeType == 3)
this.data = "Vote";
});
But with plain dom methods it may be clearer:
var countTextNode, voteTextNode;
$(this).parent('div').find('b').each(function() {
countTextNode = this.firstChild;
voteTextNode = this.nextSibling;
});
return function setVotes(num) {
countTextNode.data = num;
votTextNode.data = num == 1 ? 'Vote' : 'Votes';
};
put it in a span
<div class="votes">
<b>5</b> <span id="votesTxt">Votes</span>
<a id="vote-' + element_id +'" href="#" class="vote-btn"></a>
</div>
and then
$("#votesTxt").text(( newCount == '1' ) ? 'Vote' : 'Votes');
EDIT if you don't wish to use span then just change the text for the element after the b tag:
$("#votes b:first")[0].nextSibling.data = (( newCount == '1' ) ? 'Vote' : 'Votes');
Treat it as the DOM tree it is: what you probably want is to get the first <b> element inside each <div> with class "votes" and then change the text in the text node that immediately follows it. jQuery is good at selecting and iterating over elements so use it for this part if you want. Once you've got the <b> elements, switch to regular DOM. Here's an example:
Demo: http://jsfiddle.net/Qq3T7/
Code:
$("div.votes").find("b:first").each(function() {
this.nextSibling.data = ($(this).text() == "1") ? " Vote" : " Votes";
});
Can you change the initial markup? You'll have a much easier time doing this if you just wrap the text you want to change in a tag:
<span id="votetext">Vote</span>
And then you can easily set the text:
$('#votetext').text('Votes');
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 am adding some HTML tags using JavaScript like this:
function createTag(text) {
if (text != '') {
text = text.replace(',', '');
if (/^\s+$/.test(text) == false) {
var tag = $('<div class="tags">' + text + '<a class="delete">X</a></div>');
tag.insertBefore($('input.tag_list'), $('input.tag_list'));
$('input.tag_list').val('');
}
}
I want to get the values in the <div class="tags"> tags from all over the page. How can I do it?
Also how can I restrict the number of dynamically created tags of these types?
Select the tags and use the map() function to return an array. Within the function supplied to map() remove the a from a cloned tag.
var tags = $(".tags").map(function(){
var clone = $(this).clone();
$(clone).find("a").remove("a");
return clone.text();
});
JS Fiddle: http://jsfiddle.net/ELxW4/
You could make life somewhat easier by wrapping the values in span tags:
<div class="tags"><span>javascript</span><a class="delete">X</a></div>
<div class="tags"><span>java</span><a class="delete">X</a></div>
<div class="tags"><span>jquery</span><a class="delete">X</a></div>
Then get the tags using:
var tags = $(".tags").map(function(){
return $(this).find("span").text();
});
I have this code and I basically want it to read what is created in between the <span> tags (that value is created by another javascript script), and then take that to display 'article' or 'articles'.
<span id="quantity" class="simpleCart_quantity"></span>
<script type="text/javascript">
var q = document.getElementById('quantity');
if (q == 1) {
document.write("article");
}
else
{
document.write("articles");
}
</script>
So I want it to check <span id="quantity" class="simpleCart_quantity"></span>, and if the value that is present is '1', write 'article' and if the value is '0' or more than '1' write 'articles'. I hope you can get it.
Now it works, but only if you actually write something in between the <span>, like:
1
But the value is created externally and the script must be able to read the value that is created when the page is loaded right?
The result should be a sentence that says 'You have x article(s) in your shopping cart'.
I have no idea of how I should do this, I hope somebody can help me.
Thanks a lot!
<span id="quantity" class="simpleCart_quantity"></span>
<!-- ... --->
<span id="quantityText"></span>
<script type="text/javascript">
var quantity = document.getElementById("quantity"),
quantityText = document.getElementById("quantityText");
if (parseInt(quantity.innerHTML, 10) === 1) {
quantityText.innerHTML = "article";
} else {
quantityText.innerHTML = "articles";
}
</script>
Note that you must use a radix argument (10, in this case) to make sure numbers are interpreted as base10. Otherwise everything starting with '0x' would be interpreted as hexadecimal (base16), for example.
alternative syntax using the ternary operator:
<script type="text/javascript">
var quantity = document.getElementById("quantity"),
quantityText = document.getElementById("quantityText"),
quantityValue = parseInt(quantity.innerHTML, 10);
quantityText.innerHTML = "article" + (quantityValue === 1 ? "" : "s");
</script>
In addition to pure javascript, you can also use jQuery:
jQuery($this).find('span.simpleCart_quantity') // find the span with class name: simpleCart_quantity
.text() // get the text
I need a little help with a Javascript function I am creating. In essence, I need to loop through a set of DIVs with class .DetailRow and find a child DIV's content (inner text). If this text is matched to a variable, then I need to replace this inner text with an IMG HTML statement.
BTW I am kinda new at this (4 months old!) so apologies if the issue is simple, but I have tried a few combos and I am stuck.
Here's the HTML:
<div class="DetailRow" style="display: ">..</div>
<div class="DetailRow" style="display: ">..</div>
<div class="DetailRow" style="display: ">
<div class="Label">Availability:</div>
<div class="Value">in stock + Free Shipping</div>
</div>
Example, if I find "in stock" in the LABEL inner text, I want to replace it with the value of the variable "instock" which is an IMG HTML statement. See my code attempt below.
<script type="text/javascript">
$(window).load(function(){
var instock = '<img src="https://linktoimgfolder/instock.gif" title="Product available, usually ships 24hrs to 48hrs after order receipt" style="margin-top:-3px;">';
var lowstock = '<img src="https://linktoimgfolder/lowstock.gif" title="Product stcok low, order today so you do not miss out">';
var nostock = '<img src="https://linktoimgfolder/outstock.gif" title="Product out of stock, could ship 1 to 2 weeks after order receipt">';
$('div.DetailRow')each(function(){
if (indexOf($(this).childNodes[1].innerHTML, "in stock") > 0) {
$(this).childNodes[2].innerHTML = "";
$(this).childNodes[2].innerHTML = instock;
} else if (indexOf($(this).childNodes[1].innerHTML, "low stock") > 0) {
$(this).childNodes[2].innerHTML = "";
$(this).childNodes[2].innerHTML = lowstock;
} else {
$(this).childNodes[2].innerHTML = "";
$(this).childNodes[2].innerHTML = nostock;
};
});
});
</script>
By the way,m I cannot match text exactly as the text beyond the "+" will change from time to time, thus I am trying indexOf.
Many thanks in advance for your assistance!
M
Using the :contains selector
var stock = {'in stock': instock, 'low stock': lowstock, 'no stock': nostock};
Object.keys(stock).forEach(function(key) {
$('div.DetailRow div:contains(' + key + ')').html(stock[key]);
});
jsFiddle Demo
A pure jQuery solution:
$.each(stock, function(key, value) {
$('div.DetailRow div:contains(' + key + ')').html(value);
});
You have typo in this line $('div.DetailRow')each(function(){ and then you can use jQuery .text() and .html() to check value and update.
Try:
$('div.DetailRow').find("div").each(function(){
if($(this).text().indexOf("in stock")!=-1){
$(this).text("");
$(this).html(instock);
}else if($(this).text().indexOf("low stock")!=-1){
$(this).text("");
$(this).html(lowstock);
}else{
$(this).text("");
$(this).html(nostock);
}
});
DEMO FIDDLE
NOTE: Updated code to find div inside div.DetailsRow. Change it according to your requirement.
I have a HTML string ( not DOM element ) like :
<p>This is a sample dataa<p>
<img src="Randomz" alt="Randomz Image">Randomz is the name of the image</img>
I need to append a <span class="spellerror"></span> to the words that have problem and that too only the Textual contents need to be checked and appended .
<p>This is a sample dataa<p>
<img src="Randomz" alt="Randomz Image"><span class="spellerror"> Randomz </span> is the name of the image</img>
My problem is that this is a mix of HTML and regex . Is it possible:
To make this some kind of a DOM element and then work on it ?
Or is there a regex way to achieve this.
I dont want to touch the attributes and if I modify Text contents , how do I publish it back ...because I need some HTML inserted there .
I dont love this solution, but it works:
'<img src="Randomz" alt="Randomz Image">Randomz is the name of the image</img>'
.match(/<[^>]+>|[^<]+|<\/[^>]+>/g)
.map(function (text, index) {
if (index === 1) {
return text.replace(/(Randomz)/, '<span class="spellerror">$1</span>');
} else {
return text;
}
})
.join('');
The regex splits into opening tag, innerText, closing tag.
Then iterates on all members, if its the innerText, it replaces with desired text
Then joins.
Im stil trying to think of something less round-about but thats all i got
Use some form of templating:
String.prototype.template = String.prototype.template ||
function (){
var args = Array.prototype.slice.call(arguments)
,str = this
;
function replacer(a){
var aa = Number(a.substr(1))-1;
return args[aa];
}
return str.replace(/(\$\d+)/gm,replacer);
};
var thestring = [ '<p>This is a sample dataa</p><img src="Randomz"'
,' alt="Randomz Image">$1Randomz$2 '
,'is the name of the image</img>'].join('')
,nwString = theString.template('<span class="spellerror">','</span>');