0

I'm creating wizard with steps. I have two components which has no parent-child relationship:

  1. Footer component with submit button which is redirecting to the next step.
  2. Form component which has validation on some inputs.

I created also a service for communication between those 2 components above.

What I want to achieve is to invoke method on footer submit button which will check if form from component number 2 is valid. If yes, we can go to next step, if not, I need to invoke validation errors, without going to next step, until user pass some information to inputs on form.

I'm not sure how can I achieve this. Any thoughts? Thank you.

I have tried to invoke validation on button but in the same form component. It works as expected. Now I would like to invoke this method on submit button in the footer.

This is my onSubmitStep() method in footer component:

public onSubmitStep() {
    if (this.currentStep < this.maxSteps) {
        this.currentStep += 1;
        this.switchStep();
        this.showDefaultFooter = false;
    }
}

This is what I have in my form component:

public contractPropertiesContent: ContractPropertiesInput;
public contractPropertiesForm: FormGroup;

constructor(private fb: FormBuilder, private router: Router, private contractPropertiesService: ContractPropertiesService) {}

ngOnInit() {
    this.contractPropertiesContent = this.contractPropertiesService.getContractPropertiesContent();
    this.contractPropertiesForm = this.initFormGroup();
}

private initFormGroup() {
    return this.fb.group({
        paymentConditionsInput: ['', Validators.required],
        creditDaysInput: ['', Validators.required],
        targetInput: ['', Validators.required]
    });
}
Milo
  • 3,365
  • 9
  • 30
  • 44
whiteBear22
  • 377
  • 2
  • 8
  • 21
  • I suggest you create a working sample on Stackblitz, it will really help us solve it better. – Yash Aug 27 '19 at 17:52
  • Hello, thanks for response. I've prepared the structure for what I mean above here: https://stackblitz.com/edit/angular-6kdkjx – whiteBear22 Aug 27 '19 at 18:10
  • Cool, I am checking it – Yash Aug 27 '19 at 18:13
  • Do you really need to have the button and form in seperate components? – Yash Aug 27 '19 at 18:26
  • Unfortunately yes, button is in footer component and form is in separate. That will be easy if I can have those two in single one :D – whiteBear22 Aug 27 '19 at 18:27
  • Alright, I do have a solution in mind, putting it in stackblitz – Yash Aug 27 '19 at 18:28
  • it's like https://stackoverflow.com/questions/40788458/how-to-call-component-method-from-service-angular2/57669031#57669031. You only subscribe in form.component and in footer.component – Eliseo Aug 27 '19 at 18:37

1 Answers1

1

complementary the comment (see a simple stackblitz based in yours stackblitz

in your form.component

  ngOnInit() {
    this.myService.customObservable
       .pipe(filter((x:any)=>x.command)
       .subscribe(res=>{
         if (res.command=="check")
         {
           this.contractPropertiesForm.updateValueAndValidity();
           this.myService.callComponentMethod({isValid:this.contractPropertiesForm.valid})
         }
    })
    this.contractPropertiesForm=this.initFormGroup()
  }

In your footer.component

  ngOnInit() {
    this.myService.customObservable
      .pipe(filter(x=>x.isValid!=null))
      .subscribe(res=>{
         if (res.isValid)
         {
            if (this.currentStep < this.maxSteps) {
              this.currentStep += 1;
         }
       }
    })
  }

  public onSubmitStep() {
        this.myService.callComponentMethod({command:"check"})
  }

See that the button make a callComponentMethod({command:"check"}) and susbcribe to the observable. Is the observable who mannage currentStep

The form listen for an object with "command", and send to callComponentMethod if the form is valid or not

updated: a simple aproach if the form.component and footer.component belong to the same <router-outlet> (*) is using Input

If out main component is like

<app-form #form></app-form>
<app-footer [form]="form"></app-footer>

Out footer get in a Input the form.component

@Input('form') form

And we can simply

  public onSubmitStep() {
      this.form.contractPropertiesForm.updateValueAndValidity();
      if (this.form.contractPropertiesForm.valid)
          this.currentStep++;
  }

See the new stackblitz

(*)I want to say that this aproach it's not valid if we has some like

<router-outlet></router-outlet>
<app-footer ></app-footer>
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • Yes! That's it! Now it works :) I did not know that this could be so tricky. Thank you a lot! – whiteBear22 Aug 27 '19 at 19:26
  • @MichałBrzozowski, I feel so stupid.... there're a simple way to do it. I updated the answer – Eliseo Aug 28 '19 at 06:10
  • what in case instead of having`````` I have router outlet? Will the simple approach work as well? – whiteBear22 Aug 28 '19 at 06:26
  • well, if you has `` the only way I know is the first aproach: using a service. the second aproach it's only if footer.component and form.component shared the same ourlet, I correct the answer to avoid confusion – Eliseo Aug 28 '19 at 06:30