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