slab / quill

Quill is a modern WYSIWYG editor built for compatibility and extensibility
https://quilljs.com
BSD 3-Clause "New" or "Revised" License
43.21k stars 3.36k forks source link

Set Alt Attribute image #2432

Closed SebastienCruz closed 5 years ago

SebastienCruz commented 5 years ago

Hi,

Maybe I missed something but I didn't find a simple way to set/edit the alt attribute of an image in QuillJS.

It seems to me that it should be a feature that any user could change easily as it is very important in SEO.

Is there a way to change alt attribute of an image easily ?

Thank you very much,

vinitpradhn18 commented 5 years ago

You could use the quill format method.

Example:

const range = quill.getSelection();
quill.formatLine(range.index, range.length, 'alt', 'new value');
quill.setSelection(range.length + 1, Quill.sources.USER);
SebastienCruz commented 5 years ago

Hi,

Thank you for your answer. Could you show me where I can find the documentation to understand how to implement it ? I'm new to Quilljs, I managed to use it, to use autosave module, but I don't know exactly how to add functionality.

vinitpradhn18 commented 5 years ago

You can find here at here.

See the video documentation

SebastienCruz commented 5 years ago

Hello Every body,

I managed to code a little fork to edit image name and alt. It's not perfect, but it works pretty well for what I need.

Eventually, here's what I did :

//IMAGE ALT TEXT AND SRC EDIT
            const ImageBlot = Quill.import('formats/image');
            const Parchment = Quill.import('parchment');

            // We test every time there is a click in the editor
            quill.root.addEventListener('click', (ev) => {
              let image = Parchment.find(ev.target);

              // If it is a image, we show a form to edit name and alt. The name is a small part of the src, without path nor file extension.
              if (image instanceof ImageBlot) {
                quill.setSelection(image.offset(quill.scroll), 1, 'user');

                var urlimage=image.domNode.getAttribute('src');
                var imagepath=urlimage.split("/").slice(0, -1).join("/")+"/";
                var filenameimage=urlimage.split('/').pop();
                var extimage='.'+filenameimage.split('.').pop();
                var nameimage=filenameimage.replace(extimage,'');
                var altimage=image.domNode.getAttribute('alt');

                if(altimage == null){
                 altimage='';
                }

                //We set the current values in the form according with the current selected image infos
                $('#pageeditor_imageinfos input[name=imagename]').val(nameimage);
                $('#pageeditor_imageinfos input[name=imagealt]').val(altimage);

                //Maybe set the change handler everytime is not very optimized, but it works...
                $('#pageeditor_imageinfos input[name=imagename]').change(function(){

                    // When the name of the image change, we call an ajax function to modify the name of the image server side.
                    // get the name entered by user
                    var newname = $('#pageeditor_imageinfos input[name=imagename]').val();
                    // copy this name in clipboard ( not mandatory ). The var copy to clipboard is used in case of failure. 
                    $('#pageeditor_imageinfos input[name=imagename]').select();
                    var copytoclipboard='';
                    if(document.execCommand('copy'))
                    {
                        copytoclipboard=' - name copied to clipboard. You can simply paste it if necessary.';
                    }

                    $.post("bleu/bleuoffice/ajax/changeimageurl.php",{oldname:nameimage,newname:newname,imagepath:imagepath,extimage:extimage})
                    .done(function(data){
                        if(data=='')
                        {
                            // We set the src attr with the new path
                            image.domNode.setAttribute('src',imagepath+newname+extimage);
                        }
                        else{
                            // to show it didn't work, I decided to cancel the modification in the input. That's why I copied the entered value in clipboard.
                            alert(data+copytoclipboard);
                            $('#pageeditor_imageinfos input[name=imagename]').val(nameimage);
                        }
                    })
                    .fail(function(){
                        console.log('Ajax Failure : Problem while updating the image URL.');
                    });

                });

                // for alt attr, we juste have to change it in the editor
                $('#pageeditor_imageinfos input[name=imagealt]').change(function(){
                    image.domNode.setAttribute('alt',$('#pageeditor_imageinfos input[name=imagealt]').val());
                });
                $('#pageeditor_imageinfos').show();
              }
              else{
                $('#pageeditor_imageinfos').hide(); 
              }
            });
SebastienCruz commented 5 years ago

Actually I have a problem with this solution.

When I type backspace in the input when image is selected, the image is deleted.

I tried to bind key, but it didn't work. I tried to modify all the implementation by creating a module which extends Tooltip, I still have the problem. When I put a listener on my input keydown, I can neutralize this behavior, but only when I put a debug stop in it. If I wait a second or two, it doesn't delete the image...

SebastienCruz commented 5 years ago

Ok, I had a problem with the BlotFormatter Module ( fork of quill-image-resize-module ). The only way I found was to block the module when shifKey+click, and then open the alt and name editor.

I can be more specific if you need.

Seb

manhtruongwang commented 9 months ago

Add this after you init quilljs

// Custom image handler
        editor.getModule('toolbar').addHandler('image', () => {
            let fileInput = document.createElement('input');
            fileInput.setAttribute('type', 'file');
            fileInput.setAttribute('accept', 'image/webp, image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
            fileInput.click();

            fileInput.addEventListener('change', () => {
                let file = fileInput.files[0];
                let reader = new FileReader();

                reader.addEventListener('load', () => {
                    let range = editor.getSelection(true);
                    let altText = prompt("Enter alt text for the image:");
                    let img = document.createElement('img');
                    img.src = reader.result;
                    img.alt = altText;
                    editor.clipboard.dangerouslyPasteHTML(range.index, img.outerHTML);
                }, false);

                if (file) {
                    reader.readAsDataURL(file);
                }
            });
        });
nfacciolo commented 6 months ago

Documentation available at https://quilljs.com/docs/modules/toolbar:

const toolbarOptions = {
  handlers: {
    // handlers object will be merged with default handlers object
    link: function (value) {
      if (value) {
        const href = prompt('Enter the URL');
        this.quill.format('link', href);
      } else {
        this.quill.format('link', false);
      }
    }
  }
};

const quill = new Quill('#editor', {
  modules: {
    toolbar: toolbarOptions
  }
});

// Handlers can also be added post initialization
const toolbar = quill.getModule('toolbar');
toolbar.addHandler('image', showImageUI);