Wysiwyg button with form #3

Print

Welcome to the second article in my tutorial about building a wysiwyg button for drupal 7 which enables use to inserting tokens.

This will be a four step tutorial

This next part will cover how to expand the javascript wysiwyg button to include a form with multiple textfields which will the generate the token for displaying our entity.

First we need a form which will allow the user to enter the id of the entity to display using the token. For this we will make a drupal form in our .module file.

 

 

  1. function ting_token_insert_form($form, &$form_state) {
  2.   drupal_add_library('system', 'ui.dialog');
  3.   $form['#tree'] = TRUE;
  4.  
  5.   $form['objects'] = array(
  6.     '#type' => 'fieldset',
  7.     '#title' => t('Entities'),
  8.     '#prefix' => '<div id="ting-token-fieldset-wrapper">',
  9.     '#suffix' => '</div>',
  10.   );
  11.  
  12.   $form['objects']['entity1'] = array(
  13.     '#type' => 'textfield',
  14.     '#title' => t('Entity id'),
  15.     '#default_value' => '',
  16.   );
  17.   $form['objects']['entity2'] = array(
  18.     '#type' => 'textfield',
  19.     '#title' => t('Entity id'),
  20.     '#default_value' => '',
  21.   );
  22.  
  23.   $form['submit'] = array(
  24.     '#type' => 'submit',
  25.     '#value' => t('Submit'),
  26.     '#attributes' => array(
  27.       'class' => array('form-save-ids'),
  28.     ),
  29.   );
  30.  
  31.   return $form;
  32. }

Now with the form ready we need to create a way for our javascript to retrieve it, and for this we need a menu hook and a custom content function.

  1. /**
  2.  * implements hook_menu
  3.  */
  4. function example_menu() {
  5.   $items = array();
  6.   $items['example/insert/nojs'] = array(
  7.     'page callback' => 'example_get_insert_form',
  8.     'page arguments' => array(2),
  9.     'access callback' => TRUE,
  10.     'type' => MENU_CALLBACK,
  11.   );
  12.   $items['example/insert/ajax'] = array(
  13.     'delivery callback' => 'ajax_deliver'
  14.   ) + $items['example/insert/nojs'];
  15.   return $items;
  16. }
  17.  
  18. function example_get_insert_form($ajax) {
  19.   $is_ajax = $ajax === 'ajax';
  20.   $form = drupal_get_form('example_insert_form', $ids);
  21.   if ($is_ajax) {
  22.     $form = drupal_render($form);
  23.     die($form);
  24.   }
  25.   else {
  26.     return $form;
  27.   }
  28. }

The menu hook is pretty strait forward, it uses drupals ajax system to handle the data return. The example_get_insert_form returns a rendered form is the parameter is ajax and a form render array if it's not. Now we are ready to rewrite our javascript.

  1. // $Id$
  2. (function ($) {
  3.  
  4. Drupal.wysiwyg.plugins['tokenInsert'] = {
  5.  
  6.   /**
  7.    * Return whether the passed node belongs to this plugin (note that "node" in this context is a JQuery node, not a Drupal node).
  8.    *
  9.    * We identify code managed by this example plugin by giving it the HTML class
  10.    * 'tokenInsert'.
  11.    */
  12.   isNode: function(node) {
  13.     res = $(node).is('.tokenInsert');
  14.     return ($(node).is('.tokenInsert'));
  15.   },
  16.  
  17.   /**
  18.    * Invoke is called when the toolbar button is clicked.
  19.    */
  20.   invoke: function(data, settings, instanceId) {
  21.     // Typically, an icon might be added to the WYSIWYG, which HTML gets added
  22.     // to the plain-text version.
  23.     if (data.format == 'html') {
  24.       var content = this._getIds(data.content);
  25.       if(content !== '') {
  26.         settings.ids = content
  27.       } else {
  28.         settings.ids = '';
  29.       }
  30.     }
  31.     else {
  32.       var content = '<!--exampleInsert-->';
  33.     }
  34.     if (typeof content !== 'undefined') {
  35.       Drupal.wysiwyg.plugins.tokenInsert.insert_form(data, settings, instanceId);
  36.     }
  37.   },
  38.   insert_form: function (data, settings, instanceId) {
  39.     // Location, where to fetch the dialog.
  40.     var aurl = Drupal.settings.basePath + 'example/insert/ajax';
  41.     var dialogdiv = $('<div id="example-insert-dialog"></div>');
  42.     dialogdiv.load(aurl, function(){
  43.       var dialogClose = function () {
  44.         try {
  45.           dialogdiv.dialog('destroy').remove();
  46.         } catch (e) {};
  47.       };
  48.       var btns = {};
  49.       btns[Drupal.t('Cancel')] = function () {
  50.         $(this).dialog("close");
  51.       };
  52.       var $this = this;
  53.       dialogdiv.find('.form-save-ids').click(function(evt) {
  54.         evt.preventDefault();
  55.         var ids = [],
  56.           $items = dialogdiv.find('#ting-token-fieldset-wrapper .form-text');
  57.         $items.each(function() {
  58.           ids.push($(this).val());
  59.         });
  60.         settings.tingIds = ids;
  61.         var content = Drupal.wysiwyg.plugins['tokenInsert']._getPlaceholder(settings);
  62.         Drupal.wysiwyg.instances[instanceId].insert(content);
  63.         dialogdiv.dialog("close");
  64.       });
  65.       dialogdiv.dialog({
  66.         modal: true,
  67.         autoOpen: false,
  68.         closeOnEscape: true,
  69.         resizable: true,
  70.         draggable: true,
  71.         autoresize: true,
  72.         namespace: 'jquery_ui_dialog_default_ns',
  73.         dialogClass: 'jquery_ui_dialog-dialog',
  74.         title: Drupal.t('Insert'),
  75.         buttons: btns,
  76.         width: '70%',
  77.         close: dialogClose
  78.       });
  79.       dialogdiv.dialog("open");
  80.       Drupal.attachBehaviors();
  81.     });
  82.   },
  83.   /**
  84.    * Replace all <!--exampleInsert--> tags with the icon.
  85.    */
  86.   attach: function(content, settings, instanceId) {
  87.     content = content.replace(/<!--exampleInsert-->/g, this._getPlaceholder(settings));
  88.     return content;
  89.   },
  90.  
  91.   /**
  92.    * Replace the icons with <!--exampleInsert--> tags in content upon detaching editor.
  93.    */
  94.   detach: function(content, settings, instanceId) {
  95.     var $content = $('<div>' + content + '</div>');
  96.     $.each($('.exampleInsert', $content), function (i, elem) {
  97.       elem.parentNode.removeChild(elem);
  98.     });
  99.     return $content.html();
  100.   },
  101.  
  102.   /**
  103.    * Helper function to return a HTML placeholder.
  104.    */
  105.   _getPlaceholder: function (settings) {
  106.     if(settings.ids) {
  107.       return '[ting:teaser:' + settings.ids.join() + ']';
  108.     }
  109.     return '';
  110.   },
  111.  
  112.   /**
  113.    * Helper function to return ids from a placeholder.
  114.    */
  115.   _getIds: function (content) {
  116.     var ids = ''
  117.     if(content.indexOf('[ting:teaser:') === 0 && content.indexOf(']') === (content.length - 1)) {
  118.       content = content.replace('[ting:teaser:', '');
  119.       content = content.replace(']', '');
  120.       ids = content.split(',');
  121.     }
  122.     return ids;
  123.   }
  124. };
  125.  
  126. })(jQuery);

We can now insert two entities using our new insert form, but we still want more. We want to be able to insert multiple ids using ajax to add and remove id's, so stay tuned for the next tutorial.

Category: 

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.