0

I have created a Single Page Application in which create three HTML Pages names: 1. Index.html (Master Page), 2. Home.html, and 3. Contact.html and also two JavaScript Pages: 1. Index.js (for Master HTML Page), and 2. Contact.js (For Contact.html Page). I have bind the Home.html and Contact.html pages on index.html like a partial view using JQuery when clicking on the link button that is on the index.html page.

Here is my code of all the pages

index.html page

    <!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"></script>
    <title>Knockout.js SPA</title>
</head>

<body>
    <div id="app" class="container-fluid my-4">
        <div class="container">
            <nav>
                <ul class="nav justify-content-end">
                    <li class="nav-item">
                        <a data-bind="click: navigateToPage.bind($data, 'Home')" class="nav-link active"
                            aria-current="page" href="#">Home</a>
                    </li>
                    <li class="nav-item">
                        <a data-bind="click: navigateToPage.bind($data, 'Contact')" class="nav-link"
                            href="#">Contact</a>
                    </li>
                </ul>
            </nav>
        </div>
        <hr />
        <!-- Page content -->
        <div data-bind="visible: currentPage().length > 0">

            <!-- Content will be loaded dynamically here -->
            <div data-bind="html: currentPageContent"></div>
        </div>

    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.4/knockout.validation.min.js"></script>
    <script src="index.js"></script>
    <script src="Contact.js"></script>
</body>

</html>

index.js Page

   function AppViewModel() {
    var self = this;

    self.currentPage = ko.observable('');
    self.currentPageContent = ko.observable('');

    self.DataSet = function (page) {
        $.ajax({
            url: page + '.html',
            method: 'GET',
            success: function (data) {
                self.currentPage(page);
                self.currentPageContent(data);
            },
            error: function () {
                console.error('Error loading page: ' + page);
            }
        });
    };

    // Load home page by default
    self.DataSet('Home');


    self.navigateToPage = function (page) {
        // Load page content dynamically
        self.DataSet(page);
        applyBindingsForPage(page);
    };
}

var CurrentModel;

// Apply the correct ViewModel after loading page content
function applyBindingsForPage(page) {
    if (page === "Home") {
        CurrentModel = new AppViewModel();
    } else if (page === "Contact") {
        CurrentModel = new ContactViewModel();
    }
}

$(document).ready(function () {
    // default binding Home.html page
    applyBindingsForPage("Home");
    ko.applyBindings(CurrentModel, document.getElementById("app"));
});

Home.html Page

<div class="container my-3">
    <div class="my-4 row">
        <div class="col-12 col-lg-2 col-xl-3"></div>
        <div class="col-12 col-lg-8 col-xl-6 text-center">
            <h2>Knockout JS SPA</h2>
            <p>Creating a single-page application (SPA) using Knockout.js involves building a web application where the
                entire content is loaded dynamically without refreshing the page. Knockout.js provides data binding and
                dependency tracking features that facilitate the development of SPAs.</p>
        </div>
        <div class="col-12 col-lg-2 col-xl-3"></div>
    </div>
</div>
</div>

Contact.html Page

   <div class="container py-5 p-3 bg-body-tertiary border border-5">
    <form data-bind="submit: submitForm" class="g-3 needs-validation" novalidate>
        <div class="row p-4">
            <div class="col-12 col-md-6">
                <label class="form-label">Name</label>
                <input type="text" data-bind="value: name" class="form-control" placeholder="enter name" required>
                <div class="invalid-feedback">
                    Please enter Name.
                </div>
            </div>
            <div class="col-12 col-md-6">
                <label class="form-label">EmailID</label>
                <input type="text" data-bind="value: EmailID" class="form-control" aria-describedby="inputGroupPrepend"
                    placeholder="[email protected]" required>
                <div class="invalid-feedback">
                    Please choose a username.
                </div>
            </div>
            <div class="text-center m-3">
                <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </div>
    </form>
</div>

<script src="Contact.js"></script>

And the last one is Contact.js Page

function ContactViewModel() {
    var self = this;

    self.name = ko.observable("").extend({
        required: true,
        minLength: 2,
        maxLength: 25
    });

    self.EmailID = ko.observable("").extend({
        required: true,
        email: true
    });

    self.submitForm = function () {
        if (self.errors().length === 0) {
            // Form is valid, proceed with submission
            console.log("Form is valid!");
        } else {
            // Form is invalid, display validation messages
            self.errors.showAllMessages();
        }
    };

    self.errors = ko.validation.group(self);
}

If you look carefully at the Contact.js file, I have added a knockout form validation code for the Contact.html page. My problem is that when I click on the submit button, the knockout.js form validation code is not working. Provide me a good solution, How do I bind knockout.js code on separated HTML files in Single Page Application

0