function() {

  this.requiresPagination = this.config.pagination && this.config.pagination > 0;

  // Set width
  if (isset(this.config, "width")) {
    if (util.isInt(this.config.width)) {
      this.width = this.config.width + "px";
    } else {
      if (this.config.width === "auto") {
        this.width = "100%";
      } else if (util.includes(this.config.width, "%")) {
        this.width = this.config.width;
      }
    }
  }

  this.container = util.createElement("div", {
    class: "selectr-container"
  });

  // Custom className
  if (this.config.customClass) {
    util.addClass(this.container, this.config.customClass);
  }

  // Mobile device
  if (this.mobileDevice) {
    util.addClass(this.container, "selectr-mobile");
  } else {
    util.addClass(this.container, "selectr-desktop");
  }

  // Hide the HTMLSelectElement and prevent focus
  this.el.tabIndex = -1;

  // Native dropdown
  if (this.config.nativeDropdown || this.mobileDevice) {
    util.addClass(this.el, "selectr-visible");
  } else {
    util.addClass(this.el, "selectr-hidden");
  }

  this.selected = util.createElement("div", {
    class: "selectr-selected",
    disabled: this.disabled,
    tabIndex: 1, // enable tabIndex (#9)
    "aria-expanded": false
  });

  this.label = util.createElement(this.el.multiple ? "ul" : "span", {
    class: "selectr-label"
  });

  var dropdown = util.createElement("div", {
    class: "selectr-options-container"
  });

  this.tree = util.createElement("ul", {
    class: "selectr-options",
    role: "tree",
    "aria-hidden": true,
    "aria-expanded": false
  });

  this.notice = util.createElement("div", {
    class: "selectr-notice"
  });

  this.el.setAttribute("aria-hidden", true);

  if (this.disabled) {
    this.el.disabled = true;
  }

  if (this.el.multiple) {
    util.addClass(this.label, "selectr-tags");
    util.addClass(this.container, "multiple");

    // Collection of tags
    this.tags = [];

    // Collection of selected values
    this.selectedValues = this.getSelectedProperties('value');

    // Collection of selected indexes
    this.selectedIndexes = this.getSelectedProperties('idx');
  }

  this.selected.appendChild(this.label);

  if (this.config.clearable) {
    this.selectClear = util.createElement("button", {
      class: "selectr-clear",
      type: "button"
    });

    this.container.appendChild(this.selectClear);

    util.addClass(this.container, "clearable");
  }

  if (this.config.taggable) {
    var li = util.createElement('li', {
      class: 'input-tag'
    });
    this.input = util.createElement("input", {
      class: "selectr-tag-input",
      placeholder: this.config.tagPlaceholder,
      tagIndex: 0,
      autocomplete: "off",
      autocorrect: "off",
      autocapitalize: "off",
      spellcheck: "false",
      role: "textbox",
      type: "search"
    });

    li.appendChild(this.input);
    this.label.appendChild(li);
    util.addClass(this.container, "taggable");

    this.tagSeperators = [","];
    if (this.config.tagSeperators) {
      this.tagSeperators = this.tagSeperators.concat(this.config.tagSeperators);
    }
  }

  if (this.config.searchable) {
    this.input = util.createElement("input", {
      class: "selectr-input",
      tagIndex: -1,
      autocomplete: "off",
      autocorrect: "off",
      autocapitalize: "off",
      spellcheck: "false",
      role: "textbox",
      type: "search"
    });
    this.inputClear = util.createElement("button", {
      class: "selectr-input-clear",
      type: "button"
    });
    this.inputContainer = util.createElement("div", {
      class: "selectr-input-container"
    });

    this.inputContainer.appendChild(this.input);
    this.inputContainer.appendChild(this.inputClear);
    dropdown.appendChild(this.inputContainer);
  }

  dropdown.appendChild(this.notice);
  dropdown.appendChild(this.tree);

  // List of items for the dropdown
  this.items = [];

  // Establish options
  this.options = [];

  // Check for options in the element
  if (this.el.options.length) {
    this.options = [].slice.call(this.el.options);
  }

  // Element may have optgroups so
  // iterate element.children instead of element.options
  var group = false,
      j = 0;
  if (this.el.children.length) {
    util.each(this.el.children, function(i, element) {
      if (element.nodeName === "OPTGROUP") {

        group = util.createElement("ul", {
          class: "selectr-optgroup",
          role: "group",
          html: "<li class='selectr-optgroup--label'>" + element.label + "</li>"
        });

        util.each(element.children, function(x, el) {
          el.idx = j;
          group.appendChild(createItem.call(this, el, group));
          j++;
        }, this);
      } else {
        element.idx = j;
        createItem.call(this, element);
        j++;
      }
    }, this);
  }

  // Options defined by the data option
  if (this.config.data && Array.isArray(this.config.data)) {
    this.data = [];
    var optgroup = false,
        option;

    group = false;
    j = 0;

    util.each(this.config.data, function(i, opt) {
      // Check for group options
      if (isset(opt, "children")) {
        optgroup = util.createElement("optgroup", {
          label: opt.text
        });

        group = util.createElement("ul", {
          class: "selectr-optgroup",
          role: "group",
          html: "<li class='selectr-optgroup--label'>" + opt.text + "</li>"
        });

        util.each(opt.children, function(x, data) {
          option = new Option(data.text, data.value, false, data.hasOwnProperty("selected") && data.selected === true);

          option.disabled = isset(data, "disabled");

          this.options.push(option);

          optgroup.appendChild(option);

          option.idx = j;

          group.appendChild(createItem.call(this, option, data));

          this.data[j] = data;

          j++;
        }, this);
      } else {
        option = new Option(opt.text, opt.value, false, opt.hasOwnProperty("selected") && opt.selected === true);

        option.disabled = isset(opt, "disabled");

        this.options.push(option);

        option.idx = j;

        createItem.call(this, option, opt);

        this.data[j] = opt;

        j++;
      }
    }, this);
  }

  this.setSelected(true);

  var first;
  this.navIndex = 0;
  for (var i = 0; i < this.items.length; i++) {
    first = this.items[i];

    if (!util.hasClass(first, "disabled")) {

      util.addClass(first, "active");
      this.navIndex = i;
      break;
    }
  }

  // Check for pagination / infinite scroll
  if (this.requiresPagination) {
    this.pageIndex = 1;

    // Create the pages
    this.paginate();
  }

  this.container.appendChild(this.selected);
  this.container.appendChild(dropdown);

  this.placeEl = util.createElement("div", {
    class: "selectr-placeholder"
  });

  // Set the placeholder
  this.setPlaceholder();

  this.selected.appendChild(this.placeEl);

  // Disable if required
  if (this.disabled) {
    this.disable();
  }

  this.el.parentNode.insertBefore(this.container, this.el);
  this.container.appendChild(this.el);
}
function() {

  this.requiresPagination = this.config.pagination && this.config.pagination > 0;

  
  if (isset(this.config, "width")) {
    if (util.isInt(this.config.width)) {
      this.width = this.config.width + "px";
    } else {
      if (this.config.width === "auto") {
        this.width = "100%";
      } else if (util.includes(this.config.width, "%")) {
        this.width = this.config.width;
      }
    }
  }

  this.container = util.createElement("div", {
    class: "selectr-container"
  });

  
  if (this.config.customClass) {
    util.addClass(this.container, this.config.customClass);
  }

  
  if (this.mobileDevice) {
    util.addClass(this.container, "selectr-mobile");
  } else {
    util.addClass(this.container, "selectr-desktop");
  }

  
  this.el.tabIndex = -1;

  
  if (this.config.nativeDropdown || this.mobileDevice) {
    util.addClass(this.el, "selectr-visible");
  } else {
    util.addClass(this.el, "selectr-hidden");
  }

  this.selected = util.createElement("div", {
    class: "selectr-selected",
    disabled: this.disabled,
    tabIndex: 1, 
    "aria-expanded": false
  });

  this.label = util.createElement(this.el.multiple ? "ul" : "span", {
    class: "selectr-label"
  });

  var dropdown = util.createElement("div", {
    class: "selectr-options-container"
  });

  this.tree = util.createElement("ul", {
    class: "selectr-options",
    role: "tree",
    "aria-hidden": true,
    "aria-expanded": false
  });

  this.notice = util.createElement("div", {
    class: "selectr-notice"
  });

  this.el.setAttribute("aria-hidden", true);

  if (this.disabled) {
    this.el.disabled = true;
  }

  if (this.el.multiple) {
    util.addClass(this.label, "selectr-tags");
    util.addClass(this.container, "multiple");

    
    this.tags = [];

    
    this.selectedValues = this.getSelectedProperties('value');

    
    this.selectedIndexes = this.getSelectedProperties('idx');
  }

  this.selected.appendChild(this.label);

  if (this.config.clearable) {
    this.selectClear = util.createElement("button", {
      class: "selectr-clear",
      type: "button"
    });

    this.container.appendChild(this.selectClear);

    util.addClass(this.container, "clearable");
  }

  if (this.config.taggable) {
    var li = util.createElement('li', {
      class: 'input-tag'
    });
    this.input = util.createElement("input", {
      class: "selectr-tag-input",
      placeholder: this.config.tagPlaceholder,
      tagIndex: 0,
      autocomplete: "off",
      autocorrect: "off",
      autocapitalize: "off",
      spellcheck: "false",
      role: "textbox",
      type: "search"
    });

    li.appendChild(this.input);
    this.label.appendChild(li);
    util.addClass(this.container, "taggable");

    this.tagSeperators = [","];
    if (this.config.tagSeperators) {
      this.tagSeperators = this.tagSeperators.concat(this.config.tagSeperators);
    }
  }

  if (this.config.searchable) {
    this.input = util.createElement("input", {
      class: "selectr-input",
      tagIndex: -1,
      autocomplete: "off",
      autocorrect: "off",
      autocapitalize: "off",
      spellcheck: "false",
      role: "textbox",
      type: "search"
    });
    this.inputClear = util.createElement("button", {
      class: "selectr-input-clear",
      type: "button"
    });
    this.inputContainer = util.createElement("div", {
      class: "selectr-input-container"
    });

    this.inputContainer.appendChild(this.input);
    this.inputContainer.appendChild(this.inputClear);
    dropdown.appendChild(this.inputContainer);
  }

  dropdown.appendChild(this.notice);
  dropdown.appendChild(this.tree);

  
  this.items = [];

  
  this.options = [];

  
  if (this.el.options.length) {
    this.options = [].slice.call(this.el.options);
  }

  
  
  var group = false,
      j = 0;
  if (this.el.children.length) {
    util.each(this.el.children, function(i, element) {
      if (element.nodeName === "OPTGROUP") {

        group = util.createElement("ul", {
          class: "selectr-optgroup",
          role: "group",
          html: "<li class='selectr-optgroup--label'>" + element.label + "</li>"
        });

        util.each(element.children, function(x, el) {
          el.idx = j;
          group.appendChild(createItem.call(this, el, group));
          j++;
        }, this);
      } else {
        element.idx = j;
        createItem.call(this, element);
        j++;
      }
    }, this);
  }

  
  if (this.config.data && Array.isArray(this.config.data)) {
    this.data = [];
    var optgroup = false,
        option;

    group = false;
    j = 0;

    util.each(this.config.data, function(i, opt) {
      
      if (isset(opt, "children")) {
        optgroup = util.createElement("optgroup", {
          label: opt.text
        });

        group = util.createElement("ul", {
          class: "selectr-optgroup",
          role: "group",
          html: "<li class='selectr-optgroup--label'>" + opt.text + "</li>"
        });

        util.each(opt.children, function(x, data) {
          option = new Option(data.text, data.value, false, data.hasOwnProperty("selected") && data.selected === true);

          option.disabled = isset(data, "disabled");

          this.options.push(option);

          optgroup.appendChild(option);

          option.idx = j;

          group.appendChild(createItem.call(this, option, data));

          this.data[j] = data;

          j++;
        }, this);
      } else {
        option = new Option(opt.text, opt.value, false, opt.hasOwnProperty("selected") && opt.selected === true);

        option.disabled = isset(opt, "disabled");

        this.options.push(option);

        option.idx = j;

        createItem.call(this, option, opt);

        this.data[j] = opt;

        j++;
      }
    }, this);
  }

  this.setSelected(true);

  var first;
  this.navIndex = 0;
  for (var i = 0; i < this.items.length; i++) {
    first = this.items[i];

    if (!util.hasClass(first, "disabled")) {

      util.addClass(first, "active");
      this.navIndex = i;
      break;
    }
  }

  
  if (this.requiresPagination) {
    this.pageIndex = 1;

    
    this.paginate();
  }

  this.container.appendChild(this.selected);
  this.container.appendChild(dropdown);

  this.placeEl = util.createElement("div", {
    class: "selectr-placeholder"
  });

  
  this.setPlaceholder();

  this.selected.appendChild(this.placeEl);

  
  if (this.disabled) {
    this.disable();
  }

  this.el.parentNode.insertBefore(this.container, this.el);
  this.container.appendChild(this.el);
}
function ( ) { this . requiresPagination = this . config . pagination && this . config . pagination > 0 ; // Set width if ( isset ( this . config , "width" ) ) { if ( util . isInt ( this . config . width ) ) { this . width = this . config . width + "px" ; } else { if ( this . config . width === "auto" ) { this . width = "100%" ; } else if ( util . includes ( this . config . width , "%" ) ) { this . width = this . config . width ; } } } this . container = util . createElement ( "div" , { class : "selectr-container" } ) ; // Custom className if ( this . config . customClass ) { util . addClass ( this . container , this . config . customClass ) ; } // Mobile device if ( this . mobileDevice ) { util . addClass ( this . container , "selectr-mobile" ) ; } else { util . addClass ( this . container , "selectr-desktop" ) ; } // Hide the HTMLSelectElement and prevent focus this . el . tabIndex = - 1 ; // Native dropdown if ( this . config . nativeDropdown || this . mobileDevice ) { util . addClass ( this . el , "selectr-visible" ) ; } else { util . addClass ( this . el , "selectr-hidden" ) ; } this . selected = util . createElement ( "div" , { class : "selectr-selected" , disabled : this . disabled , tabIndex : 1 , // enable tabIndex (#9) "aria-expanded" : false } ) ; this . label = util . createElement ( this . el . multiple ? "ul" : "span" , { class : "selectr-label" } ) ; var dropdown = util . createElement ( "div" , { class : "selectr-options-container" } ) ; this . tree = util . createElement ( "ul" , { class : "selectr-options" , role : "tree" , "aria-hidden" : true , "aria-expanded" : false } ) ; this . notice = util . createElement ( "div" , { class : "selectr-notice" } ) ; this . el . setAttribute ( "aria-hidden" , true ) ; if ( this . disabled ) { this . el . disabled = true ; } if ( this . el . multiple ) { util . addClass ( this . label , "selectr-tags" ) ; util . addClass ( this . container , "multiple" ) ; // Collection of tags this . tags = [ ] ; // Collection of selected values this . selectedValues = this . getSelectedProperties ( 'value' ) ; // Collection of selected indexes this . selectedIndexes = this . getSelectedProperties ( 'idx' ) ; } this . selected . appendChild ( this . label ) ; if ( this . config . clearable ) { this . selectClear = util . createElement ( "button" , { class : "selectr-clear" , type : "button" } ) ; this . container . appendChild ( this . selectClear ) ; util . addClass ( this . container , "clearable" ) ; } if ( this . config . taggable ) { var li = util . createElement ( 'li' , { class : 'input-tag' } ) ; this . input = util . createElement ( "input" , { class : "selectr-tag-input" , placeholder : this . config . tagPlaceholder , tagIndex : 0 , autocomplete : "off" , autocorrect : "off" , autocapitalize : "off" , spellcheck : "false" , role : "textbox" , type : "search" } ) ; li . appendChild ( this . input ) ; this . label . appendChild ( li ) ; util . addClass ( this . container , "taggable" ) ; this . tagSeperators = [ "," ] ; if ( this . config . tagSeperators ) { this . tagSeperators = this . tagSeperators . concat ( this . config . tagSeperators ) ; } } if ( this . config . searchable ) { this . input = util . createElement ( "input" , { class : "selectr-input" , tagIndex : - 1 , autocomplete : "off" , autocorrect : "off" , autocapitalize : "off" , spellcheck : "false" , role : "textbox" , type : "search" } ) ; this . inputClear = util . createElement ( "button" , { class : "selectr-input-clear" , type : "button" } ) ; this . inputContainer = util . createElement ( "div" , { class : "selectr-input-container" } ) ; this . inputContainer . appendChild ( this . input ) ; this . inputContainer . appendChild ( this . inputClear ) ; dropdown . appendChild ( this . inputContainer ) ; } dropdown . appendChild ( this . notice ) ; dropdown . appendChild ( this . tree ) ; // List of items for the dropdown this . items = [ ] ; // Establish options this . options = [ ] ; // Check for options in the element if ( this . el . options . length ) { this . options = [ ] . slice . call ( this . el . options ) ; } // Element may have optgroups so // iterate element.children instead of element.options var group = false , j = 0 ; if ( this . el . children . length ) { util . each ( this . el . children , function ( i , element ) { if ( element . nodeName === "OPTGROUP" ) { group = util . createElement ( "ul" , { class : "selectr-optgroup" , role : "group" , html : "<li class='selectr-optgroup--label'>" + element . label + "</li>" } ) ; util . each ( element . children , function ( x , el ) { el . idx = j ; group . appendChild ( createItem . call ( this , el , group ) ) ; j ++ ; } , this ) ; } else { element . idx = j ; createItem . call ( this , element ) ; j ++ ; } } , this ) ; } // Options defined by the data option if ( this . config . data && Array . isArray ( this . config . data ) ) { this . data = [ ] ; var optgroup = false , option ; group = false ; j = 0 ; util . each ( this . config . data , function ( i , opt ) { // Check for group options if ( isset ( opt , "children" ) ) { optgroup = util . createElement ( "optgroup" , { label : opt . text } ) ; group = util . createElement ( "ul" , { class : "selectr-optgroup" , role : "group" , html : "<li class='selectr-optgroup--label'>" + opt . text + "</li>" } ) ; util . each ( opt . children , function ( x , data ) { option = new Option ( data . text , data . value , false , data . hasOwnProperty ( "selected" ) && data . selected === true ) ; option . disabled = isset ( data , "disabled" ) ; this . options . push ( option ) ; optgroup . appendChild ( option ) ; option . idx = j ; group . appendChild ( createItem . call ( this , option , data ) ) ; this . data [ j ] = data ; j ++ ; } , this ) ; } else { option = new Option ( opt . text , opt . value , false , opt . hasOwnProperty ( "selected" ) && opt . selected === true ) ; option . disabled = isset ( opt , "disabled" ) ; this . options . push ( option ) ; option . idx = j ; createItem . call ( this , option , opt ) ; this . data [ j ] = opt ; j ++ ; } } , this ) ; } this . setSelected ( true ) ; var first ; this . navIndex = 0 ; for ( var i = 0 ; i < this . items . length ; i ++ ) { first = this . items [ i ] ; if ( ! util . hasClass ( first , "disabled" ) ) { util . addClass ( first , "active" ) ; this . navIndex = i ; break ; } } // Check for pagination / infinite scroll if ( this . requiresPagination ) { this . pageIndex = 1 ; // Create the pages this . paginate ( ) ; } this . container . appendChild ( this . selected ) ; this . container . appendChild ( dropdown ) ; this . placeEl = util . createElement ( "div" , { class : "selectr-placeholder" } ) ; // Set the placeholder this . setPlaceholder ( ) ; this . selected . appendChild ( this . placeEl ) ; // Disable if required if ( this . disabled ) { this . disable ( ) ; } this . el . parentNode . insertBefore ( this . container , this . el ) ; this . container . appendChild ( this . el ) ; }
Build the container
@return {Void}
Build the container