Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing Action Button for Dropdown #56

Merged
merged 16 commits into from Jan 28, 2019
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,16 @@ const quill = new Quill('#editor', {
| `mentionDenotationChars` | `["@"]` | Specifies which characters will cause the mention autocomplete to open
| `isolateCharacter` | `false` | Whether or not the denotation character(s) should be isolated. For example, to avoid mentioning in an email.
| `fixMentionsToQuill` | `false` | When set to true, the mentions menu will be rendered above or below the quill container. Otherwise, the mentions menu will track the denotation character(s);
|`showDenotationChar` | `true` | Whether to show the used denotation character in the mention item or not
| `defaultMenuOrientation` | `'bottom'` | Options are `'bottom'` and `'top'`. Determines what the default orientation of the menu will be. Quill-mention will attempt to render the menu either above or below the editor. If `'top'` is provided as a value, and there is not enough space above the editor, the menu will be rendered below. Vice versa, if there is not enough space below the editor, and `'bottom'` is provided as a value (or no value is provided at all), the menu will be rendered above the editor.
| `dataAttributes` | `['id', 'value', 'denotationChar', 'link', 'target']` | A list of data values you wish to be passed from your list data to the html node. (`id, value, denotationChar, link, target` are included by default).
| `onOpen` | `function` | Callback when mention dropdown is open.
| `onClose` | `function` | Callback when mention dropdown is closed.
|`onSelect(item, insertItem)` | `function` | Callback for a selected item. When overriding this method, `insertItem` should be used to insert `item` to the editor. This makes async requests possible.
| `linkTarget` | `'_blank'` | Link target for mentions with a link


| `listItemClass` | `'ql-mention-list-item'` | Style class to be used for list items (may be null)
| `mentionContainerClass` | `'ql-mention-list-container'` | Style class to be used for the mention list container (may be null)
| `mentionListClass` | `'ql-mention-list'` | Style class to be used for the mention list (may be null)
## Authors

**Fredrik Sundqvist** ([MadSpindel](https://github.com/MadSpindel))
Expand Down
2 changes: 1 addition & 1 deletion dist/quill.mention.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/quill.mention.min.js

Large diffs are not rendered by default.

Binary file added src/favicon.ico
Binary file not shown.
114 changes: 109 additions & 5 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@
<h1>Quill Mention Demo</h1>

<!-- Create the editor container -->
<h2>Basic</h2>
<div id="editor"></div>

<h2>Action Button & Custom Style</h2>
<div id="editor-onselect"></div>
<div id="action-data" style="margin: 8px;"></div>

<!-- Include the Quill library -->
<script src="https://cdn.quilljs.com/1.3.4/quill.js"></script>
<script src="quill.mention.min.js"></script>
Expand All @@ -30,6 +35,12 @@ <h1>Quill Mention Demo</h1>
border-radius: 6px;
}

.ql-editor-disabled {
border-radius: 6px;
background-color: rgba(124, 0, 0, 0.2);
transition-duration: 0.5s;
}

.ql-editor:focus {
border: 1px solid #025FAE;
}
Expand All @@ -38,6 +49,30 @@ <h1>Quill Mention Demo</h1>
max-height: 300px;
overflow: auto;
}

.cql-list-item {
cursor: crosshair;
color: #7c0000;
padding: 12px;
background-color: white;
transition-duration: 0.6s;
}

.cql-list-item:hover {
padding-left: 20px;
color: white;
background-color: #7c0000;
transition-duration: 0.3s;
}

.cql-list-item-action {
cursor: pointer;
padding: 12px;
color: white;
background-color: #7c0000;
border-top: 4px dashed white;
}

</style>
<!-- Initialize Quill editor -->
<script>
Expand All @@ -61,7 +96,13 @@ <h1>Quill Mention Demo</h1>
{ "id": "5a97b2a4436c2c9acc6b5ad2", "value": "Maria Cruiser", "myCustomProperty": "custom value" },
{ "id": "5a97b2a4436c2c9acc6b5ad3", "value": "Pablo Escobeer", "myCustomProperty": "custom value" },
{ "id": "5a97b2a4436c2c9acc6b5ad4", "value": "Richard Schmidt", "myCustomProperty": "custom value" }
]
];

const actionValues = [
{"id": "1", "value": "Porsche"},
{"id": "1", "value": "Volkswagen"},
{"id": "1", "value": "BMW"},
];

var quill = new Quill('#editor', {
modules: {
Expand All @@ -73,19 +114,82 @@ <h1>Quill Mention Demo</h1>
let values;

if (mentionChar === "@") {
values = atValues;
values = atValues;
} else {
values = hashValues;
values = hashValues;
}

if (searchTerm.length === 0) {
renderList(values, searchTerm);
} else {
const matches = [];
for (i = 0; i < values.length; i++)
if (~values[i].value.toLowerCase().indexOf(searchTerm.toLowerCase())) matches.push(values[i]);
renderList(matches, searchTerm);
}
},
},
}
});

let quillAction = null;

