зеркало из
https://github.com/rs-pro/activeadmin-quill_editor.git
synced 2026-08-28 15:36:17 +03:00
Сравнить коммиты
7 Коммитов
| Автор | SHA1 | Дата | |
|---|---|---|---|
|
|
e6e6742753 | ||
|
|
c2c8d48795 | ||
|
|
72062c1a30 | ||
|
|
c4aa91225b | ||
|
|
3cc6edb302 | ||
|
|
d78fb2eb9c | ||
|
|
e5db64af96 |
23
README.md
23
README.md
@@ -5,7 +5,10 @@ An Active Admin plugin to use [Quill Rich Text Editor](https://github.com/quillj
|
||||

|
||||
|
||||
## Install
|
||||
- After installing Active Admin, add to your Gemfile: `gem 'activeadmin_quill_editor'` (and execute *bundle*)
|
||||
After installing Active Admin, add to your Gemfile: `gem 'activeadmin_quill_editor'` (and execute *bundle*)
|
||||
|
||||
If you installed Active Admin without Webpacker support (default for now):
|
||||
|
||||
- Add at the end of your Active Admin styles (_app/assets/stylesheets/active_admin.scss_):
|
||||
```scss
|
||||
@import 'activeadmin/quill_editor/quill.snow';
|
||||
@@ -16,13 +19,23 @@ An Active Admin plugin to use [Quill Rich Text Editor](https://github.com/quillj
|
||||
//= require activeadmin/quill_editor/quill
|
||||
//= require activeadmin/quill_editor_input
|
||||
```
|
||||
- Use the input with `as: :quill_editor` in Active Admin model conf
|
||||
|
||||
Why 2 separated scripts/styles? In this way you can include a different version of *quill editor* if you like.
|
||||
|
||||
> **UPDATE FROM VERSION <= 2.0**: please add to your _app/assets/stylesheets/active_admin.scss_ the line `@import 'activeadmin/quill_editor/quill.snow';`
|
||||
|
||||
## Options
|
||||
If you installed Active Admin with Webpacker support:
|
||||
|
||||
- Execute in your project root:
|
||||
```sh
|
||||
yarn add blocknotes/activeadmin_quill_editor
|
||||
```
|
||||
- Add to your *app/javascript/packs/active_admin.js*:
|
||||
```js
|
||||
require('activeadmin_quill_editor')
|
||||
```
|
||||
|
||||
## Usage
|
||||
In your Active Admin models, form configuration, set the text inputs with `as: :quill_editor` where needed.
|
||||
|
||||
**data-options**: permits to set *quill editor* options directly - see [options list](https://quilljs.com/docs/configuration/)
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -1,91 +1,95 @@
|
||||
// --- functions ---------------------------------------------------------------
|
||||
function initQuillEditors() {
|
||||
var default_theme = 'snow';
|
||||
var default_toolbar = [
|
||||
['bold', 'italic', 'underline'],
|
||||
['link', 'blockquote', 'code-block'],
|
||||
[{ 'script': 'sub'}, { 'script': 'super' }],
|
||||
[{ 'align': [] }, { list: 'ordered' }, { list: 'bullet' }],
|
||||
[{ 'color': [] }, { 'background': [] }],
|
||||
['image'],
|
||||
['clean'],
|
||||
];
|
||||
var editors = document.querySelectorAll('.quill-editor');
|
||||
var registered_plugins = {};
|
||||
(function () {
|
||||
'use strict'
|
||||
|
||||
for(var i = 0; i < editors.length; i++) {
|
||||
var content = editors[i].querySelector('.quill-editor-content');
|
||||
var isActive = editors[i].classList.contains('quill-editor--active');
|
||||
if(content && !isActive) {
|
||||
// Setup editor options
|
||||
var options = editors[i].getAttribute('data-options') ? JSON.parse(editors[i].getAttribute('data-options')) : {};
|
||||
if(!options.theme) options.theme = default_theme;
|
||||
if(!options.modules) options.modules = {};
|
||||
if(!options.modules.toolbar) options.modules.toolbar = default_toolbar;
|
||||
// --- functions ---------------------------------------------------------------
|
||||
function initQuillEditors() {
|
||||
let default_theme = 'snow'
|
||||
let default_toolbar = [
|
||||
['bold', 'italic', 'underline'],
|
||||
['link', 'blockquote', 'code-block'],
|
||||
[{ 'script': 'sub' }, { 'script': 'super' }],
|
||||
[{ 'align': [] }, { list: 'ordered' }, { list: 'bullet' }],
|
||||
[{ 'color': [] }, { 'background': [] }],
|
||||
['image'],
|
||||
['clean'],
|
||||
]
|
||||
let editors = document.querySelectorAll('[data-aa-quill-editor]')
|
||||
let registered_plugins = {}
|
||||
|
||||
// Setup plugin options
|
||||
var plugin_options = editors[i].getAttribute('data-plugins') ? JSON.parse(editors[i].getAttribute('data-plugins')) : {};
|
||||
if(plugin_options.image_uploader && plugin_options.image_uploader.server_url) {
|
||||
if(!registered_plugins.image_uploader) {
|
||||
Quill.register('modules/imageUploader', ImageUploader);
|
||||
registered_plugins.image_uploader = true;
|
||||
for (let i = 0; i < editors.length; i++) {
|
||||
let content = editors[i].querySelector('[data-aa-quill-content]')
|
||||
let isActive = editors[i].classList.contains('quill-editor--active')
|
||||
if (content && !isActive) {
|
||||
// Setup editor options
|
||||
let options = editors[i].getAttribute('data-options') ? JSON.parse(editors[i].getAttribute('data-options')) : {}
|
||||
if (!options.theme) options.theme = default_theme
|
||||
if (!options.modules) options.modules = {}
|
||||
if (!options.modules.toolbar) options.modules.toolbar = default_toolbar
|
||||
|
||||
// Setup plugin options
|
||||
let plugin_options = editors[i].getAttribute('data-plugins') ? JSON.parse(editors[i].getAttribute('data-plugins')) : {}
|
||||
if (plugin_options.image_uploader && plugin_options.image_uploader.server_url) {
|
||||
if (!registered_plugins.image_uploader) {
|
||||
Quill.register('modules/imageUploader', ImageUploader)
|
||||
registered_plugins.image_uploader = true
|
||||
}
|
||||
let opts = plugin_options.image_uploader
|
||||
options.modules.imageUploader = setupImageUploader(opts.server_url, opts.field_name)
|
||||
}
|
||||
var opts = plugin_options.image_uploader;
|
||||
options.modules.imageUploader = setupImageUploader(opts.server_url, opts.field_name);
|
||||
}
|
||||
|
||||
// Init editor
|
||||
editors[i]['_quill-editor'] = new Quill(content, options);
|
||||
editors[i].classList += ' quill-editor--active';
|
||||
// Init editor
|
||||
editors[i]['_quill-editor'] = new Quill(content, options)
|
||||
editors[i].classList += ' quill-editor--active'
|
||||
}
|
||||
}
|
||||
|
||||
let formtastic = document.querySelector('form.formtastic')
|
||||
if (formtastic) {
|
||||
formtastic.onsubmit = () => {
|
||||
for (let i = 0; i < editors.length; i++) {
|
||||
let input = editors[i].querySelector('input[type="hidden"]')
|
||||
if (editors[i]['_quill-editor'].editor.isBlank()) {
|
||||
input.value = ''
|
||||
} else {
|
||||
input.value = editors[i]['_quill-editor'].root.innerHTML
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var formtastic = document.querySelector('form.formtastic');
|
||||
if(formtastic) {
|
||||
formtastic.onsubmit = function() {
|
||||
for(var i = 0; i < editors.length; i++) {
|
||||
var input = editors[i].querySelector('input[type="hidden"]');
|
||||
if (editors[i]['_quill-editor'].editor.isBlank()) {
|
||||
input.value = '';
|
||||
} else {
|
||||
input.value = editors[i]['_quill-editor'].root.innerHTML;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
function setupImageUploader(server_url, field_name) {
|
||||
return {
|
||||
upload: file => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const formData = new FormData()
|
||||
formData.append(field_name || 'file_upload', file)
|
||||
|
||||
function setupImageUploader(server_url, field_name) {
|
||||
return {
|
||||
upload: file => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const formData = new FormData();
|
||||
formData.append(field_name || 'file_upload', file);
|
||||
|
||||
fetch(server_url, {
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||||
},
|
||||
method: 'POST'
|
||||
}).then(response => response.json())
|
||||
.then(result => {
|
||||
resolve(result.url);
|
||||
fetch(server_url, {
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||||
},
|
||||
method: 'POST'
|
||||
}).then(response => response.json())
|
||||
.then(result => {
|
||||
resolve(result.url);
|
||||
})
|
||||
.catch(error => {
|
||||
reject('Upload failed')
|
||||
console.error('Error: ', error)
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
reject('Upload failed');
|
||||
console.error('Error: ', error);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- events ------------------------------------------------------------------
|
||||
$(document).ready( function() {
|
||||
initQuillEditors();
|
||||
});
|
||||
// --- events ------------------------------------------------------------------
|
||||
$(document).ready(() => {
|
||||
initQuillEditors()
|
||||
})
|
||||
|
||||
$(document).on('has_many_add:after', function() {
|
||||
initQuillEditors();
|
||||
});
|
||||
$(document).on('has_many_add:after', '.has_many_container', () => {
|
||||
initQuillEditors()
|
||||
})
|
||||
})()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
text-align: initial;
|
||||
}
|
||||
|
||||
body.active_admin .quill-editor {
|
||||
body.active_admin [data-aa-quill-editor] {
|
||||
display: inline-block;
|
||||
width: calc(80% - 2px);
|
||||
|
||||
|
||||
7
index.js
Обычный файл
7
index.js
Обычный файл
@@ -0,0 +1,7 @@
|
||||
// Styles
|
||||
import 'activeadmin_quill_editor/app/assets/stylesheets/activeadmin/quill_editor/quill.snow'
|
||||
import 'activeadmin_quill_editor/app/assets/stylesheets/activeadmin/_quill_editor_input'
|
||||
|
||||
// JS
|
||||
window.Quill = require('activeadmin_quill_editor/app/assets/javascripts/activeadmin/quill_editor/quill')
|
||||
require('activeadmin_quill_editor/app/assets/javascripts/activeadmin/quill_editor_input')
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
module ActiveAdmin
|
||||
module QuillEditor
|
||||
VERSION = '0.2.10'
|
||||
VERSION = '0.3.0'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,9 +6,9 @@ module Formtastic
|
||||
def to_html
|
||||
input_wrapping do
|
||||
label_html <<
|
||||
template.content_tag(:div, input_html_options.merge(class: 'quill-editor')) do
|
||||
template.content_tag(:div, input_html_options.merge('data-aa-quill-editor': '1')) do
|
||||
builder.hidden_field(input_name) <<
|
||||
template.content_tag(:div, class: 'quill-editor-content') do
|
||||
template.content_tag(:div, 'data-aa-quill-content': '1') do
|
||||
object.send(method).try :html_safe
|
||||
end
|
||||
end
|
||||
|
||||
9
package.json
Обычный файл
9
package.json
Обычный файл
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "activeadmin_quill_editor",
|
||||
"version": "0.3.0",
|
||||
"description": "Quill Editor for ActiveAdmin",
|
||||
"author": "Mattia Roccoberton <mat@blocknot.es>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/blocknotes/activeadmin_quill_editor",
|
||||
"main": "index.js"
|
||||
}
|
||||
@@ -38,10 +38,11 @@ ActiveAdmin.register Post do
|
||||
end
|
||||
|
||||
form do |f|
|
||||
toolbar = %w[bold italic underline link]
|
||||
f.inputs 'Post' do
|
||||
f.input :author
|
||||
f.input :title
|
||||
f.input :description, as: :quill_editor
|
||||
f.input :description, as: :quill_editor, input_html: { data: { options: { modules: { toolbar: toolbar } } } }
|
||||
f.input :category
|
||||
f.input :dt
|
||||
f.input :position
|
||||
|
||||
@@ -17,6 +17,10 @@ RSpec.describe 'Quill editor', type: :system do
|
||||
it 'updates some HTML content' do
|
||||
visit "/admin/posts/#{post.id}/edit"
|
||||
|
||||
%w[bold italic underline link].each do |button|
|
||||
expect(page).to have_css(".ql-toolbar button.ql-#{button}")
|
||||
end
|
||||
expect(page).to have_css('#post_description[data-aa-quill-editor]')
|
||||
expect(page).to have_css('#post_description_input .ql-editor', text: 'Some content...')
|
||||
find('#post_description_input .ql-editor').click
|
||||
find('#post_description_input .ql-editor').base.send_keys('more text')
|
||||
|
||||
Ссылка в новой задаче
Block a user