YUI 3.x Home -

YUI Library Examples: Editor: YUI Editor with AlloyUI Toolbar

Editor: YUI Editor with AlloyUI Toolbar

This example uses the AlloyUI Toolbar module from the YUI 3 Gallery to add a GUI to EditorBase.

Working with EditorBase

EditorBase is not a fully functional Editor, it's simply the base utility under the hood that will be used to create an Editor. In this example we will show how to setup EditorBase and use the AlloyUI Toolbar Gallery module to interact with the it.

Setting up the HTML Source

The first step is to create the markup for our toolbar and our container for the Editor. Here we are creating a wrapper for the entire editor that includes a toolbar with Font Family and Font Size select lists and a container to render the Editor.

  1. <div id="editor_cont">
  2. <div id="toolbar">
  3. <h2 tabindex="-1">Text Editing Tools</h2>
  4. <select id="fontname">
  5. <option selected> </option>
  6. <option>Arial</option>
  7. <option>Arial Black</option>
  8. <option>Comic Sans MS</option>
  9. <option>Courier New</option>
  10. <option>Lucida Console</option>
  11. <option>Tahoma</option>
  12. <option>Times New Roman</option>
  13. <option>Trebuchet MS</option>
  14. <option>Verdana</option>
  15. </select>
  16. <select id="fontsize">
  17. <option selected> </option>
  18. <option value="1">10</option>
  19. <option value="2">13</option>
  20. <option value="3">16</option>
  21. <option value="4">18</option>
  22. <option value="5">24</option>
  23. <option value="6">32</option>
  24. <option value="7">48</option>
  25. </select>
  26. </div>
  27. <div id="editor"></div>
  28. </div>
<div id="editor_cont">
    <div id="toolbar">
        <h2 tabindex="-1">Text Editing Tools</h2>
        <select id="fontname">
            <option selected> </option>
            <option>Arial</option>
            <option>Arial Black</option>
            <option>Comic Sans MS</option>
            <option>Courier New</option>
            <option>Lucida Console</option>
            <option>Tahoma</option>
            <option>Times New Roman</option>
            <option>Trebuchet MS</option>
            <option>Verdana</option>
        </select>
        <select id="fontsize">
            <option selected> </option>
            <option value="1">10</option>
            <option value="2">13</option>
            <option value="3">16</option>
            <option value="4">18</option>
            <option value="5">24</option>
            <option value="6">32</option>
            <option value="7">48</option>
        </select>
    </div>
    <div id="editor"></div>
</div>

Creating the Editor

In this step we are going to do the inital render of the Editor, set it's content and focus it when it's ready.

  1. YUI().use('editor', 'editor-lists', 'createlink-base', function(Y) {
  2.  
  3. //Create the Base Editor
  4. var editor = new Y.EditorBase({
  5. content: '<strong>This is <em>a test</em></strong> <strong>This is <em>a test</em></strong> '
  6. });
  7. //Focusing the Editor when the frame is ready..
  8. editor.on('frame:ready', function() {
  9. this.focus();
  10. });
  11. //Rendering the Editor.
  12. editor.render('#editor');
  13.  
  14. });
YUI().use('editor', 'editor-lists', 'createlink-base', function(Y) {
 
    //Create the Base Editor
    var editor = new Y.EditorBase({
        content: '<strong>This is <em>a test</em></strong> <strong>This is <em>a test</em></strong> '
    });
    //Focusing the Editor when the frame is ready..
    editor.on('frame:ready', function() {
        this.focus();
    });
    //Rendering the Editor.
    editor.render('#editor');
 
});

Adding the Toolbar

Now we need to add the AlloyUI Toolbar Gallery module and render it with the buttons we want to add. Then we will listen for a button click event and call the execCommand method on the Editor to invoke that action.

  1. YUIConfig.modules = {
  2. 'gallery-aui-skin-base': {
  3. fullpath: 'http://yui.yahooapis.com/gallery-2010.06.07-17-52/build/gallery-aui-skin-base/css/gallery-aui-skin-base-min.css',
  4. type: 'css'
  5. },
  6. 'gallery-aui-skin-classic': {
  7. fullpath: 'http://yui.yahooapis.com/gallery-2010.06.07-17-52/build/gallery-aui-skin-classic/css/gallery-aui-skin-classic-min.css',
  8. type: 'css',
  9. requires: ['gallery-aui-skin-base']
  10. }
  11. };
  12.  
  13.  
  14. YUI(YUIConfig).use('gallery-aui-toolbar', 'editor', 'editor-lists', 'createlink-base', function(Y) {
  15.  
  16. //Create the Base Editor
  17. //SNIPPED FROM ABOVE
  18.  
  19. //Creating a new AlloyUI Toolbar
  20. var toolbar = new Y.Toolbar({
  21. activeState: true,
  22. children: [
  23. { icon: 'bold' },
  24. { icon: 'italic' },
  25. { icon: 'underline' },
  26. { icon: 'createlink' }
  27. ]
  28. }
  29. ).render('#toolbar');
  30.  
  31. //Listening for a button click on the Toolbar and firing an execCommand
  32. toolbar.on('buttonitem:click', function(e) {
  33. var cmd = e.target.get('icon');
  34. editor.focus();
  35. var ex_return = editor.execCommand(cmd, '');
  36.  
  37. });
  38.  
  39. });
YUIConfig.modules = {
    'gallery-aui-skin-base': {
        fullpath: 'http://yui.yahooapis.com/gallery-2010.06.07-17-52/build/gallery-aui-skin-base/css/gallery-aui-skin-base-min.css',
        type: 'css'
    },
    'gallery-aui-skin-classic': {
        fullpath: 'http://yui.yahooapis.com/gallery-2010.06.07-17-52/build/gallery-aui-skin-classic/css/gallery-aui-skin-classic-min.css',
        type: 'css',
        requires: ['gallery-aui-skin-base']
    }
};
 
 
YUI(YUIConfig).use('gallery-aui-toolbar', 'editor', 'editor-lists', 'createlink-base', function(Y) {
 
    //Create the Base Editor
    //SNIPPED FROM ABOVE
 
    //Creating a new AlloyUI Toolbar
    var toolbar = new Y.Toolbar({
			activeState: true,
			children: [
				{ icon: 'bold' },
				{ icon: 'italic' },
				{ icon: 'underline' },
				{ icon: 'createlink' }
			]
		}
	).render('#toolbar');
 
    //Listening for a button click on the Toolbar and firing an execCommand
    toolbar.on('buttonitem:click', function(e) {
        var cmd = e.target.get('icon');
        editor.focus();
        var ex_return = editor.execCommand(cmd, '');
 
    });
 
});

Hooking up the Events

First we will listen for a nodeChange event from the Editor (scoped to 2 DOM events) and call a method called updateButtons, which will update the toolbar's state to reflect that of the Editor. We will also attach a listener to the select lists to update the font family/size in the Editor.

  1.  
  2. //Create the Base Editor
  3. var editor = new Y.EditorBase({
  4. content: '<strong>This is <em>a test</em></strong> <strong>This is <em>a test</em></strong> '
  5. });
  6. //Hookup the Toolbar changes
  7. editor.after('nodeChange', function(e) {
  8. //Scoping the toolbar update to only a couple nodeChange events.
  9. //So it doesn't happen too often
  10. switch (e.changedType) {
  11. case 'keyup':
  12. case 'mousedown':
  13. updateButtons(e);
  14. break;
  15. }
  16. });
  17.  
  18. //Caching a reference to the options
  19. var f_options = Y.all('#fontname option');
  20. var s_options = Y.all('#fontsize option');
  21.  
  22. //Updating the toolbar with the current Editor state
  23. var updateButtons = function(e) {
  24. var tar = e.changedNode;
  25. if (tar) {
  26. var cmds = e.commands;
  27.  
  28. //Resetting the buttons to their proper states based on the commands from the event
  29. toolbar.each(function(b) {
  30. var st = false;
  31. if (cmds[b.get('icon')]) {
  32. st = true;
  33. }
  34. b.StateInteraction.set('active', st);
  35. });
  36.  
  37. var fname = e.fontFamily,
  38. size = e.fontSize;
  39.  
  40. //Updating the font family select
  41. f_options.item(0).set('selected', true);
  42. f_options.each(function(v) {
  43. var val = v.get('value').toLowerCase();
  44. if (val === fname.toLowerCase()) {
  45. v.set('selected', true);
  46. }
  47. });
  48.  
  49. //Updating the font size select
  50. s_options.item(0).set('selected', true);
  51. size = size.replace('px', '');
  52. s_options.each(function(v) {
  53. var val = v.get('value').toLowerCase(),
  54. txt = v.get('text');
  55. if (size === txt) {
  56. v.set('selected', true);
  57. }
  58. });
  59. }
  60. };
  61.  
  62. //Listening for the change event on the 2 select boxes
  63. Y.delegate('change', function(e) {
  64. var cmd = e.currentTarget.get('id'),
  65. val = e.currentTarget.get('value');
  66. editor.focus();
  67. var ex_return = editor.execCommand(cmd, val);
  68. }, '#toolbar', 'select');
  69.  
  70.  
 
    //Create the Base Editor
    var editor = new Y.EditorBase({
        content: '<strong>This is <em>a test</em></strong> <strong>This is <em>a test</em></strong> '
    });
    //Hookup the Toolbar changes
    editor.after('nodeChange', function(e) {
        //Scoping the toolbar update to only a couple nodeChange events.
        //So it doesn't happen too often
        switch (e.changedType) {
            case 'keyup':
            case 'mousedown':
                updateButtons(e);
                break;
        }
    });
 
    //Caching a reference to the options
    var f_options = Y.all('#fontname option');
    var s_options = Y.all('#fontsize option');
 
    //Updating the toolbar with the current Editor state
    var updateButtons = function(e) {
        var tar = e.changedNode;
        if (tar) {
            var cmds = e.commands;
 
            //Resetting the buttons to their proper states based on the commands from the event
            toolbar.each(function(b) {
                var st = false;
                if (cmds[b.get('icon')]) {
                    st = true;
                }
                b.StateInteraction.set('active', st);
            });
 
            var fname = e.fontFamily,
            size = e.fontSize;
 
            //Updating the font family select
            f_options.item(0).set('selected', true);
            f_options.each(function(v) {
                var val = v.get('value').toLowerCase();
                if (val === fname.toLowerCase()) {
                    v.set('selected', true);
                }
            });
 
            //Updating the font size select
            s_options.item(0).set('selected', true);
            size = size.replace('px', '');
            s_options.each(function(v) {
                var val = v.get('value').toLowerCase(),
                    txt = v.get('text');
                if (size === txt) {
                    v.set('selected', true);
                }
            });
        }
    };
 
    //Listening for the change event on the 2 select boxes
    Y.delegate('change', function(e) {
        var cmd = e.currentTarget.get('id'),
            val = e.currentTarget.get('value');
        editor.focus();
        var ex_return = editor.execCommand(cmd, val);
    }, '#toolbar', 'select');
 
 

Making look pretty

Here is the CSS used in this example to make the toolbar and the Editor look similar to the YUI 2 SimpleEditor.

  1. #editor_cont {
  2. width: 600px;
  3. border: 1px solid #999;
  4. margin: 2em;
  5. }
  6. #editor {
  7. height: 265px;
  8. }
  9. #toolbar {
  10. border-bottom: 1px solid #999;
  11. background-color: #F2F2F2;
  12. min-height: 25px;
  13. position: relative;
  14. }
  15. #toolbar select {
  16. position: relative;
  17. top: -4px;
  18. margin-right: 7px;
  19. }
  20. #fontname {
  21. margin-left: 7px;
  22. }
  23. #toolbar .yui3-icon {
  24. background: url("http://yui.yahooapis.com/2.8.1/build/editor/assets/skins/sam/editor-sprite.gif") no-repeat scroll 30px 30px transparent;
  25. }
  26. #toolbar .yui3-icon-bold {
  27. background-position: 0 -1px;
  28. }
  29. #toolbar .yui3-icon-italic {
  30. background-position:0 -37px;
  31. }
  32. #toolbar .yui3-icon-underline {
  33. background-position:0 -73px;
  34. }
  35. #toolbar .yui3-icon-createlink {
  36. background-position:0 -794px;
  37. }
  38. #toolbar .yui3-state-default,
  39. #toolbar .yui3-state-active,
  40. #toolbar .yui3-state-hover {
  41. margin-left: -1px;
  42. border-color: #808080;
  43. background:url("http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png") repeat-x scroll 0 0 transparent;
  44. }
  45. #toolbar .yui3-state-active {
  46. background-position: 0 -1700px;
  47. }
  48. #toolbar .yui3-state-hover {
  49. background-position: 0 -1300px;
  50. }
  51.  
  52. #toolbar h2 {
  53. letter-spacing:0;
  54. margin:0;
  55. color:#000000;
  56. font-size:100%;
  57. font-weight:bold;
  58. margin: 0;
  59. margin-bottom: 7px;
  60. padding: 0.3em 1em;
  61. text-align:left;
  62. background:url("http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png") repeat-x scroll 0 -206px transparent;
  63. }
    #editor_cont {
        width: 600px;
        border: 1px solid #999;
        margin: 2em;
    }
    #editor {
        height: 265px;
    }
    #toolbar {
        border-bottom: 1px solid #999;
        background-color: #F2F2F2;
        min-height: 25px;
        position: relative;
    }
    #toolbar select {
        position: relative;
        top: -4px;
        margin-right: 7px;
    }
    #fontname {
        margin-left: 7px;
    }
    #toolbar .yui3-icon {
        background: url("http://yui.yahooapis.com/2.8.1/build/editor/assets/skins/sam/editor-sprite.gif") no-repeat scroll 30px 30px transparent;
    }
    #toolbar .yui3-icon-bold {
        background-position: 0 -1px;
    }
    #toolbar .yui3-icon-italic {
        background-position:0 -37px;
    }
    #toolbar .yui3-icon-underline {
        background-position:0 -73px;
    }
    #toolbar .yui3-icon-createlink {
        background-position:0 -794px;
    }
    #toolbar .yui3-state-default, 
        #toolbar .yui3-state-active,
        #toolbar .yui3-state-hover {
        margin-left: -1px;
        border-color: #808080;
        background:url("http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png") repeat-x scroll 0 0 transparent;
    }
    #toolbar .yui3-state-active {
        background-position: 0 -1700px;
    }
    #toolbar .yui3-state-hover {
        background-position: 0 -1300px;
    }
 
    #toolbar h2 {
        letter-spacing:0;
        margin:0;
        color:#000000;
        font-size:100%;
        font-weight:bold;
        margin: 0;
        margin-bottom: 7px;
        padding: 0.3em 1em;
        text-align:left;
        background:url("http://yui.yahooapis.com/2.8.1/build/assets/skins/sam/sprite.png") repeat-x scroll 0 -206px transparent;
    }

Full Javascript Source

  1. var YUIConfig = {};
  2.  
  3. YUIConfig.modules = {
  4. 'gallery-aui-skin-base': {
  5. fullpath: 'http://yui.yahooapis.com/gallery-2010.06.07-17-52/build/gallery-aui-skin-base/css/gallery-aui-skin-base-min.css',
  6. type: 'css'
  7. },
  8. 'gallery-aui-skin-classic': {
  9. fullpath: 'http://yui.yahooapis.com/gallery-2010.06.07-17-52/build/gallery-aui-skin-classic/css/gallery-aui-skin-classic-min.css',
  10. type: 'css',
  11. requires: ['gallery-aui-skin-base']
  12. }
  13. };
  14.  
  15.  
  16. YUI(YUIConfig).use('gallery-aui-toolbar', 'node', 'editor', 'editor-lists', 'createlink-base', function(Y) {
  17.  
  18. //Create the Base Editor
  19. var editor = new Y.EditorBase({
  20. content: '<strong>This is <em>a test</em></strong> <strong>This is <em>a test</em></strong> '
  21. });
  22. //Hookup the Toolbar changes
  23. editor.after('nodeChange', function(e) {
  24. //Scoping the toolbar update to only a couple nodeChange events.
  25. //So it doesn't happen too often
  26. switch (e.changedType) {
  27. case 'keyup':
  28. case 'mousedown':
  29. updateButtons(e);
  30. break;
  31. }
  32. });
  33. //Focusing the Editor when the frame is ready..
  34. editor.on('frame:ready', function() {
  35. this.focus();
  36. });
  37. //Rendering the Editor.
  38. editor.render('#editor');
  39.  
  40. //Creating a new AlloyUI Toolbar
  41. var toolbar = new Y.Toolbar({
  42. activeState: true,
  43. children: [
  44. { icon: 'bold' },
  45. { icon: 'italic' },
  46. { icon: 'underline' },
  47. { icon: 'createlink' }
  48. ]
  49. }
  50. ).render('#toolbar');
  51.  
  52. //Listening for a button click on the Toolbar and firing an execCommand
  53. toolbar.on('buttonitem:click', function(e) {
  54. var cmd = e.target.get('icon');
  55. editor.focus();
  56. var ex_return = editor.execCommand(cmd, '');
  57.  
  58. });
  59.  
  60. //Listening for the change event on the 2 select boxes
  61. Y.delegate('change', function(e) {
  62. var cmd = e.currentTarget.get('id'),
  63. val = e.currentTarget.get('value');
  64. editor.focus();
  65. var ex_return = editor.execCommand(cmd, val);
  66. }, '#toolbar', 'select');
  67.  
  68. //Caching a reference to the options
  69. var f_options = Y.all('#fontname option');
  70. var s_options = Y.all('#fontsize option');
  71.  
  72. //Updating the toolbar with the current Editor state
  73. var updateButtons = function(e) {
  74. var tar = e.changedNode;
  75. if (tar) {
  76. var cmds = e.commands;
  77.  
  78. //Resetting the buttons to their proper states based on the commands from the event
  79. toolbar.each(function(b) {
  80. var st = false;
  81. if (cmds[b.get('icon')]) {
  82. st = true;
  83. }
  84. b.StateInteraction.set('active', st);
  85. });
  86.  
  87. var fname = e.fontFamily,
  88. size = e.fontSize;
  89.  
  90. //Updating the font family select
  91. f_options.item(0).set('selected', true);
  92. f_options.each(function(v) {
  93. var val = v.get('value').toLowerCase();
  94. if (val === fname.toLowerCase()) {
  95. v.set('selected', true);
  96. }
  97. });
  98.  
  99. //Updating the font size select
  100. s_options.item(0).set('selected', true);
  101. size = size.replace('px', '');
  102. s_options.each(function(v) {
  103. var val = v.get('value').toLowerCase(),
  104. txt = v.get('text');
  105. if (size === txt) {
  106. v.set('selected', true);
  107. }
  108. });
  109. }
  110. };
  111.  
  112. });
