Skip to content

Instantly share code, notes, and snippets.

@ncherro
Created November 20, 2012 16:58
Show Gist options
  • Save ncherro/4119244 to your computer and use it in GitHub Desktop.
Save ncherro/4119244 to your computer and use it in GitHub Desktop.
Rails SimpleForm Select or Other input, with jQuery plugin
/**
* SelectOrOther plugin
*
* works with our custom simple_form select_or_other input
*/
(function($) {
var SelectOrOther = function(el, opts) {
var settings = $.extend({}, $.fn.selectorother.defaults, opts), $el,
$select, $other;
function init() {
$el = $(el);
$select = $el.find(settings.select_sel);
$other = $el.find(settings.other_sel);
$select.change(on_change).trigger('change');
}
function on_change(e) {
if ($select.val() == settings.other_key) {
$other.removeAttr('disabled').show().focus();
} else {
$other.attr('disabled', 'disabled').hide();
}
}
init();
};
$.fn.selectorother = function(options) {
return this.each(function(idx, el) {
var $el = $(this), key = 'selectorother';
if ($el.data(key)) { return; }
var selectorother = new SelectOrOther(this, options);
$el.data(key, selectorother);
});
};
// default settings
$.fn.selectorother.defaults = {
other_key: '--other--',
select_sel: 'select',
other_sel: '.other'
};
})(jQuery);
class SelectOrOtherInput < SimpleForm::Inputs::CollectionSelectInput
include ActionView::Helpers::FormOptionsHelper
include ActionView::Helpers::FormTagHelper
def input
label_method, value_method = detect_collection_methods output = ""
val = @builder.object.send(attribute_name)
other_key = '--other--'
other_val = 'Other'
other_attributes = {
:class => 'other',
:placeholder => 'Enter a value',
:value => '',
}
# manually convert our collection to an array
# see source for options_from_collection_for_select()
selected = val
soo_options = collection.map do |element|
[element.send(label_method), element.send(value_method)]
end
selected, disabled = extract_selected_and_disabled(selected)
select_deselect = {}
select_deselect[:selected] = extract_values_from_collection(collection, value_method, selected)
select_deselect[:disabled] = extract_values_from_collection(collection, value_method, disabled)
soo_options << [other_val, other_key]
if val && select_deselect[:selected] && soo_options.rassoc(select_deselect[:selected].first).nil?
# 'other' should be selected
select_deselect[:selected] = other_key
other_attributes[:value] = val
else
other_attributes[:disabled] = 'disabled'
end
output << @builder.select(attribute_name, soo_options, select_deselect.merge(input_options), input_html_options)
output << @builder.text_field(attribute_name, other_attributes)
output.html_safe
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment