0

I have a plugin (https://github.com/olivM/jQuery-Selectbox) that populates a select drop down and styles the drop down.

Given the following methods I can not do a detach, attach of the element modification on the drop down via the even handler in my code.

I can only do this in the firebug inspector manually.

$('#elem').selectbox('detach');
$('#elem').selectbox('attach');

What do I need to do to detach then attach the selectbox to the html dropdown?

Method      Description
attach  .selectbox("attach")    Attach the select box to a jQuery selection. This will hide the element and create its custom replacement.
change  .selectbox("change")    Change selected attribute of the selectbox.
close   .selectbox("close")     Close opened selectbox.
detach  .selectbox("detach")    Remove the selectbox functionality completely. This will return the element back to its pre-init state.
disable .selectbox("disable")   Disable the selectbox.
enable  .selectbox("enable")    Enable the selectbox.
open    .selectbox("open")  Call up attached selectbox.
option  .selectbox("option", options)   Get or set any selectbox option. If no value is specified, will act as a getter.
Vahe
  • 1,699
  • 3
  • 25
  • 76
  • The original page of the plugin is not available so I fetched an archive - https://web.archive.org/web/20160323122843/http://www.bulgaria-web-developers.com/projects/javascript/selectbox/ – Vahe Sep 14 '16 at 18:18
  • Strangely, I needed to use a timeout to get my commands to work. I guess it is a synchronization issue. – Vahe Sep 14 '16 at 18:32

2 Answers2

0

My problem was not with the code not executing but with async nature of getting data.

Adding a timeout solved the issue.

  setTimeout(function(){
              $('#elem').selectbox("detach");
              $('#elem').selectbox("attach");
              }, 10);

HTML Script

 $(function () {
          $('#elem').selectbox("attach");
        });

Fetch Dropdown code - residing in angular controller

$http.get( 'some json resource').success(function(data){
            $scope.States = data;
             $scope.abbreviation = data[0].abbreviation;

            setTimeout(function(){ 
              $('#elem').val($scope.abbreviation);
              $('#elem').selectbox("detach");
              $('#elem').selectbox("attach");
            }, 10);

      });
Vahe
  • 1,699
  • 3
  • 25
  • 76
  • 1
    Why not have a callback for your dropdown population, and after the dropdown populates execute this? I think it's always better to stray away from timeouts where you can – Adjit Sep 14 '16 at 19:23
  • Thank you for your suggestion. In my case are you suggesting I modify the library to have a new callback? Is there an example you can provide if possible? – Vahe Sep 14 '16 at 19:26
  • I'm not really sure of your program structure, so it's hard to say - if you could provide some context and show where you are trying to execute `attach` and `detach` in your program that would be helpful – Adjit Sep 14 '16 at 19:31
  • I created a modification to my answer with more code. Please let me know if it helps. – Vahe Sep 14 '16 at 19:38
  • 1
    Ahh, ok! So I suggest instead of using the `$.get()` wrapper you should just use `$.ajax()` and then you have your `success` function as well as a `complete` function which should take care of the issue. Have a look here - http://stackoverflow.com/a/23283596/1887101 – Adjit Sep 14 '16 at 19:47
  • Ok, this helps, and thank you very much for the resource! – Vahe Sep 14 '16 at 19:48
0

A more recent modification of the library that I added subsequently resolved the issue.

In this._defaults I added 3 lines (onBind, onInit, onDetach)

function Selectbox() {
        this._state = [];
        this._defaults = { // Global defaults for all the select box instances
            classHolder: "sbHolder",
            classHolderDisabled: "sbHolderDisabled",
            classSelector: "sbSelector",
            classOptions: "sbOptions",
            classGroup: "sbGroup",
            classSub: "sbSub",
            classDisabled: "sbDisabled",
            classToggleOpen: "sbToggleOpen",
            classToggle: "sbToggle",
            classFocus: "sbFocus",
            speed: 200,
            effect: "slide", // "slide" or "fade"
            onChange: null, //Define a callback function when the selectbox is changed
            onOpen: null, //Define a callback function when the selectbox is open
            onClose: null, //Define a callback function when the selectbox is closed

            onBind: null,
            onInit: null,
            onDetach: null
        };
}

Added lines in +

+      self._initSelectBox(target);
       sbSelector.appendTo(sbHolder);
       sbOptions.appendTo(sbHolder);
       sbHolder.insertAfter($target);

       $("html").on('mousedown', function(e){
                e.stopPropagation();
                $("select").selectbox('close');
       });
       $([".", inst.settings.classHolder, ", ,", inst.settings.classSelector].join("")).mousedown(function(e){
                e.stopPropagation;
       });
+      self._bindSelectbox(target);

Within _detachSelectbox added the following

var onDetach = this._get(inst, 'onDetach');
if (onDetach != null)
{
     onDetach.apply({inst.input ? inst.input[0]: null), [inst]);
}

Right above

$("#sbHolder_" + inst.uid).remove();
$.data(target, PROP_NAME, null);
$(target).show();

Then I Added the Init and Bind Methods

 _initSelectbox: funciton (target){
    var onInit, inst = this._getInst(target);
    if (inst) {
       onInit = this._get(inst, 'onInit');
       if (onInit != null)
       {
         onInit.apply({inst.input ? inst.input[0]: null), [inst]);
       }
    }
 }
  _bindSelectbox: funciton (target){
    var onBind, inst = this._getInst(target);
    if (inst) {
       onBind = this._get(inst, 'onBind');
       if (onBind != null)
       {
         onBind.apply({inst.input ? inst.input[0]: null), [inst]);
       }
    }
 }

Invoking Code (AngularJS)

function bindDrodown(selector)
{
    angular.forEach($(".selector").function(elem){
       //set span value to selected value of dropdown
       id = $(elem).attr("id");
       itemid = $("#"+id).data("itemid");
       setDrowDownValue(elem);
       setSpanValue(itemid);
    });

   $(selector).selectbox({
       onInit: function (inst){
       },
       onBind: function (inst){
       },
       onChange: function (id, inst){
           //change code here     
       },
       onDetach: function(inst){
       }
   });
}
Vahe
  • 1,699
  • 3
  • 25
  • 76