Search code examples
htmlangularsweetalertsweetalert2

How to use the InputValidator from sweetalert2 within angular 6 project?


I want to do the following thing:

<button mat-icon-button color="primary" matTooltip="Merge" [swal]="{
    title: 'Are you sure?',
    input: 'text', inputPlaceholder: 'Please type the description in',
    type: 'warning',
    showCancelButton: true,
    confirmButtonText: 'Yes',
    cancelButtonText: 'Cancel',
    confirmButtonClass: 'btn btn-primary',
    cancelButtonClass: 'btn btn-outline-primary',
    inputValidator: (value) => {
        return new Promise((resolve) => {
            if (value.length >= 3) {
                resolve();
            } else {
                resolve('The description should be at least 3 characters!')
            }
        });
        }
    }">
    <mat-icon>call_merge</mat-icon>
</button>

As you can see, I have here one button and sweetalert2 stuff. When user presses the button, a window appears with a text box. This text field must contain at least 3 characters, otherwise the user will see an error message from sweetalert.

The problem is: The Angular compiler is not happy with the inputValidator. The compiler always says that somewhere in the lambda expression of inputValidator a parenthesis is missing. However, if I delete inputValidator, the code works.

I also tried to define the swal components separately, such as

<swal
    #MergeSwal
    title="Are you sure?"
    type="warning"
    input="text"
    inputPlaceholder="Please type the description in"
    [showCancelButton]="true"
    confirmButtonText="Yes"
    cancelButtonText="Cancel"
    confirmButtonClass="btn btn-primary"
    cancelButtonClass="btn btn-outline-primary"
    (inputValidator)="validate($event)">
    </swal>

with a validate function

validate(event) {
    console.log('It works');
    return new Promise((resolve) => {
        if (event.length >= 3) {
            resolve();
        } else {
            resolve('The description should be at least 3 characters!')
        }
      });
}

and with this code for the button

<button mat-icon-button color="primary" matTooltip="Merge" [swal]="MergeSwal">
     <mat-icon>call_merge</mat-icon>
</button>

In this case, the sweetalert window is displayed correctly, but the validator does not work. The validate(...) function is not executed for some reason.

I also tried to define the function

merge() {
    swal({
        title: 'Are you sure?',
        input: 'text',
        inputPlaceholder: 'Please type the description in',
        type: 'warning',
        showCancelButton: true,
        confirmButtonText: 'Yes',
        cancelButtonText: 'Cancel',
        confirmButtonClass: 'btn btn-primary',
        cancelButtonClass: 'btn btn-outline-primary',
        inputValidator: (value) => {
            return new Promise((resolve) => {
            if (value.length >= 3) {
                resolve();
            } else {
                resolve('The description should be at least 3 characters!')
            }
            });
        }
    });
}

Then I call this function when the button is pressed

<button mat-icon-button color="primary" matTooltip="Merge" (click)="merge()">
    <mat-icon>call_merge</mat-icon>
</button>

In this case, everything works well except the .css classes. The necessary error message is displayed, but the Angular compiler obviously does not see any .css classes defined in the .ts file. As a result, the sweetalet window is displayed with standard .css classes.

What is the easiest way to force the inputValidator to work properly?


Solution

  • I solved the problem as follows:

    In my .ts file:

    import { SwalComponent } from '@toverux/ngx-sweetalert2';
    ...
    @ViewChild('mergeDialogSwal') private mergeDialogSwal: SwalComponent;
    ...
    mergeDialogValidator(): void {
        if (this.mergeDialogSwal === undefined) { return; }
        this.mergeDialogSwal.inputValidator = (value) => {
          return new Promise((resolve) => {
            if (value.length >= 3) {
              resolve();
            } else {
              resolve('The description should be at least 3 characters!');
            }
          });
        };
      }
    

    In my .html file:

    <swal #mergeDialogSwal 
          title="Do you really want to merge the batches?"
          text="You can not undo this action!"
          type="warning"
          input="text"
          inputPlaceholder="Specify a description for the merged batch" 
          [showCancelButton]="true"
          confirmButtonText="Yes, merge"
          cancelButtonText="Cancel"
          confirmButtonClass="btn btn-primary"
          cancelButtonClass="btn btn-outline-primary" 
          [inputValidator]="mergeDialogValidator()"
          (confirm)="mergeBatches()">
    </swal>
    ...
    <button (click)="mergeDialogSwal.show()">Click Me</button>
    

    Maybe this solution is not quite good, but I have no other idea. If someone can suggest a better solution, I would be happy.

    Stackblitz: https://stackblitz.com/edit/angular-xhdv9z