froala / angular-froala-wysiwyg

Angular 4, 5, 6, 7, 8 and 9 plugin for Froala WYSIWYG HTML Rich Text Editor.
https://froala.com/wysiwyg-editor
734 stars 201 forks source link

Using Native Angular Events #191

Open dockleryxk opened 6 years ago

dockleryxk commented 6 years ago

I know that this question has popped up a few times, #74 for example. However I don't think the answer supplied each time (see https://github.com/froala/angular2-froala-wysiwyg#events-and-methods) is what users of this package are looking for. So, I am going to try to explain what I think the issue is a bit more in-depth as I have gone through the same thing.

Goal: save the contents of the editor on blur event for example.

How I am currently making it work: Instead of using the traditional Angular way of listening for an event, I have to add a button to the DOM to call a click event from the froala blur event callback. Below is the relevant code.

HTML:

<div id="froalaEditor"
        (froalaInit)="initialize($event)"
        [froalaEditor]="options"
        [(froalaModel)]="pageData.html">
</div>
<button id="hacky-button-because-froala"
              (click)="someFunction()"></button>

TS:

export class EditCustomPageComponent implements OnInit, AfterViewInit {

...

options = {
    charCounterCount: true,
    fontSizeDefaultSelection: '14',
    heightMin: 500,
    events: {
      'froalaEditor.blur': function (e, editor) {
        document.getElementById('hacky-button-because-froala').click();
      }
    }
  };

...

}

CSS:

#hacky-button-because-froala {
  display: block;
  height: 0;
  width: 0;
  background: transparent;
  position: absolute;
  top: -1000px;
  left: -1000px;
}

While this works, it is not a desirable solution, because I want direct access to the rest of the methods and members of my component class. Also, this solution would probably not work if I needed to render on the server.

Desired functionality: What I believe to be the desired functionality of most angular devs would be something like the following:

<div id="froalaEditor"
        (froalaInit)="initialize($event)"
        [froalaEditor]="options"
        [(froalaModel)]="pageData.html"
        (blur)="someFunction()">
</div>

TS:

export class EditCustomPageComponent implements OnInit, AfterViewInit {

...

someFunction() {
    // do something, but with access to the component members
}

...

}
RookieLittleFatty commented 6 years ago

I have a similar usage, and what my problem is , i new a eventEmiter, fire it when the editor blur to get the new content, but when i focus to edit and next click the button immediately, it only fire the blur function , never fire the buttong click . why? Did i make any mistake?

jdodsoncollins commented 6 years ago

I'm having an issue which sounds like has the same source as the two commenters above me:

I have a callback function which is reliant on rxjs but it will not properly fire unless I do the following 1) Click custom button in froala 2) Click form input element OUTSIDE froala (to de-focus?) 3) Click custom button in froala a second time => then the modal appears

At at that point the rxjs-based modal system referenced in my callback function will fully work. Normally, the modals are kept hidden via display:none until provided a component and requested, and they are staying hidden unless the above steps happen. No console errors, and definitely no problem in the modal system which is used extremely heavily elsewhere in the web app.

If I click the custom froala button immediately upon page load, it will also work fine. In the interim, I've learned that using v1.0 of angula-froala-wysiwyg works fine. Anything under angula-froala-wysiwyg 2.x has this issue

Code:

Using froala 2.8 + ng 5.2.7 + rxjs 5.5.6

    $.FroalaEditor.DefineIcon('custom_insertImage', { NAME: 'image' });
    $.FroalaEditor.RegisterCommand('custom_insertImage', {
        title: 'Insert Image',
        focus: false,
        undo: true,
        callback: function() { parent.launchImageEditor(this) },
    });

which calls in an ng service that opens a modal:

private launchImageEditor(scope) {
    let component = this;
    let modal: Modal = new Modal();
    modal.title = 'Upload an Image';
    modal.component = UploadImageComponent;
    modal.data = scope;
    component.modalService.changeModal(modal);
}

In this launchImageEditor method, all data is passed in properly and the code paths are all making it all the way though. Something is preventing rxjs/angular from updating the Dom to remove the 'display:none' to reveal the modal.

The mention of rxjs is added in case it helps. I don't know if that has any bearing on the issue.

stefanneculai commented 6 years ago

@dockleryxk thanks for all these. Probably it somehow makes sense to expose all the editor events like (froalaEventName)="someFunction()". I am marking this as a feature-request.

dockleryxk commented 6 years ago

@stefanneculai Exactly! Thank you, even with having to use a workaround for now, Froala is super awesome!

ghost commented 6 years ago

This feature is what I need to make proper use of readonly on my editor

thomasvasbinder commented 6 years ago

I think I have a related issue.

I add a new command (custom-command) and I want to emit an event when the corresponding button is clicked in the toolbar.

export class EditorComponent {

  @Output() customOutput = new EventEmitter<void>();

  public froalaOptions: Object = {
    toolbarButtons,
    toolbarButtonsMD,
    toolbarButtonsSM,
    ...
    events: {
      'froalaEditor.commands.after': (e, editor, cmd) =>
      {
        if (cmd === 'custom-command')
        {
          this.customOutput.emit();
          console.log('Executed');
        }
      },
    },
    ...
  };
}

However, the event is not emitted when I click on the button (only the message Executed is logged to the console). I have to click somewhere else on the page to trigger the event.

dockleryxk commented 6 years ago

@thomasvasbinder you will have to implement a similar method to what I did for now. The event function is out of scope and does not have access to your component's info

timnguyentps commented 4 years ago

Hi Everyone. I Can't capture Backspace or Delete key event events: { 'froalaEditor.keydown': (e: any, editor: any, keydownEvent: any) => { return false } The text has been removed before I can prevent it.

rekna1 commented 4 years ago

What is the status ? I have similar problem : button on toolbar needs to trigger a rxjs subject... but apparently it is not inside angular zone which I would expect from an angular component

marcramser commented 2 years ago

If anyone tries to prevent backspace in angular (we use angular-froala-wysiwyg: "^4.0.8". I was able to make it work with this (hacky code):

const option = {
    events: {
      'initialized' : function() {
        (this as any).events.on('keydown', (keypressEvent: any) => {
          if (keypressEvent.which == 8) {
            keypressEvent.preventDefault();
            keypressEvent.stopPropagation();
            return false;
          }
          return true;
        }, true);
      }
    }
}
Hiaslafson commented 2 years ago

Any update on this issue. The hacky button still the best option?

dockleryxk commented 1 year ago

@Hiaslafson I am still using the hacky button. The good news is that it still works well enough.