Create a custom Widget or Plugin in your Application
Overview
You can create a custom Widget or a custom Plugin to extend a Widget or Application Shell/Workspace.
Directory Structure
A Widget or a Plugin is composed by multiple files. At least one JS and the widget.json (configuration file).
app
|-- <app-name>
|-- widgets
|-- <widget-or-plugin-name>
|-- js
| `-- <widget-or-plugin-name>.js
|-- scss
| `-- <widget-or-plugin-name>.scss
|-- html
| `-- <widget-or-plugin-name>.tpl.html
`-- widget.json
1. Create the custom widget's folder:
a) Must be in app/[app-name]/widgets;
b) The name of the folder should be equals to the name of the widget.
2. Create the necessary programming language's folders:
a) Must be in app/[app-name]/widgets/[widget-or-plugin-name];
b) This folder whould have the JS, SCSS or HTML subfolders has needed and
the widget.json file.
3. Create the implementation of your widget or plugin javascript:
a) Must be in app/[app-name]/widgets/[widget-or-plugin-name]/js/[widget-or-plugin-name].js;
b) More files could be added.
4. Create widget.json file:
a) Define the name, version and file Inicludes in this file.
Source Code
Some source code tempaltes.
JavaScript
1 var [widget-or-plugin-name-capitalized] =
2 {
3 isExtendable: function(item)
4 {
5 if (Frames.inDesignMode || Frames.isUndef(item.elem))
6 {
7 return false;
8 }
9 var wname = item.widgetcls();
10 return wname == '[widget-name]';
11 },
12
13 register: function(item)
14 {
15 if (this.isExtendable(item))
16 {
17 item.elem.addClass('ui-[widget-or-plugin-name]);
18
19 //Create/contruct extension
20 //Ex: adding more methods or changing some functionality
21 }
22 },
23
24 unregister: function(item)
25 {
26 if (this.isExtendable(item))
27 {
28 //Revert/destroy extension
29 }
30 }
31 };
32
33 Frames.regplug("[widget-or-plugin-name]", [widget-or-plugin-name-capitalized], Frames.PLUGIN
SCSS
Style of the Widget or Plugin. Note that this files should be added has imports to the mains theme SASS.
1.ui-[widget-or-plugin-name] {
2 //Add content
3}
HTML
Add the following code to the HTML file:
1<script id="[widget-or-plugin-name]-template" type="text/html">
2 //Add content
3</script>
To use the HTML code, you need to add the following code to the JS file:
1(...)
2var template = Frames.Template.get('widgets/[plugin-name]/html/[plugin-name].html#[widget-or-plug
3var html = template({});
4this.element.html(html);
5(...)
Configuration File (Widget.json)
widget.json
1{
2 "name": "[widget-or-plugin-name-capitalized]",
3 "version": "1.0.0",
4 "scripts": [
5 "js/[plugin-name].js"
6 ],
7 "stylesheets": [
8 "css/[plugin-name].css"
9 ]
10}
Integrate in your application
Add the custom widget or plugin to package.json, located on app/[app-name]:
package.json
1{
2 (...)
3 "widgets": [
4 (...),
5 "widgets/[widget-or-plugin-name]"
6 ],
7 (...)
8}
Testing and Running
Check if was loaded
To make sure the widget or plugin was loaded:
1. Open the browser;
2. Go to your localhost environment;
3. Press F12 and go to Console:
a. Write Frames.getplugs(Frames.PLUGIN_WIDGET).get('[plugin-name]'):
i. If returns undefined, your custom widget hasn't been added to Frames - review tutorial.
Add and widget to the View (XVC) file
1. Open a XVC file;
2. Add the following code:
1(...)
2<widget type="[custom-widget-name]" />
3(...)
Associate Plugin to a Widget by CSS class
1. Open a XVC file;
2. Add the following code to View (XVC):
1(...)
2<textinput class="ui-custom-plugin-enabled" />
3(...)
3. Add the following code to your js file:
1 var CustomPlugin =
2 {
3 isExtendable: function (item)
4 {
5 return item.elem && item.elem.hasClass('.ui-custom-plugin-enabled');
6 },
7...
Example Widget - TextInputMask
Step 1 - Directory Structure and Files
app
|-- example
|-- widgets
|-- textinputmask
|-- css
| `-- textinputmask.css
|-- html
| `-- textinputmask.html
|-- js
| `-- textinputmask.js
`-- widget.json
Step 2 - Add Source Code
textinputmask.js
1(function($) {
2 $.widget("ui.textinputmask", {
3 version: "@VERSION",
4 options: {
5 temp: 'widgets/textinputmask/html/textinputmask.html#textinputmask-template'
6 },
7
8 _create: function() {
9 var self = this;
10 this.element.addClass("ui-textinputmask");
11
12 var template = Frames.Template.get(this.options.temp);
13 if (Frames.isUndef(template))
14 {
15 return;
16 }
17
18 var html = template({});
19 this.element.html(html);
20 this._lbl = $("label", this.element);
21 this._inp = $("input", this.element);
22 this._inp.on('change', function(event)
23 {
24 var item = $(event.target);
25 var pattern = item.data('mask');
26 var regex = new RegExp(pattern);
27 if (!regex.test(item.val()))
28 {
29 Frames.Workspace.showMessage('Value doesn\'t follow the pattern: ' + pattern
30 }
31 });
32 },
33
34 input: function()
35 {
36 return $.ui.textinput.prototype.input.apply(this);
37 },
38
39 labelObj: function()
40 {
41 return $.ui.textinput.prototype.labelObj.apply(this);
42 }
43 });
44
45 Frames.TextInputMask = $.inherit(Frames.TextInput, {
46 widgetcls: function() {
47 return 'textinputmask';
48 },
49
50 customInputmask: function()
51 {
52 if (arguments.length > 0)
53 {
54 this.input().data('mask', arguments[0]);
55 } else
56 {
57 return this.input().data('mask');
58 }
59 }
60 });
61
62 Frames.Item.PROP_MAP.CustomInputmask = { method: 'customInputmask' };
63
64 Frames.regtype("textinputmask", Frames.TextInputMask);
65})(jQuery);
66
67//# sourceURL=app/soul/widgets/textinputmask/js/textinputmask.js
textinputmask.css
1.ui-textinputmask {
2 width: 50px;
3 height: 22px;
4}
textinputmask.html
1<script id="textinputmask-template" type="text/html">
2 <input type="text"/>
3 <label/>
4</script>
widget.json
1{
2 "name": "TextInputMask",
3 "version": "1.0.0",
4 "scripts": [
5 "js/textinputmask.js"
6 ],
7 "stylesheets": [
8 "css/textinputmask.css"
9 ]
10}
Step 3 - Integrate with the application
package.json
1{
2 (...)
3 "widgets": [
4 (...),
5 "widgets/textinputmask"
6 ],
7 (...)
8}
Step 4 - Check if was correctly loaded
Step 5 - Add Widget to View (XVC) file
PanelCgPage1.xvc
1(...)
2<widget type="textinputmask" top="50px" a:inputmask="^[0-9]{2}$" block="ATENDIME1" member="HR_ATE
3(...)
This widget uses a custom attribute - a:inputmask. To create a custom attributes click HERE.
Step 6 - Open View to see if it's working
Example Plugin - HintManager
Warning
HintManager isn't applied via XVC and doesn't extend a specific widget.
Step 1 - Directory Structure and Files
app
|-- example
|-- widgets
|-- hintmanager
|-- js
| `-- hintmanager.js
`-- widget.json
Step 2 - Add Source Code
hintmanager.js
1 var HintManager =
2 {
3 isExtendable: function (item)
4 {
5 return item.elem && item.member && item.input();
6 },
7
8 register: function (item)
9 {
10
11 if (Frames.inDesignMode)
12 {
13 return;
14 }
15
16 if (this._isInitialized())
17 {
18 this.hintEl = $(document).find('#hint').children('span.hint');
19 } else
20 {
21 return;
22 }
23
24 if (this.isExtendable(item))
25 {
26 var i = item.input();
27 i.bind('focusin', this._focusEvent);
28 }
29 },
30
31 _isInitialized: function ()
32 {
33 return !Frames.isUndef(this.hintEl) ||
34 $(document).find('#hint').length > 0;
35 },
36
37 _focusEvent: function (event)
38 {
39 var elem = $(event.target);
40 if ($.browser.webkit && event.type == 'click' && !elem.hasClass('ui-widget'))
41 {
42 elem = elem.parents('.ui-widget').eq(0);
43 }
44
45 var item = elem.data('frames');
46 if (item)
47 {
48 var hint = item.data('hint');
49 HintManager.hintEl.html(Frames.isEmpty(hint) ? ' ' : hint);
50 }
51
52 return true;
53 },
54
55 unregister: function (item)
56 {
57 if (!this._isInitialized())
58 {
59 return;
60 }
61
62 this.hintEl.html(' ');
63 var i = item.input();
64 if (Frames.isUndef(i))
65 {
66 return;
67 }
68
69 i.off('focusin', this._focusEvent);
70 }
71 };
72
73 Frames.regplug('hintmanager', HintManager, Frames.PLUGIN_WIDGET);
74
75
76//# sourceURL=app/soul/widgets/hintmanager/js/hintmanager.js
widget.json
1{
2 "name": "HintManager",
3 "version": "1.0.0",
4 "scripts": [
5 "js/hintmanager.js"
6 ]
7}
And other steps are basically the same has the Widget example.
Debug Frames in environments
without source
Saltar al final de los metadatos
Creado por Usuario desconocido (nuno.guerreiro), modificado por última vez en dic 22, 2016
Ir al inicio de los metadatos
When you need to debug in a release environment where the frames framework source code is not available.
We'll discuss 2 approaches, the first and easier, will allow you to debug using the release in use by the remote
server. The second, will allow you to debug with the latest version in your own local environment, which allows you
to develop new features and test immediately without needing to wait for a deploy.
Using the release from the remote server
One way to work around not having the Frames source code in a specific environment, is adding the .map files from
your computer.
Open Developer Tools in Chrome and in the Sources tab open (Ctrl+P or Ctrl+O) jquery.frames.min.js file:
Right click on the opened file and use Attach Source Map option:
Add the url to your local or an environment that has the .map file:
Valid URL examples:
http://localhost:8080/wrksp/runtime/js/jquery.frames.min.js.map
file:///Users/kimus/Develop/morphis/frames/runtime-html5/workspace/js/jquery.frames.min.js.map
And then, open some source file and add a breakpoint for debugging: