select2 with qTip2 on focus, addClass at runtime

236 views
Skip to first unread message

Ken Hadden

unread,
Dec 27, 2016, 2:51:45 PM12/27/16
to select2

Hi, I have two issues I'm trying to solve with select2. 
1. Add a css class at run-time. This is for form validation. For instance if the user clears a required (select2) field. In that case I need to add an class that adds a border and makes the entire background yellowish. Then after the user selects a value, the class should be removed. That works on normal inputs but it's not so good on the select2.
2. I also need to add a qTip2 to the select2. In the validation case, the qTip2 shows the validation message. And, this is what is the issue is: I need the qTip2 to show on focus. Not mouse over.

I've tried a few things and I'm not making much progress. 

Fiddle showing the 2 issues:

When this fiddle loads, the normal text box is focused. Tab from the text box into the select2 field. That should show the qTip. Then tab from the select2 field into the second text box. There you can see that qTip2 is working on focus. 

How can I fix these?

Ken Hadden

unread,
Dec 28, 2016, 3:28:47 AM12/28/16
to select2
In case any one cares, I got it working with this adapter jQuery plugin, which, in my opinion the select2 plugin should handle these by default:

/* select2 val, add/remove Class and qtip adapter */
( function ( $ )
{
var get_select2_style_element = function ( self )
{
var select2 = self.data( "select2" ); // this is a hack to get to the right element to style
if ( null != select2 )
{
var $combo = select2.$container.find( "[role='combobox']" );
if ( $combo.length > 0 )
{
return $combo;
}
}
else if ( self.is( 'input:radio' ) || self.is( 'input:checkbox' ) )
{
return self.parent();
}
return self;
};

var get_select2_search_element = function ( self )
{
var select2 = self.data( "select2" ); // this is a hack to get to the right element to style
if ( null != select2 )
{
var $textbox = select2.$container.find( '[role="textbox"]' );
if ( $textbox.length > 0 )
{
return $textbox;
}
}
return self;
};

var jqueryVal = $.fn.val;
$.fn.val = function ()
{
var ret = jqueryVal.apply( this, arguments );
if ( typeof arguments != 'undefined' && arguments.length >= 1 )
{
var $this = $( this );
if ( null != $this.data( 'select2' ) )
{
$this.trigger( 'change' );
}
}
return ret;
};

var jqueryAddClass = $.fn.addClass;
$.fn.addClass = function ()
{
var self = this;
var target = get_select2_style_element( self );
jqueryAddClass.apply( target, arguments );
return self;
};

var jqueryRemoveClass = $.fn.removeClass;
$.fn.removeClass = function ( options )
{
var self = this;
var target = get_select2_style_element( self );
jqueryRemoveClass.apply( target, arguments );
return self;
};


var jqueryQtip = $.fn.qtip;
$.fn.qtip = function ( args )
{
var options = args;
return this.each( function (  )
{
var self = $(this);
var style_element = get_select2_style_element( self );
var settings = options;
if ( style_element != self && typeof options == 'object' )
{
var showsetting = { target: self, event: 'mouseenter' };
var search_element = get_select2_search_element( self );

if ( typeof settings.show == 'string' ) { showsetting.event = settings.show; }
else if ( typeof settings.show == 'object' ) { showsetting.event = settings.show.event || 'mouseenter'; showsetting = $.extend( {}, settings.show, showsetting ); }
showsetting.target = search_element;

var hidesetting = { target: self, event: 'mouseleave' };
if ( typeof settings.hide == 'string' ) { hidesetting.event = settings.hide; }
else if ( typeof settings.hide == 'object' ) { hidesetting.event = settings.hide.event || 'mouseleave'; hidesetting = $.extend( {}, settings.hide, hidesetting ); }
hidesetting.target = search_element;

settings = $.extend( true, {}, options, { show: showsetting, hide: hidesetting } );
}
jqueryQtip.call( style_element, settings );
} );
};

}( jQuery ) );
Reply all
Reply to author
Forward
0 new messages