disable = function(id, value) {
const editor = document.getElementById(id);
if (value === false) {
quillAction.enable(true);
editor.classList.remove('ql-editor-disabled');
quillAction.setSelection(quillAction.getText().length, 0);
} else {
quillAction.enable(false);
editor.classList.add('ql-editor-disabled');
}
};

quillAction = new Quill('#editor-onselect', {
modules: {
mention: {
listItemClass: null,
allowedChars: /^[A-Za-z\sÅÄÖåäö]*$/,
mentionDenotationChars: ["@", "#"],
showDenotationChar: false,
dataAttributes: ['query'],
renderItem(item, searchTerm) {
if (item.hasOwnProperty('query')) {
return `<div class="cql-list-item-action">Create \"<i>${searchTerm}</i>\"</div>`;
}
return `<div class="cql-list-item">${item.value}</div>`;
},
onSelect(data, insertItem) {
console.log('onSelect');
console.log(data);
if (data.hasOwnProperty('query')) {
disable('editor-onselect', true);
document.getElementById('action-data').innerHTML = `<span>Creating: ${data.query}</span>`;
setTimeout(() => {
insertItem({"id": "fake-id", "value": data.query});
disable('editor-onselect', false);
}, 1000);
} else {
insertItem(data);
}
},
source: function (searchTerm, renderList, mentionChar) {
let values = actionValues;

if (searchTerm.length === 0) {
renderList(values, searchTerm);
} else {
const matches = [];
for (i = 0; i < values.length; i++)
if (~values[i].value.toLowerCase().indexOf(searchTerm.toLowerCase())) matches.push(values[i]);
for (i = 0; i < values.length; i++) {
if (~values[i].value.toLowerCase().indexOf(searchTerm.toLowerCase())) {
matches.push(values[i])
}
}
matches.push({"query": searchTerm});
renderList(matches, searchTerm);
}

},
},
}
Expand Down
34 changes: 28 additions & 6 deletions src/quill.mention.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ class Mention {
renderItem(item, searchTerm) {
return `${item.value}`;
},
onSelect(item, insertItem) {
insertItem(item);
},
mentionDenotationChars: ['@'],
showDenotationChar: true,
allowedChars: /^[a-zA-Z0-9_]*$/,
minChars: 0,
maxChars: 31,
Expand All @@ -37,7 +41,11 @@ class Mention {
},
onClose() {
return true;
}
},
// Style options
listItemClass: 'ql-mention-list-item',
mentionContainerClass: 'ql-mention-list-container',
mentionListClass: 'ql-mention-list',
};

Object.assign(this.options, options, {
Expand All @@ -47,7 +55,7 @@ class Mention {
});

this.mentionContainer = document.createElement('div');
this.mentionContainer.className = 'ql-mention-list-container';
this.mentionContainer.className = this.options.mentionContainerClass ? this.options.mentionContainerClass : '';
this.mentionContainer.style.cssText = 'display: none; position: absolute;';
this.mentionContainer.onmousemove = this.onContainerMouseMove.bind(this);

Expand All @@ -56,7 +64,7 @@ class Mention {
}

this.mentionList = document.createElement('ul');
this.mentionList.className = 'ql-mention-list';
this.mentionList.className = this.options.mentionListClass ? this.options.mentionListClass : '';
this.mentionContainer.appendChild(this.mentionList);

this.quill.container.appendChild(this.mentionContainer);
Expand Down Expand Up @@ -124,7 +132,6 @@ class Mention {
this.mentionContainer.style.display = '';
this.setMentionContainerPosition();
this.setIsOpen(true);

}

hideMentionList() {
Expand Down Expand Up @@ -170,9 +177,23 @@ class Mention {

selectItem() {
const data = this.getItemData();
this.options.onSelect(data, (asyncData) => {
this.insertItem(asyncData);
});
this.hideMentionList();
}

insertItem(data) {
const render = data;
if (render === null) {
return;
}
if (!this.options.showDenotationChar) {
render.denotationChar = '';
}
this.quill
.deleteText(this.mentionCharPos, this.cursorPos - this.mentionCharPos, Quill.sources.API);
this.quill.insertEmbed(this.mentionCharPos, 'mention', data, Quill.sources.API);
this.quill.insertEmbed(this.mentionCharPos, 'mention', render, Quill.sources.API);
this.quill.insertText(this.mentionCharPos + 1, ' ', Quill.sources.API);
this.quill.setSelection(this.mentionCharPos + 2, Quill.sources.API);
this.hideMentionList();
Expand Down Expand Up @@ -215,9 +236,10 @@ class Mention {
if (data && data.length > 0) {
this.values = data;
this.mentionList.innerHTML = '';

for (let i = 0; i < data.length; i += 1) {
const li = document.createElement('li');
li.className = 'ql-mention-list-item';
li.className = this.options.listItemClass ? this.options.listItemClass : '';
li.dataset.index = i;
li.innerHTML = this.options.renderItem(data[i], searchTerm);
li.onmouseenter = this.onItemMouseEnter.bind(this);
Expand Down