2

I have created a modal with css and pure html for my angular application, I try to show it and hide it with the ng-if property and with @input.

but the problem is that I can only open it once and close it once, after closing it it won't open again.

and I don't know what the problem is in my logic

This is my component modal HTML.

<div class="card mymodal z-depth-5" *ngIf="noDisplay">
  <form class="form center" (ngSubmit)="enviar(f)" #f="ngForm">
    <div>
      <h3 class="center">Crear Usuario</h3>
    </div>

    <!-- nombre  -->
    <div class="row">
      <div class="input-field col s6">
        <input id="name" type="text" name="nombre" [(ngModel)]="usuario.nombre" >
        <label for="first_name">Nombre</label>
      </div>

      <!-- nombre  -->

      <!-- Apellido  -->
      <div class="input-field col s6">
        <input id="name" type="text" [(ngModel)]="usuario.apellido" name="apellido">
        <label for="first_name">Apellido</label>
      </div>
    </div>
    <!-- Apellido  -->


    <!-- Usuario  -->
    <div class="row">
      <div class="input-field col s6">
        <input id="name" type="text" [(ngModel)]="usuario.usuario" name="usuario">
        <label for="first_name">Nombre de Usuario</label>
      </div>
      <!-- Usuario  -->

      <!-- Email  -->
      <div class="input-field col s6">
        <input id="email" type="email" [(ngModel)]="usuario.email" name="email">
        <label for="email">Email</label>
      </div>
    </div>
<!-- Email  -->

<!-- Passwor  -->
    <div class="row">
      <div class="input-field col s6">
        <input id="password" type="password" [(ngModel)]="usuario.password" name="password">
        <label for="password">Password</label>
      </div>
<!-- Passwor  -->

    </div>
    <div class="row">
      <div class="row">
        <div class="input-field col s12">
          <button  (click)="cerrar()" class="btn waves-effect waves-light right ml-1 mt-2 grey darken-1"
          type="submit" name="action">Cancelar
          </button>
          <button class="btn waves-effect  gradient-45deg-light-blue-cyan right mt-2" type="submit" name="action">Guardar
            <i class="material-icons right">save</i>
          </button>
        </div>
      </div>
    </div>
  </form>
</div>

CSS

.mymodal{
  position: fixed;
  z-index: 2000;
  height: 500px;
  width: 70%;
  background-color: aliceblue;
}

.form{
  padding-left: 10%;
  padding-right: 10%;
}

TS file

import { Component, OnInit, Output, Input } from '@angular/core';
import { EventEmitter } from 'protractor';
import { AuthService } from 'src/app/services/services.index';
import { NgForm } from '@angular/forms';
import { NuevoUsuario } from 'src/app/models/nuevosUsuario';


@Component({
  selector: 'app-modal-form',
  templateUrl: './modal-form.component.html',
  styleUrls: ['./modal-form.component.css']
})
export class ModalFormComponent implements OnInit {

  usuario: NuevoUsuario;
  errorMessage: boolean;
  @Input() noDisplay: boolean;

  constructor(private register: AuthService) { }

  ngOnInit(): void {
    this.usuario = new NuevoUsuario();
  }


  enviar(form: NgForm) {
    if (form.invalid) {
      console.log('Formulario Invalido');
      return;
    }

    this.register.createUser(this.usuario).subscribe(resp => {
      console.log('usuario registrado');
    }, (err) => {
      this.errorMessage = true;
      console.log(err.message);
      console.log('ocurrio un error');
    }

    );
  }

  // close the modal
  cerrar() {
    this.noDisplay = false;
  }    

}

and this is where I try to use it

<app-modal-form [noDisplay]="modal" ></app-modal-form>

<div class="row">
  <button class="btn gradient-45deg-light-blue-cyan ml-5" (click)="activarModal()">Nuevo
    <i class="material-icons right">person_add</i>
  </button>
</div>

import { Component, OnInit } from '@angular/core';
import { UsuariosService } from '../../services/services.index';
import { Usuario } from 'src/app/models/usuario';

@Component({
  selector: 'app-admin-panel',
  templateUrl: './admin-panel.component.html',
  styleUrls: ['./admin-panel.component.css']
})
export class AdminPanelComponent implements OnInit {

  modal: boolean;
  usuariosData: Usuario[] = [];
  total: number;
  // total_activos: Usuario[] = [];

  constructor(private usuario: UsuariosService) { }

  ngOnInit(): void {
    this.getAllusers();
  }


  // optiene todos los usuarios
  getAllusers() {
    this.usuario.getAllUsers().subscribe((data: any) => {
      this.usuariosData = data.usuarios;
      this.total = this.usuariosData.length;
    });
  }


  // Open the modal
  activarModal() {
    this.modal = true;
  }    
}

enter image description here enter image description here

geraktOfRivia
  • 325
  • 3
  • 7
  • 19

2 Answers2

1

After looking at your code again it appears the problem is that you're setting noDisplay to equal the value of modal. But modal is only false when the parent component first loads. You set it to true when you trigger this function:

  activarModal() {
    this.modal = true;
  }    

Now, that's going to be leave this.modal as true until the parent component re-mounts. So, logically, that's why you can only open the modal once with your current implementation.

To resolve this, use @Output() someEvent = new EventEmitter(); to pass details back to the parent from the child component, and re-set this.modal to false when that event fires. The event you want to trigger on for the @Output() is this one in your modal component:

  // close the modal
  cerrar() {
    this.noDisplay = false;
  }

See this answer for more details on @Output(): Pass Event from child component to parent component Angular 5

Muirik
  • 6,049
  • 7
  • 58
  • 116
1

in your parent component

export class AdminPanelComponent implements OnInit {

// open modal
activarModal() {
    this.noDisplay = true;
}

// close modal
onHidePopup() {
    this.noDisplay = false;
}

in your popup component

export class ModalFormComponent implements OnInit {
@Input() noDisplay;
// use output to pass event
@Output() onHidePopup = new EventEmitter();

cerrar() {
  this.onHidePopup.emit();
}

and in html admin you should pass noDisplay for showing popup and onHidePopup to back the parent

<app-modal-form [noDisplay]="noDisplay" (onHidePopup)="onHidePopup()"></app-modal-form>
agung
  • 136
  • 2