Избранные Материалы

7080

Linux :: AutoKey — простой, гибкий и универсальный инструмент десктоп-автоматизации

Linux :: AutoKey — простой, гибкий и универсальный инструмент десктоп-автоматизации

12745

Linux :: Тест-Драйв Synapse IM Alpha

Linux :: Тест-Драйв Synapse IM Alpha

11401

Релиз Ext GWT (GXT) 2.0

Релиз Ext GWT (GXT) 2.0

24734

Светлое будущее Java

Светлое будущее Java

5839

Фриланс :: Стоит ли?

Фриланс :: Стоит ли?

Ext GWT (GXT) :: Интеграция WYSIWYG-редактора TinyMCE

Постановка задачи

Те разработчики программного обеспечения, которые регулярно используют в своей работе популярный и мощный фреймворк Ext GWT (GXT), наверняка сталкивались с одним из его немногих недостатков — отсутствием стандартного компонента типа «WYSIWYG-редактор» (тоесть «живого» редактора, в случае работы с которым конечный результат виден в процессе непосредственного редактирования), предоставляющего средства для комфортного и быстрого редактирования HTML-контента «обогащенного» форматированным текстом, списками, ссылками, изображениями и т.д. Одним из наиболее популярных и многофункциональных редакторов такого типа является TinyMCE. (Рек.: ) А ведь было бы неплохо иметь возможность интегрировать его в Web-приложения, разрабатываемые с использованием фреймворка GXT, верно? Именно о том, как это осуществить, мы и поговорим в данной заметке.

Решение

Итак, решение вышеописанной задачи будет состоять в том, чтобы «обернуть» редактор TinyMCE, написанный на JavaScript, в «родной» GXT-компонент, представляющий из себя стандартный «филд»-компонент (класс-расширение абстрактного класса com.extjs.gxt.ui.client.widget.form.Field, который используется совместно со стандартным компонентом «панель-формы» com.extjs.gxt.ui.client.widget.form.FormPanel). В целом для выполнения задачи необходимо подключить к проекту JS-код самого редактора, выполнить некоторые настройки и реализовать сам компонент-»обертку». Преимущества такого подхода очевидны: реализовавши такой компонент единожды, его можно будет с легкостью использовать повторно сколь угодно раз в любом другом проекте, разрабатываемом с использованием фреймворка GXT. При этом время, затраченное на такую интеграцию, будет минимальным.

Инструкции и код

— Загружаем код TinyMCE (http://tinymce.moxiecode.com/download.php) и распаковываем его в директорию public соответствующего проекта

— В главном HTML-файле проекта, непосредственно перед кодом, который выглядит следующим образом:

<script language='javascript' src='gwtproject.nocache.js'></script>

(где GWTProject — название вашего проекта) вставляем следующий код:

<script language="javascript" type="text/javascript" src="tinymce/tiny_mce.js"></script>
<script language="javascript" type="text/javascript">
tinyMCE.init({
mode: "none", theme : "simple"
});
</script>

Важным моментом здесь является атрибут mode со значением none — в нашем случае мы должны использовать именно такую комбинацию, так как будем самостоятельно вызывать в коде создание редактора.

Документацию о расширенных настройках можно найти на сайте http://tinymce.moxiecode.com

Ниже следует код «филд»-компонента.

public class TinyMCE extends Field {

    protected String selector;

    @Override
    protected void onRender(Element target, int index) {
        if (el() == null) {
            // создаем текстовое поле
            setElement(DOM.createTextArea());
            el().insertInto(target, index);
            getElement().setAttribute("id", getId());
        }
        initTinyMCE(getId());
        super.onRender(target, index);
    }

    @Override
    public String getValue() {
        if (rendered) {
            super.setValue(getTextData(getId()));
        }
        return super.getValue();
    }

    @Override
    public void setValue(String value) {
        if (value == null) {
            value = "";
        }
        super.setValue(value);
        if (rendered) {
            updateContent(getId(), value);
        }
    }

    protected native String getTextData(String id) /*-{
        // используя API TinyMCE возвращаем текст, который находится в редакторе
        return $wnd.tinyMCE.getInstanceById(id).getContent({format : 'raw'});
    }-*/;

    protected native void updateContent(String id, String value) /*-{
        var editor = $wnd.tinyMCE.getInstanceById(id);
        if (editor) {
            editor.setContent(value);
        }
    }-*/;

    private native void initTinyMCE(String id)/*-{
        // нативно вызываем создание TinyMCE-редактора
        $wnd.tinyMCE.execCommand("mceAddControl", true, id);
        // опционально добавляем к редактору кастомную функциональность
        var editor = $wnd.tinyMCE.getInstanceById(id);
        if (editor) {
            var insertButton = editor.controlManager.get('insertimage');
            if (insertButton) {
                insertButton = $wnd.document.getElementById(insertButton.id);
                @com.company.gwt.ui.client.widget.tinymce.AbstractImageManager::addEventsSunk
                (Ljava/lang/String;Lcom/google/gwt/user/client/Element;)(id,insertButton);
            }
        }
    }-*/;

    @Override
    public void focus() {
        super.focus();
        focusMCE(getId());
    }

    protected native void focusMCE(String id) /*-{
        // передаем редактору фокус
        $wnd.tinyMCE.execCommand('mceFocus', true, id);
    }-*/;

    public String getSelector() {
        return selector;
    }

    public void setSelector(String selector) {
        this.selector = selector;
    }

}

Простой код для проверки работоспособности компонента:

public class UIWiget implements EntryPoint {
    public void onModuleLoad() {
        Viewport viewPort = new Viewport();
        viewPort.setLayout(new FitLayout());

        FormPanel formPanel = new FormPanel();
        final TinyMCE field = new TinyMCE();
        field.setValue("test");
        formPanel.add(field);
        formPanel.addButton(new Button("test",new SelectionListener(){
            public void componentSelected(ButtonEvent ce) {
                Window.alert(field.getValue());
            }}));
        viewPort.add(formPanel);
        RootPanel.get().add(viewPort);
    }
}

Вот и все. Выполнив вышеописанные несложные манипуляции и подключив реализованный компонент к вашему GXT-проекту, в него можно легко встроить удобный и функциональный WYSIWYG-редактор.

Удачи!

Tweet

Об авторе:
Профессиональный разработчик программного обеспечения, блоггер, адепт Open Source, казуальный путешественник, фотограф-аматор.
Подробнее »
Комментировать Послать ссылку на эту статью по e-mail