closedquestion-8.x-3.x-dev/assets/js/libraries/jquery/jquery.simpleTableEdit.js

assets/js/libraries/jquery/jquery.simpleTableEdit.js
/**
 * simpleTableEdit
 * based on boilerplate version 1.3
 * @param {object} $ A jQuery object
 **/
(function ($) {
  "use strict"; //ECMA5 strict modus

  $.simpleTableEdit = function (element, settings) {
    /* define vars
     */

    /* this object will be exposed to other objects */
    var publicObj = this;

    //the version number of the plugin
    publicObj.version = "1.0";

    /* this object holds functions used by the plugin boilerplate */
    var _helper = {
      /**
       * Call hooks, additinal parameters will be passed on to registered plugins
       * @param {string} name
       */
      doHook: function (name) {
        var i;
        var pluginFunctionArgs = [];

        /* remove first two arguments */
        for (i = 1; i < arguments.length; i++) {
          pluginFunctionArgs.push(arguments[i]);
        }

        /* call plugin functions */
        if (_globals.plugins !== undefined) {
          /* call plugins */
          $.each(_globals.plugins, function (simpleTableEdit, extPlugin) {
            if (
              extPlugin.__hooks !== undefined &&
              extPlugin.__hooks[name] !== undefined
              ) {
              extPlugin.__hooks[name].apply(publicObj, pluginFunctionArgs);
            }
          });
        }

        /* trigger event on main element */
        _globals.$element.trigger(name, pluginFunctionArgs);
      },
      /**
       * Initializes the plugin
       */
      doInit: function () {
        _helper.doHook(
          "simpleTableEdit.beforeInit",
          publicObj,
          element,
          settings
          );
        publicObj.init();
        _helper.doHook("simpleTableEdit.init", publicObj);
      },
      /**
       * Loads an external script
       * @param {string} libName
       * @param {string} errorMessage
       */
      loadScript: function (libName, errorMessage) {
        /* remember libname */
        _cdnFilesToBeLoaded.push(libName);

        /* load script */
        $.ajax({
          type: "GET",
          url: _globals.dependencies[libName].cdnUrl,
          success: function () {
            /* forget libname */
            _cdnFilesToBeLoaded.splice(_cdnFilesToBeLoaded.indexOf(libName), 1); //remove element from _cdnFilesToBeLoaded array

            /* call init function when all scripts are loaded */
            if (_cdnFilesToBeLoaded.length === 0) {
              _helper.doInit();
            }
          },
          fail: function () {
            console.error(errorMessage);
          },
          dataType: "script",
          cache: "cache"
        });
      },
      /**
       * Registers a plugin
       * @param {string} name Name of plugin, must be unique
       * @param {object} object An object {("functions": {},) (, "hooks: {})}
       */
      registerPlugin: function (name, object) {
        var plugin;
        var hooks;

        /* reorder plugin */
        hooks = $.extend(true, {}, object.hooks);
        plugin = object.functions !== undefined ? object.functions : {};
        plugin.__hooks = hooks;

        /* add plugin */
        _globals.plugins[name] = plugin;
      },
      /**
       * Calls a plugin function, all additional arguments will be passed on
       * @param {string} simpleTableEdit
       * @param {string} pluginFunctionName
       */
      callPluginFunction: function (simpleTableEdit, pluginFunctionName) {
        var i;

        /* remove first two arguments */
        var pluginFunctionArgs = [];
        for (i = 2; i < arguments.length; i++) {
          pluginFunctionArgs.push(arguments[i]);
        }

        /* call function */
        _globals.plugins[simpleTableEdit][pluginFunctionName].apply(
          null,
          pluginFunctionArgs
          );
      },
      /**
       * Checks dependencies based on the _globals.dependencies object
       * @returns {boolean}
       */
      checkDependencies: function () {
        var dependenciesPresent = true;
        for (var libName in _globals.dependencies) {
          var errorMessage =
            "jquery.simpleTableEdit: Library " +
            libName +
            " not found! This may give unexpected results or errors.";
          var doesExist = $.isFunction(_globals.dependencies[libName])
            ? _globals.dependencies[libName]
            : _globals.dependencies[libName].doesExist;
          if (doesExist.call() === false) {
            if (
              $.isFunction(_globals.dependencies[libName]) === false &&
              _globals.dependencies[libName].cdnUrl !== undefined
              ) {
              /* cdn url provided: Load script from external source */
              _helper.loadScript(libName, errorMessage);
            }
            else {
              console.error(errorMessage);
              dependenciesPresent = false;
            }
          }
        }
        return dependenciesPresent;
      }
    };
    /* keeps track of external libs loaded via their CDN */
    var _cdnFilesToBeLoaded = [];

    /* this object holds all global variables */
    var _globals = {};

    /* handle settings */
    var defaultSettings = {};

    _globals.settings = {};

    if ($.isPlainObject(settings) === true) {
      _globals.settings = $.extend(true, {}, defaultSettings, settings);
    }
    else {
      _globals.settings = defaultSettings;
    }

    /* this object contains a number of functions to test for dependencies,
     * doesExist function should return TRUE if the library/browser/etc is present
     */
    _globals.dependencies = {
      /* check for jQuery 1.6+ to be present */
      "jquery1.6+": {
        doesExist: function () {
          var jqv, jqv_main, jqv_sub;
          if (window.jQuery) {
            jqv = jQuery().jquery.split(".");
            jqv_main = parseInt(jqv[0], 10);
            jqv_sub = parseInt(jqv[1], 10);
            if (jqv_main > 1 || (jqv_main === 1 && jqv_sub >= 6)) {
              return true;
            }
          }
          return false;
        },
        cdnUrl: "http://code.jquery.com/jquery-git1.js"
      }
    };
    _helper.checkDependencies();

    //this object holds all plugins
    _globals.plugins = {};

    /* register DOM elements
     * jQuerified elements start with $
     */
    _globals.$element = $(element);

    _globals.tableTemplate = "<table border=1><tr><th>Header 1</th><th>Header 2</th></tr><tr><td>Cell A</td><td>Cell B</td></tr></table><p>&nbsp;</p>";

    /**
     * Init function
     **/
    publicObj.init = function () {

    };

    /**
     * Adds a table.
     */
    publicObj.addTable = function () {
      var $activeTable = getActiveTable();
      if ($activeTable.length === 0) {
        addEmptyTable();
        return;
      }
    }

    /**
     * Adds a row.
     */
    publicObj.addRow = function () {
      var $activeTable = getActiveTable();
      var $activeRow = getActiveRow();
      var $newRow = getRowClone();

      // No table.
      if ($activeTable.length === 0) {
        return;
      }

      if ($activeRow.length === 1) {
        // Add after active row.
        $activeRow.after($newRow);
      }
      else {
        // Add at end of table.
        $activeTable.append($newRow);
      }
    };

    /**
     * Changes the selected cell into a header cell or vice versa.
     */
    publicObj.toggleHeaderCell = function () {
      var $activeNode = getActiveNode();
      var $replacer, $cell;

      // Determine what to replace with what.
      $cell = $activeNode.closest("td", _globals.$element[0]);
      if ($cell.length > 0) {
        $replacer = $('<th />');
      }
      else {
        $cell = $activeNode.closest("th", _globals.$element[0]);
        if ($cell.length > 0) {
          $replacer = $('<td />');
        }
      }

      // Do the trick.
      if ($replacer) {
        $replacer.append($cell.html());
        $cell.replaceWith($replacer);

        setCaret($replacer[0]); // Set caret in new cell.
      }
    };

    /**
     * Removes the currently selected row.
     */
    publicObj.removeRow = function () {
      var $activeRow = getActiveRow();
      var $activeTable = getActiveTable();
      var $nextRow, $prevRow;

      if ($activeTable.length === 0) {
        return;
      }

      if ($activeRow.length === 1) {
        /* Set cursor in different cell than current one */
        $nextRow = $activeRow.next('tr');
        $prevRow = $activeRow.prev('tr');
        if ($nextRow.length === 1) {
          setCaret($nextRow.find('td,th').eq(0)[0]);
        }
        else if ($prevRow.length === 1) {
          setCaret($prevRow.find('td,th').eq(0)[0]);
        }
        else {
          setCaret($activeTable.find('td').eq(0)[0]);
        }

        /* Remove row */
        $activeRow.remove();
      }
      removeTableIfEmpty();
    };

    /**
     * Adds a column to the active table
     */
    publicObj.addColumn = function () {
      var activeColumnIndex = getActiveColumnIndex() + 1;
      var $activeTable = getActiveTable();

      if ($activeTable.length === 0) {
        return;
      }

      if ($activeTable.length === 1) {
        if (activeColumnIndex >= 0) {
          /* Add headers */
          $activeTable.find("tr th:nth-child(" + activeColumnIndex + ")").each(function () {
            $(this).after("<th>&nbsp;</th>");
          });

          /* Add cells */
          $activeTable.find("tr td:nth-child(" + activeColumnIndex + ")").each(function () {
            $(this).after("<td>&nbsp;</td>");
          });
        }
      }
    };



    /**
     * Adds a column to the active table
     */
    publicObj.removeColumn = function () {
      var $activeTable = getActiveTable();
      var activeColumnIndex = getActiveColumnIndex();
      var $activeNode = getActiveNode();
      var $prevCell, $nextCell;
      if ($activeTable.length === 0) {
        return;
      }

      if ($activeTable.length === 1) {
        /* Set cursor in different cell than current one */
        $prevCell = $activeNode.prev('td,th');
        $nextCell = $activeNode.next('td,th');
        if ($prevCell.length === 1) {
          setCaret($prevCell[0]);
        }
        else if ($nextCell.length === 1) {
          setCaret($nextCell[0]);
        }
        else {
          setCaret($activeTable.find('td').eq(0)[0]);
        }

        /* Remove headers */
        $activeTable.find("tr").each(function () {
          $(this)
            .find("th")
            .eq(activeColumnIndex)
            .remove();
        });

        /* Remove cells */
        $activeTable.find("tr").each(function () {
          $(this)
            .find("td")
            .eq(activeColumnIndex)
            .remove();
        });
      }

      removeTableIfEmpty();
    };

    /**
     * Returns whether cursor is inside table.
     *
     * @returns {Boolean}
     */
    publicObj.inTable = function () {
      return getActiveTable().length !== 0
    };


    /**
     * Adds an empty table.
     */
    function addEmptyTable() {
      var $activeNode = getActiveNode();
      if ($activeNode[0] === element) {
        var sel = window.getSelection();
        var range = sel.getRangeAt(0);
        range.insertNode(jQuery(_globals.tableTemplate)[0]);
      }
      else {
        // Add table after active node.
        if (isBlockLevelElement($activeNode[0])) {
          $activeNode.after(_globals.tableTemplate);
        }
        else {
          // Fixes IE bug sometimes inserting the table inside an inline element.
          $activeNode.parents().filter(function () {
            return $(this).css("display") === "block";
          }).first().after(_globals.tableTemplate);
        }
      }
    }

    /**
     * Returns whether DOM element is block-level or inline.
     *
     * @param {object} domEl
     * @returns {Boolean}
     */
    function isBlockLevelElement(domEl) {
      var displayStyle;
      if (domEl) { // Only if the element exists
        if (window.getComputedStyle) {
          displayStyle = window.getComputedStyle(domEl, null).getPropertyValue('display');
        }
        else {
          displayStyle = domEl.currentStyle.display;
        }
      }
      return displayStyle === 'block';
    }

    /**
     * Removes an empty table.
     */
    function removeTableIfEmpty() {
      var $activeTable = getActiveTable();
      if ($activeTable.length === 1 && (($activeTable.find('td').length === 0 && $activeTable.find('th').length === 0) || $activeTable.find('tr').length === 0)) {
        $activeTable.remove();
      }
    }

    /**
     * Get a row clone
     *
     * @return {object} A jQuery object.
     */
    function getRowClone() {
      var $activeTable = getActiveTable();
      if ($activeTable.length !== 0) {
        var $newTr = jQuery("tr", $activeTable).last().clone();
        $newTr.find('td,th').html('&nbsp;');
        return $newTr;
      }
      else {
        return jQuery("");
      }
    }

    /**
     * Returns the active table in a contenteditable field.
     *
     * @return {object} A jQuery object.
     **/
    function getActiveTable() {
      var $activeNode = getActiveNode();
      if ($activeNode) {
        return $activeNode.closest("table", _globals.$element[0]);
      }
      return jQuery("");
    }

    /**
     * Returns the active row in a contenteditable field.
     *
     * @return {object} A jQuery object.
     **/
    function getActiveRow() {
      var $activeNode = getActiveNode();
      if ($activeNode) {
        return $activeNode.closest("tr", _globals.$element[0]);
      }
      return jQuery("");
    }

    /**
     * Returns the active table in a contenteditable field.
     *
     * @return {mixed} Column index or FALSE.
     **/
    function getActiveColumnIndex() {
      var $activeNode = getActiveNode();
      if ($activeNode) {
        return $activeNode.closest("td,th", _globals.$element[0]).index();
      }
      return false;
    }

    /**
     * Returns the active node in a contenteditable field.
     *
     * $return {object}  A JQuery object.
     **/
    function getActiveNode() {
      var selection;
      var returnNode;
      if (window.getSelection) {
        selection = window.getSelection();
      }
      else if (document.selection && document.selection.type != "Control") {
        selection = document.selection;
      }
      if (selection.anchorNode && selection.anchorNode.nodeType === 3) {
        returnNode = selection.anchorNode.parentNode;
      }
      else {
        returnNode = selection.anchorNode;
      }

      return jQuery(returnNode);
    }


    /**
     * Sets the caret inside a DOM element
     * @param {object} domEl
     *   A DOM object.
     * @credits
     *   https://stackoverflow.com/questions/6249095/how-to-set-caretcursor-position-in-contenteditable-element-div?answertab=active#tab-top
     * @returns {undefined}
     */
    function setCaret(domEl) {
      if (domEl) {
        var range = document.createRange();
        var sel = window.getSelection();
        range.setStart(domEl, 0);
        range.collapse(true);
        sel.removeAllRanges();
        sel.addRange(range);
      }
      _globals.$element[0].focus();

    }

    /* initialize simpleTableEdit
     */
    if (_cdnFilesToBeLoaded.length === 0) {
      _helper.doInit();
    }
  };

  $.fn.simpleTableEdit = function (settings) {
    return this.each(function () {
      if (undefined === $(this).data("simpleTableEdit")) {
        var plugin = new $.simpleTableEdit(this, settings);
        $(this).data("simpleTableEdit", plugin);
      }
    });
  };
})(jQuery);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc