CodeCoupler UI Component
The Component
class is the base class of all CodeCoupler components. All the following
functionalities and rules affect all components.
Each component will have the following members:
Component Construction
prepare()
andfinalize()
-
These method names are used internally and should not be used. Otherwise the component will not work properly.
init()
:-
All components use this method name for custom initialization code. It will always used when a component is created.
boot()
andstart()
:-
These method names is only used for the initialization process of some components.
initialized
-
The property
this.initialized
return a promise which will be resolved if the component ist initialized or rejected if an error occurs while initializing.This can be used for example in the
init
methods to define actions that will be executed after the initialization phase ends. You need to know that after the init method, additional steps may be carried out. In some cases it makes sense to wait for this first:
Common Getters
env
-
Prepared environment and options variables.
id
-
With
this.id
you can read the id of the current component. settings
-
Access the system wide settings. Details explained in "System Wide Settings".
options
,constructor.defaults
-
Over the property
this.options
the component get access to the options the user have defined in the start definition object for your component.The options will be merged with the static property
defaults
of the component class and all static propertiesdefaults
of all prototypes of the component.With this mechanism you can define the default values for all options and the user can set default values for each new instance.
If you set a new value to
this.options
it will be merged to the already existing ones!
Destroying
asyc destroy()
,destroying
,Event destroyed
-
Method to destroy the component. The base method will call all
destroy
methods of all child components. The function can be called multiple times, but is only executed once. To get the status if destroying is running, test if the propertythis.destroying
returnstrue
.At the end of the destroying process the component will trigger the event
destroyed
. As argument the event will have the component instance.The method blocks the component with the message from the system wide setting
messages.COMMON.DESTROYING
while executing. On finish the component will be blocked with the messagemessages.COMMON.DESTROYED
with a special overlay styledestroyed
which is black and non-transparent. The method do not wait while the last blocking is ready.The method can be overriden to add own functionality. In this case the super method should be called. You should ensure that no error will be thrown:
Widget Handling
widget(widgetStart)
-
Widget factory method to initialize an new widget instance.
Application Handling
app(appStart)
-
Application factory method to initialize an new application instance.
apps
-
With
this.apps
you can access an object of all applications of this component. The id of the application is used as property name.You get only running apps. If the id is not in this object the application was closed. This can be done by a user or programmatically. This is important to check because the application instance can continue to exist, even the application was closed.
frontedApp
-
Returns the instance of the fronted application. Can be null if component do not have an application started.
Event Management
on(event,handler)
,one(event,handler)
,off([event],[handler])
,trigger(event,argments)
-
Each component provide methods to bind and trigger functions based on event names.
on
: Add a handler to an event.one
: Add a handler to an event that will be executed only one time.off
: Remove a handler to an event. Ifhandler
is omitted all, handler to this event will be removed. Ifevent
andhandler
are omitted, all handler for all events will be removed.trigger
: Trigger an event.
Hints
hint(text)
,hint(type, text)
,hint(type, text, element)
,$hintContainer
-
Show an hint with the given style in
type
. Depending on which component this method is used, the hint is displayed in the following places:Component Hint Target System In the current stage Stage In the stage element Application In the content area of the application Widget In the widget element The argument
type
specifies the hint style. Predefined areinfo
,success
anderror
. If ommitedsuccess
will be taken. You can add or modify these styles in the system wide settinghints
. Each property in this object represents one style. A style is a configuration object which will start a jPanel hint extension.The signature including
element
is used internally. If you need to specify a custom element in which the hint should be displayed, you can use `element which can be defined as HTMLElement, jQuery object or selector string.The getter
$hintContainer
is used internally. Do not override.
Visibility
visibility
,$visibility
,static visibilityValues
,static $visibilityValues(value)
,Event visibility
-
With
this.visibility
you get one of the value from the static objectComponent.visibilityValues
:Component.visibilityValues.HIDDEN
Component.visibilityValues.VISIBLE
Component.visibilityValues.PARTLY
A component can set its visibility status with
this.visibility
to one of these values. But as soon as you ask for the value, it does not mean that exactly the same will be returned.If you ask for the value, further conditions are checked to determine whether a component is visible or not. A component is not visible for example if it is inside of an application panel that is minimized. Or it is also not visible if it is in an application panel behind another maximized panel. This is not only checked for the panel above, but also for the entire route down to the system.
The value
PARTLY
will returned if a component is in a panel behind other panel which are normalized. This means that the component can be partially visible or completely covered by other panels. This cannot be determined more precisely.It is very important if you implement widgets which hold itself other widgets to maintain the visibility status of these widgets. For example if you implement a tabed display of multiple widgets, you should set the visibility of each one, depending on which tab is displayed.
Whenever the visibility of a component is supposedly changed, the event
visibility
is triggered. The eventvisibility
will be triggered often without checking if the visibility have really changed. This is becuase the calculation of the visibility is much more intensive and is not used everytime. You can bind a callback to this event, check withthis.visibility
and get the new or old status.The static function
$visibilityValues(value)
is just a helper which converts a visibility value to its name.The getter
this.$visibility
returns the value that have been set for the component, not the calculated.
Resizing
Event resize
-
Whenever the resize event is triggered in a component, the component will trigger this event on all child components. An application will trigger this event if the panel is resized, normalized or maximaized. If you implement a component wich change its size you should trigger this event one time in your component. If you change sizes of child components you should trigger this event in the affected components one time.
Blocking
► Read more about blocking components
Blocking Methods
async block({type, text, handle, settings, sticky})
-
Block the the component with a message. Keep in mind that this is an async method. This is because the blocking layer will fade in and the method will resolve if the fading is finished.
Different signatures are available for this method:
block()
block(text)
:block(text, {...})
block(handle, {...})
block(handle, text)
block(type, text)
block(type, text, {...})
type
: String-
If you set
type
toinfo
orerror
a different stylesheet will be used. If you do not specifytype
,info
will be used as default.Styles will be configured in the system wide settings in the property
block
.Will not used if
handle
is given. text
: String | HTMLElement | jQuery Object-
message
can be a simple string with HTML elements, an HTMLElement or a jQuery object which will be displayed.If you set
message
to an empty string,null
, orundefined
the method produce an empty container which have the fill width and height of the component. This can be used to display just an empty blocking layer or to add or modify the content as you like over the return valuecontainer
. handle
: String-
Use
handle
to call theblock
method again and update an existing blocking layer. Must be created withnew BlockHandle()
or read from the return value of previousblock
calls. settings
: Object-
Here you can override the system wide settings of
block
for only this blocking call.Will not used if
handle
is given. sticky
: Boolean-
Create a "sticky" blocking layer if
true
. Please read the section about the "stacking concept" above for more details.
async unblock(handle)
-
Unblock the component. Keep in mind that this is an async method. This is because the blocking layer will fade out and the method will resolve if the fading is finished.
handle
: String-
The handle returned from the
block
method have to be used here to unblock a specific blocking layer.
async block({..., element})
andasync unblock(handle, element)
-
The methods
block
andunblock
have one more signature with which you can specify an element to block instead the current component.Normally you cannot set what HTMLElement should be blocked. This will be set by the component. The only case you could use this property is calling the methods from the super instance with type of
Component
. Theelement
can be defined as HTMLElement, jQuery object or selector string.
Blocking Getter
blocked
-
Returns
false
if component is not blocked or one of the stringsinfo
orerror
depending on the block type. $blockContainer
and$blockArguments
-
Used internally. Do not change.
Preloading Assets
With the method preload
you can preload assets. The default progress behaviour is to block the
component and show the progress in percent.
Important: Do not use the preload
functions in the init
method of an application. Because at
this time the application do not have a panel and the default progress handler will try to block the
application. This leads to an exception.
Preloading Methods
async preload(config,[args],[settings])
-
To start a loading process you have to call the method
async preload()
with a configuration object.config
: Object-
Each property of this configuration object have to be a name of a preloading handler. It's value will be used as argument for the specific handler. The returned promise of the method will resolve if all assets are loaded or reject if an error occurs.
The default preloading handlers are
dataSources
,fonts
andfontsRequired
. Custom handlers can be added. args
: Any-
Specify here whatever you want, that will be passed on to the progress callbacks (see below).
settings
: Object-
Specify an object with some options. Default values will be taken from
settings.preloader
of the system instance. The object can have the following properties:delay
: Object-
Specify a delay for debuging purposes. The object have the following properties:
enabled
: Boolean.-
If
true
delaying will be enabled. minMSec
: Integer.-
The minimal time in milliseconds that will use each asset for loading.
maxMSec
: Integer.-
The maximal time in milliseconds that will be added to the minimal time above. It will be used a random time between minimal and maximal delay on each asset loading.
progress
: Class-
Progress handler which will be instatiated for each
preload
call. The methods get notified for each progress update and can use this information to present them to the user. Read below for more informations.
registerPreloader(name,func)
-
Method to register a new preloading handler.
name
: String-
The the property name of the configuration object that will be used for this handler.
func(assets, progress, delay)
-
Callback function of the custom handler.
assets
: Any-
The configuration value for this handler.
progress
: Object-
The object have three properties that have to be updated by the handler during the loading process.
total
: Number-
The handler have to count the assets given in the argument
assets
as soon as possible and update the number here. success
: Number-
Whenever an asset is loaded you have to increase the number here.
failed
: Number-
Whenever an asset cannot be loaded you have to increase the number here.
delay
: Object-
Whenever possible implement a delay according to the
delay
argument (details are explained above).
Progress Handler Class
The start have to provide the following methods:
async start(component,args)
-
Callback that will be called when the preload processes starts.
component
: Component-
The current component instance that initiated the preload process.
args
: Any-
The value that have been used starting the preload process.
async update(component,progress,args)
-
Callback that Will be called everytime the progress summary of the loading process have changed. Everytime a handler will change its progress object, the component will calculate a summary of all loading assets.
component
: Component-
The current component instance that initiated the preload process.
progress
: Object-
An object with the following properties:
total
: Number-
Total Assets that have to be loaded.
success
: Number-
Number of succesful loaded assets.
failed
: Number-
Number of assets that failed loading.
percent
: Number-
Percent of assets that sucesful loaded or failed.
args
: Any-
The value that have been used starting the preload process.
async end(component)
-
Callback that will be called when all preload processes finished and all calls to the
update
methods have been completed.component
: Component-
The current component instance that initiated the preload process.
Default Preloading Handlers
dataSources
: Object[]-
The value of
dataSources
must be an array of objects. The objects have to be the arguments used in thecomponent.dataSource()
method. fonts
andfontsRequired
: string[] | object-
The value of
fonts
andfontsRequired
can be an array offont-face
names to load. The difference betweenfonts
andfontsRequired
is that the promise will rejected if loading fails infontsRequired
and will always resolve infonts
.In addition to the name, the variation can also be specified. Herefore the
Font Variation Description
will be used like explained here: [https://github.com/typekit/fvd]Example: "Font Awesome 5 Free:n4,n9" will load the font
Font Awesome 5 Free
in normal style and with the weights 400 and 900.Because the external library Web Font Loader is used under the hood, you can alternatively set the configuration object directly.
Data Handling
Datasource Factory
dataSource()
,dataSources
-
Create and retrieve datasources created by this component. With
this.dataSources
you can access an object of all datasources of this component. The id of the datasource is used as property name.
Handling Data Changes
Each component have some prepared methods to handle pending data changes in datasources. Whenever a
data item of a datasource have been modified, created or deleted the datasource is marked as dirty
and this means that pending data changes exists.
Each component handle self-created datasources and all datasources of all child components.
In many cases a component receive a datasource instance as option. In this case all the data
handling will not work as expected. For this case you can and should link the datasources with
dataSourceLink()
. All data handling methods will take linked datasources also into account.
dataSourceLink(dataSource)
: Void-
Link an existing datasource which was not created by the component itself and was passed via an option from a parent component.
All linked datasources will be handled from all other data handling methods as they would be self-created.
hasChanges(commited)
: Boolean | Null-
Checks if any own datasource or any datasource of any child component have pending changes.
Returns
true
if pending changes exists,false
if no pending changes exists andnull
if the method cannot decide if pending changes exists.The last case, returning
null
occurs if a component cannot commit its current input values. To check this before checking the datasourcesthis.commitChanges()
will be called. If this method returnsfalse
the methodhasChanges
returnsnull
.If you want to add more checks in your component, override this method. You should call firstly the
super.hasChanges()
method and interrupt if changes already detected: commitChanges(blured)
: Boolean-
Perform any needed actions to take over currently entered values in input fields or other editor elements and save them in data items of datasources.
The method can return
true
if the commit has succeeded andfalse
otherwise. This can occur for example if an input field have an invalid value.The base method just calls
document.activeElement.blur()
if the browser supports this. This is done so that the focus is removed from the current input field and the entered data may also change a datasource.After this the method calls the
commitChanges
method of any child component. All method of all components will be called regardless of their return values. If any of these methods returnsfalse
the method will return alsofalse
.If you want to add more actions in your component, override this method. You should override this method especially if your component use input elements. In case the
commitChanges
is called you should perform a validation of all input fields. If a validation fails you should returnfalse
. Do not show the error messages at this time. Wait for callingtoggleErrors(true)
.If the validation succeed you should persist your values into the datasource.
In your override you should call firstly the
super.commitChanges
method and merge its return value with yours: async refreshData()
: void-
Calls the
read
method of any own datasource or any datasource of any child component. The method will fetch all data from the remote server.You have to pay attention, because this method will discard all local modifications.
The method try to call all
read
methods in each component in parallel.If you want to add more actions in your component, override this method. You should call firstly
await super.refreshData()
: cancelChanges()
: void-
Calls the
cancelChanges
method of any own datasource or any datasource of any child component. The method will reset all data items to the values fetched from the remote server.You have to pay attention, because this method will discard all local modifications.
If you want to add more actions in your component, override this method. You should call firstly the
super.cancelChanges
method: async saveData(commited)
: void-
Calls the
sync
method of any own datasource or any datasource of any child component. The method will send all modified data to the remote server.Before all checks
this.commitChanges()
will be called. If this method returnsfalse
an exception will be thrown. For now a simple Error object will be thrown with the messageCommit not possible
. In future versions this may change.You can avoid commiting changes by setting the argument
commited
totrue
. You should check in this case the return value ofthis.commitChanges()
or betterthis.hasChanges()
before callingsaveData(true)
.The method try to call all
sync
methods in each component in parallel.If you want to add more actions in your component, override this method. You should call firstly
await super.refreshData()
: toggleErrors(mode)
: void-
Set the error mode in component and in any child component.
mode
should be a boolean value.The idea behind this is to controll of how the input validation errors should be shown. You do not have to follow these pattern:
- The component start with the status of not showing any errors.
- The user start to enter values in an input field. Either the field prevent an input of an invalid value or show a subtle note like a red border.
- The user try to save although validation errors exists.
- The parent logic detects validation errors with
hasChanges
orcommitChanges
and callstoggleErrors(true)
. - Now the component should show detailed validation error messages.
- The user correct the values and save again.
- The parent logic do not detect any validation errors, the sync of all datasources
succeed and calls
toggleErrors(false)
. - From now on no detailed error messages will be shown and anything starts from beginning.
The method
saveDataUI
implements this pattern.You should override this method especially if your component use input elements. You should call firstly
super.toggleErrors()
and remember the current status:
Data Handling UI Methods
In addition to the previous data handling methods exists some data handling methods with UI elements and user interactions. They cover the most use cases in which the data handling methods will be used in combination with UI elements:
refreshDataUI()
-
Will check pending data changes with
this.hasChanges()
and callthis.refreshData()
if no changes detected. Returnstrue
on success, otherwisefalse
.If they are pending changes the user will be asked if he want to discard all changes before calling
this.refreshData()
. The confirm messages will be taken frommessages.DATA.CONFIRM_REFRESH
After refreshing an error or success hint will be shown. The messages of the hints will be taken from the system wide settings
messages.DATA.SUCCESS
andmessages.DATA.ERROR
. An error will be loged in the console. cancelChangesUI()
-
Will check pending data changes with
this.hasChanges()
and callthis.cancelChanges()
if no changes detected. Returnstrue
on success, otherwisefalse
.If they are pending changes the user will be asked if he want to discard all changes before calling
this.cancelData()
. The confirm messages will be taken frommessages.DATA.CONFIRM_CANCEL
saveDataUI(consoleError)
-
Will check pending data changes with
this.hasChanges()
and callthis.saveData()
if changes detected. Returnstrue
on success, otherwisefalse
.If they are no changes just a hint will be shown. The messages of the hints will be taken from the system wide settings
messages.DATA.NO_CHANGES
. In this case the method returnstrue
.If validation errors exists and
hasChanges
returnsnull
a hint will be shown andsaveData
will not be called. Insteadthis.toggleError(true)
will be called.After synchronizing the datasources an error or success hint will be shown. The messages of the hints will be taken from the system wide settings
messages.DATA.SUCCESS
andmessages.DATA.ERROR
. An error will be loged in the console if you set the argumentconsoleError
totrue
.If no error occurs
app.toggleErrors(false)
will be called.
Manifest
A component can provide a static field manifest
which contains properties of how the component
should be presented and other descriptive informations. This is used for example for displaying an
application component in titles, launching buttons or other UI elements. Because these informations
are needed before the application is created it is a static property.
Because a developer maybe do not specify all properties in its component you cannot just read the
static property manifest
to get all informations. You have to use the static method
Component.$manifest(component)
which will merge the values of all static properties of all parent
classes.
name
[ String ] (Default: Taken from base class)-
The name of the application.
iconHtml
[ String ] (Default: Taken from base class)-
The html element should inherit the font-size. If you use FontAwesome, you should always add the
fa-fw
class. level
[ String ]-
In which stage level this componenet will be loaded if not otherwise specified.