carla
carla

Reputation: 2117

Duplicate div with script/style tags inside using JS

I have the following html code:

<table><tbody><tr><td>
      <div id="div_1">
          <style>...</style>
          <div><label> 1 </label></div>
          <div><input type="text" name="text_1"/></div>
          <script>$("#text_1").mask("99/99/9999");</script>   
          <div><label><a onclick="javascript:insert_div()"> </a></label></div>  
          ...    
      </div>                    
      ...                
      <div id="div_20">
           <style>...</style>
           <div><label> 1 </label></div>
           <div><input type="text" name="text_20"/></div>
           <script>$("#text_20").mask("99/99/9999");</script>   
           <div><label><a onclick="javascript:insert_div()"> </a></label></div>  
           ...    
      </div>
</td></tr></tbody></table>  

That generates this (from 1 to 20, actually):

enter image description here

What I need is to insert a whole new div when the user presses the arrow button. It should copy the div with scripts and styles and insert after them with a new number (e.g. 21, then 22, etc.).

Upvotes: 0

Views: 100

Answers (2)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93571

This is purely an instructional example of an alternate way of doing this task. It is intentionally wordy to provide ideas.

Suggestion: Avoid attribute-based event handlers when using jQuery:

To clarify my first comment. If you use onclick=javascript handlers, you are placing the registration of the event in the HTML, separate to the actual handler in the script. The "jQuery way" is to apply the handler function to a selection of elements, using methods like .click() and the rather useful .on() which I use below. This makes maintaining pages easier as you are not hunting through the HTML for JavaScript snippets. jQuery event handlers also support having more than one handler, for the same event, attached to an element which you simply cannot do with onclick=.

Concepts shown:

  • Use a global counter for the next id number and simply increment it after each use
  • Use a delegated event handler to process the "add" clicks as the elements are added dynamically (so do not exist until later).
  • Use a template stored in a dummy <script> block to hold your template HTML (this text/template type is unknown so is ignored by all browsers. It also makes maintenance a breeze.
  • Replace placeholder markers in the template with the new id information
  • Convert the HTML to DOM elements using $(html)
  • Find descendants in the new row to add things like mask.
  • Append the new row

JSFiddle: http://jsfiddle.net/TrueBlueAussie/Lu0q0na2/2/

// Declare a global counter for our new IDs
id = 2;

// Listen for click events at a non-changing ancestor element (delegated event handler)
$(document).on('click', '.addnew', function(e){

    // get the HTML of the template from the dummy script block
    var template = $('#template').html();

    // Change the template names etc based on the new id
    template = template.replace('{name}', 'name' + id).replace('{id}', id);

    // Increase next id to use
    id++;

    // Convert the HTML into a DOM tree (so we can search it easily)
    var $template= $(template);

    // Apply the mask to the newly added input - alter this to suit
    $template.find('input').mask("99/99/9999");

    // Append the new row
    $('table').append($template);

    // stop the link from moving to page top
    return false;
});

I will be happy to explain any part of this if you have questions. I realise it may be a bit of a shock compared to the existing way of doing it you have :)

Upvotes: 1

M. Page
M. Page

Reputation: 2814

I give you the basic idea: the rest if left as an exercise as teachers say:

<script type="text/javascript">
 var last_inserted = 0;

 function insert_div(){
     $d = $("#div_" + last_inserted).clone();
     $d.attr('id', 'div_' + last_inserted++);
     $("table").append($d);
 }
</script>

And something else: <a onclick="javascript:insert_div()"> is probably not correct (untested).

Either: <a onclick="insert_div()"> or <a href="javascript:insert_div()">

Upvotes: 1

Related Questions