Несколько BBcode редакторов на одной странице

Всем привет, прошу помощи.
Есть Jquery BBcode редактор, все прекрасно работает до того момента, когда пытаешься вставить несколько редакторов на одной странице.
Подскажите, как сделать так, чтобы можно было встроить несколько редакторов на одной странице.
Спасибо за ответы.

Html часть
<script>
$(function() {
  $('#t1').bbcodeeditor({bbarea:'bbcode1'});
});
</script>
<div id="bbcode1">
<li data-tag="b">bold</li>
</div>
<textarea id="t1"></textarea>

<script>
$(function() {
  $('#t2').bbcodeeditor({bbarea:'bbcode2'});
});
</script>

<div id="bbcode2">
<li data-tag="b">bold</li>
</div>
<textarea id="t2"></textarea>


Javascript часть
(function ($) {
  var textarea;
  var options;
  var undo_pos = 0;
  var ie_cache = null;
  var ie_btn = null;
  var lb = '\n';

  $.fn.bbcodeeditor = function (opt) {
    options = $.extend({}, $.fn.bbcodeeditor.defaults, opt);
    textarea = this;
    bbcode = $('#' + options.bbarea + ' li');

    if (!$.browser.opera) textarea.keydown(key_handler);
    else textarea.keypress(key_handler);

    if ($.browser.msie) {
      $(document).mousedown(function (e) {
        if (ie_btn != null && ie_btn == textarea[0]) ie_cache = document.selection.createRange();
        ie_btn = e.target;
      });
    }
    if ($.browser.msie || $.browser.opera) lb = '\r\n';

    bbcode.click(function () {
      var tag = $(this).data('tag');
      if (tag == 'b') {
        print_bbc('bold', '[b]', '[/b]')
      }
    });

    return this;
  };

  function key_handler(e) {
    if ($.browser.msie) ie_cache = document.selection.createRange();

    if (e.keyCode == 13) {
      var start = selection_range().start;
      var line = textarea[0].value.substring(0, start).lastIndexOf('\n');
      line = (line == -1 ? 0 : line + 1);

      var matches = textarea[0].value.substring(line, start).match(/^\t+/g);
      if (matches != null) {
        e.preventDefault();
        var scroll_fix = fix_scroll_pre();
        var tabs = lb;
        for (var i = 0; i < matches[0].length; i++) tabs += '\t';
        textarea[0].value = textarea[0].value.substring(0, start) + tabs + textarea[0].value.substring(start);
        set_focus(start + tabs.length, start + tabs.length);
        fix_scroll(scroll_fix);
      }
    } else if (e.keyCode == 9) {
      e.preventDefault();

      var scroll_fix = fix_scroll_pre();

      var range = selection_range();

      if (range.start != range.end && textarea[0].value.substr(range.start, 1) == '\n') range.start++;

      var matches = textarea[0].value.substring(range.start, range.end).match(/\n/g); // check if multiline

      if (matches != null) {
        var index = textarea[0].value.substring(0, range.start).lastIndexOf(lb);
        var start_tab = (index != -1 ? index : 0);

        if (!e.shiftKey) {
          var tab = textarea[0].value.substring(start_tab, range.end).replace(/\n/g, '\n\t');

          textarea[0].value = (index == -1 ? '\t' : '') + textarea[0].value.substring(0, start_tab) + tab + textarea[0].value.substring(range.end);

          set_focus(range.start + 1, range.end + matches.length + 1);
        } else {
          var i = (textarea[0].value.substr((index != -1 ? index + lb.length : 0), 1) == '\t' ? 1 : 0);

          var removed = textarea[0].value.substring(start_tab, range.end).match(/\n\t/g, '\n');

          if (index == -1 && textarea[0].value.substr(0, 1) == '\t') {
            textarea[0].value = textarea[0].value.substr(1);
            removed.push(0);
          }

          var tab = textarea[0].value.substring(start_tab, range.end).replace(/\n\t/g, '\n');

          textarea[0].value = textarea[0].value.substring(0, start_tab) + tab + textarea[0].value.substring(range.end);

          set_focus(range.start - i, range.end - (removed != null ? removed.length : 0));
        }
      } else {
        if (!e.shiftKey) {
          textarea[0].value = textarea[0].value.substring(0, range.start) + '\t' + textarea[0].value.substring(range.start);
          set_focus(range.start + 1, range.start + 1);
        } else {
          var i_o = textarea[0].value.substring(0, range.start).lastIndexOf('\n');
          var i_s = (i_o == -1 ? 0 : i_o);

          var i_e = textarea[0].value.substring(i_s + 1).indexOf('\n');
          if (i_e == -1) i_e = textarea[0].value.length;
          else i_e += i_s + 1;

          if (i_o == -1) {
            var match = textarea[0].value.substring(i_s, i_e).match(/^\t/);
            var tab = textarea[0].value.substring(i_s, i_e).replace(/^\t/, '');
          } else {
            var match = textarea[0].value.substring(i_s, i_e).match(/\n\t/);
            var tab = textarea[0].value.substring(i_s, i_e).replace(/\n\t/, '\n');
          }

          textarea[0].value = textarea[0].value.substring(0, i_s) + tab + textarea[0].value.substring(i_e);

          if (match != null) set_focus(range.start - (range.start - 1 > i_o ? 1 : 0), range.end - ((range.start - 1 > i_o || range.start != range.end) ? 1 : 0));
        }
      }

      fix_scroll(scroll_fix);
    }
  }

  function fix_scroll_pre() {
    return {
      scrollTop: textarea.scrollTop(),
      scrollHeight: textarea[0].scrollHeight
    }
  }

  function fix_scroll(obj) {
    textarea.scrollTop(obj.scrollTop + textarea[0].scrollHeight - obj.scrollHeight);
  }

  function print_bbc(txt, open, close) {

    var range = selection_range();
    var scroll_fix = fix_scroll_pre();

    if (range.start != range.end) {
      txt = textarea[0].value;

      var re_b = new RegExp('\\[' + close.substring(2, close.length - 1) + '([^\\]]*?)\\]$', 'g');
      var re_a = new RegExp('^\\[\/' + close.substring(2, close.length - 1) + '\\]', 'g');

      var m_b = txt.substring(0, range.start).match(re_b);
      var m_a = txt.substring(range.end).match(re_a);

      if (m_b != null && m_a != null) {
        textarea[0].value = txt.substring(0, range.start).replace(re_b, '') + txt.substring(range.start, range.end) + txt.substring(range.end).replace(re_a, '');

        set_focus(range.start - m_b[0].length, range.end - m_b[0].length);
      } else {
        textarea[0].value = textarea[0].value.substr(0, range.start) + open + textarea[0].value.substring(range.start, range.end) + close + textarea[0].value.substr(range.end);

        set_focus(range.start + open.length, range.end + open.length);
      }
    } else {
      textarea[0].value = textarea[0].value.substring(0, range.start) + open + txt + close + textarea[0].value.substring(range.end);

      set_focus(range.start + open.length, range.start + open.length + txt.length);
    }

    fix_scroll(scroll_fix);
  };

  function set_focus(start, end) {
    if (!$.browser.msie) {
      textarea[0].setSelectionRange(start, end);
      textarea.focus();
    } else {
      var m_s = textarea[0].value.substring(0, start).match(/\r/g);
      m_s = (m_s != null ? m_s.length : 0);
      var m_e = textarea[0].value.substring(start, end).match(/\r/g);
      m_e = (m_e != null ? m_e.length : 0);

      var range = textarea[0].createTextRange();
      range.collapse(true);
      range.moveStart('character', start - m_s);
      range.moveEnd('character', end - start - m_e);
      range.select();
      ie_cache = document.selection.createRange();
    }
  };

  function selection_range() {
    if (!$.browser.msie) {
      return {
        start: textarea[0].selectionStart,
        end: textarea[0].selectionEnd
      }
    } else {
      if (ie_cache == null) return {
        start: textarea[0].value.length,
        end: textarea[0].value.length
      };

      var selection_range = ie_cache.duplicate();

      var before_range = document.body.createTextRange();
      before_range.moveToElementText(textarea[0]);
      before_range.setEndPoint("EndToStart", selection_range);

      var after_range = document.body.createTextRange();
      after_range.moveToElementText(textarea[0]);
      after_range.setEndPoint("StartToEnd", selection_range);

      var before_finished = false,
        selection_finished = false,
        after_finished = false;
      var before_text, untrimmed_before_text, selection_text, untrimmed_selection_text, after_text, untrimmed_after_text;

      before_text = untrimmed_before_text = before_range.text;
      selection_text = untrimmed_selection_text = selection_range.text;
      after_text = untrimmed_after_text = after_range.text;

      do {
        if (!before_finished) {
          if (before_range.compareEndPoints("StartToEnd", before_range) == 0) {
            before_finished = true;
          } else {
            before_range.moveEnd("character", -1)
            if (before_range.text == before_text) {
              untrimmed_before_text += "\r\n";
            } else {
              before_finished = true;
            }
          }
        }
        if (!selection_finished) {
          if (selection_range.compareEndPoints("StartToEnd", selection_range) == 0) {
            selection_finished = true;
          } else {
            selection_range.moveEnd("character", -1)
            if (selection_range.text == selection_text) {
              untrimmed_selection_text += "\r\n";
            } else {
              selection_finished = true;
            }
          }
        }
        if (!after_finished) {
          if (after_range.compareEndPoints("StartToEnd", after_range) == 0) {
            after_finished = true;
          } else {
            after_range.moveEnd("character", -1)
            if (after_range.text == after_text) {
              untrimmed_after_text += "\r\n";
            } else {
              after_finished = true;
            }
          }
        }

      } while ((!before_finished || !selection_finished || !after_finished));

      return {
        start: untrimmed_before_text.length,
        end: untrimmed_before_text.length + untrimmed_selection_text.length
      };
    }
  }

  $.fn.bbcodeeditor.defaults = {
    bbarea: 'bbcode'
  };

})(jQuery);
no image

Аноним

4 февраля, 16:39
555

Нет комментариев

Добавить комментарий
Вы не можете оставлять комментарии. Чтобы добавить комментарий, залогиньтесь или зарегистрируйтесь
Вы не можете голосовать. Чтобы проголосовать, залогиньтесь или зарегистрируйтесь

1 ответ

Я не знаток в плане расширения jQuery, но думаю, что проблема в этом:

(function ($) {
  var textarea; // указывает на текстовое поле
...
  $.fn.bbcodeeditor = function (opt) {
    options = $.extend({}, $.fn.bbcodeeditor.defaults, opt);
    textarea = this; // назначает текстовое поле


Получается, что после вызыва $('#textarea').bbcodeeditor(...) для разных полей, переменная textarea будет указывать на последнее поле, независимо от того, на кнопки каких полей будем потом нажимать. Решение 1 - сделать textarea массивом с id полей в качестве ключей. Решение 2 - при назначении обработчиков передавать в обработчики ссылку на нужное поле.

no image

Аноним

4 февраля, 16:39

Нет комментариев

Добавить комментарий
Вы не можете отвечать на вопросы. Чтобы ответить на вопрос, пожалуйста залогиньтесь или зарегистрируйтесь
Работа в Украине
Вакансии от WORK.ua
Модератор, контент-менеджер
Запорожье, Брама-Инженерные Системы, ООО
Инженер-программист информационной безопасности
Одесса, Пивденный, Акционерный Банк
Программист 1С, 30000 грн.
Киев, Агро-Регіон, ПЗ, ТОВ
Системный администратор
Черкассы, Теко Трейд (бренд Overseer)
Content Writer
Киев, Skyline Health Group
Программист 1С
Днепр, Сокол
Content manager, 8000 грн.
Киев, MyDutyFree LLC
Junior SMM-менеджер
Киев, Soda Solutions