Step 1: HTML Structure
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Meta tags and title -->
</head>
<body>
<!-- Container for the application -->
<div class="container">
<!-- Product management heading -->
<h1>Product Management</h1>
<!-- Form to add a new product -->
<form>
<!-- Input fields for product name and price -->
<!-- Button to add a new product -->
</form>
<!-- Table to display products -->
<table>
<!-- Table headers -->
<!-- Table body for products -->
<!-- Rows for each product -->
<!-- Columns for product details -->
<!-- Actions for each product (Edit and Delete buttons) -->
<!-- End of table body -->
</table>
<!-- Form to edit a product -->
<form>
<!-- Input fields for edited product name and price -->
<!-- Buttons to save changes and cancel editing -->
</form>
</div>
<!-- JavaScript library Knockout.js -->
<!-- Script to initialize Knockout.js bindings -->
</body>
</html>
Step 2: Data Model and View Model
- Define a Product constructor function to represent each product.
- Create an instance of Product for each product with observable properties.
- Define the AppViewModel to manage the application state and operations.
<script> function AppViewModel() { var self = this; // Data self.newProductName = ko.observable(''); self.newProductPrice = ko.observable(''); self.products = ko.observableArray([]); self.editedProductName = ko.observable(''); self.editedProductPrice = ko.observable(''); self.isEditing = ko.observable(false); self.currentProduct = ko.observable(null); } ko.applyBindings(new AppViewModel()); </script>
Step 3: Add Products
- Implement a function in the view model to add new products to the array.
- Bind this function to the submit event of the add product form.
// Operations self.addProduct = function () { self.products.push({ name: ko.observable(self.newProductName()), price: ko.observable(self.newProductPrice()) }); self.newProductName(''); self.newProductPrice(''); };
Step 4: Edit Products
- Implement functions in the view model to handle editing a product.
- Bind these functions to the click event of the Edit button.
- Use observables to track the edited product's name and price.
self.editProduct = function (product) { self.currentProduct(product); self.editedProductName(product.name()); self.editedProductPrice(product.price()); self.isEditing(true); };
Step 5: Save Changes
- Implement a function in the view model to save changes made to the edited product.
- Bind this function to the submit event of the edit product form.
- Update the product's properties with the new values.
self.saveProduct = function () { var product = self.currentProduct(); product.name(self.editedProductName()); product.price(self.editedProductPrice()); self.isEditing(false); };
Step 6: Cancel Editing
- Implement a function in the view model to cancel editing.
- Bind this function to the click event of the Cancel button.
- Set the edited product to null to exit edit mode.
self.cancelEdit = function () { self.isEditing(false); };
Step 7: Delete Products
- Implement a function in the view model to delete a product.
- Bind this function to the click event of the Delete button.
- Use the remove method of the observable array to remove the product.
self.deleteProduct = function (product) { self.products.remove(product); };
Step 8: Apply Bindings
- Use the ko.applyBindings function to apply the view model bindings to the HTML elements.
This breakdown outlines the key steps involved in creating a CRUD application using Knockout.js. Each step contributes to the overall functionality of the application, allowing users to manage products effectively.
ko.applyBindings(new AppViewModel());
At last bind all code in one program.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Knockout.js CRUD Demo</title>
<!-- <link rel="stylesheet" href="styles.css"> -->
<!-- Link to Bootstrap CSS for styling -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> </head> <body> <div class="container"> <h1>Product Management</h1> <hr /> <form class="row g-3" data-bind="submit: addProduct"> <div class="col-12"> <label for="productName" class="fw-bold form-label">Product Name:</label> <input type="text" class="form-control" placeholder="Product Name" id="productName" data-bind="value: newProductName, valueUpdate: 'input'" required> </div> <div class="col-12"> <label for="productPrice" class="form-label fw-bold">Product Price:</label> <input type="number" class="form-control " placeholder="Price" id="productPrice" data-bind="value: newProductPrice, valueUpdate: 'input'" required> </div> <div class="col-12"> <button type="submit" class="btn btn-outline-primary">Add Product</button> </div> </form> <hr /> <div class="table-responsive" data-bind="if: products().length > 0"> <table class="table"> <thead> <tr> <th scope="col">#</th> <th>Product Name</th> <th>Product Price</th> <th>Actions</th> </tr> </thead> <tbody data-bind="foreach: products"> <tr> <th class="" scope="col" data-bind="text: ($index()+1)"></th> <td><span data-bind="text: name"></span></td> <td><span data-bind="text: price"></span></td> <td class="d-flex"> <button class="btn btn-link text-primary" data-bind="click: $parent.editProduct">Edit</button> <button class="btn btn-link text-danger" data-bind="click: $parent.deleteProduct">Delete</button> </td> </tr> </tbody> </table> </div> <div class="my-3" data-bind="if: isEditing"> <h2>Edit Product</h2> <form class="row g-3" data-bind="submit: saveProduct"> <div class="col-12"> <label for="editProductName" class="form-label fw-bold">Product Name:</label> <input type="text" id="editProductName" class="form-control " placeholder="Product Name" data-bind="value: editedProductName, valueUpdate: 'input'" required> </div> <div class="col-12"> <label for="editProductPrice" class="form-label fw-bold">Product Price:</label> <input type="number" id="editProductPrice" class="form-control " placeholder="Price" data-bind="value: editedProductPrice, valueUpdate: 'input'" required> </div> <div class="col-12"> <button type="submit" class="btn btn-outline-primary">Save Changes</button> <button type="button" data-bind="click: cancelEdit" class="btn btn-secondary">Cancel</button> </div> </form> </div> </div> <!-- Link to Knockout.js library for MVVM pattern support --> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js" integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script> function AppViewModel() { var self = this; // Data self.newProductName = ko.observable(''); self.newProductPrice = ko.observable(''); self.products = ko.observableArray([]); self.editedProductName = ko.observable(''); self.editedProductPrice = ko.observable(''); self.isEditing = ko.observable(false); self.currentProduct = ko.observable(null); // Operations self.addProduct = function () { self.products.push({ name: ko.observable(self.newProductName()), price: ko.observable(self.newProductPrice()) }); self.newProductName(''); self.newProductPrice(''); }; self.editProduct = function (product) { self.currentProduct(product); self.editedProductName(product.name()); self.editedProductPrice(product.price()); self.isEditing(true); }; self.saveProduct = function () { var product = self.currentProduct(); product.name(self.editedProductName()); product.price(self.editedProductPrice()); self.isEditing(false); }; self.deleteProduct = function (product) { self.products.remove(product); }; self.cancelEdit = function () { self.isEditing(false); }; } ko.applyBindings(new AppViewModel()); </script> </body> </html>
Output -
![CRUD operation in KnockoutJS.](/Images/mindstick-loader-image.png)
Thank you.
Leave Comment