3

I've read millions of similar posts on this but I just can't get my head around it. So far I understand that I need to use Drupal.attachBehaviors, and I've tried so many different approaches that I've seen but nothing works.

Basically I have a jQuery plugin that is styling any select boxes on the site, which works great, apart from on my views exposed form with ajax enabled. The jQuery is literally as simple as $('select').styledSelect(); after including the plugin itself.

EDIT: this is almost there:

      Drupal.behaviors.styledSelect = {
        attach: function() {
          $("select").styledSelect();
        }
      };

But now the ajax call seems to be looping.

EDIT again:

Well it seems to be something to do with the actual plugin, as other Javascript seems to work fine. I'm so close! Here is the plugin:

jQuery.fn.styledSelect = function(options) {
var isFF2 = jQuery.browser.mozilla && jQuery.browser.version.indexOf('1.8.')==0;
var prefs = {
    coverClass : 'select-replace-cover',
    innerClass : 'select-replace',
    adjustPosition : { top:0, left:0 },
    selectOpacity : 0
    }
if (options) jQuery.extend(prefs,options);
return this.each( function() {
    if (isFF2) return false;
    var selElm = jQuery(this);
    selElm.wrap('<span><'+'/span>');
    selElm.after('<span><'+'/span>');
    var selReplace = selElm.next();
    var selCover = selElm.parent();
    selElm.css({
        'opacity':prefs.selectOpacity,
        'visibility':'visible',
        'position':'absolute',
        'top':0,
        'left':0,
        'display':'inline',
        'z-index':1
        });
    selCover.addClass(prefs.coverClass).css({
        'display':'inline-block',
        'position':'relative',
        'top':prefs.adjustPosition.top,
        'left':prefs.adjustPosition.left,
        'z-index':0,
        'vertical-align':'middle',
        'text-align':'left'
        });
    selReplace.addClass(prefs.innerClass).css({
        'display':'block',
        'white-space':'nowrap'
        });

    selElm.bind('change',function() {
        jQuery(this).next().text(this.options[this.selectedIndex].text);
        }).bind('resize',function() {
        jQuery(this).parent().width( jQuery(this).width()+'px' );
        });
    selElm.trigger('change').trigger('resize');
    });
}

EDIT again:

it was the trigger 'change' that was causing the problems - I've changed it to click, and it all seems good woohoo!

As ever, thanks for everyone's wonderful advice.

1

You'll need to wrap the JS in a Drupal behaviour, so that it is attached after the ajax refresh.

You should also ensure it only runs once

 Drupal.behaviors.styledSelect = {
   attach: function() {
     $('select').once('ss', function() {
       $(this).styledSelect();
     }
   }
 };

That way it won't get 'styled' on every ajax change.

1

I do not like to use drupal behaviors in this instance as it does fire multiple times. Another option is to simply wait for the ajax to complete like this:

$(document).ajaxComplete(function(){
  $("select").styledSelect();
});

Ideally you want to replace document with the element that is getting fired via ajax. But this works as well but will fire on any ajax on the page (or globally if its loaded on every page)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.