views:

537

answers:

6

I am writing an 'inline translator' application to be used with a cloud computing platform to extend non-supported languages. The majority of this uses jQuery to find the text value, replace it with the translation, then append the element with a span tag that has an unique ID, to be used elsewhere within the application. The problem arises however, when there are more than one element, say , that have the exact same value to be translated (matched elements). What happens in the function in question is that it puts all matched elements in the same span, taking the second, third, fourth, etc. out of their parent tags. My code is pretty much like this example:

<script src='jquery-1.4.2.js'></script>
<script>
jQuery.noConflict();
var uniqueID='asdfjkl';
jQuery(window).ready(function() {
var myQ1 = jQuery("input[id~=test1]");
myClone=myQ1.clone();
myClone.val('Replaced this button');
myQ1.replaceWith('<span id='+uniqueID+'></span>');
jQuery('#'+uniqueID).append(myClone);
});
</script>
<table>
<tr><td>
<input id='test1' type='button' value="I'm a button!"></input> &nbsp;
<input id='test2' type='button' value="And so am I"></input>
</tr></td>
<tr><td>
<input id='test1' type='button' value="I'm a button!"></input>
</tr></td>
</table>

As a workaround, I've experimented with using a loop to create a class for each span, rising in increment until jQuery("input[id~=test1]").length, but I can't seem to get anything I do to work. Is there any way to give each matched element an unique ID? My fluency in jQuery is being put to the test!

Thanks for any help in advance.

Aaron

A: 

I think what you are looking for is wrap. The following will wrap each element that contains test in the id with a span.

jQuery.noConflict();
jQuery(document).ready(function() {
    jQuery("input[id*=test]").wrap('<span></span>');
});

Note that you can use the existing ids to match the span using a parent selector so there isn't really a need to duplicate it or generate one.

$("input[id*=test]').parent('span')...

If you really wanted to create new elements with ids, you could use each with some unique naming scheme.

jQuery.noConflict();
jQuery(document).ready(function() {
    jQuery("input[id*=test]").each(function() {
        var $this = $(this);
        var id = $this.attr('id');
        $this.wrap('<span id="span-' + id + '"></span>");
    });
});
tvanfosson
A: 

Thank you for the help. However, even though I got rid of the part of my code clone/replace the elements, they're still ending up in the same span together, rather than staying in their respective <td>'s. I modified the JavaScript like so:

var uniqueID='asdfjkl';
jQuery(window).ready(function() {
var myQ1 = jQuery("input[id~=test1]");
myQ1.wrapAll('<span id='+uniqueID+'></span>');
myQ1.val('Replaced this button');
});

...Ah I just saw the function you added. Let me give that a go.

AnGafraidh
A: 

Thanks, this part is definitely along the lines of what I'm looking for:

jQuery("input[id*=test]").each(function() {
    var $this = $(this);
    var id = $this.attr('id');
    $this.wrap('<span id="span-' + id + '"></span>");
});

However, the challenge is that I'm writing this to work over HTML I don't have the access to change. You are right, the HTML I did with ID was illegal (it was just a sample I threw together), but on the actual site it would use input name: jQuery("input[name*=test]"). Since the name is going to be identical, he problem here is finding something else by which to make the span unique, say an auto-number. I'm looking at your example now trying to think of a way I might use a loop. Any ideas?

AnGafraidh
Please note that, while Stack Overflow may be inspired by discussion forums, **it doesn't work the same way**.Answers are not the proper way to reply to another answer. Please use comments to accomplish that (via the appropriate "add comment" button).
Jonathan Lonowski
A: 

My take was to generate a random number and append it to the initial id:

jQuery.noConflict();
jQuery(window).ready(function() {

   var myQ1 = jQuery("input[id*='test']");
   var uniqueNum = Math.floor( Math.random()*99999 );
   var uniqueID = myQ1.attr('id')+'-'+String(uniqueNum);

   myClone=myQ1.clone();
   myClone.text('Replaced this button');

   myQ1.replaceWith('<span id='uniqueID+'></span>');

   jQuery('#'+uniqueID).append(myClone);

});
mVChr
A: 

you say: ...when there are more than one element, say , that have the exact same value to be translated...

so you don't need to complicate all the thing, since you are using a Loop!!!

what you need is to check if this particular text is already translated and span created!

try this:

jQuery("input[id*=test]").each(function(i) {
    var $this = $(this);
    if ( $this.parent().text() != $this.val() )
    $this.wrap('<span id="span_' + i + '"></span>");
});

of course you can have also an unique id.. since you are using the $each method for loop it give itself the iterator see the example i

then for make all work properly and strict your html code should look like this:

<input class="translate_input" type='button' value="I'm a button!" />

then one more thing, i'm not sure why you are cloning!?

can you just do this!?

jQuery("input[id*=test]").each(function(i) {
    var $this = $(this);
    var tranlated_text = translateMyText( $this.val() );
    if ( $this.parent().text() != tranlated_text )
    $this.wrap('<span id="span_' + i + '"></span>");
    $(tranlated_text).insertBefore($this);
});

<span> TRANSLATED TEXT <input class="translate_input" type='button' value="TEXT TO TRANSLATE" /></span>
aSeptik
A: 

That's good stuff, thanks to all! In the end it looks like:

var myQ1 = jQuery("input[name~=test1]");
myQ1.each(function() {
    var id = Math.floor( Math.random()*99999 );
    jQuery(this).wrap("<span id=\"span-"+id+"\"></span>");
...

Aseptik, there is a lot more code, much more than I drug into this, so I wanted to keep the part I was hung up on brief. Thanks again for the input.

Regards, Aaron

AnGafraidh
The way to thank users on StackOverflow is to hit the up arrow next to their answer or accept it as the correct answer if you decide to use their code as part of your solution. Thanks.
mVChr
holy words bro! ;)
aSeptik