Creating Custom Elements

Version Date Notes By
0.1 2017-02-15 Initial release JFM

NPM Plugin base custom element (very very drafty stuff)

Creating custom elements that are not strictly html can be a little tricky, and theres not a particular formula to create them. This will document will try to guide you through the "normal" steps on creating the element using an example, wich in this case is the http://www.virtuosoft.eu/code/bootstrap-duallistbox/ plugin.

Install the npm package Ex: npm install bootstrap-duallistbox

Go the the common/components/aurelia-form/form-field.js file and on the viewModels object add an entry to the new custom element with the following format:

custom_element_name : path to view-viewmodel

Example 'duallistbox': './components/form-duallistbox'

Next you must create the View-ViewModel for the custom element on the common\components\aurelia-form\components folder. The name of the files must be in accordance to path you defined in the common/components/aurelia-form/form-field.js file. In our case: form-duallistbox.js and form-duallistbox.html.

model.value - valor/valores selecionados

de forma a percebr oq ue se deve importar no viewmodel, deve-se abrir o .js do plugin e verificar o metodo utilizador para instanciar o plyugin

Ex: $('.listbox-no-selection').bootstrapDualListbox({ ..... })

import {bootstrapDualListbox} from "bootstrap-duallistbox"

bootstrap-duallistbox - nome do plugin aquando da instalação (npm install bootstrap-duallistbox)

fetchData()
{
    let parameters = {};

    if (typeof this.model.element.remoteSourceParameters === 'function') {
        parameters = this.model.element.remoteSourceParameters();
    }

    return this.model.element.remoteSource(parameters)
        .then((response) => {
            return this.model.element.options = response;
        })
}

O método remoteSourceParameters tem de ser implementado no viewmodel do forma que usa este elemento

Implementar o metodo createElement()

Exemplo:

createElement()
{
    let htmlElement = $('#' + this.modelElementId);

    // Multiple selection
    $(htmlElement).bootstrapDualListbox({
        preserveSelectionOnMove: 'moved',
        moveOnSelect:            false
    });
}

Implementar o metodo destroyElement()

destroyElement()
{
    return this.simplePromise(() => {

        $('#' + this.modelElementId).bootstrapDualListbox('destroy');

    });
}
selectedAttribute(option)
{
    if (this.model.value === null || typeof this.model.value === 'undefined') {
        return '';
    }

    return this.model.value.indexOf(option) > -1 ? 'selected' : ''
}
;
subscribeEventListeners()
{
    super.subscribeEventListeners();

    // subscribes `form-element-options-updated` event
    this.eventListeners.push(
        this.appContainer.eventAggregator.subscribe('form-element-options-updated', (elementId) => {
            if (elementId === this.modelElementId) {
                this.destroyElement()
                    .then((response) => {
                        // TODO - TEMPORALLY HERE TO FORCE EXECUTION IN NEXT CLOCK TICK
                        setTimeout(() => {
                            this.createElement();
                        }, 0);
                    });
            }
        })
    );
}

Caso de um erro semelhante:

bluebird.min.js:31 Unhandled rejection (SystemJS) XHR error (404 Not Found) loading http://localhost:9000/jspm_packages/npm/bootstrap-duallistbox@3.0.6.js
Error: XHR error (404 Not Found) loading http://localhost:9000/jspm_packages/npm/bootstrap-duallistbox@3.0.6.js
Error loading http://localhost:9000/jspm_packages/npm/bootstrap-duallistbox@3.0.6.js as "bootstrap-duallistbox" from http://localhost:9000/dist/common/components/aurelia-form/components/form-duallistbox.js

Deve-se adicionar o ficheiro bootstrap-duallistbox@3.0.6.js na pasta jspm_packages/npm/ com o códido:

module.exports = require("npm:bootstrap-duallistbox@3.0.6/dist/jquery.bootstrap-duallistbox.js");