The Image button on the toolbar allows you to insert an image from your local machine.
It would be brilliant if this could be extended to also allow an image URL to be provided.
It is possible to drag & drop an image from the web, but this may not be obvious to all users. Also, in our particular case, we have custom drag & drop handling which prevents this from working in our applications.
Version: 1.0.0-rc2
P.S. Thank you for all your hard work on 1.0 - it really is fantastic.
Any progress on this?
Also interested in this :)
[edit]Best Approach is something like the adding a matcher to the clipboard module, watching for copypasted urls and converting them to images (new Delta().insert({image: url}); works) like the code found here: https://github.com/quilljs/quill/issues/109 by @schneidmaster
Couldnt get it to works for images still tho...learning...
[edit 2] this custom matcher converts urls to links and in case they link to image, converts the urls to inline images (put it in quill.on('text-change', function(delta, oldDelta, source) {)
var Delta = Quill.import('delta');
//convert img links to actual images
quill.clipboard.addMatcher(Node.TEXT_NODE, function(node, delta) {
var regex = /https?:\/\/[^\s]+/g;
if(typeof(node.data) !== 'string') return;
var matches = node.data.match(regex);
if(matches && matches.length > 0) {
var ops = [];
var str = node.data;
matches.forEach(function(match) {
var split = str.split(match);
if(match.match(/\.(png|jpg|jpeg|gif)$/)!=null){
var beforeLink = split.shift();
ops.push({ insert: beforeLink });
ops.push({ insert:{image: match}, attributes: { link: match }
});
str = split.join(match);
} else { //if link is not an image
var beforeLink = split.shift();
ops.push({ insert: beforeLink });
ops.push({ insert: match, attributes: { link: match }
});
str = split.join(match);
}
});
ops.push({ insert: str });
delta.ops = ops;
}
return delta;
});
Obviously the wrong approach > I tried to implement this in the form of a custom module, but my JS skills suck. Behaviour im looking for is to replace all urls containing images to 'inline' images (like the etherpad image plugin). I made (read: copypasta) an example that sorta works here: http://codepen.io/anon/pen/PpYjxG
In the example, type a bit and Copy/Paste an image url in the editor field and it will appear as inline image. Only after that the ability to edit/type stops, which must be something obvious, but as I said..major noob...
Would love to see this as well. As a side note, this was how images were handled in the early stages of QuillJS. Any reason why this was removed?
I don't understand why there is base64 upload images and no support for third-party image upload. This is VERY important!
Still no update :(
I got it working like this:
https://stackoverflow.com/questions/43857373/quill-editor-vuejs2-image-upload-base64-image-to-url
Not directly from clipboard tho
I think here https://github.com/quilljs/quill/issues/863#issuecomment-240579430 it is written pretty well. All you need to do is to create custom handler
+6666
+1
I too would like to make public my desire for such a feature.
+1
+1 how is this not a feature yet?
Could someone from the team maybe shed some light on this please? This feature is really, REALLY needed.
+1 my team would love this feature.
For what it's worth... would be really really nice to have...
Keeping the fire alive for this request 🔥
I toss some bricks into that fire so it keeps burning longer
We got it working by extracting the base64 encoded image, storing it on the hard drive and replacing thesrc="data..." code with src="/folder/file..." but quill doesn't display the picture when the HTML is loaded with dangerouslyPasteHTML the next time we open it, see https://github.com/quilljs/quill/issues/1449.
+1 would also like to see this feature built-in
```
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'], // remove formatting button
['image']
];
var quill = new Quill('#editor', {
theme: 'snow',
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
image: imageHandler
}
}
},
});
function imageHandler() {
var range = this.quill.getSelection();
var value = prompt('What is the image URL');
if(value){
this.quill.insertEmbed(range.index, 'image', value, Quill.sources.USER);
}
}
Any progress on this?
å•¥
Hey there! Any progress?
@siberiadev in case you're working with laravel, for extracting the image you can use extract_inline_img() from my package here: https://packagist.org/packages/repat/laravel-helper
Or just have a look at the function here and extract what you need.
In terms of displaying I haven't seen any progress.
@repat, thank you. I use Node.js for backend.
PHP and Laravel (MVC, similar to express I think) is fairly eary to read so you could:
/src=\"data:image\/([a-zA-Z]*);base64,([^\"]*)\"/ to from PCRE to EcmaScriptstr_finish come from the official Laravel helpers: https://laravel.com/docs/5.8/helpers=> Translate it into a js function
I posted a solution above
This works like a charm
var toolbarOptions = [ ['bold', 'italic', 'underline', 'strike'], // toggled buttons ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], // custom button values [{ 'list': 'ordered' }, { 'list': 'bullet' }], [{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript [{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent [{ 'direction': 'rtl' }], // text direction [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown [{ 'header': [1, 2, 3, 4, 5, 6, false] }], [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme [{ 'font': [] }], [{ 'align': [] }], ['clean'], // remove formatting button ['image'] ]; var quill = new Quill('#editor', { theme: 'snow', modules: { toolbar: { container: toolbarOptions, handlers: { image: imageHandler } } }, }); function imageHandler() { var range = this.quill.getSelection(); var value = prompt('What is the image URL'); if(value){ this.quill.insertEmbed(range.index, 'image', value, Quill.sources.USER); } }
For anyone coming here using ngx-quill:
import { QuillModules, defaultModules } from 'ngx-quill';
export class MyComponent {
quillModules: QuillModules = {
toolbar: {
container: defaultModules.toolbar,
handlers: {
image: imageHandler
}
}
};
}
imageHandler(this: any) {
const tooltip = this.quill.theme.tooltip;
const originalSave = tooltip.save;
const originalHide = tooltip.hide;
tooltip.save = function(this: any) {
const range = this.quill.getSelection(true);
const value = this.textbox.value;
if (value) {
this.quill.insertEmbed(range.index, 'image', value, 'user');
}
};
// Called on hide and save.
tooltip.hide = function (this: any) {
tooltip.save = originalSave;
tooltip.hide = originalHide;
tooltip.hide();
};
tooltip.edit('image');
tooltip.textbox.placeholder = "Embed URL";
}
<quill-editor [modules]="quillModules"></quill-editor>
@chrisbmoore this works great for ngx-quill! However, it clobbers the tooltip saves for links and videos. Need to set the original save back when done. Instead of this:
function imageHandler(this: any) { const tooltip = this.quill.theme.tooltip; tooltip.save = function (this: any) { const range = this.quill.getSelection(true); const value = this.textbox.value; if (value) { this.quill.insertEmbed(range.index, 'image', value, 'user'); } } tooltip.edit('image'); }
do something like this:
imageHandler(this: any) {
const tooltip = this.quill.theme.tooltip;
const originalSave = tooltip.save;
tooltip.save = function(this: any) {
const range = this.quill.getSelection(true);
const value = this.textbox.value;
if (value) {
this.quill.insertEmbed(range.index, 'image', value, 'user');
}
tooltip.save = originalSave;
};
tooltip.edit('image');
}
@pburrows You're right, the original save function should be reset. Thanks!
@pburrows @chrisbmoore If the tooltip is closed without clicking "Save" the original save function is not restored, as the save method is not called. Do you have any idea how to solve this? I did not find some callback that is called in that case.
Update: I found a solution myself by overriding tooltip.hide() with the restore code:
tooltip.hide = function(this: any) {
tooltip.save = originalSave;
tooltip.hide = originalHide;
tooltip.hide();
};
@digilist Thanks for the correction! Yep your solution makes sense and I'll add it to my code.
Any Update on this ?
Most helpful comment
```
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],