Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ACE editor: create a new editor dynamically

I have a layout tab based where i can add and remove tabs, when i create a new tab i want to add a new istance of ACE editor (http://ace.ajax.org/) to it (i'm using jquery ui tabs) but so doesn't work:

$(function() {
    var $tab_title_input = $( "#tab_title"),
        $tab_content_input = $( "#tab_content" );
    var tab_counter = 3;

    // tabs init with a custom tab template and an "add" callback filling in the content
    var $tabs = $( "#tabs").tabs({
        tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
        add: function( event, ui ) {
            var tab_content = $tab_content_input.val() || "Tab " + tab_counter + " content.";
            $( ui.panel ).append("<div id=\"editor2\">" + tab_content + "</div>");  }       

    });

    // modal dialog init: custom buttons and a "close" callback reseting the form inside
    var $dialog = $( "#dialog" ).dialog({
        autoOpen: false,
        modal: true,
        buttons: {
            Add: function() {
                addTab();
                $( this ).dialog( "close" );
            },
            Cancel: function() {
                $( this ).dialog( "close" );
            }
        },
        open: function() {
            $tab_title_input.focus();
        },
        close: function() {
            $form[ 0 ].reset();
        }
    });

    // addTab form: calls addTab function on submit and closes the dialog
    var $form = $( "form", $dialog ).submit(function() {
        addTab();
        $dialog.dialog( "close" );
        return false;
    });

    // actual addTab function: adds new tab using the title input from the form above
    function addTab() {
        var tab_title = $tab_title_input.val() || "Tab " + tab_counter;
        $tabs.tabs( "add", "#tabs-" + tab_counter, tab_title )
             .tabs( "select", "#tabs-" + tab_counter, tab_title );
        tab_counter++;
        var content_height = $('.content').height();
        $('.ui-tabs-panel').css('height', content_height - 97);
        $('div#editor').css('height', content_height - 97);
                    var editor2 = ace.edit("editor2");
    var scroll = editor2.renderer.setHScrollBarAlwaysVisible(false);
    var JavaScriptMode = require("ace/mode/javascript").Mode;
    editor2.getSession().setMode(new JavaScriptMode());
    editor2.setTheme("ace/theme/twilight");
                var content_height = $('.content').height();
        $('.ui-tabs-panel').css('height', content_height - 97);
        $('div#editor').css('height', content_height - 97);
    }

    // addTab button: just opens the dialog
    $( "#add_tab" )
        .button()
        .click(function() {
            $dialog.dialog( "open" );
        });

    // close icon: removing the tab on click
    // note: closable tabs gonna be an option in the future - see http://dev.jqueryui.com/ticket/3924
    $( "#tabs span.ui-icon-close" ).live( "click", function() {
        var index = $( "li", $tabs ).index( $( this ).parent() );
        $tabs.tabs( "remove", index );
    });
});
</script>
like image 540
Matteo Pagliazzi Avatar asked Nov 01 '11 20:11

Matteo Pagliazzi


1 Answers

I have created a little fiddle so that you can get started with ui tabs and the ace editor: http://jsfiddle.net/VEfyU/2/

as you can see on the left under external resources, i have added jquery ui and the ace editor js file. I use jquery ui 1.10.3 and have not used "add" as it is now deprecated.

javascript:

$(document).ready(function() {

    // initialize tabs
    $('#tabs').tabs();

    // array containing all the editors we will create
    var editors = [];

    // initialize button listener
    $('#addTab').on('click', function() {

        console.log('add a tab with an ace editor instance');

        var tabsElement = $('#tabs');
        var tabsUlElement = tabsElement.find('ul');

        // the panel id is a timestamp plus a random number from 0 to 10000
        var tabUniqueId = new Date().getTime() + Math.floor(Math.random()*10000);

        // create a navigation bar item for the new panel
        var newTabNavElement = $('<li id="panel_nav_' + tabUniqueId + '"><a href="#panel_' + tabUniqueId + '">' + tabUniqueId + '</a></li>');

        // add the new nav item to the DOM
        tabsUlElement.append(newTabNavElement);

        // create a new panel DOM
        var newTabPanelElement = $('<div id="panel_' + tabUniqueId + '" data-tab-id="' + tabUniqueId + '">New editor ' + tabUniqueId + ': <br/></div>');

        tabsElement.append(newTabPanelElement);

        // refresh the tabs widget
        tabsElement.tabs('refresh');

        var tabIndex = $('#tabs ul li').index($('#panel_nav_' + tabUniqueId));

        console.log('tabIndex: ' + tabIndex);

        // activate the new panel
        tabsElement.tabs('option', 'active', tabIndex);

        // create the editor dom
        var newEditorElement = $('<div id="editor_' + tabUniqueId + '">// some code here</div>');

        newTabPanelElement.append(newEditorElement);

        // initialize the editor in the tab
        var editor = ace.edit('editor_' + tabUniqueId);
        editor.setTheme("ace/theme/monokai");
        editor.getSession().setMode("ace/mode/javascript");

        // set the size of the panel
        newTabPanelElement.width('600');
        newTabPanelElement.height('600');

        // set the size of the editor
        newEditorElement.width('500');
        newEditorElement.height('500');

        // resize the editor
        editor.resize();

        editors.push({ id: tabUniqueId, instance: editor });

        // add an editor/panel close button to the panel dom
        var closeButton = $('<button class="close">close</button>');

        newTabPanelElement.prepend(closeButton);

    });

    $('#tabs').on('click', '.close', function() {

        console.log('close a tab and destroy the ace editor instance');

        console.log($(this).parent());

        var tabUniqueId = $(this).parent().attr('data-tab-id');

        console.log(tabUniqueId);        

        var resultArray = $.grep(editors, function(n,i){
            return n.id === tabUniqueId;
        }, true);

        var editor = resultArray[0].instance;

        // destroy the editor instance
        editor.destroy();

        // remove the panel and panel nav dom
        $('#tabs').find('#panel_nav_' + tabUniqueId).remove();
        $('#tabs').find('#panel_' + tabUniqueId).remove();

    });

});

html:

<div id="tabs">
    <ul>
    </ul>
</div>

<button id="addTab">Add an editor</button>
like image 78
chrisweb Avatar answered Oct 08 '22 13:10

chrisweb