kolkov / angular-editor

A simple native WYSIWYG editor component for Angular 6 -14+
https://angular-editor.kolkov.ru
MIT License
675 stars 361 forks source link

Angular Editor Link #457

Open kvinay18 opened 2 years ago

kvinay18 commented 2 years ago

Can we open custom Popup when we click on Link? image

ShemiNechmad commented 2 years ago

Hey, I was looking for a solution myself, I did some digging in the package and found an answer that would work.

  1. First you make a custom button for a link, put it in an absolute position somewhere, something like: <button (click)="link()" style="position: absolute; top: 5px; right: 5px; width: 20px; height: 20px;" >[link icon]
  2. Create your own pop up window which is triggered when button is clicked.
  3. Add this to the angular-editor tag in the html file: <angular editor (mouseout)="onTextAreaMouseOut($event)".....
  4. Add the next code to your component ts file:

    
    onTextAreaMouseOut = (): void => {
    if (document.getSelection) {
      const sel = document.getSelection();
      if (sel.getRangeAt && sel.rangeCount) {
        this.savedSelection = sel.getRangeAt(0);
        this.selectedText = sel.toString();
      }
    } else if (document.getSelection && document.createRange) {
      this.savedSelection = document.createRange();
    } else {
      this.savedSelection = null;
    }
    }
    
    createLink(url: string) {
    if (!url.includes('http')) {
      document.execCommand('createlink', false, url);
    } else {
      const newUrl = '<a href="' + url + '" target="_blank">' + this.selectedText + '</a>';
      this.editor.editorService.insertHtml(newUrl);
    }
    }

    These are 2 functions. The first is to save a selection you made for the link (before clicking somewhere else on the page). The second function should be fired after the pop up is closed and it makes the selected text to be a link. Should do the job definitely and no need to look for a huge ckeditor package which also cost money for plugins :) Good luck.

teamolhuang commented 4 months ago

Ran into similar issue (I was trying to insert hyperlink on img), tried @ShemiNechmad 's suggestion, but editorService is private in AngularEditorComponent, so seems like the method doesn't work?

teamolhuang commented 4 months ago

Though the service cannot be accessed by other components, the command insertHtml is there. So we used this one to handle hyperlink images, but the idea should be easily translated into one for links.

HTML

An standalone button for adding image, and a input file for handling file prompts, same as @ShemiNechmad 's idea.

          <button type="button" (click)="fileInput.click()"><mat-icon>open_in_new</mat-icon>Add Image</button>
          <input
          style="display: none"
          accept="image/*"
          type="file" (change)="uploadImage($event)" (click)="fileInput.value = ''" 
          #fileInput>
          <!-- note: we clearing fileInput.value so user can choose same image -->

component


@ViewChild(AngularEditorComponent) editor: AngularEditorComponent;

 uploadImage(event: Event) {
    // file handling, basically same as the lib's process of uploading image
    const target = event?.target as HTMLInputElement;
    const files = target?.files;

    if (!files)
      return;

    const file = files[0]; 

    this.productService.uploadFile({
      fileName: file.name,
      file: file
    })
    .pipe(take(1),
     tap((response: any) => {
      const imageUrl = environment.baseApiUrl + response.result.fileNameWithPath;

      const hyperlink = prompt("Hyperlink the image? (Optional)", '');

      // string / empty string: user chose submit, so we should proceed.
     // null: user chose cancel, therefore we end early.
      if (hyperlink == null)
        return;

      let html = `<img src="${imageUrl}"></img>`;

      if (hyperlink) {
        html = `<a href="${hyperlink}" target="_blank">` + html + `</a>`;
      }

      this.editor.executeCommand("insertHtml", html); // using the lib's command to write raw html.
     }))
     .subscribe();
  }

A bit hacky, but it works for me.