Help us understand the problem. What is going on with this article?

Aurelia に Quill を導入する

More than 1 year has passed since last update.

Aurelia を使った社内向けシステムの開発中に Quill 導入したので、手順とサンプルを載せてみる。

Quill とは

Your powerful, rich text editor.

要するに WYSIWYG エディタ。
見た目がモダンっぽくて良い感じなので、これを Aurelia アプリに組み込む。

TL;DR

  • Quill はモダンで導入も楽チンだよ
  • 簡単な設置までの手順を書いたよ
  • ちょっと実用的な「記事」の表示・編集サンプルも書いたよ

対象読者

Aurelia に Quill の導入を考えている人。

前提環境

導入するもの

導入手順

jspm を使ってインストール

入れるのは一つだけで良いから楽チン。

$ jspm install npm:quill

package.json に以下の内容が追記されればインストール完了。

package.json
{
  "jspm": {
    "dependencies": {
      "quill": "npm:quill@^1.3.2",
    }
  }
}

Aurelia に組み込む

Aurelia Plugin ではないので main.js に設定は要らない。

まずは html 側に css を読み込んで Editor を組み込ませるタグを作る。
専用のタグなどは不要で、後で Javascript 側でセレクタ指定できれば良い。今回は div#editor としておく。

editor.html
<require from="quill/dist/quill.snow.css"></require>

<div id="editor"></div>

次に Javascript 側に処理を組み込む。
DOM が生成されてから組み込みたいので attached() が適当。

editor.js
import Quill from 'quill/dist/quill.min.js';

export class Editor {
  attached() {
    this.quill = new Quill('#editor', {
      theme: 'snow',
    });
  }
}

画面を開いて、以下のように表示されれば設置完了。

 2017-09-24 20.14.01.png

Quill はテーマ設定ができて、上記の例では snow を適用している。
他に bubble というものがあるので、変えたければ snow を全部 bubble に置き換えれば良い。

他にもオプション設定は多様にできるので、詳細は公式の Configuration とかを見れば良いと思う。

もう少し実用的に作ってみる

設置するだけなら以上。
さすがにこれだと実用性皆無なので、もう少し実用性のあるっぽい「記事」の表示・編集を考えて作ってみる。

新規投稿と編集の画面は似通っていると思うので、以下では編集画面だけ作る。
新規投稿画面を作りたければ、編集画面を手直しすれば良いよ。

なお、簡単に見栄えを整えるために Bootstrap をしれっと使用しているので、留意してね。

ざっくりディレクトリ構成

  • article
    • index.html
    • index.js
    • edit.html
    • edit.js

ざっくりテーブル

  • article
    • id: int(11)
    • title: varchar(255)
    • body: text

実装

index:投稿された記事を表示する

html 側は複数件の表示に対応。
ql-container クラスなどを使って要素を用意しておけば、エディターと同等の見栄えを確保できる。

index.html
<require from="quill/dist/quill.snow.css"></require>

<div class="card" repeat.for="article of articles">
  <div class="card-block">
    <h2 class="card-title">${article.title}</h2>
    <p class="card-text">
      <div class="ql-container ql-snow">
        <div class="ql-editor" innerhtml.bind="article.body"></div>
      </div>
    </p>
    <a href="article/edit/${article.id}" class="btn btn-primary" for="articleEdit">Edit</a>
  </div>
</div>

Javascript 側は取得するだけ。
API アクセスは https://github.com/SpoonX/aurelia-api を使ってます。

index.js
import {inject} from "aurelia-framework";
import {Endpoint} from 'aurelia-api';

@inject(Endpoint.of('api'))

export class Index {
  constructor(endpoint) {
    this.endpoint = endpoint;
  }

  activate() {
    this.endpoint.find('article')
    .then(response => {
      this.articles = response;
    })
    .catch(error => {
    });
  }

画面を開いてこうなれば完了。
データは適当に入れてある前提。

 2017-09-24 21.08.24.png

edit:記事を編集する

html 側はこんな感じ。
body は bind できないので Javascript 側で対応する。

edit.html
<require from="quill/dist/quill.snow.css"></require>

<div class="form-group">
  <label for="articleTitle">Title</label>
  <input type="text" class="form-control" placeholder="title" value.bind="article.title">
</div>
<div class="form-group">
  <label for="articleBody">Body</label>
  <div id="article-body"></div>
</div>
<div class="form-group">
  <button type="button" class="btn btn-primary" for="articleSubmit" click.trigger="submit()">Submit</button>
</div>

Javascript 側はこんな感じ。
body は bind できていないので quill.root.innerHTML を介して設定・取得を行う。

edit.js
import {inject} from "aurelia-framework";
import {Endpoint} from 'aurelia-api';
import Quill from 'quill/dist/quill.min.js';

@inject(Endpoint.of('api'))

export class Edit {
  constructor(endpoint) {
    this.endpoint = endpoint;
  }

  attached() {
    this.quill = new Quill('#article-body', {
      theme: 'snow',
      placeholder: 'body',
    });
  }

  activate(params) {
    this.endpoint.find('article/' + params.id)
    .then(response => {
      this.article = response;
      this.quill.root.innerHTML = this.article.body;
    })
    .catch(error => {
    });
  }

  submit() {
    let params = {
      article: {
        title: this.article.title,
        body: this.quill.root.innerHTML,
      }
    };

    this.endpoint.update('article', this.article.id, params)
    .then((response) => {
      this.successSubmit();
    })
    .catch(error => {
    });
  }

  successSubmit() {
    location.href = 'article/index';
  }
}

画面を開いてこうなれば完了。

 2017-09-24 21.10.14.png

おわりに

設置は簡単で、必要なスタイルは css を読み込めば終わるので、導入コストが低くて楽チン。
テーマとして snowbubble があって、見た目がモダンっぽくて、ちょっとオシャレなのは好印象だった。
とりあえず WYSIWYG を入れるにはもってこいって感じ。

ただ、やっぱり外部プラグインで実現すると js でお世話しないといけない辛さがある。
innerHTML プロパティとか書かないといけないので、 Aurelia でやっている感が薄れてしまうのは嫌かも。

Aurelia Plugin に寄せて template 呼び出し的なことができれば、もう少しシンプルに書けるかもしれない。
けど、それはまたいずれ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした