{"id":28359003,"url":"https://github.com/quickcorp/qcobjects-sdk","last_synced_at":"2025-06-26T08:05:20.115Z","repository":{"id":34761168,"uuid":"183351163","full_name":"QuickCorp/QCObjects-SDK","owner":"QuickCorp","description":"A software library with a set of Controllers, Views and Components that are elementary and useful to assist developers to build applications under MVC patterns using QCObjects.","archived":false,"fork":false,"pushed_at":"2025-04-01T15:14:39.000Z","size":1373,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-28T09:08:46.350Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/QuickCorp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["jeanmachuca"],"patreon":"qcobjects","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["http://sponsorsignup.qcobjects.dev/"]}},"created_at":"2019-04-25T03:41:27.000Z","updated_at":"2024-09-29T00:35:30.000Z","dependencies_parsed_at":"2024-06-19T11:26:18.010Z","dependency_job_id":"2316553a-15b6-4747-babf-05f6e31a3307","html_url":"https://github.com/QuickCorp/QCObjects-SDK","commit_stats":{"total_commits":473,"total_committers":6,"mean_commits":78.83333333333333,"dds":0.03594080338266381,"last_synced_commit":"be131703d7777321733a2e1d51f8098046afb7fb"},"previous_names":[],"tags_count":230,"template":false,"template_full_name":null,"purl":"pkg:github/QuickCorp/QCObjects-SDK","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuickCorp%2FQCObjects-SDK","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuickCorp%2FQCObjects-SDK/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuickCorp%2FQCObjects-SDK/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuickCorp%2FQCObjects-SDK/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QuickCorp","download_url":"https://codeload.github.com/QuickCorp/QCObjects-SDK/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QuickCorp%2FQCObjects-SDK/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261092809,"owners_count":23108537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-28T09:08:41.260Z","updated_at":"2025-06-26T08:05:20.107Z","avatar_url":"https://github.com/QuickCorp.png","language":"JavaScript","funding_links":["https://github.com/sponsors/jeanmachuca","https://patreon.com/qcobjects","http://sponsorsignup.qcobjects.dev/","https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=UUTDBUQHCS4PU\u0026source=url)!"],"categories":[],"sub_categories":[],"readme":"![logo](https://qcobjects.dev/qcobjects_01.png)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects-SDK.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects-SDK?ref=badge_shield)\n\nQCObjects SDK\n=============\nCopyright (c) Jean Machuca and QuickCorp \u003cinfo@quickcorp.cl\u003e\n\nPlease fork this project or make a link to this project into your README.md file. Read the LICENSE.txt file before you use this code.\n\nIf you like this code please [DONATE ](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=UUTDBUQHCS4PU\u0026source=url)!\n\n\n# Cross Browser Javascript Framework for MVC Patterns\n\n[QCObjects](https://qcobjects.dev) is a javascript framework designed to make easier everything about the MVC patterns implementation into the pure javascript scope.\n\n[QCObjects SDK](https://sdk.qcobjects.dev) is a set of Controllers, Views and Components that are elementary and useful to assist developers to build applications under MVC patterns using [QCObjects](https://qcobjects.dev).\n\nCheckout the [QCObjects SDK 2.4 beta version](https://sdk.qcobjects.dev/v2.4/)\n\nIf you like more code samples feel free to write your questions to info@quickcorp.cl\n\n\n\n# Installing with NPM:\n\n```shell\n\u003e npm install qcobjects-sdk@v2.4\n```\n\n# Using the code in the straight way into HTML5:\n\n```html\n\u003cscript type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/qcobjects/2.4.20/QCObjects.js\"\u003e\u003c/script\u003e\n```\n\nNOTE: SDK dependence is included by default in the QCObjects runtime execution. You only need to install it if your having issues with default paths\n\n\n## SDK\n\n### SDK Components\n\n#### org.qcobjects.components.ShadowedComponent\n\n**ShadowedComponent** Class is a custom component class designed to allow you to create a component using the Shadow DOM of browsers. Read more about Shadowed Components on [this article on Hackernoon] (https://www.hackernoon.com/shadowed-components-and-qcobjects-kd703yld).\n\n##### Usage:\n\n```html\n\u003ccomponent componentClass=\"ShadowedComponent\"\u003e\u003c/component\u003e\n\n\u003cmy-custom-widget componentClass=\"ShadowedComponent\"\u003e\u003c/my-custom-widget\u003e\n```\n\n#### org.qcobjects.components.FormField\n\n**FormField** is a Class for **QCObjects** custom components that allows you to inject a Form Field generic behavior to your components. It has a reverse data-binding feature to detect the values of the DOM fields inside your form and assign them to the data values of your component. By this way, you don't loose performance making an old-fashioned two-way data binding based on observables. To implement this advanced behavior. You only need to do the following:\n\n1.- Assign a **data-field** attribute to the DOM tag inside the component body, with the corresponding field name in your data object.\n\n2.- To your **component tag**, assign **FormField** in the **componentClass** attribute.\n\n3.- To recover the data of the form inside your component, just use the componentInstance.data object. Every property of the componentInstance.data object will be linked by the binding events with the value properties on every DOM object of the form that has a data-field assigned.\n\n##### Usage:\n\n```html\n\u003c!-- Where you place the component --\u003e\n\u003ccomponent name=\"myform\" componentClass=\"FormField\"\u003e\u003c/component\u003e\n```\n\n```html\n\u003c!-- usage using smart widgets --\u003e\n\n\u003cmy-custom-widget name=\"myform\" componentClass=\"FormField\"\u003e\u003c/my-custom-widget\u003e\n\n```\n\n```html\n\u003c!-- template: myform.tpl.html --\u003e\n\u003clabel for=\"email\"\u003e\u003cb\u003eEmail\u003c/b\u003e\u003c/label\u003e\n\u003cinput data-field=\"email\" type=\"email\" placeholder=\"Enter Email\" name=\"email\" required\u003e\n\n\u003clabel for=\"psw\"\u003e\u003cb\u003ePassword\u003c/b\u003e\u003c/label\u003e\n\u003cinput data-field=\"name\" type=\"text\" placeholder=\"Enter Your Name\" name=\"name\" required\u003e\n```\n\n**data-field=\"name\"** will be matched with **this.data.name** inside the component class and will be updated everytime a data binding event is triggered. The same will happen to **data-field=\"email\"** and so on.\n\n##### FormField.executeBindings():\n\nThe method **executeBindings** of FormField component will find the **data-field** attribute values and match them with the corresponding **data** fields in the component instance.\n\n##### Data Binding Event Change:\n\nInside of the body of your component, when it is a **FormField** component, every time the DOM dispatches a \"change\" event, it will trigger the executeBindings method of your component.\n\n##### Data Binding Event Blur:\n\nInside of the body of your component, when it is a **FormField** component, every time the DOM dispatches a \"Blur\" event, it will trigger the executeBindings method of your component.\n\n##### Data Binding Event Focus:\n\nInside of the body of your component, when it is a **FormField** component, every time the DOM dispatches a \"Focus\" event, it will trigger the executeBindings method of your component.\n\n##### Data Binding Event Keydown:\n\nInside of the body of your component, when it is a **FormField** component, every time the DOM dispatches a \"Keydown\" event, it will trigger the executeBindings method of your component.\n\n\n#### org.qcobjects.components.ButtonField\n\n**ButtonField** is a sub-definition of **FormField**, that is commonly used for almost the same purpose of FormField. The main difference between ButtonField and FormField is that ButtonField has a **```\u003cbutton\u003e```** DOM element as the body of the component by default. And FormField hasn't a pre-defined body.\n\n##### Usage:\n\n```html\n\u003ccomponent name=\"name_of_component\" componentClass=\"ButtonField\"\u003e\u003c/component\u003e\n```\n\n```html\n\u003c!-- using smart widgets --\u003e\n\u003cname-of-widget componentClass=\"ButtonField\"\u003e\u003c/name-of-widget\u003e\n```\n\n#### org.qcobjects.components.InputField\n\n**InputField** is a sub-definition of **FormField**, that is commonly used for almost the same purpose of FormField. The main difference between InputField and FormField is that InputField has a **\u003cinput\u003e** DOM element as the body of the component by default. And FormField hasn't a pre-defined body.\n\n##### Usage:\n\n```html\n\u003ccomponent name=\"name_of_component\" componentClass=\"InputField\"\u003e\u003c/component\u003e\n```\n\n```html\n\u003c!-- using smart widgets --\u003e\n\u003cname-of-widget componentClass=\"InputField\"\u003e\u003c/name-of-widget\u003e\n```\n\n\n#### org.qcobjects.components.TextField\n\n**ButtonField** is a sub-definition of **FormField**, that is commonly used for almost the same purpose of FormField. The main difference between InputField and FormField is that ButtonField has a **```\u003ctextarea\u003e```** DOM element as the body of the component by default. And FormField hasn't a pre-defined body.\n\n##### Usage:\n\n```html\n\u003ccomponent name=\"name_of_component\" componentClass=\"TextField\"\u003e\u003c/component\u003e\n```\n\n```html\n\u003c!-- using smart widgets --\u003e\n\u003cname-of-widget componentClass=\"TextField\"\u003e\u003c/name-of-widget\u003e\n```\n\n\n#### org.qcobjects.components.EmailField\n\n**EmailField** is a sub-definition of **FormField**, that is commonly used for almost the same purpose of FormField. The main difference between ButtonField and FormField is that ButtonField has a **```\u003cinput\u003e```** DOM element as the body of the component by default. And FormField hasn't a pre-defined body.\n\n##### Usage:\n\n```html\n\u003ccomponent name=\"name_of_component\" componentClass=\"EmailField\"\u003e\u003c/component\u003e\n```\n\n```html\n\u003c!-- smart widget syntax --\u003e\n\u003cname-of-widget componentClass=\"EmailField\"\u003e\u003c/name-of-widget\u003e\n\n```\n\n#### org.qcobjects.components.GridComponent\n\nGridComponent has a predefined name assigned to the value \"grid\", so be aware of it when you use this component class. Also, GridComponent is intended to be used in conjunction with GridController to expand its behavior to a CSS Grid.\n\n##### Usage:\n\n```html\n\u003ccomponent componentClass=\"GridComponent\" ...\u003e\u003c/component\u003e\n\n\u003cname-of-widget componentClass=\"GridComponent\" ...\u003e\u003c/name-of-widget\u003e\n```\n\n##### Example:\n\n```html\n\u003ccomponent rows=\"2\" cols=\"2\" componentClass=\"GridComponent\" controllerClass=\"GridController\"\u003e\n  \u003c!-- It is recommended to use subcomponents as the Grid elements--\u003e\n\t\u003ccomponent name=\"name_of_subcomponent1\"\u003e\u003c/component\u003e\n\t\u003ccomponent name=\"name_of_subcomponent2\"\u003e\u003c/component\u003e\n\t\u003ccomponent name=\"name_of_subcomponent3\"\u003e\u003c/component\u003e\n\t\u003ccomponent name=\"name_of_subcomponent4\"\u003e\u003c/component\u003e\n\u003c/controller\u003e\n```\n\n```html\n\u003c!-- syntax using smart widgets --\u003e\n\u003cname-of-widget rows=\"2\" cols=\"2\" componentClass=\"GridComponent\" controllerClass=\"GridController\"\u003e\n\t\u003cname-of-subwidget1\u003e\u003c/name-of-widget\u003e\n\t\u003cname-of-subwidget2\u003e\u003c/name-of-widget\u003e\n\t\u003cname-of-subwidget3\u003e\u003c/name-of-widget\u003e\n\t\u003cname-of-subwidget4\u003e\u003c/name-of-widget\u003e\n\u003c/name-of-widget\u003e\n```\n\nThe above example will draw a css grid of two columns and two rows and place the subcomponents into it.\n\nDon't forget this file:\n\n```html\n\u003c!-- file: grid.tpl.html, you can use the grid template either to draw the grid itself or to draw a loading information --\u003e\n\u003cp\u003eLoading grid...\u003c/p\u003e\n```\n\n#### org.qcobjects.components.ModalEnclosureComponent\n\n#### org.qcobjects.components.ModalComponent\n\n#### org.qcobjects.components.SwaggerUIComponent\n\nIt is used to inject a swagger-ui DOM needed to the Swagger UI API. Learn more in this article of QCObjects DevBlog called [Working with Swagger UI as a QCObjects Component](https://devblog.qcobjects.org/working-with-swagger-ui-as-a-qcobjects-component-ck6xzoqkg05indfs1i4rxq72e)\n\n##### Usage:\n\n```html\n\u003ccomponent componentClass=\"SwaggerUIComponent\" controllerClass=\"SwaggerUIController\" \u003e\u003c/component\u003e\n```\n\n```html\n\u003c!-- syntax using smart widgets --\u003e\n\u003cmy-custom-widget componentClass=\"SwaggerUIComponent\" controllerClass=\"SwaggerUIController\" \u003e\u003c/my-custom-widget\u003e\n```\n\n#### org.qcobjects.components.splashscreen.VideoSplashScreenComponent\n\nA powerful component definition to allow you create an awesome Video Splash Screen for your progressive web app.\n\n##### Example:\n\n```html\n\u003c!-- Add the splash screen component tag as the first component in your HTML document --\u003e\n\u003ccomponent componentClass=\"VideoSplashScreenComponent\"\n\tdata-background=\"./img/splash/splashscreen-aqua.png\"\n\tdata-video_mp4=\"./img/splash/splashscreen-aqua.mp4\"\n\tdata-video_webm=\"./img/splash/splashscreen-aqua.webm\"\n\tdata-video_ogg=\"./img/splash/splashscreen-aqua.ogv\" duration=\"5000\"\u003e\n\t\u003cimg slot=\"logo\" alt=\"logo\" src=\"./img/logo-qcobjects-white.svg\"\u003e\u003c/div\u003e\n\u003c/component\u003e\n\u003c!-- Then you can put your main component as always --\u003e\n\u003ccomponent splashscreen name=\"main\" cached=true controllerClass=\"MainController\"\u003e\n\u003c/component\u003e\n```\n\n```html\n\u003c!-- using smart widgets --\u003e\n\u003c!-- Add the splash screen component tag as the first component in your HTML document --\u003e\n\u003csplash-screen componentClass=\"VideoSplashScreenComponent\"\n\tdata-background=\"./img/splash/splashscreen-aqua.png\"\n\tdata-video_mp4=\"./img/splash/splashscreen-aqua.mp4\"\n\tdata-video_webm=\"./img/splash/splashscreen-aqua.webm\"\n\tdata-video_ogg=\"./img/splash/splashscreen-aqua.ogv\" duration=\"5000\"\u003e\n\t\u003cimg slot=\"logo\" alt=\"logo\" src=\"./img/logo-qcobjects-white.svg\"\u003e\u003c/div\u003e\n\u003c/splash-screen\u003e\n\u003c!-- Then you can put your main layout as always --\u003e\n\u003clayout-basic splashscreen name=\"main\" cached=true controllerClass=\"MainController\"\u003e\n\u003c/layout-basic\u003e\n```\n\n\n### SDK Controllers\n\n#### org.qcobjects.controllers.GridController\n\n**GridController** is intended to be used in conjunction with **GridComponent** to allow you to create a CSS grid to place subcomponents. More info in [org.qcobjects.components.GridComponent](#org.qcobjects.components.GridComponent)\n\n#### org.qcobjects.controllers.DataGridController\n\n**DataGridController** will take the data of your component and map a set of subcomponents to fill it up.\nThis is commonly used to render a dynamic list of components. It used a **subcomponentClass** attribute value in the **component** tag to determine what component definition to use to build and render every sub-component. The data on every sub-component will be filled up with the value of the element mapped to the sub-component.\n\n##### Usage:\n\n```html\n\u003ccomponent name=\"name_of_component\" controllerClass=\"DataGridController\" subcomponentClass=\"SubComponentClass\"\u003e\n\u003c/component\u003e\n```\n\n```html\n\u003c!-- Using smart widgets --\u003e\n\u003cmy-custom-grid controllerClass=\"DataGridController\" subcomponentClass=\"SubComponentClass\"\u003e\n\u003c/my-custom-grid\u003e\n```\n\n\n##### Example:\n\nSuppose you have to render a list of profiles. Every profile has a profile picture, a name and an email.\nYou want to use a card to represent every profile in the list.\n\nSo you define a CardComponent to render the picture, the name and email of an element in the list.\n\n```javascript\nclass CardComponent extends Component {\n\tconstructor () {\n\t\tsuper();\n\t\tthis.name = \"card\"; // this will point to templates/components/card.tpl.html\n\t\tthis.data = { // the value of this object will be overriden by DataGridController\n\t\t\tname:\"\u003cname of contact\u003e\",\n\t\t\temail:\"email@example.com\",\n\t\t\tprofilePicture:\"img/photo.png\"\n\t\t};\n\n\t\t\n\t}\n}\n```\n\n```html\n\u003c!-- template: card.tpl.html --\u003e\n\u003cimg src=\"{{profilePicture}}\"/\u003e\n\u003ch3\u003e{{name}}\u003c/h3\u003e\n\u003cp\u003e{{email}}\u003c/p\u003e\n```\n\nThen, you have to place a component to generate the list of cards.\n\n```html\n\u003ccomponent name=\"loading_list\" componentClass=\"MyListComponent\" controllerClass=\"DataGridController\"\nsubcomponentClass=\"CardComponent\"\u003e\n\u003c/component\u003e\n```\n\n```html\n\u003cloading-list componentClass=\"MyListComponent\" controllerClass=\"DataGridController\"\nsubcomponentClass=\"CardComponent\"\u003e\n\u003c/loading-list\u003e\n```\n\n```html\n\u003c!-- template: loading_list.tpl.html --\u003e\n\u003cp\u003eLoading list...\u003c/p\u003e\n```\n\nLast, you have to define MyListComponent to assign the dynamic data of the list.\n\n```javascript\n\nclass MyListComponent extends Component {\n\tconstructor () {\n\t\tsuper();\n\t\tthis.data=[\n\t\t\t{ // the value of this object will be mapped to a subcomponent by DataGridController\n\t\t\t\tname:\"\u003cname of contact\u003e\",\n\t\t\t\temail:\"email@example.com\",\n\t\t\t\tprofilePicture:\"img/photo.png\"\n\t\t\t},\n\t\t\t{ // the value of this object will be mapped to a subcomponent by DataGridController\n\t\t\t\tname:\"\u003cname of contact\u003e\",\n\t\t\t\temail:\"email@example.com\",\n\t\t\t\tprofilePicture:\"img/photo.png\"\n\t\t\t},\n\t\t\t{ // the value of this object will be mapped to a subcomponent by DataGridController\n\t\t\t\tname:\"\u003cname of contact\u003e\",\n\t\t\t\temail:\"email@example.com\",\n\t\t\t\tprofilePicture:\"img/photo.png\"\n\t\t\t}\n\t\t]\n\n\t}\n\n}\n```\n\nThe resulting component will be a list of **CardComponent** with the data of every profile mapped into them by **DataGridController**.\n\n#### org.qcobjects.controllers.ModalController\n\n#### org.qcobjects.controllers.FormValidations\n\n**FormValidations** is used to handle default validations for the **FormController**\n\n#### Usage:\n\n```html\nFormValidations.getDefault(validationName)\n```\n\nWhere **validationName** is the name of the validation present in the **validations** property of the **FormController**\n\n#### org.qcobjects.controllers.FormController\n\nThe FormController definition is intended to help you to handle dynamic forms. By using the normalised syntax of the FormController definition, you don't have to code the complexity of the logic of a submit form, as it is atomised here in three steps.\n\n- Assign a serviceClass\n- Define the formSettings\n- Asign or code the field validations\n\n##### [FormController].serviceClass\n\nIt is the string name of the Class definition. FormController will load this class using the ClassFactory helper function, so the name can be a complete package name plus definition.\n\n##### [FormController].formSettings\n\nIt is an object with the special properties of the form. The default settings are: backRouting:'#', loadingRouting:'#loading', nextRouting:'#signupsuccessful'. These settings are meant to handle the flow behavior of the form.\n\n**loadingRouting** is the name of the routing that will be triggered while the **serviceClass** is beign called until the service loader returns a response.\n\n**backRouting** is the name of the routing that will be triggered if the call for the **serviceClass** fails.\n\n**nextRouting** is the name of the routing that will be triggered when the call for the **serviceClass** finishes OK.\n\n##### [FormController].validations\n\nIt is an object with the helper functions that you want to define to validate every form field. When you define a validation function for a field, FormController will ask if the execution of that function returns true before to submit the form.\n\nTo define validations for the fields of the form, you just need to add them as a part of the validations property.\n\n##### Usage:\n\n```javascript\n\t// Let's say you have a form field called \"name\"\n\tvalidations: {\n\t\tname (){\n\t\t\treturn (fieldName, dataValue, element)=\u003e {\n\t\t\t\treturn [true ... or false condition];\n\t\t\t}\n\t\t}, //... add a validation for every form field that you want to be validated\n\t}\n```\n\nYou can also use **FormValidations.getDefault** for simplicity.\n\n```javascript\n\t// Let's say you have a form field called \"name\"\n\tvalidations: {\n\t\tname (){\n\t\t\treturn FormValidations.getDefault('name')\n\t\t}, //... add a validation for every form field that you want to be validated\n\t}\n```\n\n\n\n##### [FormController].formSaveTouchHandler\n\nThis method is internally used by FormController to call the serviceClass as a submit action.\nIt will be binded to any click or touch event of any element inside the form that has a CSS \".submit\" class assigned.\n\nExample:\n\n```html\n\u003cbutton class=\"submit\"\u003e\u003cp\u003eSend\u003c/p\u003e\u003c/button\u003e\n```\n\nWhen the click or touch event of the above button is triggered, FormController will call the service defined in **serviceClass**, this action will be done by **formSaveTouchHandler**. If you like to change this behavior just override this method in your custom controller.\n\n##### A complete example of FormController\n\nBelow is a complete example of a definition for a Signup Form using FormController.\n\n```javascript\n// First, define a service class that will be called on submit.\nclass SignupClientService extends JSONService {\n\tconstructor (){\n\t\tthis.name='signup';\n\t\tthis.external=true;\n\t\tthis.cached=false;\n\t\tthis.method='POST';\n\t\tthis.url=Service.basePath+'createaccount';\n\t\tthis.withCredentials=false;\n\n\t}\n\n\tdone (successfulResponse) {\n\t\t// service loaded\n\t\tsuper.done(successfulResponse.service, successfulResponse);\n\t\tconsole.log(successfulResponse.service.JSONresponse);\n\t}\n\n}\n```\n\n```javascript\n// To safe extend FormController, we extend first from Controller, then\n// we use a defaultController to instance a new FormController\n\nclass SignupFormController extends Controller {\n\tconstructor () {\n\t\tthis.serviceClass= 'SignupClientService';\n\t\tthis.formSettings={ /* routings that will be triggered once the serviceClass is called*/\n\t\t\tbackRouting:'#'\n\t\t\tloadingRouting:'#loading'\n\t\t\tnextRouting:'#signupsuccessful'\n\t\t};\n\t\tthis.validations: { /* validation definitions for every field in the form to be validated before submit */\n\t\t\tname (){\n\t\t\t\treturn FormValidations.getDefault('name')\n\t\t\t},\n\t\t\temail (){\n\t\t\t\treturn FormValidations.getDefault('email')\n\t\t\t},\n\t\t\tcomment (){\n\t\t\t\treturn function (fieldName, dataValue, element){\n\t\t\t\t\treturn (dataValue !== '')?(true):(false);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tthis.defaulController=null;\n\n\t}\n\n\t_new_ (o){\n\t\tsuper._new_(o);\n\t\to.serviceClass = this.serviceClass;\n\t\to.formSettings = this.formSettings;\n\t\to.validations = this.validations;\n\t\t// here we instance a defaultController with a New FormController\n\t\t// passing the o object declaration coming from the components stack building process.\n\t\tthis.defaulController = new FormController (o);\n\t}\n\n\tdone (){\n\t\tsuper.done();\n\t\t// we define a custom done callback function to inject a custom behavior as well as calling the defaultController behavior\n\t\tlogger.debugEnabled=true;\n\t\tvar controller = this.defaulController;\n\t\ttry {\n\t\t\tcontroller.done.call(controller);\n\t\t}catch (e){\n\t\t\tlogger.debug('Unable to execute default behavior');\n\t\t}\n\t}\n}\n```\n\n```html\n\u003c!-- A Shadowed Component to render the signup forms --\u003e\n\u003c!-- template: signup-form.tpl.html --\u003e\n\n\u003cform action=\"#\" style=\"border:1px solid #ccc;border-radius:20px\"\u003e\n\t\u003cdiv class=\"container\"\u003e\n\t\t\u003cslot name=\"title\"\u003e\n\t\t\t\u003ch1\u003eSignup Form\u003c/h1\u003e\n\t\t\u003c/slot\u003e\n\t\t\u003cslot name=\"subtitle\"\u003e\n\t\t\t\u003cp\u003ePlease fill up this form to ask for a quote.\u003c/p\u003e\n\t\t\u003c/slot\u003e\n\t\t\u003chr /\u003e\n\t\t\u003cslot id=\"field_control\" name=\"field-control\"\u003e\n\t\t\u003c/slot\u003e\n\t\t\u003chr /\u003e\n\t\t\u003cslot name=\"submit_button\"\u003e\u003c/slot\u003e\n\t\u003c/div\u003e\n\u003c/form\u003e\n```\n\n```html\n\u003c!-- A signup form using the shadowed component signup-form --\u003e\n\u003c!-- template: signup.tpl.html --\u003e\n\u003csignup-form shadowed=\"true\" controllerClass=\"SignupFormController\"\u003e\n  \u003ch1 slot=\"title\"\u003eSignup Form\u003c/h1\u003e\n  \u003cp slot=\"subtitle\"\u003ePlease fill up this form to ask for a quote.\u003c/p\u003e\n  \u003clabel slot=\"field-control\" id=\"name_label\" for=\"name\"\u003e\u003cb\u003e\u0026#x1F9D1; Full Name\u003c/b\u003e\u003c/label\u003e\n  \u003cinput slot=\"field-control\" type=\"text\" pattern=\"^[a-zA-Z]+(([',. -][a-zA-Z ])?[a-zA-Z]*)*$\" title=\"Please write your full name\" placeholder=\"Full Name\" name=\"name\" data-field=\"name\" aria-labelledby=\"name_label\" required\u003e\n  \u003clabel slot=\"field-control\" id=\"email_label\" for=\"email\"\u003e\u003cb\u003e\u0026#x1F4E7; Email\u003c/b\u003e\u003c/label\u003e\n  \u003cinput slot=\"field-control\" type=\"email\" pattern=\"^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$\" title=\"Please write a right email address\" placeholder=\"Enter Email\" name=\"email\" data-field=\"email\" aria-labelledby=\"email_label\" required\u003e\n  \u003clabel slot=\"field-control\" for=\"comment\" id=\"comment_label\"\u003e\u003cb\u003e\u0026#x1F4DD; Comment\u003c/b\u003e\u003c/label\u003e\n  \u003ctextarea slot=\"field-control\" name=\"comment\" title=\"Please write a comment\" rows=\"10\" cols=\"100\" data-field=\"comment\" aria-labelledby=\"comment_label\"\u003e\u003c/textarea\u003e\n  \u003cp slot=\"field-control\"\u003eBy submitting this form you agree to our \u003ca href=\"#\" style=\"color:dodgerblue\"\u003eTerms \u0026 Privacy\u003c/a\u003e.\u003c/p\u003e\n\t\u003cdiv class=\"clearfix\"\u003e\n\t    \u003cbutton aria-label=\"Cancel\" onclick=\"location.href='/#'\" role=\"button\" tabindex=\"-1\" type=\"button\" class=\"cancelbtn\"\u003e\u003cp\u003eCancel\u003c/p\u003e\u003c/button\u003e\n\t    \u003cbutton  aria-label=\"Send\" role=\"button\" tabindex=\"-1\" type=\"button\" class=\"signupbtn submit\"\u003e\u003cp\u003eSend\u003c/p\u003e\u003c/button\u003e\n\t\u003c/div\u003e\n\u003c/signup-form\u003e\n```\n\n```javascript\nRegisterWidget(\"signup-form\");\n```\n\n#### org.qcobjects.controllers.SwaggerUIController\n\nIt is used to inject a swagger-ui DOM needed to the Swagger UI API. Learn more in this article of QCObjects DevBlog called [Working with Swagger UI as a QCObjects Component](https://devblog.qcobjects.org/working-with-swagger-ui-as-a-qcobjects-component-ck6xzoqkg05indfs1i4rxq72e)\n\n##### Usage:\n\n```html\n\u003ccomponent componentClass=\"SwaggerUIComponent\" controllerClass=\"SwaggerUIController\" \u003e\u003c/component\u003e\n```\n\n```html\n\u003c!-- using a smart widget --\u003e\n\u003cswagger-ui componentClass=\"SwaggerUIComponent\" controllerClass=\"SwaggerUIController\"\u003e\u003c/swagger-ui\u003e\n```\n\n\n### SDK Effects\n\nQCObjects has an **Effect** definition to handle and produce new effects and transitions for the components.\nBelow are some custom effect definitions that will help you to build amazing visual features to your components. To improve the performance, effects are changing CSS internally to apply the effect in a smart way. And all the effects engine is based on the **requestAnimationFrame** definition, read more [here](https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#animation-frames)\n\n#### org.qcobjects.tools.effects.Move\n\nMoves a DOM object from one position to another.\n\n##### Usage:\n\n```javascript\nlet move = new Move();\nmove.apply(element, xfrom, yfrom, xto, yto);\n```\n\n##### Example:\n\n```javascript\n// The next line will move all the images from (0,0) to (10,10)\nTag('img').map(img =\u003e (new Move()).apply(img,0,0,10,10))\n```\n\n#### org.qcobjects.tools.effects.MoveXInFromRight\n\nMoves an element from the right side in X axis to the original position of the object.\n\n##### Usage:\n\n```javascript\nlet moveXInFromRight = new MoveXInFromRight();\nmoveXInFromRight.apply(element)\n```\n\n##### Example:\n\n```javascript\n// the next line will move every canvas on the document from right side to its original position\nTag('canvas').map(canvas =\u003e (new MoveXInFromRight()).apply(canvas));\n```\n\n#### org.qcobjects.tools.effects.MoveXInFromLeft\n\nMoves an element from the left side in X axis to the original position of the object.\n\n##### Usage:\n\n```javascript\nlet moveXInFromLeft = new MoveXInFromLeft();\nmoveXInFromLeft.apply(element);\n```\n\n##### Example:\n\n```javascript\n// the next line will move every canvas on the document from left side to its original position\nTag('canvas').map(canvas =\u003e (new MoveXInFromLeft()).apply(canvas));\n```\n\n#### org.qcobjects.tools.effects.MoveYInFromBottom\n\nMoves an object of the DOM from bottom to its original position using Y axis.\n\n##### Usage:\n\n```javascript\nlet moveYInFromBottom = new MoveYInFromBottom();\nmoveYInFromBottom.apply(element);\n```\n\n##### Example:\n\n```javascript\n// the next line will move the body of every component named \"comp1\" from bottom to its original position\nTag('component[name=comp1]').map(componentBody =\u003e (new MoveYInFromBottom()).apply(componentBody));\n```\n\n#### org.qcobjects.tools.effects.MoveYInFromTop\n\nMoves an object of the DOM from top to its original position using Y axis.\n\n##### Usage:\n\n```javascript\nlet moveYInFromTop = new MoveYInFromTop();\nmoveYInFromTop.apply(element)\n```\n\n##### Example:\n\n```javascript\n// the next line will move the body of every component named \"comp1\" from top to its original position\nTag('component[name=comp1]').map(componentBody =\u003e (new MoveYInFromTop()).apply(componentBody));\n```\n\n#### org.qcobjects.tools.effects.RotateX\n\nRotates an object in X axis.\n\n##### Usage:\n\n```javascript\nlet rotateX = new RotateX();\nRotateX.apply(element, angleFrom, angleTo);\n```\n\n**angleFrom** and **angleTo** represent an angle value expressed in degrees, starting from 0 (zero) to 360.\n\n##### Example:\n\n```javascript\n// the next line will rotate in X axis the div called #id from 180 degrees to 240 degrees\nTag('div#id').map(div =\u003e (new RotateX()).apply(div, 180, 240));\n```\n\n\n#### org.qcobjects.tools.effects.RotateY\n\nRotates an object in Y axis.\n\n##### Usage:\n\n```javascript\nlet rotateY = new RotateY();\nrotateY.apply(element, angleFrom, angleTo)\n```\n\n**angleFrom** and **angleTo** represent an angle value expressed in degrees, starting from 0 (zero) to 360.\n\n##### Example:\n\n```javascript\n// the next line will rotate in Y axis the div called #id from 0 degrees to 270 degrees\nTag('div#id').map(div =\u003e (new RotateY()).apply(div, 0, 270));\n```\n\n#### org.qcobjects.tools.effects.RotateZ\n\nRotates an object in Z axis.\n\n##### Usage:\n\n```javascript\nlet rotateZ = new RotateZ();\nRotateZ.apply(element, angleFrom, angleTo);\n```\n\n**angleFrom** and **angleTo** represent an angle value expressed in degrees, starting from 0 (zero) to 360.\n\n##### Example:\n\n```javascript\n// the next line will rotate in Z axis the div called #id from 0 degrees to 60 degrees\nTag('div#id').map(div =\u003e (new RotateZ()).apply(div, 0, 60));\n```\n\n\n\n#### org.qcobjects.tools.effects.Rotate\n\nRotates an object in X, Y, Z axes. All axes will rotate in paralell at the same time producing a 3d visual effect perception.\n\n##### Usage:\n\n```javascript\nlet rotate = new Rotate ();\nRotate.apply(element, angleFrom, angleTo);\n```\n\n**angleFrom** and **angleTo** represent an angle value expressed in degrees, starting from 0 (zero) to 360.\n\n##### Example:\n\n```javascript\n// the next line will rotate in X, Y and Z axes the div called #id form 0 to 270 degrees\nTag('div#id').map(div =\u003e (new Rotate()).apply(div, 0, 270));\n```\n\n#### org.qcobjects.tools.effects.Fade\n\nProduces a fade effect by lowering the opacity of the element.\n\n##### Usage:\n\n```javascript\nlet fade = new Fade();\nFade.apply(element, alphaFrom, alphaTo);\n```\n\n**alphaFrom** and **alphaTo** are numbers between 0 (zero) and 1.\n\n```javascript\n// the following line will fade a \u003cb class=\"header\"\u003e element from 0.5 (mid visibility) to 1 (full visibility)\nTag('b.header').map(header=\u003e(new Fade()).apply(header, 0.5, 1))\n```\n\n#### org.qcobjects.tools.effects.Radius\n\nRounds the corner of an element\n\n##### Usage:\n\n```javascript\nlet radius = new Radius();\nradius.apply(element, radiusFrom, radiusTo)\n```\n\n**radiusFrom** and **radiusTo** are numeric values.\n\n##### Example:\n\n```javascript\n// the next line will round the corners of every image in the document\nTag('img').map(element =\u003e (new Radius()).apply(element, 0, 100))\n```\n\n#### org.qcobjects.tools.effects.Resize\n\n##### Usage:\n\n```javascript\nlet resize = new Resize ();\nresize.apply(element, scaleFrom, scaleTo)\n```\n\n**scaleFrom** and **scaleTo** are numeric values.\nA value of 1 is regular size, a value of 2 is double size, a value between 0 and 1 is a small scale.\n\n##### Example:\n\n```javascript\n// the next line will make a zoom-out effect on every image in the document\nTag('img').map(element =\u003e (new Resize()).apply(element, 2,0))\n\n// the next line will make a zoom-in effect on every image in the document\nTag('img').map(element =\u003e (new Resize()).apply(element, 0,1))\n\n// the next line will make a zoom-in-out effect on every image in the document\nTag('img').map(element =\u003e (new Resize()).apply(element, 2,1))\n```\n\n#### org.qcobjects.tools.effects.WipeLeft\n\nMakes a Wipe effect from Left side to the origin of the element.\n\n##### Usage:\n\n```javascript\nlet wipeLeft = new WipeLeft();\nwipeLeft.apply(element, scaleFrom, scaleTo)\n```\n\n**scaleFrom** and **scaleTo** are numeric values.\nA value of 1 is regular size, a value of 2 is double size, a value between 0 and 1 is a small scale.\n\n##### Example\n\n```javascript\nTag('img').map(element =\u003e (new WipeLeft()).apply(element,0,1))\n```\n\n#### org.qcobjects.tools.effects.WipeRight\n\nMakes a Wipe effect from right side to the origin of the element.\n\n##### Usage:\n\n```javascript\nlet wipeRight = new WipeRight();\nwipeRight.apply(element, scaleFrom, scaleTo)\n```\n\n**scaleFrom** and **scaleTo** are numeric values.\nA value of 1 is regular size, a value of 2 is double size, a value between 0 and 1 is a small scale.\n\n##### Example\n\n```javascript\nTag('img').map(element =\u003e (new WipeRight()).apply(element,0,1))\n```\n\n\n#### org.qcobjects.tools.effects.WipeUp\n\nMakes a Wipe effect from down to up the origin of the element.\n\n##### Usage:\n\n```javascript\nlet wipeUp = new WipeUp();\nwipeUp.apply(element, scaleFrom, scaleTo);\n```\n\n**scaleFrom** and **scaleTo** are numeric values.\nA value of 1 is regular size, a value of 2 is double size, a value between 0 and 1 is a small scale.\n\n##### Example\n\n```javascript\nTag('img').map(element =\u003e (new WipeUp()).apply(element,0,1))\n```\n\n#### org.qcobjects.tools.effects.WipeDown\n\nMakes a Wipe effect from up to down the origin of the element.\n\n##### Usage:\n\n```javascript\nlet wipeDown = new WipeDown();\nwipeDown.apply(element, scaleFrom, scaleTo);\n```\n\n**scaleFrom** and **scaleTo** are numeric values.\nA value of 1 is regular size, a value of 2 is double size, a value between 0 and 1 is a small scale.\n\n##### Example\n\n```javascript\nTag('img').map(element =\u003e (new WipeDown()).apply(element,0,1))\n```\n\n\n### SDK Misc Tools\n\n#### org.qcobjects.tools.canvas.CanvasTool\n\n#### org.qcobjects.tools.layouts.BasicLayout\n\n### SDK Views\n\nBelow are a set of pre-defined views for common use.\n\n#### org.qcobjects.views.GridView\n\nA generic GridView definition for use with grids.\n\n### SDK i18n messages\n\nThe QCObjects i18n engine allows you to define custom messages . Learn more in this article in the DevBlog called [i18n Internationalisation for your Progressive Web Apps](https://devblog.qcobjects.org/i18n-internationalisation-for-your-progressive-web-apps-ck90h4qz301ca7vs1ue7joopu)\n\n#### org.qcobjects.i18n_messages.i18n_messages\n\nUsed to call the i18n engine.\n\n##### Usage:\n\n```javascript\n\tclass i18n_messages_\u003ccustom lang\u003e extends i18n_messages {\n\t\t...\n\t}\n```\n\n##### Example\n\n```javascript\n'use strict';\n// file: js/packages/org.qcobjects.i18n_messages.es.js\nPackage('org.qcobjects.i18n_messages.es', [\n\tclass i18n_messages_es extends i18n_messages {\n\t\tconstructor () {\n\t\t\tthis.messages= [\n\t\t\t// ... your custom language dictionary is here\n\t\t\t{\n\t\t\t\t\"en\":\"This is a paragraph\",\n\t\t\t\t\"es\":\"Esto es un párrafo\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"en\":\"Welcome to my new app\",\n\t\t\t\t\"es\":\"Bienvenido a mi nueva app\"\n\t\t\t}\n\t\t\t];\n\t\t}\n\t},\n\t{\n\t\t// the next line generates an instance of the i18n engine and attaches it automatically in the package\n\t\t_i18n_messages_es: new i18n_messages_es()\n\t}\n]);\n```\n\n## License\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects-SDK.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects-SDK?ref=badge_large)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquickcorp%2Fqcobjects-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquickcorp%2Fqcobjects-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquickcorp%2Fqcobjects-sdk/lists"}