Jquery dynamic textarea menu
<p>I have a page that allows a user to add and remove dynamic textareas.</p>

<p>When the user clicks the 'Add Textarea' button a new textarea is loaded. At the top of the textarea is a small menu including the Bold, Italic and Underline buttons.</p>

<p>When the user clicks one of these buttons the textarea is populated with markup coressponding to the button.</p>

<p>However when the user adds a second textarea, the menu for the first textarea doubles up the output into the first textarea. If the user then adds a third textarea the menu of the first textarea triples the output into the first textarea, and the second area doubles the output...</p>

<p>Hope that makes sense. How do I stop this doubling up each time an additional textarea is added?</p>

<p>This is the complete script:</p>

<pre><code>$('.article-button').click( function() {
    var target = '#about-elements';
    var button_type = $(this).attr('id');
    var id = new Date().getTime();
    var right_id = (new Date().getTime())+1;
    var get_icons = appendIcons(id);
    var menu = $.fn.menuOption();
    var out = false;

    if(button_type == 'about-textarea') {
        var out = '&lt;div id="' + id + '" class="sortable-div"&gt;&lt;label&gt;Paragraph&lt;/label&gt;&lt;div class="menu-option" rel="menu_' + id + '"&gt;' + menu + '&lt;/div&gt;&lt;textarea id="element_' + id + '" class="about-textarea" name="element_' + id + '[]" /&gt;&lt;/textarea&gt;';
    }
    else
        return false;                   

    if(out != false) {
        var out = out += get_icons;
        var l_out = out + '&lt;/div&gt;';
        $(l_out).css('display', 'none').appendTo(target).fadeIn(500);
        $('.field-option').click(function() {
            var link_id = $(this).attr('rel');
            var type = $(this).attr('class').replace('field-option ', '');
            $.fn.fieldOption(type, link_id);
        });
        $('.article-menu').click(function() {
            var parent_id = $(this).closest('.menu-option').attr('rel').replace('menu_', '');
            var type = $(this).attr('rel');
            $.fn.menuOutput(type, parent_id);
        });
    }
    $(".droppable").droppable({ accept: ".draggable", activeClass: "drop-list-hover", drop: function(event, ui) {
        var drag_id = ($(ui.draggable).attr("id")).replace('upload_', '');
        var drag_src = ($(ui.draggable).attr("src"));
        var drop_id = $(this).attr('rel');
        var new_img = '&lt;img src="' + drag_src + '" /&gt;';

        $('input[id=img_' + drop_id + ']').val(drag_id);
        $('div.sortable [id=' + drop_id + '] div.droppable').hide().html(new_img).fadeIn(500);
        }
    });                                             
});
</code></pre>

<p>And the fieldOption and menuOutput functions:</p>

<pre><code>$.fn.fieldOption = function(type, link_id) {
    var list_id = 'div[id=' + link_id + ']';

    if(type == "remove") {
        $('#dialog-confirm').dialog({
            resizable: false,
            height:140,
            modal: true,
            draggable: false,
            buttons: {
                "Remove field": function() {
                    $(this).dialog('close');
                    $(list_id).css('min-height', '0');
                    $(list_id).animate({
                        opacity: 0,
                        height: '0px'
                        }, 800, 'swing', function() {
                            $(list_id).remove();
                    });                                         
                },
                Cancel: function() {
                    $(this).dialog('close');
                }
            }
        });
    };
};

$.fn.menuOption = function() {
    var menu = '&lt;ul class="article-buttons"&gt;' +
        '&lt;li&gt;&lt;a title="Bold" class="article-menu bold" href="javascript:void(0);" rel="bold"&gt;&lt;img src="images/icons/article/article-menu-bold.png" width="29" height="29" /&gt;&lt;/a&gt;&lt;/li&gt;' +
        '&lt;li&gt;&lt;a title="Italic" class="article-menu italic" href="javascript:void(0);" rel="italic"&gt;&lt;img src="images/icons/article/article-menu-italic.png" width="29" height="29" /&gt;&lt;/a&gt;&lt;/li&gt;' +
        '&lt;li&gt;&lt;a title="Underline" class="article-menu underline" href="javascript:void(0);" rel="underline"&gt;&lt;img src="images/icons/article/article-menu-underline.png" width="29" height="29" /&gt;&lt;/a&gt;&lt;/li&gt;' +
        '&lt;/ul&gt;';
    return menu;
}

$.fn.menuOutput = function(type, parent_id) {
    if(type == 'bold') {
        var str = '[bold]...[/bold]';
    }
    else if(type == 'italic') {
        var str = '[italic]...[/italic]';
    }
    else if(type == 'underline') {
        var str = '[underline]...[/underline]';
    }
    $('textarea[id=element_' +  parent_id + ']').insertAtCaret(str);
}   
</code></pre>

<p>Quick Update:</p>

<p>The problem as Ive found it so far is that is that the article-menu click function is inside the article-button click function.</p>

<pre><code>$('.article-button').click( function() {
.....
    $('.article-menu').click(function() {
        var parent_id = $(this).closest('.menu-option').attr('rel').replace('menu_', '');
        var type = $(this).attr('rel');
        $.fn.menuOutput(type, parent_id);
    });
.....
});
</code></pre>

<p>When I move this portion outside of the main function and change 'click( function()' to 'on('click', function ()'...nothing. However if I change .on to .live everything seems to work perfectly. Live is deprecated though.</p>

<p>SOLVED</p>

<p>As mentioned above I moved the 'article-menu' on click function out of the 'article-button' function and changed it to:</p>

<pre><code>                $(document.body).on('click', '.article-menu', function() {
                    var parent_id = $(this).parent().parent().parent().attr('rel').replace('menu_', '');
                    var menu_type = $(this).attr('rel');
                    $.fn.menuOutput(menu_type, parent_id);
                }); 
</code></pre>
