(function($) {
$.fn.bindWithDelay = function( type, data, fn, timeout, throttle ) {
if ( $.isFunction( data ) ) {
throttle = timeout;
timeout = fn;
fn = data;
data = undefined;
}
// Allow delayed function to be removed with fn in unbind function
fn.guid = fn.guid || ($.guid && $.guid++);
// Bind each separately so that each element has its own delay
return this.each(function() {
var wait = null;
function cb() {
var e = $.extend(true, { }, arguments[0]);
var ctx = this;
var throttler = function() {
wait = null;
fn.apply(ctx, [e]);
};
if (!throttle) { clearTimeout(wait); wait = null; }
if (!wait) { wait = setTimeout(throttler, timeout); }
}
cb.guid = fn.guid;
$(this).bind(type, data, cb);
});
};
})(jQuery);
var REQUEST = new Object();
function chosen_ajaxify(id, ajax_url){
var div_id = id;
div_id = div_id.split("-").join("_");
// if single
if(jQuery('div#' + div_id + '_chosen').hasClass('chosen-container-single')){
jQuery('div#' + div_id + '_chosen' + ' .chosen-search input').bindWithDelay('keyup', function(event){
// ignore arrow key
if(event.keyCode >= 37 && event.keyCode <= 40){
return null;
}
// ignore enter
if(event.keyCode == 13){
return null;
}
// abort previous ajax
if(REQUEST[id] != null){
REQUEST[id].abort();
}
// get keyword and build regex pattern (use to emphasis search result)
var keyword = jQuery('div#' + div_id + '_chosen' + ' .chosen-search input').val();
if ( keyword.length < 3 ) {
return null;
}
var keyword_pattern = new RegExp(keyword, 'gi');
// remove all options of chosen
jQuery('div#' + div_id + '_chosen ul.chosen-results').empty();
// remove all options of original select
jQuery("#"+id).empty();
REQUEST[id] = jQuery.ajax({
url: ajax_url + keyword,
dataType: "json",
success: function(response){
// map, just as in functional programming :). Other way to say "foreach"
// add new options to original select
jQuery('#'+id).append('');
jQuery.map(response, function(item){
jQuery('#'+id).append('');
});
},
complete: function(){
keyword = jQuery('div#' + div_id + '_chosen' + ' .chosen-search input').val();
// update chosen
jQuery("#"+id).trigger("chosen:updated");
// some trivial UI adjustment
jQuery('div#' + div_id + '_chosen').removeClass('chosen-container-single-nosearch');
jQuery('div#' + div_id + '_chosen' + ' .chosen-search input').val(keyword);
jQuery('div#' + div_id + '_chosen' + ' .chosen-search input').removeAttr('readonly');
jQuery('div#' + div_id + '_chosen' + ' .chosen-search input').focus();
// emphasis keywords
jQuery('div#' + div_id + '_chosen' + ' .active-result').each(function(){
var html = jQuery(this).html();
jQuery(this).html(html.replace(keyword_pattern, function(matched){
return '' + matched + '';
}));
});
}
}, 500);
});
} else if(jQuery('div#' + div_id + '_chosen').hasClass('chosen-container-multi')){ // if multi
jQuery('div#' + div_id + '_chosen' + ' input').bindWithDelay('keyup', function(event){
// ignore arrow key
if(event.keyCode >= 37 && event.keyCode <= 40){
return null;
}
// ignore enter
if(event.keyCode == 13){
return null;
}
if(REQUEST[id] != null){
REQUEST[id].abort();
}
var old_input_width = jQuery('div#' + div_id + '_chosen' + ' input').css('width');
// get keyword and build regex pattern (use to emphasis search result)
var keyword = jQuery(this).val();
if ( keyword.length < 3 ) {
return null;
}
var keyword_pattern = new RegExp(keyword, 'gi');
// old values and captions
var old_values = new Array();
jQuery('#'+id+' option:selected').each(function(){
old_value = jQuery(this).val();
old_values.push(old_value);
});
// remove all options of chosen
jQuery('div#' + div_id + '_chosen ul.chosen-results').empty();
jQuery('option', '#'+id).not(':selected').remove();
REQUEST[id] = jQuery.ajax({
url: ajax_url + keyword,
dataType: "json",
success: function(response){
// map, just as in functional programming :). Other way to say "foreach"
jQuery.map(response, function(item){
// this is ineffective, is there any "in" syntax in javascript?
var found = false;
for(i=0; i' + item.caption + '');
}
});
},
complete: function(response){
keyword = jQuery('div#' + div_id + '_chosen' + ' input').val();
jQuery("#"+id).trigger("chosen:updated");
jQuery('div#' + div_id + '_chosen').removeClass('chosen-container-single-nosearch');
jQuery('div#' + div_id + '_chosen' + ' input').val(keyword);
jQuery('div#' + div_id + '_chosen' + ' input').removeAttr('readonly');
jQuery('div#' + div_id + '_chosen' + ' input').css('width', old_input_width);
jQuery('div#' + div_id + '_chosen' + ' input').focus();
// put that underscores
jQuery('div#' + div_id + '_chosen' + ' .active-result').each(function(){
var html = jQuery(this).html();
jQuery(this).html(html.replace(keyword_pattern, function(matched){
return '' + matched + '';
}));
});
}
});
}, 500);
}
}
function chosen_depend_on(id, id_depend_on, ajax_url){
var OLD_VALUE = jQuery('#'+id_depend_on).val();
jQuery('#'+id_depend_on).change(function(event){
var val = jQuery(this).val();
if(val != OLD_VALUE){
jQuery.ajax({
'url' : ajax_url + val,
'dataType' : 'json',
'success' : function(response){
jQuery('#'+id).empty();
jQuery.map(response, function(item){
jQuery('#'+id).append('');
});
jQuery('#'+id).trigger("chosen:updated");
jQuery('#'+id).trigger("change");
}
});
}
})
}