// selectbox
$(function() {
function selectbox(widgetSelector, optionsContainerSelector, optionsSelector, selectedOptionSelector, selectedOptionClassName, selectorClassName) {
var target = widgetSelector;
function initialize() {
var widget = $(this);
var selectboxNamespace = widget.data('selectbox-ns');
var options = optionsContainerSelector; // The container which contains the options
var option = optionsSelector; // The options nested directly inside the options container
var selected = selectedOptionSelector; // This is the selector you will style, no visible at all times portion of the selectbox
var selectedOption = selectedOptionClassName; // This class is mechanical but be used to allow the user to visually track the item which is selected once the placeholder pops back into the selected region
var selector = selectorClassName; // Set the selector switch to a local var for reuse
function closeAllOptions(event) { // For blurring and defocus of any intances of the selectbox widget
// This portion is for reseting the placeholder or selection text (depending if an items has indeed been selected yet)
$(options).hide(); // Hide all intances of the options container
$(target).children().children(selected).each(function(){ // Iterate through each one
$(this).html( $(this).parent().parent().children(options).children('.'+selectedOption).html() )
// Set each instance of the selected class innerHTML to that of the selectedOption class if one has been selected
});
}
function closeOptions(event) {
$(options).hide();
// When the an item is selected, we'll close all instances the options container
}
function injectPlaceholder() {
// We will use this again below (2) times
widget.children().children(selected).html(widget.children().children(selected).data('placeholder'));
}
injectPlaceholder(); // Ensure the initial content is where it should be on load
function toggleOptions(event) {
// this = .options
if (widget.children(options).is(':visible')) { // If selectbox is opened
widget.children(options).hide(); // Hide the options based on where the function was envoked from
widget.children().children(selected).html(widget.children(options).children('.' + selectedOption).html())
} else { // if selectbox is closed
$(options).hide() // Hide all options (all instances)
widget.children(options).show(); // Show this particular instance
injectPlaceholder(); // Another time where injectPlaceholder is envoked()
}
event.stopPropagation(); // Stop the event from bubbling up the DOM further
}
function selectOption(event) { // Selecting an option from the now visible options container
// this = .option
var reqOption = $(this).html(); // Store the option content that was selected
var reqData = $(this).attr('data-value'); // Store the value held by the option selected
widget.children(options).children(option).removeClass(selectedOption) // This class is mechanical but be used to allow the user to visually track the item which is selected once the placeholder pops back into the selected region
$(this).addClass(selectedOption); // for tracking purposes
widget.children().children(selected).html(reqOption) // Insert the selected options data into the 'selected'/selection area
widget.children().children(selected).attr('data-value', reqData) // Append a data-attribute matching the value of the option selected
$('.test-box').append(selectboxNamespace + ' was selected and ' + 'reports its selected value: ' + reqData + ',' + ' because the user selected the option reading: ' + '"' + reqOption + '"<br />');
event.stopPropagation(); // Stop the event from bubbling up the DOM
closeOptions(); // Close options after an item is selected and the rest is done...
}
// Bind our event handlers
$(this).on('click', option, selectOption) // If an option is clicked -> selectOption()
$(this).on('click', toggleOptions) // If the options container is clicked -> toggleOption()
$(this).on('click', selector, toggleOptions) // If the selector element is clicked -> toggleOptions()
$('html').on('click', closeAllOptions) // If the widget is blurred/defocused -> closeAllOptions
}
$(target).each(initialize) // Apply this functionality to each instance of the select box
}
window.selectbox = selectbox('.selectbox', '.options', '.option', '.selected', 'selected-option', '.selector');
// API : widgetSelector, optionsContainerSelector, optionsSelector, selectedOptionSelector, selectedOptionClassName, selectorClassName ) The last param must be a class name (any classname)
});
Here are the widgets requirements which I managed to meet:
Must retain placeholder if nothing is selected through all states (click and then click the selector not to select an actual option, and the placeholder content should stay)
When the options menu is open, it should show the placeholder instruction as the selected option text, however once the menu is contracted or toggled, it should show the selected text (if there is any)
The selectbox must close on blur, and also on selection of another instance of the widget
Obv it must grab a value and identifier for the selected option, and pair that with an identifier that lets the app know which box the data and value came from
PROBLEM:
With JQuery 1.7 loaded there is a bug when you attempt to toggle the selectbox without actually selecting an item, the innerHTML of the selection display reads nothing, instead of the desired placeholder content being re-added to the selection display as desired (the logic is there and working error free, please test it for yourself)
Also, when the body is clicked, all menu options should close, and if the widget/widgets have no option selected then the selected display area should again be injected with the placeholder content, if there has been an item selected in that instance then it should retain that instead.
Thanks for the help, Nicholas