primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
10.45k stars 4.6k forks source link

primeng stepperpanel is missing documentation on how to use onClick, prevCallback and nextCallback #15746

Open swapnil0545 opened 5 months ago

swapnil0545 commented 5 months ago

Describe the bug

image Hi all,

First of all thanks to the primeng community for doing great work. I like this library a lot.

Attached is the screenshot of the document link. I am trying to use the new stepper component. I have a form in my first stepperpanel which I want to validate on the click of next button and then allow it to move to next step. But I am finding it hard to figure out on how to achieve this.

Any pointers would be appriciated. Here is the documentation link for same : https://primeng.org/stepper#api.stepper.interfaces.StepperPanelContentTemplate.nextCallback

Thanks, Swapnil

Environment

Windows 11, VS Code node v20 npm 10.5.0

Reproducer

No response

Angular version

17.x.x

PrimeNG version

17.17.0

Build / Runtime

Angular CLI App

Language

TypeScript

Node version (for AoT issues node --version)

20

Browser(s)

No response

Steps to reproduce the behavior

No response

Expected behavior

No response

sergiomachadosilva commented 4 months ago

Managed to solve?

I am facing the same problem

Junior-Stalin commented 3 months ago

same problem

Picoquio commented 2 months ago

Please, this should be addressed. It's quite a common scenario to need validations while navigating between sections of a stepper. As of now it's not clear how to implement it, or even if it's possible.

sergiomachadosilva commented 2 months ago

Solution I found. Below is a simple example of how we can validate each step in the Stepper component.

steps

TypeScript Component

import { Component, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ButtonModule } from 'primeng/button';
import { TriStateCheckboxModule } from 'primeng/tristatecheckbox';
import { Stepper, StepperModule } from 'primeng/stepper';

@Component({
    selector: 'app-test-stepper',
    standalone: true,
    imports: [FormsModule, ButtonModule, TriStateCheckboxModule, StepperModule],
    templateUrl: './test-stepper.component.html',
    styleUrl: './test-stepper.component.scss'
})
export class TestStepperComponent {

    @ViewChild('customStepper') customStepper!: Stepper;

    value: boolean | null = null;
    valueTwo: boolean | null = null;
    valueThree: boolean | null = null;

    onNextStepper(index: number) {
        if (index === 0) {
            if (this.value) {
                this.customStepper.activeStep = index + 1
            } else {
                alert('Invalid Content I')
            }
        } else if (index === 1) {
            if (this.valueTwo && this.valueThree) {
                this.customStepper.activeStep = index + 1
            } else {
                alert('Invalid Content II')
            }
        }
    }

    onSubmit(){
        alert('Finish')
    }
}

HTML Template

<div class="card flex justify-content-center">
    <p-stepper [linear]="true" #customStepper>
        <p-stepperPanel header="Header I">
            <ng-template pTemplate="content" let-index="index">
                <div class="flex flex-column h-12rem">
                    <div class="border-2 border-dashed surface-border border-round surface-ground flex-auto flex justify-content-center align-items-center font-medium">
                        <div class="card flex flex-column gap-3 align-items-center">
                            <p-triStateCheckbox [(ngModel)]="value" inputId="tricheckbox" />
                            <label for="tricheckbox">{{ value === null ? 'null' : value }}</label>
                        </div>
                    </div>
                </div>
                <div class="flex pt-4 justify-content-end">
                    <p-button label="Next" icon="pi pi-arrow-right" iconPos="right" (onClick)="onNextStepper(index)" />
                </div>
            </ng-template>
        </p-stepperPanel>
        <p-stepperPanel header="Header II">
            <ng-template pTemplate="content" let-prevCallback="prevCallback" let-index="index">
                <div class="flex flex-column h-12rem">
                    <div class="border-2 border-dashed surface-border border-round surface-ground flex-auto flex justify-content-center align-items-center font-medium">

                        <div class="mr-3">
                            <p-triStateCheckbox [(ngModel)]="valueTwo" inputId="checkboxTwo" />
                            <label for="checkboxTwo">{{ valueTwo === null ? 'null' : valueTwo }}</label>
                        </div>

                        <p-triStateCheckbox [(ngModel)]="valueThree" inputId="checkboxThree" />
                        <label for="checkboxThree">{{ valueThree === null ? 'null' : valueThree }}</label>
                    </div>
                </div>
                <div class="flex pt-4 justify-content-between">
                    <p-button label="Back" icon="pi pi-arrow-left" (onClick)="prevCallback.emit()" />
                    <p-button label="Next" icon="pi pi-arrow-right" iconPos="right" (onClick)="onNextStepper(index)" />
                </div>
            </ng-template>
        </p-stepperPanel>
        <p-stepperPanel header="Header III">
            <ng-template pTemplate="content" let-prevCallback="prevCallback" let-index="index">
                <div class="flex flex-column h-12rem">
                    <div class="border-2 border-dashed surface-border border-round surface-ground flex-auto flex justify-content-center align-items-center font-medium">
                        Content III
                    </div>
                </div>
                <div class="flex pt-4 justify-content-between">
                    <p-button label="Back" icon="pi pi-arrow-left" (onClick)="prevCallback.emit()" />
                    <p-button severity="success" label="Submit" icon="pi pi-save" iconPos="right" (onClick)="onSubmit()" />
                </div>
            </ng-template>
        </p-stepperPanel>
    </p-stepper>
</div>