Form builder
{ _: TK.Form, Model: { Name: "Duck", Active: true, Age: 5 }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
{ _: TK.Form, SaveButtonText: "Woop", Model: { Name: "", Active: true, Age: 5, From: "2018-04-27", Id: 99 }, Fields: { // Setting a type or display name From: { Type: "date", DisplayName: "Active From" }, // Marking a field as required Name: { Required: true, PlaceHolder: "Name here" }, // Hide the ID field (Original result will still be available in the saved model) Id: { Type: "ignore"}, // Using a custom template Age: { Template: { _: "span", Init: function() { this.Elements.NumberInput.value = this.Data; }, GetValue: function () { return parseFloat(this.Elements.NumberInput.value); }, Elements: { NumberInput: {}, AddButton: { innerHTML: "+", type: "button", onclick: function() { this.Near("NumberInput").value = parseInt(this.Near("NumberInput").value) + 1; } } } } } }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
{ _: TK.Form, Model: { Name: "Duck", Food: { Name: "Donuts", Amount: 20 } }, Fields: { Food: { Type: "form", Fields: { Name: { Required: true, DisplayName: "Name of the food" } } } }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
{ _: TK.Form, Model: { Name: "Duck", Active: true, Age: 5, Food: [ { Name: "Grass", Amount: 5 }, { Name: "Donuts", Amount: 2 } ] }, Fields: { Food: { Type: "forms", NewItem: { Name: "", Amount: 0 }, AddButtonText: "ADD!", // Default: Add RemoveButtonText: "REMOVE!", // Default: Remove Fields: { Name: { Required: true, DisplayName: "Name of the food" } } } }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
This executes the save callback when there is any potential change.
{ Elements: { Form: { _: TK.Form, AutoSave: true, SaveButtonText: null, // Hide the normal save button Model: { Name: "Duck", Active: true, Age: 5 }, Save: function(newModel) { this.Near("Status").innerHTML = "Name is now: " + newModel.Name; } }, Status: {} } }
The selectable options can be retrieved using ajax. This will be done once during exection and cached for any other form elements using this Url. It is also possible to add onchange / onblur / onfocus events to most fields.
{ Elements: { Form: { _: TK.Form, Model: { Name: "Pink Banana", Active: true, Age: 5 }, Fields: { Name: { Type: "ajaxselect", Url: "ExampleData.txt", GetName: function(a) { return a.Description; }, // Default: a.Name GetValue: function(a) { return a.Description; }, // Default: a.Id ValueIsText: true, onchange: function() { alert(this.value); } }, Age: { onfocus: function() { this.value = 123; }, onblur: function() { this.value = 456; } } } } } }
When using the SortByFields setting, the fields will be added in the order of the Fields setting. This also enables the use of sections which will create html fieldsets and allows adding other (non-field) elements in between.
{ _: TK.Form, SortByFields: true, Model: { FirstName: "", LastName: "", Street: "", Postcode: "", City: "", Country: "" }, Fields: { FirstSection: { Type: "section", DisplayName: "Name"}, FirstName: { Required: true,DisplayName: "First Name", Inline: 1 }, LastName: { Required: true, DisplayName: "Last Name", Inline: 1 }, SecondSection: { Type: "section", DisplayName: "Address"}, Desc: { _: "p", innerHTML: "Please fill in your address below"}, Street: { Required: true, DisplayName: "Street", Width: "300px" }, Postcode: { Required: true, DisplayName: "Postcode", Inline: 1, Width: "100px" }, City: { Required: true, DisplayName: "City", Inline: 1 }, Country: { Required: true, Type: "select", ValueIsText: true, Options: [ { Text: "- Please select -", Value: "" }, { Text: "Netherlands", Value: "NL" }, { Text: "United Kingdom", Value: "UK" }, ]} }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
It is also possible to use the property .LabelWidth (both on field as form) to place the labels on the left side of fields.
{ _: TK.Form, LabelWidth: 200, Model: { FirstName: "", LastName: "", AllowContact: false }, Fields: { FirstName: { Required: true,DisplayName: "First Name" }, LastName: { Required: true, DisplayName: "Last Name" }, AllowContact: { DisplayName: "Allow contact", Type: "switch", TextBefore: "No", TextAfter: "Yes" } }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
A field can be linked to another field. When the other field changes, the linking field will be cleared and Init in the template will be called again. The property LinkedData is filled with the value of the linked field.
{ _: TK.Form, Model: { Country: "", Custom: "" }, Fields: { Country: { Required: true, Type: "select", ValueIsText: true, Options: [ { Text: "- Please select -", Value: "" }, { Text: "Netherlands", Value: "NL" }, { Text: "United Kingdom", Value: "UK" }, ] }, Custom: { LinkField: "Country", Template: { _: "input", Init: function() { if (!this.LinkedData) { this.value = "Nothing selected"; } else { this.value = "You selected " + this.LinkedData + "!"; } }, GetValue: function() { return this.value; } } } }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
The IsVisible method is called at Init and whenever the 'onchange' is called by any of the fields.
{ _: TK.Form, Model: { Name: "Duck", ShowAge: false, Age: 5 }, Fields: { ShowAge: { DisplayName: "Show age field" }, Age: { IsVisible: function(model) { // Return true if this field should be visible // Return false to hide it return model.ShowAge; } } }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
By using the form field type and the LinkSettings property, it is possible to dynamically change the form based on the value of the linked field.
{ _: TK.Form, Model: { ContactType: "Personal", ContactDetails: null }, Fields: { ContactType: { Required: true, Type: "select", ValueIsText: true, DisplayName: "Contact Type", Options: [ { Text: "Personal", Value: "Personal" }, { Text: "Business", Value: "Business" }, ] }, ContactDetails: { Type: "form", DisplayName: "Contact Details", LinkField: "ContactType", LinkSettings: { Personal: { DefaultModel: { Name: "", Address: "", City: "" } }, Business: { DefaultModel: { ContactPerson: "", Name: "", Address: "", City: "" }, Fields: { ContactPerson: { DisplayName: "Contact person" }, Address: { DisplayName: "Address main office" } } } } } }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
Assign a custom validation function to do extra validations. The result needs to be passed by calling the given callBack function. This allows for ajax requests.
{ _: TK.Form, Model: { Name: "Duck", Active: true, Age: 5 }, CustomValidation: function(newModel, callBackResult) { if (newModel.Age < 10) callBackResult(["At least 10 years or older!"]); else callBackResult(); // OK }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }
{ _: TK.Form, Model: { Name: "", Active: true, Age: 5 }, Fields: { Name: { Required: true } }, RenderErrors: function(errors, textBefore) { TK.Toast.Create("Could not save form", textBefore + ": " + errors.join(", ")); }, Save: function(newModel) { alert(JSON.stringify(newModel)); } }