option-selector.js - Ubuntu HTML5 API

# Ubuntu HTML5 API: option-selector.js

API Docs for: HTML-14.04-dev~bzr202

#### option-selector.js

    /*
     * Copyright (C) 2013 Adnane Belmadiaf <daker@ubuntu.com>
     * License granted by Canonical Limited
     *
     * This file is part of ubuntu-html5-ui-toolkit.
     *
     * This package is free software; you can redistribute it and/or modify
     * it under the terms of the GNU Lesser General Public License as
     * published by the Free Software Foundation; either version 3 of the
     * License, or
     * (at your option) any later version.

     * This package is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.

     * You should have received a copy of the GNU Lesser General Public
     * License along with this program. If not, see
     * <http://www.gnu.org/licenses/>
     */

    /**
     * OptionSelector is a component displaying either a single selected value or expanded multiple choice with an optional image and subtext when not expanded, when expanding it opens a
        listing of all the possible values for selection with an additional option of always being expanded. If multiple choice is selected the list is expanded automatically.

     * @class OptionSelector
     * @constructor
     * @namespace UbuntuUI
     * @example
          <section data-role="option-selector" id="OptionSelectorID">
            <ul>
              <li data-value="0">
                <p>Label 1</p>
              </li>
              <li data-value="1">
                <p>Label 2</p>
              </li>
              <li data-value="3">
                <p>Label 3</p>
              </li>
            </ul>
          </section>

          JavaScript access:

          Expanded:
            UI.optionselector("OptionSelectorID", true);
          Expanded and multi selection:
            UI.optionselector("OptionSelectorID", true, true);
          Multi selection:
            UI.optionselector("OptionSelectorID", false, true);
    */
    var OptionSelector = (function () {

        var  __values = "";

        function OptionSelector (id, expanded, multiSelection) {
            this.currentIndex = 0;
            this.currentlyExpanded = false;
            this.expanded = typeof expanded !== 'undefined' ? expanded : false;
            this.multiSelection = typeof multiSelection !== 'undefined' ? multiSelection : false;

            if (this.multiSelection)
                this.expanded = true;

            this.optionselector = document.getElementById(id);

            if (this.optionselector == null) {
                console.error('The OptionSelector with the ID #' + this.id + ' doesn\'t exist');
                return;
            }

            this.optionselector_ul = this.optionselector.querySelectorAll('ul')[0];
            if (this.optionselector_ul == null)
                return;

            if (this.optionselector_ul.length == 0)
                return;

            this.optionselector_ul_li = this.optionselector.querySelectorAll('li');
            if (this.optionselector_ul == null)
                return;
            if (this.optionselector_ul_li.length == 0)
                return;

            [].forEach.call(this.optionselector_ul_li, function (elm) {
                elm.addEventListener('click', this.__onClicked.bind(this, elm), false);
            }.bind(this));

            if (this.expanded) {
                this.__open();
                this.optionselector_ul_li[0].classList.add('active');
            }
            else {
                if (this.currentlyExpanded) {
                    this.__open();
                    this.optionselector_ul_li[0].classList.add('active');
                } else {
                    this.__close(this.currentIndex);
                    this.optionselector_ul_li[0].classList.add('closed');
                }
            }
        }

        OptionSelector.prototype = {

            /**
             * @private
             */
            __onClicked: function (elm, e) {
                __values = "";
                this.currentIndex = 0;

                if (this.expanded) {
                    if (!this.multiSelection) {
                        [].forEach.call(this.optionselector_ul_li, function (elm) {
                            elm.classList.remove('active');
                        });
                        elm.classList.toggle('active');
                    }
                    else {
                        elm.classList.toggle('active');
                    }
                }
                else {

                    for(i = 0, max = this.optionselector_ul_li.length; i < max; i++) {
                        if (this.optionselector_ul_li[i]==elm) break;
                        this.currentIndex++;
                    }

                    if (this.currentlyExpanded) {
                        this.__close(this.currentIndex);
                        elm.classList.add('active');
                        elm.classList.add('closed');
                        elm.style.borderTop = '0';
                    }
                    else {
                        elm.classList.add('active');
                        elm.classList.remove('closed');
                        this.__open();
                        elm.style.borderTop = '1px solid #C7C7C7';
                    }
                }

                k = 0;
                for (i = 0, max = this.optionselector_ul_li.length; i < max; i++) {
                    var li = this.optionselector_ul_li[i];
                    if ((li.className).indexOf('active') > -1) {
                        if (k === 0) {
                            __values = li.getAttribute("data-value");
                        } else {
                            __values = __values + ", " + li.getAttribute("data-value");
                        }
                        k++;
                    }
                }

                if (!this.currentlyExpanded && !this.expanded) {
                    this.__ClickEvent(elm);
                }
                else {
                    if (this.expanded) {
                        this.__ClickEvent(elm);
                    }
                }

                e.preventDefault();
            },

            /**
             * @private
             */
            __ClickEvent: function (elm) {
                elm._evt = document.createEvent('Event');
                elm._evt.initEvent('onclicked', true, true);
                elm._evt.values = __values;
                elm.dispatchEvent(elm._evt);
            },

            /**
             * @private
             */
            __open: function () {
                this.optionselector_ul.style['-webkit-transition-duration'] = '.4s';
                this.optionselector_ul.style.webkitTransform = 'translate3d(0, 0rem,0)';
                this.optionselector.style.height = 3.07*this.optionselector_ul_li.length + 'rem';
                this.currentlyExpanded = true;
            },

            /**
             * @private
             */
            __close: function (currentIndex) {
                this.optionselector_ul.style['-webkit-transition-duration'] = '.4s';
                this.optionselector_ul.style.webkitTransform = 'translate3d(0,' + -3*currentIndex + 'rem,0)';
                this.optionselector.style.height = '3rem';
                [].forEach.call(this.optionselector_ul_li, function (elm) {
                    elm.classList.remove('active');
                });
                this.currentlyExpanded = false;
            },

            onClicked : function(callback){
                this.optionselector_ul.addEventListener("onclicked", callback);
            }
        };
        return OptionSelector;
    })();