/
The Widget Tutorial
The Widget Tutorial
WebMacro manual:tutorials.widget.Page
Source
<div class="container" data-widget="tutorials.SyncWidget"> <div class="row"> <div class="col-xs-12"> <h1>Ikona Panther Widgets</h1> <a href="/manual/content/tutorials.doc.WidgetTutorial" target="_blank">Widget Tutorial</a> <hr> </div> </div> <div class="row"> <div class="col-sm-6" data-widget="tutorials.FormWidget"> <h4>Register new email</h4> <hr> <div> <input type="text" value="" class="form-control" data-form="EmailInput" placeholder="Enter email address"> </div> <hr> <button class="btn btn-success" data-form="SubmitEmailButton">Store Email</button> </div> <div class="col-sm-6" data-widget="tutorials.ListWidget" data-list-element-class="email-element"> <h4>Registered emails</h4> <hr> <p> <span data-list="EmailsCountLabel"></span> registered emails</p> <button class="btn btn-danger" data-list="EmptyEmailsButton">Empty emails</button> <hr> <ul class="nav nav-stacked nav-pills well" data-list="EmailsList"></ul> </div> </div> <div class="row"> <div class="col-xs-12"> <hr> <div class="hidden alert alert-success" data-sync="StatusOk"> Update from server successful </div> <div class="hidden alert alert-danger" data-sync="StatusErrorEmailAlreadyExists"> The email was already in the list </div> <hr> </div> </div> </div> <script> //this code should usually be included in the main css //it is just here to show how to get panther widgets started //after page load $(function () { //global debug options var debug = true; //global is window in clients var global = window; //set scope to panther var scope = panther = global.panther = {}; /* include panther.ClientLib */ #{ panther.ClientLib } //set scope to tutorials scope = global.tutorials = {}; //create new widgets singleton for test page var widgets = scope.widgets = new panther.widgets.Widgets(); /* include tutorials.widget.SyncWidget */ #{ tutorials.widget.SyncWidget } /* include tutorials.widget.FormWidget */ #{ tutorials.widget.FormWidget } /* include tutorials.widget.ListWidget */ #{ tutorials.widget.ListWidget } //add global error handler scope.widgets.on("Error", function handleErrors(type, error) { if (console.error) { console.error(error); } else { console.log(error); if (error.stack) { console.log(error.stack); } } }); //intialized the existing widgets on this page widgets.init(); //print all widgets console.log("There are " + widgets.size() + " widgets in this page", widgets.list()); }); </script>
WebMacro manual:tutorials.widget.FormWidget
Source
scope.FormWidget = (function (panther) { panther.widgets.AbstractWidget.extend(FormWidget); //load universal for validation var scope = FormWidget; #{ tutorials.widget.ValidateEmail } function FormWidget() { FormWidget.prototype.super.constructor.call(this); } FormWidget.prototype.init = function (element) { FormWidget.prototype.super.init.call(this, element); this.updateElements(); this.emailInput.focus(); }; FormWidget.prototype.initEmailInput = function (emailInput) { this.emailInput = $(emailInput); var self = this; this.emailInput.on("keyup", function () { self.updateElements(); }); this.emailInput.on("change", function () { self.submitEmail(); }); }; FormWidget.prototype.initSubmitEmailButton = function (submitEmailButton) { this.submitEmailButton = $(submitEmailButton); var self = this; this.submitEmailButton.on('click', function () { self.submitEmail(); }); }; FormWidget.prototype.triggerAddEmail = function (email) { }; FormWidget.prototype.submitEmail = function () { if (this.updateElements()) { this.triggerAddEmail(this.emailInput.val()); this.emailInput.val(""); this.updateElements(); } }; FormWidget.prototype.updateElements = function () { //valid mail if (FormWidget.validateEmail(this.emailInput.val())) { this.emailInput.parent().removeClass("has-error"); this.submitEmailButton.removeClass("disabled"); return true; } //invalid mail else { this.emailInput.parent().addClass("has-error"); this.submitEmailButton.addClass("disabled"); return false; } }; return FormWidget; })(panther);
WebMacro manual:tutorials.widget.ListWidget
Source
scope.ListWidget = (function (panther) { panther.widgets.AbstractWidget.extend(ListWidget); function ListWidget() { ListWidget.prototype.super.constructor.call(this); } ListWidget.prototype.init = function (element) { ListWidget.prototype.super.init.call(this, element); this.emailListElementClass = this.element.data("listElementClass") || ""; this.updateElements([]); }; ListWidget.prototype.initEmailsCountLabel = function (emailsCountLabel) { this.emailsCountLabel = $(emailsCountLabel); }; ListWidget.prototype.initEmptyEmailsButton = function (emptyEmailsButton) { this.emptyEmailsButton = $(emptyEmailsButton); var self = this; //delete all item from list this.emptyEmailsButton.on("click", function () { self.triggerRemoveAllEmails(); }); }; ListWidget.prototype.initEmailsList = function (emailsList) { this.emailsList = $(emailsList); var self = this; //delete one item from list this.emailsList.on("click", "a[data-list='EmailListElement']", function (evt) { evt.preventDefault(); self.triggerRemoveEmail($(this).text()); }); }; ListWidget.prototype.triggerRemoveAllEmails = function () { }; ListWidget.prototype.triggerRemoveEmail = function (email) { }; ListWidget.prototype.onUpdateEmails = function (emails) { this.updateElements(emails); }; ListWidget.prototype.updateElements = function (emails) { //set label to email conunt this.emailsCountLabel.text(emails.length); //update list this.emailsList.empty(); for (var i = 0; i < emails.length; i++) { this.emailsList.append( $("<li>") .addClass(this.emailListElementClass) .append( $("<a>") .attr("href", "#") .attr("data-list", "EmailListElement") .text(emails[i]) ) ); } }; return ListWidget; })(panther);
WebMacro manual:tutorials.widget.SyncWidget
Source
scope.SyncWidget = (function (panther) { panther.widgets.AbstractWidget.extend(SyncWidget); function SyncWidget() { SyncWidget.prototype.super.constructor.call(this); this.apiUrl = "#{content.home('tutorials.widget.Api')}"; } SyncWidget.prototype.initStatusOk = function (statusOk) { this.statusOk = $(statusOk); }; SyncWidget.prototype.initStatusErrorEmailAlreadyExists = function (statusErrorEmailAlreadyExists) { this.statusErrorEmailAlreadyExists = $(statusErrorEmailAlreadyExists); }; SyncWidget.prototype.triggerUpdateEmails = function (emails) { }; SyncWidget.prototype.onAddEmail = function (email) { updateEmailsWithServer.call(this, { ac: "add", email: email }); }; SyncWidget.prototype.onRemoveEmail = function (email) { updateEmailsWithServer.call(this, { ac: "remove", email: email }); }; SyncWidget.prototype.onRemoveAllEmails = function () { updateEmailsWithServer.call(this, { ac: "removeAll" }); }; SyncWidget.prototype.onWidgetsInitSuccess = function () { updateEmailsWithServer.call(this, { ac: "list" }); }; SyncWidget.prototype.updateStatus = function (data) { if (data.status === "OK") { this.statusOk.removeClass("hidden"); this.statusErrorEmailAlreadyExists.addClass("hidden"); } else if (data.status === "EMAIL_ALREADY_EXISTS") { this.statusOk.addClass("hidden"); this.statusErrorEmailAlreadyExists.removeClass("hidden"); } }; function updateEmailsWithServer(data) { var self = this; $.ajax(this.apiUrl, { type: "post", cache: false, dataType: "json", data: data, success: function (data) { self.updateStatus(data); self.triggerUpdateEmails(data.emails); }, error: function (data) { self.updateStatus(data.responseJSON); throw new Error("Invalid update from server " + JSON.stringify(data)); } }); } return SyncWidget; })(panther);
WebMacro manual:tutorials.widget.Api
Source
require("request"); require("response"); require("session"); this.EmailApi = (function () { var SESSION_KEY = "tutorials.widget.emails"; //load universal for validation this.scope = EmailApi; load("tutorials.widget.ValidateEmail"); function EmailApi() {} EmailApi.prototype.handle = function (action) { if (!action) { throw new Error("ERROR_UNDEFINED_ACTION"); } if (action.length > 50) { throw new Error("ERROR_INVALID_ACTION"); } var actionName = "do" + action[0].toUpperCase() + action.slice(1); if (typeof (this[actionName]) === "function") { return this[actionName](); } else { throw new Error("ERROR_UNKNOWN_ACTION"); } }; EmailApi.prototype.doList = function () { var result = {}; result.status = "OK"; result.emails = getEmails(); return result; }; EmailApi.prototype.doAdd = function () { var result = {}; result.status = "OK"; var emails = getEmails(); var email = request.parameter("email"); //just allow to add valid emails if (!EmailApi.validateEmail(email)) { throw new Error("EMAIL_INVALID"); } //dont alow to add the same email multiple times var index = emails.indexOf(email); if (index > -1) { throw new Error("EMAIL_ALREADY_EXISTS"); } emails.push(email); setEmails(emails); result.emails = emails; return result; }; EmailApi.prototype.doRemove = function () { var result = {}; result.status = "OK"; var emails = getEmails(); var email = request.parameter("email"); var index = emails.indexOf(email); if (index > -1) { emails.splice(index, 1); } else { throw new Error("EMAIL_DOES_NOT_EXIST"); } setEmails(emails); result.emails = emails; return result; }; EmailApi.prototype.doRemoveAll = function () { var result = {}; result.status = "OK"; setEmails([]); result.emails = []; return result; }; function getEmails() { return JSON.parse(session.get(SESSION_KEY) || "[]"); } function setEmails(emails) { if (Array.isArray(emails)) { session.set(SESSION_KEY, JSON.stringify(emails)); } } return EmailApi; })(); function main() { try { var action = request.parameter("ac"); var emailApi = new EmailApi(); return JSON.stringify(emailApi.handle(action)); } catch (ex) { response.sendError(400, JSON.stringify({ status: ex.message })); } }
WebMacro manual:tutorials.widget.ValidateEmail
Source
(function ValidateEmail(scope) { scope.validateEmail = function (email) { return /^[a-z0-9\-_]?[a-z0-9.\-_]+[a-z0-9\-_]?@[a-z.-]+\.[a-z]{2,3}$/i.test(email); }; })(scope);
, multiple selections available,
Related content
Understand Visual Widgets
Understand Visual Widgets
More like this
swcl.lib.wiki
swcl.lib.wiki
More like this
swcl.lib.code
swcl.lib.code
More like this
JSMA feedback
JSMA feedback
More like this