How to perform replace on all attributes using jQuery / JavaScript?

2

I want to replace all occurrences that have __prefix__ with a number, how to accomplish this using jQuery / JavaScript?

HTML

<div class='form-modelo'>
    <input id="id_form-__prefix__-nome" name="form-__prefix__-nome" type="text">
    <input id="id_form-__prefix__-texto" name="form-__prefix__-texto" type="text">
</div>
<div class='form-real'></div>

JS

<script>
    var clone = $('.form-modelo').clone();
    var num = 1;
    // replace __prefix__ por num
    // ex: name='form-__prefix__-nome' para name='form-1-nome'
    $('.form-real').append(clone);
</script>
    
asked by anonymous 26.03.2015 / 17:16

3 answers

5

You can use a regex to replace the string "__prefix__" with the desired number from the original element HTML:

$(function() {
  var original = $('.form-modelo');
  var num = 1;
  // replace __prefix__ por num
  // ex: name='form-__prefix__-nome' para name='form-1-nome'
  var htmlNovo = $('<div>').append(original.clone()).html();
  //var htmlNovo = original.html();
  var cloneAlterado = $(htmlNovo.replace(/__prefix__/g, 1));
  $('.form-real').append(cloneAlterado);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><divclass='form-modelo'><inputid="id_form-__prefix__-nome" name="form-__prefix__-nome" type="text">
  <input id="id_form-__prefix__-texto" name="form-__prefix__-texto" type="text">
</div>
Clone
<div class='form-real'></div>

I know that regex is less semantic, and many will tell you not to use regex with HTML, but the string you want to replace seems pretty unique to me ... single enough to avoid errors. In addition, if you have control over the string to be replaced, and think that errors may occur, then just use another more unique string ... concatenate a GUID in it, I do not know, there goes the need.

    
26.03.2015 / 17:29
4

Using JQuery:

var num = 1;
var clone = $('.form-modelo').clone();
clone.attr('class', 'form-real');
clone.children().each( function() {
  $(this).attr('id', $(this).attr('id').replace( /__prefix__/, num ) );
});
$('#form-container').append(clone);


Note: I made some changes when cloning. As it was, you were generating a .form-real within a copy of the% div .form-modelo , I believe that is not the desired result.


How you are in your original code:

<div class='form-modelo'>
    <input id="id_form-__prefix__-nome" name="form-__prefix__-nome" type="text">
    <input id="id_form-__prefix__-texto" name="form-__prefix__-texto" type="text">
</div>
<div class='form-real'>
    <div class='form-modelo'>
        <input id="id_form-__prefix__-nome" name="form-__prefix__-nome" type="text">
        <input id="id_form-__prefix__-texto" name="form-__prefix__-texto" type="text">
    </div>
</div>


With the modifications we have a container:

<div class='form-modelo'>
    <input id="id_form-__prefix__-nome" name="form-__prefix__-nome" type="text">
    <input id="id_form-__prefix__-texto" name="form-__prefix__-texto" type="text">
</div>
<div id='form-container'>
    <div class='form-real'>
        <input id="id_form-1-nome" name="form-1-nome" type="text">
        <input id="id_form-1-texto" name="form-1-texto" type="text">
    </div>
</div>

Changes:

  • added clone.attr('class', 'form-real'); to dynamically rename the div;
  • used $('.form-real:last').append(clone); to add to the end of existing ones, if you want multiple numbered inputs;
  • set a #form-container to insert the forms, if you want to use more than one.


Demo:

var num;
for( num = 1; num <= 5; num++ ) {
  var clone = $('.form-modelo').clone();
  clone.attr('class', 'form-real');
  clone.children().each( function() {
    $(this).attr('id', $(this).attr('id').replace( /__prefix__/, num ) );
  });
  $('#form-container').append(clone);
}
#id_form-__prefix__-nome {border:2px solid blue;}
#id_form-1-nome {border:2px solid red;}
#id_form-2-nome {border:2px solid cyan;}
#id_form-3-nome {border:2px solid green;}
#id_form-4-nome {border:2px solid orange;}
#id_form-5-nome {border:2px solid magenta;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divclass='form-modelo'><inputid="id_form-__prefix__-nome" name="form-__prefix__-nome" type="text">
    <input id="id_form-__prefix__-texto" name="form-__prefix__-texto" type="text">
</div>
<div id='form-container'></div>
    
26.03.2015 / 17:45
3

I suggest to iterate the attributes and rewrite them:

var elements = document.querySelectorAll('.form-modelo input');
for (var i = 0; i < elements.length; i++) {
    var el = elements[i];
    el.name = el.name.split('__prefix__').join(i);
    el.id = el.id.split('__prefix__').join(i);
}

In this way you share the string by '__prefix__' and rejoin by putting the iteration number in that place.

Example: link

With jQuery and following your code could be:

var clone = $('.form-modelo').clone();
var num = 1;
clone.find('input').each(function () {
    this.name = this.name.split('__prefix__').join(num);
    this.id = this.id.split('__prefix__').join(num);
});
$('.form-real').append(clone);

jsFiddle: link

    
26.03.2015 / 17:23