AppSuite:BackboneMiniViews

Revision as of 06:00, 24 September 2014 by Christoph.kopp (talk | contribs) (Playground)
Backbone mini views:

Abstract

Mini views are small backbone views which helps you to create single form elements like input fields, checkbox and so on. They should be used to build form pages in a DRY way. To use the mini-views simply require io.ox/backbone/mini-views in your view pane.


Benefits of using mini-views

  • automatic cleanup (model & events) if the form element is removed from the DOM
  • the wiring between form element and model data is handled for each mini-view via attribute name or id of the element
  • DRY

Abstract view

The abstract view is used to manage the dispose feature for all mini-views.

Common mini-views

All mini-views provides functions for handling the common interactions between model data and form element like initial setup, update and rendering. To provide some basic a11y the tabindex is set by default to 1 and can be changed via this.options.tabindex to every needed value.

List of form-elements included

InputView

<input type="text">
new InputView({ name: [attribute], model: [model] }).render().$el

PasswordView

<input type="password">
new PasswordView({ name: [attribute], model: [model] }).render().$el

If no password value is provided via model the field value is changed to „'********“. This especially is needed since already provided passwords are not delivered via the api request. The attributes „autocomplete" and „autocorrect“ are set to „off“ by default.

TextView

<textarea>
new TextView({ name: [attribute], rows: '4', model: [model] }).render().$el

Use this.rows to set the row attribute of the area to the needed value.

CheckboxView

<input type="checkbox">
new CheckboxView({ name: [attribute], model: [model] }).render().$el

RadioView

<input type="radio">
new RadioView({ list: [radioOptions], name: [attribute], model: [model] }).render().$el

Use this.options.list to set the list of available options and labels.

var radioOptions = [
    { label: gt('first label'), value: 'firstValue' },
    { label: gt('second label'), value: 'secondValue'},
    { label: gt('third label'), value: 'thirdValue'}
 ];

SelectView

<select>
new SelectView({ list: [selectOptions], name: [attribute], model: [model] }).render().$el

Use this.options.list to set the list of available options and labels.

ErrorView

<div class="inline-error" aria-live="assertive"></div>
var defer = $.Deferred();
new mini.ErrorView().render(defer).$el;
// when form rendering has been completed
defer.resolve();

DateView

Day, month and year will each be represented by a single <select> item.

new DateView({ name: [attribute], model: [model] }).render().$el

Dropdown

The Dropdown mini view provides an easy solution to create a drop down. Multiple settings and / or links may be provided to the user in a single drop-down view. To use the dropdown mini view simply require io.ox/backbone/mini-views/dropdown in your view pane.

Use this.option to fill the drop down with a single selectable option.
arguments: [attribute], [value], [text used for labeling]

Use this.link to provide a simple link with a callback.
arguments: [value for attribute "data-name"], [text for link], [callback]

Use this.header to build logical groups in the drop down while setting headers between the options.
arguments: [text for header]

Use this.divider to provide a visual devider between groups.

var dropdown = new Dropdown({ model: model, label: gt('Dropdown'), tagName: 'li' })
    .header(gt('Options'))
    .option('options', 'firstOption', gt('first option'))
    .option('options', 'secondOption', gt('second option'))
    .divider()
    .header(gt('Choices'))
    .option(‚'choice', 'firstChoice', gt('first choice'))
    .option('choice', 'secondChoice', gt('second choice'))
    .divider()
    .link('link', gt('link'), function () { console.log('clicked'); }
);

dropdown.render().$el;

Playground

Simply copy/paste the code beneath in to your browser console while being logged in. This creates an playground for the mentioned mini views.

