Create wizard using Tab

31 Jul 202324 minutes to read

Tab items can be disabled initial control rendering by passing the boolean value to disabled property of TabItem class.

In the below Wizard sample, each Tab is integrated with required components to complete the reservation. Each field is provided with validation for all mandatory option to proceed to next tabs. Using Tab item’s template property the components are added into content.

Create the following contents for each tab in the wizard.

  1. Search tab:
    Created with [DropDownList] to select the source, destination and type of ticket. A [DatePicker] for choosing the date of journey.
  2. Train tab:
    Based on the selected start and end point, populated Grid with random list of available seats and train list. Initially define the columnsand row selected event for validating, after the source and destination chosen update the [dataSource] for the Grid.
  3. Passenger tab:
    A table with Textbox, Numeric, DropDownList for adding passenger name, age, gender and preferred berth/seat. Add validation on entering passenger details to proceed.
  4. Payment tab:
    Calculate the ticket cost based on location, passenger count and ticket type. Generate data for Grid with passenger details, train number and ticket cost summary.

You can go back on each tab using buttons available in it and tabs are disabled to navigate through tab header click actions. Once you end the wizard all the data get cleared and wizard goes back to starting tab.

@using Syncfusion.EJ2.Navigations

@{
    var dlgTarget = "#ej2Tab";
}

<div class="e-tab-section">
    <div class="e-sample-resize-container">
        <div id="booking" style="display: none">
            <div class="wizard-title">Plan your journey</div>
            <div class="responsive-align">
                <div class="row">
                    <div class="col-xs-6 col-sm-6 col-lg-6 col-md-6 search-item">
                        <ejs-dropdownlist id="startPoint" width="100%" dataSource="@ViewBag.citiesData" placeholder="From">
                            <e-dropdownlist-fields text="Name" value="Name"></e-dropdownlist-fields>
                        </ejs-dropdownlist>
                    </div>
                    <div class="col-xs-6 col-sm-6 col-lg-6 col-md-6 search-item">
                        <ejs-dropdownlist id="endPoint" width="100%" dataSource="@ViewBag.citiesData" placeholder="To">
                            <e-dropdownlist-fields text="Name" value="Name"></e-dropdownlist-fields>
                        </ejs-dropdownlist>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 col-sm-6 col-lg-6 col-md-6 search-item">
                        <ejs-datepicker id="date" width="100%" placeholder="Journey Date" min="@ViewBag.min" max="@ViewBag.max" focus="showDate"></ejs-datepicker>
                    </div>
                    <div class="col-xs-6 col-sm-6 col-lg-6 col-md-6 search-item">
                        <ejs-dropdownlist id="quota" dataSource="@ViewBag.quota" placeholder="Ticket type">
                            <e-dropdownlist-fields text="Text" value="Text"></e-dropdownlist-fields>
                        </ejs-dropdownlist>
                    </div>
                </div>
                <div class="btn-container">
                    <button id="searchNext" class="e-btn">Search Train</button>
                </div>
                <span id="err1"></span>
            </div>
        </div>
        <div id="selectTrain" style="display: none">
            <div class="wizard-title">Select the train from the list </div>
            <ejs-grid id="availableTrain" rowSelected="trainSelected" width="100%">
                <e-grid-columns>
                    <e-grid-column field="TrainNo" headerText="Train No" width=120 type="number"></e-grid-column>
                    <e-grid-column field="Name" headerText="Name" width=140></e-grid-column>
                    <e-grid-column field="Departure" headerText="Departure" width=120></e-grid-column>
                    <e-grid-column field="Arrival" headerText="Arrival" width=140></e-grid-column>
                    <e-grid-column field="Availability" headerText="Availability" width=140 type="number"></e-grid-column>
                </e-grid-columns>
            </ejs-grid>
            <br />
            <div class="btn-container">
                <button id="goToSearch" class="e-btn">Back</button>
                <button id="bookTickets" class="e-btn">Continue</button>
            </div>
            <span id="err2"></span>
        </div>
        <div id="details" style="display: none">
            <div class="details-page wizard-title">Enter the passenger details</div>
            <div id="PassengersList">
                <table id="passenger-table">
                    <colgroup>
                        <col />
                        <col />
                        <col />
                        <col />
                        <col />
                        <col />
                    </colgroup>
                    <thead>
                        <tr>
                            <th class="name-header">Name</th>
                            <th class="age-header">Age</th>
                            <th class="gender-header">Gender</th>
                            <th class="type-header">Berth Preference</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>
                                <input id="pass_name1" class="e-input" type="text" placeholder="Passenger Name">
                            </td>
                            <td>
                                <ejs-numerictextbox id="pass_age1" min=1 max=100 value=18 format=n0 showSpinButton="false"></ejs-numerictextbox>
                            </td>
                            <td>
                                <ejs-dropdownlist id="pass_gender1" text="Male" dataSource="@ViewBag.gender">
                                    <e-dropdownlist-fields text="Text" value="Text"></e-dropdownlist-fields>
                                </ejs-dropdownlist>
                            </td>
                            <td>
                                <ejs-dropdownlist id="pass_berth1" placeholder="Optional" dataSource="@ViewBag.berth">
                                    <e-dropdownlist-fields text="Text" value="Text"></e-dropdownlist-fields>
                                </ejs-dropdownlist>
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <input id="pass_name2" class="e-input" type="text" placeholder="Passenger Name">
                            </td>
                            <td>
                                <ejs-numerictextbox id="pass_age2" min=1 max=100 value=18 format=n0 showSpinButton="false"></ejs-numerictextbox>
                            </td>
                            <td>
                                <ejs-dropdownlist id="pass_gender2" text="Male" dataSource="@ViewBag.gender">
                                    <e-dropdownlist-fields text="Text" value="Text"></e-dropdownlist-fields>
                                </ejs-dropdownlist>
                            </td>
                            <td>
                                <ejs-dropdownlist id="pass_berth2" placeholder="Optional" dataSource="@ViewBag.berth">
                                    <e-dropdownlist-fields text="Text" value="Text"></e-dropdownlist-fields>
                                </ejs-dropdownlist>
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <input id="pass_name3" class="e-input" type="text" placeholder="Passenger Name">
                            </td>
                            <td>
                                <ejs-numerictextbox id="pass_age3" min=1 max=100 value=18 format=n0 showSpinButton="false"></ejs-numerictextbox>
                            </td>
                            <td>
                                <ejs-dropdownlist id="pass_gender3" text="Male" dataSource="@ViewBag.gender">
                                    <e-dropdownlist-fields text="Text" value="Text"></e-dropdownlist-fields>
                                </ejs-dropdownlist>
                            </td>
                            <td>
                                <ejs-dropdownlist id="pass_berth3" placeholder="Optional" dataSource="@ViewBag.berth">
                                    <e-dropdownlist-fields text="Text" value="Text"></e-dropdownlist-fields>
                                </ejs-dropdownlist>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <br />
            <div class="btn-container">
                <button id="goBackToBook" class="e-btn">Back</button>
                <button id="confirmTickets" class="e-btn">Continue</button>
            </div>
            <span id="err3"></span>
        </div>
        <div id="confirm" style="display: none">
            <div class="tab-title1 wizard-title">Confirm the details and proceed</div>
            <ejs-grid id="ticketDetailGrid" width="100%">
                <e-grid-columns>
                    <e-grid-column field="TrainNo" headerText="Train No" width=120 type="number"></e-grid-column>
                    <e-grid-column field="PassName" headerText="Name" width=140></e-grid-column>
                    <e-grid-column field="Gender" headerText="Gender" width=120></e-grid-column>
                    <e-grid-column field="Berth" headerText="Berth" width=140></e-grid-column>
                </e-grid-columns>
            </ejs-grid>
            <br />
            <div id="amount"></div>
            <br />
            <div class="btn-container">
                <button id="goBackDetails" class="e-btn">Back</button>
                <button id="makePayment" class="e-btn">Pay</button>
            </div>
        </div>
        <ejs-tab id="ej2Tab" heightAdjustMode="None" height="390" created="tabCreated" selecting="tabSelecting">
            <e-tab-tabitems>
                <e-tab-tabitem header="@ViewBag.headerTextOne" content="@ViewBag.content1"></e-tab-tabitem>
                <e-tab-tabitem header="@ViewBag.headerTextTwo" content="@ViewBag.content2" disabled="true"></e-tab-tabitem>
                <e-tab-tabitem header="@ViewBag.headerTextThree" content="@ViewBag.content3" disabled="true"></e-tab-tabitem>
                <e-tab-tabitem header="@ViewBag.headerTextFour" content="@ViewBag.content4" disabled="true"></e-tab-tabitem>
            </e-tab-tabitems>
        </ejs-tab>
        <div>
            <ejs-dialog id="alertDialog" header="Success" width=250 target="@dlgTarget" isModal=true created="dlgCreated" visible=false showCloseIcon="true"></ejs-dialog>
        </div>
    </div>
</div>

<script>
    var tabObj;
    var endPoint;
    var alertDlg;
    var locations;
    var ticketType;
    var startPoint;
    var journeyDate;
    var selectedTrain;
    var availTrainGrid;
    var ticketDetailGrid;

    var cities = [
        { name: "Chicago", fare: 300 },
        { name: "San Francisco", fare: 125 },
        { name: "Los Angeles", fare: 175 },
        { name: "Seattle", fare: 250 },
        { name: "Florida", fare: 150 }
    ];

    function tabCreated() {
        document.getElementById("searchNext").onclick = function (e) { tabNavigations(e); };
        document.getElementById("bookTickets").onclick = function (e) { tabNavigations(e); };
        document.getElementById("confirmTickets").onclick = function (e) { tabNavigations(e); };
        document.getElementById("makePayment").onclick = function (e) { tabNavigations(e); };
        document.getElementById("goToSearch").onclick = function (e) { tabNavigations(e); };
        document.getElementById("goBackToBook").onclick = function (e) { tabNavigations(e); };
        document.getElementById("goBackDetails").onclick = function (e) { tabNavigations(e); };

        tabObj = document.getElementById("ej2Tab").ej2_instances[0];
        startPoint = document.getElementById("startPoint").ej2_instances[0];
        endPoint = document.getElementById("endPoint").ej2_instances[0];
        ticketType = document.getElementById("quota").ej2_instances[0];
        journeyDate = document.getElementById("date").ej2_instances[0];
        availTrainGrid = document.getElementById("availableTrain").ej2_instances[0];
        ticketDetailGrid = document.getElementById("ticketDetailGrid").ej2_instances[0];
    }

    function showDate() {
        journeyDate = document.getElementById("date").ej2_instances[0];
        journeyDate.show();
    }

    function tabSelecting(e) {
        if (e.isSwiped) {
            e.cancel = true;
        }
    }

    function dlgCreated() {
        alertDlg = document.getElementById("alertDialog").ej2_instances[0];
        alertDlg.content = "Your payment successflly processed";
        alertDlg.buttons = [{
            buttonModel: { content: "Ok", isPrimary: true },
            click: function () {
                alertDlg.hide();
                tabObj.enableTab(0, true);
                tabObj.enableTab(1, false);
                tabObj.enableTab(2, false);
                tabObj.enableTab(3, false);
                tabObj.select(0);
            }
        }];
        alertDlg.dataBind();
        alertDlg.hide();
    }

    function trainSelected(args) {
        selectedTrain = args.data;
    }

    function filterTrains(args) {
        /* Generating trains based on source and destination chosen */
        var result = [];
        var fromCity = startPoint.text;
        var toCity = endPoint.text;
        var count = Math.floor((Math.random() * 3) + 2);
        for (var i = 0; i < count; i++) {
            var details = [];
            details.TrainNo = Math.floor((Math.random() * 20) + 19000);
            details.Name = "Train " + i;
            details.Departure = fromCity;
            details.Arrival = toCity;
            details.Availability = Math.floor((Math.random() * 20) + 20);
            result.push(details);
        }
        availTrainGrid.dataSource = result;
    }
    function finalizeDetails(args) {
        /* Get the passenger details and update table with name and other details for confirmation */
        var reserved = [];
        var passCount = 0;
        for (var i = 1; i <= 3; i++) {
            var name = document.getElementById("pass_name" + i);
            var berthSelected = document.getElementById("pass_berth" + i);
            var gender = document.getElementById("pass_gender" + i);
            if (name.value !== "") {
                var details = [];
                var berth = berthSelected.value;
                details.TrainNo = selectedTrain.TrainNo.toString();
                details.PassName = name.value;
                details.Gender = gender.value;
                details.Berth = (berth === "") ? "Any" : berth;
                reserved.push(details);
                passCount++;
            }
            var calcFare = 0;
            for (var i in cities) {
                if (startPoint.value == cities[i].name)
                    calcFare = calcFare + cities[i].fare;
                if (endPoint.value == cities[i].name)
                    calcFare = calcFare + cities[i].fare;
            }
            var displayAmt = document.getElementById("amount");
            if (ticketType.value === "Economy Class") {
                displayAmt.innerText = "Total payable amount: $" + passCount * (300 + calcFare)
            } else if (ticketType.value === "Business Class") {
                displayAmt.innerText = "Total payable amount: $" + passCount * (500 + calcFare)
            } else if (ticketType.value === "Common Class") {
                displayAmt.innerText = "Total payable amount: $" + passCount * (150 + calcFare)
            }
        }
        ticketDetailGrid.dataSource = reserved;
    }

    function tabNavigations(args) {
        switch (args.target.id) {
            case "searchNext":
                /* Validate the Source, Destination, Date and Class chosen and proceed only if all the fields are selected */
                if (!ej.base.isNullOrUndefined(startPoint.value) && !ej.base.isNullOrUndefined(endPoint.value) &&
                    !ej.base.isNullOrUndefined(ticketType.value) && !ej.base.isNullOrUndefined(journeyDate.value)) {
                    if (!ej.base.isNullOrUndefined(startPoint.value) && startPoint.value === endPoint.value) {
                        document.getElementById("err1").innerText = "* Arrival point can\"t be same as Departure";
                    }
                    else {
                        tabObj.enableTab(0, false);
                        tabObj.enableTab(1, true);
                        filterTrains(args);
                        tabObj.select(1);
                        document.getElementById("err1").innerText = "";
                        document.getElementById("err2").innerText = "";
                    }
                }
                else {
                    document.getElementById("err1").innerText = "* Please fill all the details before proceeding";
                }
                break;
            case "bookTickets":
                /* Based on the selected station generate Grid content to display trains available */
                if (availTrainGrid.getSelectedRecords() === undefined || availTrainGrid.getSelectedRecords().length === 0) {
                    document.getElementById("err2").innerText = "* Select your convenient train";
                }
                else {
                    tabObj.enableTab(2, true);
                    tabObj.select(2);
                    tabObj.enableTab(1, false);
                    document.getElementById("err2").innerText = "";
                }
                break;
            case "confirmTickets":
                /* Get the Passenger details and validate the fields must not be left empty */
                var name = document.getElementById("pass_name1");
                var age = document.getElementById("pass_age1");
                var gender = document.getElementById("pass_gender1");
                if (name.value === "" || age.value === "" || gender.value === "") {
                    document.getElementById("err3").innerText = "* Please enter passenger details";
                }
                else {
                    tabObj.enableTab(3, true);
                    tabObj.select(3);
                    tabObj.enableTab(2, false);
                    document.getElementById("err3").innerText = "";
                    finalizeDetails(args);
                }
                break;
            case "makePayment":
                alertDlg.show();
                break;
            case "goToSearch":
                /* Go back to change class, date or boarding places */
                selectedTrain = [];
                tabObj.enableTab(0, true);
                tabObj.select(0);
                tabObj.enableTab(1, false);
                break;
            case "goBackToBook":
                /* Change the preferred train chosen already */
                tabObj.enableTab(1, true);
                tabObj.select(1);
                tabObj.enableTab(2, false);
                break;
            case "goBackDetails":
                /* Update passenger detail before confirming the payment */
                tabObj.enableTab(2, true);
                tabObj.select(2);
                tabObj.enableTab(3, false);
                break;
        }
    }
</script>

<style>
    .e-content .e-item {
        font-size: 12px;
        margin: 10px;
    }

    #amount {
        text-align: right;
        font-size: 15px;
        padding: 15px 0px;
    }

    #passenger-table th {
        text-align: center;
        font-size: 14px;
        font-weight: 400;
        border: 1px solid gainsboro;
    }

    #passenger-table td,
    th {
        padding: 10px;
    }

    #passenger-table td {
        border: 1px solid gainsboro;
    }

    .name-header {
        width: 200px;
    }

    .age-header {
        width: 80px;
    }

    .gender-header {
        width: 120px;
    }

    .type-header {
        width: 150px;
    }

    .btn-container {
        text-align: center;
    }

    .search-item {
        padding-right: 50px;
        padding-bottom: 20px;
    }

    .item-title {
        font-weight: 500;
        padding-top: 10px;
    }

    @@media (max-width: 450px) {
        .e-sample-resize-container {
            height: 450px;
        }

        .responsive-align {
            width: 75%;
            margin: 0 auto;
        }

        .search-item {
            padding: 0 0 20px 0;
            width: 100%;
        }
    }

    #err1,
    #err2,
    #err3 {
        font-weight: bold;
        color: red;
        display: block;
        margin-top: 15px;
    }

    .wizard-title {
        font-size: 15px;
    }

    #PassengersList {
        overflow: auto;
    }

    #passenger-table {
        min-width: 500px;
        width: 100%;
    }

    .e-tab-section {
        padding: 0 15px;
    }
</style>
public ActionResult Index()
{
    List<DataFields> quotaData = new List<DataFields>();
    List<DataFields> genderData = new List<DataFields>();
    List<DataFields> berthData = new List<DataFields>();
    List<CitiesFields> citiesData = new List<CitiesFields>();

    quotaData.Add(new DataFields { ID = "1", Text = "Business Class" });
    quotaData.Add(new DataFields { ID = "2", Text = "Economy Class" });
    quotaData.Add(new DataFields { ID = "3", Text = "Common Class" });

    genderData.Add(new DataFields { ID = "1", Text = "Male" });
    genderData.Add(new DataFields { ID = "2", Text = "Female" });

    berthData.Add(new DataFields { ID = "1", Text = "Upper" });
    berthData.Add(new DataFields { ID = "2", Text = "Lower" });
    berthData.Add(new DataFields { ID = "3", Text = "Middle" });
    berthData.Add(new DataFields { ID = "4", Text = "Window" });
    berthData.Add(new DataFields { ID = "5", Text = "Aisle" });

    citiesData.Add(new CitiesFields { Name = "Chicago", Fare = 300 });
    citiesData.Add(new CitiesFields { Name = "San Francisco", Fare = 125 });
    citiesData.Add(new CitiesFields { Name = "Los Angeles", Fare = 175 });
    citiesData.Add(new CitiesFields { Name = "Seattle", Fare = 250 });
    citiesData.Add(new CitiesFields { Name = "Florida", Fare = 150 });

    ViewBag.headerTextOne = new TabHeader { Text = "New Booking" };
    ViewBag.headerTextTwo = new TabHeader { Text = "Train List" };
    ViewBag.headerTextThree = new TabHeader { Text = "Add Passenger" };
    ViewBag.headerTextFour = new TabHeader { Text = "Make Payment" };

    ViewBag.quota = quotaData;
    ViewBag.gender = genderData;
    ViewBag.berth = berthData;
    ViewBag.citiesData = citiesData;

    ViewBag.content1 = "#booking";
    ViewBag.content2 = "#selectTrain";
    ViewBag.content3 = "#details";
    ViewBag.content4 = "#confirm";

    ViewBag.min = DateTime.Now;
    ViewBag.max = DateTime.Now.AddMonths(3);

    return View();
}
public class DataFields
{
    public string ID { get; set; }
    public string Text { get; set; }
}
public class CitiesFields
{
    public string Name { get; set; }
    public int Fare { get; set; }
}