テキストエディタ
Framework7には、タッチフレンドリーなリッチテキストエディタコンポーネントが搭載されています。このコンポーネントは、最新の "contenteditable "APIに基づいているので、そのままどこでも動作するはずです。
基本的な書式設定機能を備えています。しかし、その機能は必要に応じて簡単に拡張・カスタマイズすることができます。
テキストエディタのレイアウト
<div class="text-editor">
<div class="text-editor-content" contenteditable></div>
</div>
エディタのサイズを変更できるようにするには、text-editor-resizable
クラスをエディタ要素に追加する必要があります。
<!-- text-editor-resizable "クラスの追加 -->
<div class="text-editor text-editor-resizable">
<div class="text-editor-content" contenteditable></div>
</div>
テキストエディタアプリのメソッド
テキストエディタを操作するために、関連するアプリのメソッドを見てみましょう。
app.textEditor.create(parameters)- テキストエディタのインスタンス作成
- parameters - object. テキストエディターのパラメーターを持つオブジェクト
作成したテキストエディタのインスタンスを返すメソッド
app.textEditor.destroy(el)- テキストエディターインスタンスの破棄
- el - HTMLElementまたはstring(CSSセレクタ付き)またはobject。破棄するテキストエディタ要素またはテキストエディタインスタンスです。
app.textEditor.get(el)- HTML要素でテキストエディタのインスタンスを取得
- el - HTMLElement または string (CSS Selectorを使用). テキストエディタの要素です。
メソッドはテキスト・エディターのインスタンスを返します。
例:
var textEditor = app.textEditor.create({
el: '#my-text-editor',
value: <code><p>Hello</p></code>,
});
テキストエディタのパラメータ
ここでは、テキスト・エディタで使用できるすべてのパラメータの一覧を見てみましょう。
Parameter | Type | Default | Description |
---|---|---|---|
el | HTMLElement string | テキスト・エディタの要素。HTML要素、またはエディタ要素のCSSセレクタを持つ文字列。 | |
value | string | テキストエディタの初期HTMLコンテンツの値。初期値は、
| |
placeholder | string | 空のときに表示されるエディタのプレースホルダーコンテンツ。デフォルトでは指定されていません。 | |
mode | string | toolbar | テキストエディタのボタンのモードです。次のようになります。
|
buttons | array | エディタボタンを持つ配列、または、エディタボタンを持つ配列(グループ)の配列です。デフォルトでは、すべてのボタンが有効で、そのデフォルト値は:
| |
dividers | boolean | true | ボタングループの間に、視覚的な仕切りを追加します。 |
imageUrlText | string | Insert image URL | イメージのURLリクエストに表示されるプロンプトテキスト |
linkUrlText | string | Insert link URL | リンクのURLリクエスト時に表示されるプロンプトテキスト |
clearFormattingOnPaste | boolean | true | 有効にすると、クリップボードからのペースト時にフォーマットをクリアします。 |
customButtons | object | カスタムボタンを持つオブジェクトです。オブジェクトのプロパティkeyには、 例えば、
| |
on | object | イベントハンドラを持つオブジェクトです。例えば、以下のようになります。
|
以下のパラメータは、すべてのテキストエディタのデフォルトを設定するために、アプリのグローバルパラメータの textEditor
プロパティで使用できることに注意してください。例えば、以下のようになります。
var app = new Framework7({
textEditor: {
buttons: ['bold', 'italic'],
}
});
テキストエディタのメソッドとプロパティ
テキストエディタを初期化すると、その初期化されたインスタンスが変数(上記の例では textEditor
変数)に格納され、便利なメソッドやプロパティが用意されます。
Properties | |
---|---|
textEditor.app | グローバルアプリのインスタンスへのリンク |
textEditor.el | テキストエディタコンテナのHTML要素 |
textEditor.$el | テキストエディタコンテナのHTML要素を持つDom7インスタンス |
textEditor.contentEl | テキストエディタのコンテンツ (contenteditalbe ) HTML要素 |
textEditor.$contentEl | テキストエディタコンテンツ(contenteditalbe )を持つDom7インスタンスのHTML要素 |
textEditor.value | テキストエディタのHTML値 |
textEditor.params | 初期化パラメータを持つオブジェクト |
Methods | |
textEditor.setValue(value) | 新しいテキストエディタの値を設定します。value`はHTMLの文字列です。 |
textEditor.getValue() | 現在のテキストエディタの値を返します |
textEditor.clearValue() | テキストエディタの値をクリアします |
textEditor.getSelectionRange() | 現在の選択範囲を返します。 |
textEditor.setSelectionRange(range) | 渡された範囲に基づいて選択範囲を設定します。 |
textEditor.destroy() | テキストエディタのインスタンスを破棄し、すべてのイベントを削除する |
textEditor.on(event, handler) | イベントハンドラの追加 |
textEditor.once(event, handler) | 発生後に削除されるイベント・ハンドラーの追加 |
textEditor.off(event, handler) | イベントハンドラの削除 |
textEditor.off(event) | 指定されたイベントのハンドラをすべて削除する |
textEditor.emit(event, ...args) | インスタンスでのイベント発生 |
テキストエディタのイベント
テキスト・エディタは、テキスト・エディタ要素上の以下のDOMイベントと、アプリとテキスト・エディタ・インスタンス上のイベントを発生させます。
DOMイベント
Event | Description |
---|---|
texteditor:init | イベントは、エディタの初期化時に発生します。 |
texteditor:change | エディタの値が変更されたときにイベントが発生します。 |
texteditor:input | イベントは、エディタのコンテンツ "input "イベントでトリガされます。 |
texteditor:focus | イベントは、エディタのコンテンツのフォーカスでトリガされる。 |
texteditor:blur | イベントは、エディタのコンテンツのブラーでトリガされます。 |
texteditor:buttonclick | イベントは、エディタボタンのクリックでトリガされます。 |
texteditor:keyboardopen | イベントは、エディタキーボードツールバーが表示されたときにトリガされます。 |
texteditor:keyboardclose | イベントは、エディタキーボードツールバーが消えたときにトリガされます。 |
texteditor:popoveropen | イベントはエディタポップオーバーオープンでトリガされます。 |
texteditor:popoverclose | イベントはエディタポップオーバーが閉じた時に発生します。 |
texteditor:beforedestroy | イベントはテキストエディタのインスタンスが破壊される直前に発生します。 |
アプリとテキスト・エディタ・インスタンスのイベント
テキスト・エディタ・インスタンスは、セルフ・インスタンスとアプリ・インスタンスの両方でイベントを発行します。アプリのインスタンスのイベントは、同じ名前でプレフィックスが textEditor
となっています。
Event | Target | Arguments | Description |
---|---|---|---|
init | textEditor | (editor) | イベントはエディタの初期化時に発生します。 |
textEditorInit | app | ||
change | textEditor | (editor) | イベントはエディタの初期化時にトリガされます。 |
textEditorChange | app | ||
input | textEditor | (editor) | イベントは、エディタのコンテンツの "input" イベントでトリガされます。 |
textEditorInput | app | ||
focus | textEditor | (editor) | イベントは、エディタのコンテンツフォーカスでトリガされます。 |
textEditorFocus | app | ||
blur | textEditor | (editor) | イベントは、エディタのコンテンツのブラーでトリガされます。 |
textEditorBlur | app | ||
buttonClick | textEditor | (editor, button) | イベントはエディタ・ボタンのクリックでトリガされます。 第2引数としてイベント・ハンドラはクリックされたボタンのidを受け取ります、例えば bold 。 |
textEditorButtonClick | app | ||
keyboardOpen | textEditor | (editor) | イベントはエディタのキーボードツールバーが表示された時に発生します。 |
textEditorKeyboardOpen | app | ||
keyboardClose | textEditor | (editor) | イベントはエディタキーボードツールバーが消えたときにトリガーされます。 |
textEditorKeyboardClose | app | ||
popoverOpen | textEditor | (editor) | イベントはエディタポップオーバーオープンでトリガされます。 |
textEditorPopoverOpen | app | ||
popoverClose | textEditor | (editor) | イベントはエディタのポップオーバーが閉じた時に発生します。 |
textEditorPopoverClose | app | ||
beforeDestroy | textEditor | (editor) | イベントはテキストエディタのインスタンスが破壊される直前に発生します。 |
textEditorBeforeDestroy | app |
テキストエディタの自動初期化
テキストエディタAPIを使用する必要がなく、テキストエディタがページ内にあり、ページの初期化時にDOMに表示される場合は、追加の text-editor-init
クラスを追加するだけで、自動初期化することができます。
<!-- text-editor-initクラスの追加 -->
<div class="text-editor text-editor-init">
<div class="text-editor-content" contenteditable></div>
</div>
この場合、作成されたテキストエディタのインスタンスにアクセスするには、app.textEditor.get
アプリメソッドを使用します。
var textEditor = app.textEditor.get('.my-text-editor');
if (!textEditor.value) {
// 何かをする
}
auto initを使用する際には、追加のパラメータを渡す必要があるかもしれません。これは、パネル要素のdata-
属性を使って行うことができます。
<!-- data-属性で設定するパラメータ -->
<div
class="text-editor text-editor-init"
data-mode="popover"
data-placeholder="Description"
>
...
</div>
キャメルケースで使われているパラメータ、例えば imageUrlText は、data-属性では data-image-url-text のようにケバブケースで使われます。
CSS Variables
Below is the list of related CSS variables (CSS custom properties).
:root {
--f7-text-editor-font-size: inherit;
--f7-text-editor-font-weight: inherit;
--f7-text-editor-border-width: 1px;
--f7-text-editor-height: 250px;
--f7-text-editor-margin: 16px;
--f7-text-editor-padding: 8px;
--f7-text-editor-button-bg-color: transparent;
--f7-text-editor-button-size: 28px;
--f7-text-editor-button-icon-size: 20px;
--f7-text-editor-button-margin: 2px;
--f7-text-editor-button-border-radius: 2px;
--f7-text-editor-text-color: #000;
--f7-text-editor-bg-color: #fff;
--f7-text-editor-border-color: rgba(0, 0, 0, 0.1);
--f7-text-editor-toolbar-bg-color: #fff;
--f7-text-editor-button-text-color: #333;
--f7-text-editor-button-divider-color: rgba(0, 0, 0, 0.15);
--f7-text-editor-placeholder-color: rgba(0, 0, 0, 0.35);
}
:root .theme-dark,
:root.theme-dark {
--f7-text-editor-bg-color: #121212;
--f7-text-editor-border-color: rgba(255, 255, 255, 0.1);
--f7-text-editor-toolbar-bg-color: #202020;
--f7-text-editor-text-color: #fff;
--f7-text-editor-placeholder-color: rgba(255, 255, 255, 0.35);
--f7-text-editor-button-text-color: #fff;
--f7-text-editor-button-divider-color: rgba(255, 255, 255, 0.15);
}
.ios {
--f7-text-editor-toolbar-padding: 6px;
--f7-text-editor-toolbar-border-color: rgba(0, 0, 0, 0.25);
}
.ios .theme-dark,
.ios.theme-dark {
--f7-text-editor-toolbar-bg-color: #121212;
--f7-text-editor-toolbar-border-color: rgba(255, 255, 255, 0.1);
}
.md {
--f7-text-editor-toolbar-padding: 8px;
--f7-text-editor-toolbar-box-shadow: 0px 2px 3px -1px rgba(0, 0, 0, 0.25);
}
.aurora {
--f7-text-editor-toolbar-padding: 8px;
--f7-text-editor-toolbar-border-color: rgba(0, 0, 0, 0.25);
}
.aurora .theme-dark,
.aurora.theme-dark {
--f7-text-editor-toolbar-border-color: rgba(255, 255, 255, 0.1);
}
Examples
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="title">Text Editor</div>
</div>
</div>
<div class="page-content">
<div class="block-title">Default Setup</div>
<div class="text-editor text-editor-init">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">With Placeholder</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text...">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">With Default Value</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text...">
<div class="text-editor-content" contenteditable>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Consequatur sunt, sapiente quis eligendi
consectetur hic asperiores assumenda quidem dolore quasi iusto tenetur commodi qui ullam sint sed alias!
Consequatur, dolor!</p>
<p>Provident reiciendis exercitationem reprehenderit amet repellat laborum, sequi id quam quis quo quos
facere veniam ad libero dolorum animi. Nobis, illum culpa explicabo dolorem vitae ut dolor at
reprehenderit magnam?</p>
<p>Qui, animi. Dolores dicta, nobis aut expedita enim eum assumenda modi, blanditiis voluptatibus
excepturi non pariatur. Facilis fugit facere sequi molestias nemo in, suscipit inventore consequuntur,
repellat perferendis, voluptas odit.</p>
<p>Tempora voluptates, doloribus architecto eligendi numquam facilis perspiciatis autem quam voluptas
maxime ratione harum laudantium cum deleniti. In, alias deserunt voluptatibus eligendi libero nobis est
unde et perspiciatis cumque voluptatum.</p>
<p>Quam error doloribus qui laboriosam eligendi. Aspernatur quam pariatur perspiciatis reprehenderit atque
dicta culpa, aut rem? Assumenda, quibusdam? Reprehenderit necessitatibus facere nemo iure maiores porro
voluptates accusamus quibusdam. Nesciunt, assumenda?</p>
</div>
</div>
<div class="block-title">Specific Buttons</div>
<div class="block-header">It is possible to customize which buttons (commands) to show.</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text..."
data-buttons='[["bold", "italic", "underline", "strikeThrough"], ["orderedList", "unorderedList"]]'>
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">Custom Button</div>
<div class="block-header">It is possible to create custom editor buttons. Here is the custom "hr" button that
adds horizontal rule:</div>
<div class="text-editor text-editor-custom-buttons">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">Resizable</div>
<div class="block-header">Editor will be resized based on its content.</div>
<div class="text-editor text-editor-init text-editor-resizable" data-placeholder="Enter text..."
data-buttons='["bold", "italic", "underline", "strikeThrough"]'>
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">Popover Mode</div>
<div class="block-header">In this mode, there is no toolbar with buttons, but they appear as popover when you
select any text in editor.</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text..."
data-buttons='["bold", "italic", "underline", "strikeThrough"]' data-mode="popover"
style="--f7-text-editor-height: 150px">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">Keyboard Toolbar Mode</div>
<div class="block-header">In this mode, toolbar with buttons will appear on top of virtual keyboard when
editor is in the focus. It is supported only in iOS, Android cordova apps and in Android Chrome. When not
supported it will fallback to "popover" mode.</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text..." data-mode="keyboard-toolbar"
style="--f7-text-editor-height: 150px">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">As List Input</div>
<div class="block-header">Text editor can be used in list with other inputs. In this example it is enabled
with "keyboard-toolbar"/"popover" type for "About" field.</div>
<div class="list">
<ul>
<li class="item-content item-input">
<div class="item-media">
<i class="icon demo-list-icon"></i>
</div>
<div class="item-inner">
<div class="item-title item-label">Name</div>
<div class="item-input-wrap">
<input type="text" placeholder="Your name" />
</div>
</div>
</li>
<li class="item-content item-input">
<div class="item-media">
<i class="icon demo-list-icon"></i>
</div>
<div class="item-inner">
<div class="item-title item-label">About</div>
<div class="item-input-wrap">
<div class="text-editor text-editor-init text-editor-resizable" data-placeholder="About"
data-buttons='["bold", "italic", "underline", "strikeThrough"]' data-mode="popover">
<div class="text-editor-content" contenteditable></div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default (props, { $f7, $el, $on }) => {
let textEditorCustomButtons;
$on('pageInit', () => {
textEditorCustomButtons = $f7.textEditor.create({
el: $el.value.find('.text-editor-custom-buttons'),
// define custom "hr" button
customButtons: {
hr: {
content: '<hr>',
onClick(editor, buttonEl) {
document.execCommand('insertHorizontalRule', false);
},
},
},
buttons: [["bold", "italic", "underline", "strikeThrough"], "hr"],
});
});
$on('pageBeforeRemove', () => {
textEditorCustomButtons.destroy()
});
return $render;
};
</script>