views:

48

answers:

3

Here is my code:

<li class="det_price">
    <a href="/designer/customize/278258?dpid=1">Printing</a> from $10 
</li>

I have about fifteen chunks like this on any given page, and I'd like to take the text node (from $X), select X using a regular expression and set it to a numeric variable, then multiply it by a %, and append it to the original node. For example, if the original node said "from $10" I would like to replace it with "from $10 to $2.60". I can do this using replace() and regular expressions on a single node, but I'm having trouble iterating through all of them with jQuery. Can I apply such a transformation to a jQuery object, or do I need to convert it somehow and then use standard Javascript functions?

Thanks!

+1  A: 

Here's how to select a text node.

Here's (the skeleton of) what you do once you've got 'em:

$('li.det_price').contents().filter(function()
{ 
    return this.nodeType == 3;
}).text(function (i, text)
{
    return text.replace(/* your schtuff here */);
});

So apparently jQuery doesn't play that nicely with text nodes

Time to get (a little) hacky:

var rnotwhite = /\S/; // to omit text nodes that are solely white space
                      // tweak this as needed
$('li.det_price').contents().filter(function()
{ 
    return this.nodeType === 3 && rnotwhite.test($(this).text());
}).text(function (i, text)
{
    this.replaceWholeText(text + ' replaced');
    // or, for more cross-browser-ness
    // this.nodeValue = text + ' replaced';
});

--> Check out this sweet demo <--

--> IE-compatible demo here <--

Now here's the deal: if you have control of the markup, the best solution for this is to wrap the text nodes you're actually interested in, in <span>s, like this:

<li class="det_price">
  <a href="/designer/customize/278258?dpid=1">Printing</a><span> from $10</span>
</li>

and then you can just do this (way less sketch, IMO):

$('li.det_price > a + span').text(function (i, text)
{
    return text + ' replaced';
});

--> More demo goodness <--

Matt Ball
This totally makes sense - thanks Matt!
jlabau
@jlabau - I'm testing this now; I'm not sure that it works - http://jsfiddle.net/MDLBg/
Matt Ball
@Matt - Thanks for setting that up - you're right, so far no action on the button click.
jlabau
@jlabau: it's kinda sketchy, but I got it working. See my edit
Matt Ball
Ah-ha! I knew there would be some hack-ness to it. Thanks for your work on this - jQuery is great for so much, but seems ill-equipped to deal with text. Kudos.
jlabau
@jlabau: one more edit in there, have a look :)
Matt Ball
Unfortunately my lack of rep prevents me from upvoting you. Can we get some karma up in here for Mr. Ball?
jlabau
@jlabau: I +1'd your question to get you closer to 15, but you should be able to accept my answer to get yourself another 2 rep.
Matt Ball
@Matt - Now that is some efficient code. Unfortunately I don't have access to the markup, but maybe I can get them to wrap those in spans just for the economy of it all. Thanks again, Matt!
jlabau
Accepted! That's me being a jerk and not gaining rep before asking my first question :-) Great community here - I'll definitely be cruising the boards where I have some more expertise and can be of help!
jlabau
@jlabau: welcome to SO! Try not to get too distracted by "real" work :P
Matt Ball
@Matt - I know! I could just zone out here for a couple days and call it "research."
jlabau
@Matt - I got it working on my production server, and it worked great in Mozilla/Chrome. Then I tried IE, and nada. I'll take a look at the code and post my findings if I can get it to work.
jlabau
@jlabau: which one didn't work in IE? The hacky one? Let me see what I can dig up about IE sucking w/r/t `replaceWholeText()`.
Matt Ball
@jlabau: yup, of _course_ [IE (pre-9) doesn't support it](http://msdn.microsoft.com/en-us/library/ff975208). Looks like the [`nodeValue` property](http://msdn.microsoft.com/en-us/library/ms534192\(VS.85\).aspx) is the solution here. Unfortunately I can't test this in IE myself. See my edit.
Matt Ball
@Matt - Worked like a charm! Here's the (truly hacky) full code that's running on the site, with the transformations, just in case anyone's interested: http://jsfiddle.net/MDLBg/63/
jlabau
A: 

You need to use the each function:

$("li.det_price a").each(function(index, Element){
   //Element holds the current anchor, manipulate it's contents at will
   $("Element").val("some new value...");
})
Adrian Grigore
A: 

$("li.det_price a").text() would get you the text of that LI (and, unfortunately, of all LI nodes with that class reference). To get just the text of that particular LI you would have to give it an ID, or find some other way to identify it uniquely.

Once you do identify it uniquely, you could simply put a string in the .text() braces to change what you had. For example,

$("li.det_price a").text('Not Printing') would change your text above from 'Printing' to 'Not Printing'.

Robusto