var YUIConfig = {};
 
YUIConfig.modules = {
    'gallery-aui-skin-base': {
        fullpath: 'http://yui.yahooapis.com/gallery-2010.06.07-17-52/build/gallery-aui-skin-base/css/gallery-aui-skin-base-min.css',
        type: 'css'
    },
    'gallery-aui-skin-classic': {
        fullpath: 'http://yui.yahooapis.com/gallery-2010.06.07-17-52/build/gallery-aui-skin-classic/css/gallery-aui-skin-classic-min.css',
        type: 'css',
        requires: ['gallery-aui-skin-base']
    }
};
 
 
YUI(YUIConfig).use('gallery-aui-toolbar', 'node', 'editor', 'editor-lists', 'createlink-base', function(Y) {
 
    //Create the Base Editor
    var editor = new Y.EditorBase({
        content: '<strong>This is <em>a test</em></strong> <strong>This is <em>a test</em></strong> '
    });
    //Hookup the Toolbar changes
    editor.after('nodeChange', function(e) {
        //Scoping the toolbar update to only a couple nodeChange events.
        //So it doesn't happen too often
        switch (e.changedType) {
            case 'keyup':
            case 'mousedown':
                updateButtons(e);
                break;
        }
    });
    //Focusing the Editor when the frame is ready..
    editor.on('frame:ready', function() {
        this.focus();
    });
    //Rendering the Editor.
    editor.render('#editor');
 
    //Creating a new AlloyUI Toolbar
    var toolbar = new Y.Toolbar({
			activeState: true,
			children: [
				{ icon: 'bold' },
				{ icon: 'italic' },
				{ icon: 'underline' },
				{ icon: 'createlink' }
			]
		}
	).render('#toolbar');
 
    //Listening for a button click on the Toolbar and firing an execCommand
    toolbar.on('buttonitem:click', function(e) {
        var cmd = e.target.get('icon');
        editor.focus();
        var ex_return = editor.execCommand(cmd, '');
 
    });
 
    //Listening for the change event on the 2 select boxes
    Y.delegate('change', function(e) {
        var cmd = e.currentTarget.get('id'),
            val = e.currentTarget.get('value');
        editor.focus();
        var ex_return = editor.execCommand(cmd, val);
    }, '#toolbar', 'select');
 
    //Caching a reference to the options
    var f_options = Y.all('#fontname option');
    var s_options = Y.all('#fontsize option');
 
    //Updating the toolbar with the current Editor state
    var updateButtons = function(e) {
        var tar = e.changedNode;
        if (tar) {
            var cmds = e.commands;
 
            //Resetting the buttons to their proper states based on the commands from the event
            toolbar.each(function(b) {
                var st = false;
                if (cmds[b.get('icon')]) {
                    st = true;
                }
                b.StateInteraction.set('active', st);
            });
 
            var fname = e.fontFamily,
            size = e.fontSize;
 
            //Updating the font family select
            f_options.item(0).set('selected', true);
            f_options.each(function(v) {
                var val = v.get('value').toLowerCase();
                if (val === fname.toLowerCase()) {
                    v.set('selected', true);
                }
            });
 
            //Updating the font size select
            s_options.item(0).set('selected', true);
            size = size.replace('px', '');
            s_options.each(function(v) {
                var val = v.get('value').toLowerCase(),
                    txt = v.get('text');
                if (size === txt) {
                    v.set('selected', true);
                }
            });
        }
    };
 
});

Copyright © 2010 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings