<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"  href="/xslt/final.xslt"?><html>
  <head>
    <title>Превращаем jwysiwyg  в fCKEditor</title>
    <meta name="css" content=""/>
    <meta name="js" content=""/>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="id" content="39"/>
    <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"/>
  </head>
  <body>
    <div class="main">
      <div class="wrap">
        <div class="L">
          <h1><a href="/">..</a> / Превращаем jwysiwyg  в fCKEditor</h1>
          <ol class="tags big">
            <li>
              <a href="/wysiwyg">wysiwyg</a>
            </li>
            <li>
              <a href="/jquery">jquery</a>
            </li>
            <li>
              <a href="/fckeditor">fckeditor</a>
            </li>
          </ol>
          <div class="myContent">В 98% случаев <u class="external" title="code.google.com/p/jwysiwyg/"> jWysiwyg</u>
хватает за глаза. Особенно
если удалить из него совершенно лишние функции. Но в 2% приходится
ставить монстроподобного FCKEditor (или TinyMCE). 1% - тогда когда
приходится иметь дело со сложным форматированием, и 1% - с тупым
клиентом, который "за свои деньги хочет иметь полное удовольствие".
 Кстати в большинстве распространенных CMS типа Joomla или
Drupal  можно ставить любой редактор из нескольких десятков.
Но только один.  А чтобы переключиться  приходится
лезть в настройки, что не всякому клиенту под силу. Вот я и решил
сделать плагин для jwysiwyg   который по нажатию
кнопки загружает (естественно динамически)   <u class="external" title="ckeditor.com/">CKEditor</u>,
который является jQuery-клоном самого распространенного
редактора FCKEditor.  <br/>
Если
вам он не нравится - подгрузите другой. Методика та же. <br/>
Рассмотрим код:<br/>
<br/>
<span style="font-weight: bold;">HTML:</span>
<pre class="brush: plain">&lt;div class="editor"&gt;           <br/> &lt;textarea&gt;Всё - одна маята&lt;/textarea&gt;<br/> &lt;/div&gt;<br/><br/>&lt;div class="editor"&gt;           <br/> &lt;textarea&gt;Бегут все реки в море переполнится &lt;/textarea&gt;<br/>&lt;/div&gt;</pre>
<span style="font-weight: bold;">
JavaScript</span>
<pre class="brush: plain">$(function(){<br/>jQuery.ajaxSettings.cache=true;<br/>if ($('.editor').size())<br/>{<br/>   $.getScript('js/common/jwysiwyg/jquery.wysiwyg.js',<br/>   function(){<br/>         $('.editor textarea').each(<br/>          function(i)<br/>           {<br/>            var e=$(this).wysiwyg({controls: {fullEditor : {visible : true,exec: function() {<br/>                // сохраняем контент в textarea<br/>                e.wysiwyg("saveContent").val();              <br/>                // проверяем наличие загруженного CKEditor<br/>                if (window.CKEDITOR)<br/>                  $(e).ckeditor();  // переключаем jwysiwyg на ckeditor<br/>                  else        // загружаем ckeditor<br/>                  {<br/>                  var script = document.createElement('script');<br/>                  script.setAttribute('type', 'text/javascript');<br/>                  script.setAttribute('src', "js/common/ckeditor/ckeditor.js");<br/>                  var head = document.getElementsByTagName('head').item(0);<br/>                  head.insertBefore(script, head.firstChild);<br/>                  // по таймеру отслеживаем загрузку CKEditor<br/>                  var max=0;<br/>                  var intervalID=setInterval(<br/>                  function(){<br/>                      if (max++&gt;100)<br/>                        alert('CK loading error') // ошибка при ожидании &gt; 25 секунд<br/>                        else<br/>                      if (!window.CKEDITOR)<br/>                        return; // продолжаем ожидание загрузки<br/>                        else<br/> { <br/> // переключаем jwysiwyg на ckeditor <br/> e.parent().find('div').hide();<br/>                         $(e).ckeditor(); <br/> }<br/>                      clearInterval(intervalID); // сбрасываем таймер<br/>                      }, 250);<br/>                  };<br/>            }}}});<br/>           });<br/>        });<br/>}<br/>})<br/></pre>
Если <a href="/article/37">в
примере плагином Clear MS Word </a>я
поступил по-хамски и вкрячил код
непосредственно в исходник, здесь я поступил как культурный человек и
расширил возможности редактора законным путем. Рассмотри шаг за шагом. <br/>
<br/>
<ol>
  <li> jwisiwg
 загружается динамически. Подробно об этом см. здесь. Каждый
textarea обрабатывается отдельно в цикле $.each</li>
  <li>новую кнопку я создал
законным путем, так же как добавлялись или убирались кнопки <a href="/article/20">здесь</a>
    <br/>
но в примере с настройками было все просто - там  определялись
кнопки с командами встроенными в режим designMode (визивиг). Здесь я
создаю новую команду. Новая команда задается следующим образом: <br/>
$('#text').wysiwyg({controls : {Element : { visible : true,exec:
function(){бла-бла}}}});   <br/>
Т.е. кроме видимости элемента (кнопки) тулбара задается функция,
которая будет выполняться при нажатии на нее. </li>
  <li> Далее идут две команды с
коментариями: <br/>
e.wysiwyg("saveContent").val(); // сохраняем контент в textarea<br/>
e.show().parent().find('div').hide(); // прячем jwisiwig/ Именно для
этого textarea завернут в контейнер, хотя конечно можно было бы и без
него обойтись. </li>
  <li>поскольку на странице может
быть несколько редакторов, кнопка вызова FCKEditor может быть нажата
несколько раз. Неизвестно надо это или не надо, но если ранее FCKEditor
был загружен, достаточно проверить этот факт и навесить этот редактор
на  texarea: <br/>
 if (window.CKEDITOR)  $(e).ckeditor();  </li>
  <li>Далее идет код,
слабопонятный большинству юзеров jQuery и не заставших времена, когда
приходилось писать на голом JavaScript . Четыре строки начиная с <br/>
document.createElement('script') <br/>
создают в head html-страницы элемент   <br/>
&lt;script language="JavaScript" src="бла-бла-бла"
type="text/javascript"&gt;&lt;/script&gt; <br/>
который обеспечивает загрузку CKEditor. Увы, традиционным способом
jquery подключить его не получается из-за проявления в этом
случае   <u class="external" title="dev.fckeditor.net/ticket/4348">бага</u>
CKEditor'а. Надеюсь, когда-нибудь его исправят. </li>
  <li>После того как был создан
элемент обеспечивающий подгрузку CKEditor необходимо ждать, когда
броузер погрузит и обработает этот скрипт. В зависимости от можности
компьютера и канала может пройти до нескольких секунд. <br/>
Чтобы не лезть в код CKEditor'а  в примере я запускаю таймер и
дожидаюсь в течение 25 секунд появления в DOM   CKEditor. Как
только обнаруживаю его  запускаю переопределение редактора,
подключенного к textarea <br/>
Способ жутковатый, и вообще проще
приписать дополнительный код в
CKEditor, который перегружает jwysiwyg что собственно я и сделал в
реальном приложении. Возможно, что TinyMCE возможно подключить более
естественно, но я не пробовал. Мне он не нравится. </li>
</ol>
Исходники можно найти в архиве <u class="external" title="2.x9.ru/wysiwyg.zip">wysiwyg.zip</u><br/>
<u class="external" title="2.x9.ru/wysiwyg-fckeditor.htm">Демо-версия</u></div>
          <ol class="tags big">
            <li class="date">2010-02-12</li>
            <li>
              <a href="/wysiwyg">wysiwyg</a>
            </li>
            <li>
              <a href="/jquery">jquery</a>
            </li>
            <li>
              <a href="/fckeditor">fckeditor</a>
            </li>
          </ol>
          <ol class="see">
            <li>
              <a href="#"><span>ckeditor.com/</span> - <b>Домашняя страница CKEditor</b></a>
            </li>
            <li>
              <a href="#"><span>code.google.com/p/jwysiwyg/</span> - <b>Домашняя страница jWYSIWYG</b></a>
            </li>
          </ol>
          <ul class="comment">
            <li id="a438" title="a0">
              <a name="Le capitaine Nemo" title="" rel="12.02.10"/>
              <div>1. Хорошо придумано, но плохо реализовано. Фокус с таймером настораживает. Если не удается FCK подключить может лучше TinyMCE? <br/>2. у jwyisiwig на выходе невалидный код. У FCK - валидный. Как с этим обходитесь?</div>
            </li>
            <li id="a439" title="a0">
              <a name="&#x418;&#x43D;&#x441;&#x430;&#x440;" title="" rel="12.02.10"/>
              <div>Должна быть индикация загрузки и пропадание окна не до начала загрузки, а после.</div>
            </li>
            <li id="a440" title="a439">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="12.02.10"/>
              <div>Спасибо за замечание. Уже поправил.</div>
            </li>
            <li id="a441" title="a438">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="12.02.10"/>
              <div>Самому не нравится. Но и лезть в код FCK тоже не очень хорошо. Хотя лезу конечно.</div>
            </li>
            <li id="a443" title="a0">
              <a name="Le capitaine Nemo" title="" rel="12.02.10"/>
              <div>Самоликвидация. Оригинальный плагин :)</div>
            </li>
            <li id="a446" title="a438">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="13.02.10"/>
              <div>Про  валидность. По-разному. Раньше не заморачивался, сейчас пропускаю все через валидатор. Пока было без проблем.</div>
            </li>
            <li id="a447" title="a0">
              <a name="Developer" title="" rel="14.02.10"/>
              <div>У себя в CMS я вообще не даю текст по умолчанию. Редактор вызываю только по нажатию кнопки в отдельном окне.</div>
            </li>
            <li id="a448" title="a447">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="14.02.10"/>
              <div>Я видел такое. Но мне кажется, что это приводит только к путанице и лишним движениям.</div>
            </li>
            <li id="a449" title="a0">
              <a name="Le capitaine Nemo" title="" rel="16.02.10"/>
              <div>Сервер плохо работает. Редактор не загрхается.</div>
            </li>
            <li id="a453" title="a0">
              <a name="&#x439;&#x446;&#x439;&#x443;&#x43A;&#x435;&#x43D;&#x433;" title="" rel="19.02.10"/>
              <div>Подскажите пожалуйста как подключить tinymce? И если можно без таймеров. Спасибо.</div>
            </li>
            <li id="a454" title="a453">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="19.02.10"/>
              <div>Да точно также. Я не вижу разницы. Хотя позже может и напишу.</div>
            </li>
            <li id="a470" title="a0">
              <a name="Le capitaine Nemo" title="" rel="15.03.10"/>
              <div>Супер. Это именно то что я искал. FCK реально достал.<br/>Вот еще вопрос. Как можно сделать так, чтобы брать FCK с отдельного домена? чтобы использовать его для некскольких проектов сразу?</div>
            </li>
            <li id="a471" title="a470">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="15.03.10"/>
              <div>Не знаю. Не пробовал. Как минимум там возникает проблема с подгрузкой картинок и кроссдоменной авторизацией. Т.ч. с полпинка задачу не решить. Надо ковыряться.</div>
            </li>
            <li id="a498" title="a0">
              <a name="Max89" title="" rel="28.04.10"/>
              <div>Хорошее решение, но недоработанное. <br/>Если вы выносите кнопку  на инструментальную панель, вы должны предусмотреть предупреждение пользователя о том что будет загружено что-то другое.</div>
            </li>
            <li id="a499" title="a498">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="28.04.10"/>
              <div>Вы правы. Я отказался от этой идеи и вынес возможность расширенного редактирования рядом с окном. заодно присобачил чекбокс, который позволяет запомнить редактор по умолчанию.<br/>Так оно как-то корректнее?</div>
            </li>
            <li id="a500" title="a499">
              <a name="Max89" title="" rel="28.04.10"/>
              <div>Наверное.Хотя я настройки умолчания прячу в настройки.</div>
            </li>
            <li id="a556" title="a0">
              <a name="&#x410;&#x43D;&#x442;&#x43E;&#x43D;" title="joomzone.ru" rel="04.09.10"/>
              <div>Использую JCE, но он режет код. Поэтому, когда надо вставить код контекстной рекламы и пр. сперва перехожу на html, а потом уж включаю редактирование. Как упростить это ?</div>
            </li>
            <li id="a557" title="a556">
              <a name="&#x418;&#x441;&#x430;&#x430;&#x43A; &#x422;&#x44B;&#x43D;&#x433;&#x44B;&#x43B;&#x447;&#x430;&#x432;" title="erum.ru" rel="05.09.10"/>
              <div>Это как-то неправильно вставлять в контент код для баннерной вставки. <br/>Контент - он для вечности. Баннерная вставка - она для сего момента. Их нужно как-то разделить. <br/>Имхо одно должно быть в шаблоне, другое где-то еще.<br/>Необходимость редактировать шаблоны онлайн какая-то сомнительная. Если бы было очень нужно их менять через редакторский интерфейс, то я бы ограничился каким-нибудь онлайновым файл-менеджером. В этом случае юзер получает возможность редактировать шаблон проверенным и любимым инструментом. Число ошибок при этом существенно сокращается.</div>
            </li>
            <li id="a666" title="a0">
              <a name="&#x41A;&#x430;&#x434;&#x44B;&#x440; &#x411;&#x43E;&#x431;&#x43E;" title="" rel="05.11.11"/>
              <div>zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg zdg sadf sdfg sdfg</div>
            </li>
            <li id="a667" title="a439">
              <a name="&#x427;&#x430;&#x433;&#x430;&#x442;&#x430;&#x439; &#x41A;&#x43E;&#x437;&#x43E;&#x43B;&#x443;&#x43F;" title="" rel="05.11.11"/>
              <div>qwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe rqwerqwe rqwerq werqwer qwerqwer qwerqwe r</div>
            </li>
          </ul>
        </div>
      </div>
      <div class="R">
        <a href="/" title="&#x41D;&#x430; &#x433;&#x43B;&#x430;&#x432;&#x43D;&#x443;&#x44E;"/>
      </div>
    </div>
    <div id="li"/>
  </body>
</html>

