A couple of years ago I did a post entitled Adding Form Fields Dynamically with jQuery. In this post I am going to re-visit the same problem but this time use Knockout.js to create the dynamic form fields.
Introducing Knockout.js
Knockout.js is a Model-View-View-Model Javascript library. What it excels at is ‘binding’ data such as Javascript objects, arrays and JSON to your output HTML. To use Knockout.js take a trip to knockoutjs.com to view their excellent tutorials and documentation. To use it you need to either download the Knockout.js
file or you can use a distributed version of the file by adding:
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"> </script>
Data Binding
Knockout.js works by ‘binding’ your data model to your HTML output. The hook it uses for this are HTML’s custom attributes. Primarily this is done by declaring a data-bind
on a HTML element and then adding some knockout.js logic to it.
<div data-bind="someCommand">
Note: HTML attributes are part of the HTML5 specification but you can safely use in both newer HTML5 browsers as well as older ones.
In our example we are going to set up the HTML form as follows:
<form method="post"> <div data-bind="foreach: myFieldList"> <p> <label data-bind="text: label"></label> <input data-bind="attr: { name: fname}"> <span class="removeVar" data-bind="click: removeField">Remove Variable</span> </p> </div> <p> <span id="addVar" data-bind="click: addField">Add Variable</span> </p> <p class="alignRight"> <input type="submit" value="Check"> </p> </form>
Notice the use of the data-bind
custom attribute to bind various Knockout.js commands to the HTML elements
The Javascript itself consists of:
function fieldModel(){ var self = this; var noTracker = 3; self.myFieldList = ko.observableArray([{label : "Variable 1", fname : "var1"},{label : "Variable 2", fname : "var2"},{label : "Variable 3", fname : "var3"}]); self.removeField = function(dynamicField){ self.myFieldList.remove(dynamicField); } self.addField = function() { noTracker++; self.myFieldList.push({label : "Variable "+ noTracker, fname : "var"+ noTracker}); } } ko.applyBindings(fieldModel);
Primarily this is involved in creating a data model fieldModel
with initial properties as well as a couple of methods removeField
and addField
. This is fundamentally ‘vanilla’ Javascript apart from ko.observableArray
which is Knockout’s extended version of an array that makes it easier to manipulate, and the ko.applyBindings(fieldModel);
that ‘binds’ our data model to the HTML above.
[…] Note: There is a newer post that repeats the same functionality of this example but makes use of Knockout.js – Adding Form Fields Dynamically with Knockout.js […]