require(['io.ox/backbone/mini-views', 'io.ox/backbone/mini-views/dropdown'], function(mini, Dropdown) {
    
    $('<style type="text/css"> .playground .error label, .playground .error input, .playground .error .inline-error { color: #B94A48; border-color: #B94A48; } </style>').appendTo($('head'));

    var container = $('<div class="playground">').css({
        'padding': '45px 10px 10px 10px',
        'width': '600px',
        'height': '300px',
        'border': '1px solid #000',
        'position': 'absolute',
        'bottom': '0',
        'right': '0',
        'z-index': '11',
        'background-color': '#fff',
        'overflow-x': 'hidden',
        'overflow-y': 'auto'
    }).on('dispose', function () { model = null });

    var button = $('<button type="button" class="btn btn-default btn-primary">')
        .text('remove playground').css({
            'position': 'absolute',
            'top': '4px',
            'right': '8px',
            'margin': '3px'
    }).on('click', function () {
        container.remove();
        if (model === null) {
            console.log('Playground has been successfully removed');
        }
    });

    var model = new Backbone.Model({
        'text': 'text',
        'radio': '1',
        'password': 'password',
        'textarea': 'textarea',
        'checkbox': true,
        'select': '1',
        'date': 1411023212550,
        'dropdownOptions': 'firstOption',
        'dropdownChoice': 'firstChoice'
    }).on('change', function () {
        console.log(model.attributes);
    });

    var options = [
        { label: '1', value: '1' },
        { label: '2', value: '2'},
        { label: '3', value: '3'}
    ];

    var dropdown = new Dropdown({ model: model, label: 'Dropdown', tagName: 'li' })
        .header('Options')
        .option('dropdownOptions', 'firstOption', 'first option')
        .option('dropdownOptions', 'secondOption', 'second option')
        .divider()
        .header('Choices')
        .option('dropdownChoice', 'firstChoice', 'first choice')
        .option('dropdownChoice', 'secondChoice', 'second choice')
        .divider()
        .link('link', 'link', function () { console.log('clicked'); }
    );

    window.model = model;

    container.append(
        button,
        $('<fieldset>').append(
            dropdown.render().$el,
            $('<div class="row">').append(
                $('<label for="text"class="control-label col-sm-4">').text('Text'),
                $('<div class="col-sm-8">').append(
                    new mini.InputView({ id: 'text', model: model }).render().$el,
                    new mini.ErrorView({ id: 'text', model: model }).render().$el
                )
            ),
            $('<div class="row">').append(
                $('<label class="control-label col-sm-4">').text('Radio'),
                $('<div class="col-sm-8">').append(
                    new mini.RadioView({
                        list: options,
                        id: 'radio',
                        model: model
                    }).render().$el,
                    new mini.ErrorView({ id: 'radio', model: model }).render().$el
                )
           ),
           $('<div class="row">').append(
               $('<label for="password" class="control-label col-sm-4">').text('Password'),
               $('<div class="col-sm-8">').append(
                   new mini.PasswordView({ id: 'password', model: model }).render().$el,
                   new mini.ErrorView({ id: 'password', model: model }).render().$el
               )
           ),
           $('<div class="row">').append(
               $('<label for="textarea" class="control-label col-sm-4">').text('Textarea'),
               $('<div class="col-sm-8">').append(
                   new mini.TextView({ id: 'textarea', rows: '4', model: model }).render().$el,
                   new mini.ErrorView({ id: 'textarea', model: model }).render().$el
               )
           ),
           $('<div class="row">').append(
               $('<div class="col-sm-8 col-sm-offset-4">').append(
                   $('<label class="checkbox">').text('Checkbox').prepend(
                       new mini.CheckboxView({ id: 'checkbox', model: model })
                       .render().$el,
                       new mini.ErrorView({ id: 'checkbox', model: model }).render().$el
                   )
               )
           ),
           $('<div class="row">').append(
               $('<label for="select" class="control-label col-sm-4">').text('Select'),
               $('<div class="col-sm-8">').append(
                   new mini.SelectView({
                       list: options,
                       id: 'select',
                       model: model
                   }).render().$el,
                   new mini.ErrorView({ id: 'select', model: model }).render().$el
               )
           ),
           $('<div class="row">').append(
               $('<label for="date" class="control-label col-sm-4">').text('Date'),
               $('<div class="col-sm-8">').append(
                   new mini.DateView({ id: 'date', model: model }).render().$el,
                   new mini.ErrorView({ id: 'date', model: model }).render().$el
               )
           )
        )
    );

    $('body').append(container);

});
// to modify values via console
window.model.set([attribute], [new value]);

// to trigger an validation fault
window.model.trigger('invalid:' + [attribute], [Error Message]); 

// to remove an validation fault
window.model.trigger('valid:' + [attribute]);