/**
* jQuery fontIconPicker - v2.0.0
*
* An icon picker built on top of font icons and jQuery
*
* http://codeb.it/fontIconPicker
*
* Made by Alessandro Benoit & Swashata
* Under MIT License
*
* {@link https://github.com/micc83/fontIconPicker}
*/
;(function ($) {
'use strict';
// Create the defaults once
var defaults = {
theme : 'fip-grey', // The CSS theme to use with this fontIconPicker. You can set different themes on multiple elements on the same page
source : false, // Icons source (array|false|object)
emptyIcon : true, // Empty icon should be shown?
emptyIconValue : '', // The value of the empty icon, change if you select has something else, say "none"
iconsPerPage : 20, // Number of icons per page
hasSearch : true, // Is search enabled?
searchSource : false, // Give a manual search values. If using attributes then for proper search feature we also need to pass icon names under the same order of source
useAttribute : false, // Whether to use attribute selector for printing icons
attributeName : 'data-icon', // HTML Attribute name
convertToHex : true, // Whether or not to convert to hexadecimal for attribute value. If true then please pass decimal integer value to the source (or as value="" attribute of the select field)
allCategoryText : 'From all categories', // The text for the select all category option
unCategorizedText : 'Uncategorized' // The text for the select uncategorized option
};
// The actual plugin constructor
function Plugin( element, options ) {
this.element = $(element);
this.settings = $.extend({}, defaults, options);
if (this.settings.emptyIcon) {
this.settings.iconsPerPage--;
}
this.iconPicker = $('
'
});
this.iconContainer = this.iconPicker.find('.fip-icons-container');
this.searchIcon = this.iconPicker.find('.selector-search i');
this.iconsSearched = [];
this.isSearch = false;
this.totalPage = 1;
this.currentPage = 1;
this.currentIcon = false;
this.iconsCount = 0;
this.open = false;
// Set the default values for the search related variables
this.searchValues = [];
this.availableCategoriesSearch = [];
// The trigger event for change
this.triggerEvent = null;
// Backups
this.backupSource = [];
this.backupSearch = [];
// Set the default values of the category related variables
this.isCategorized = false; // Automatically detects if the icon listing is categorized
this.selectCategory = this.iconPicker.find('.icon-category-select'); // The category SELECT input field
this.selectedCategory = false; // false means all categories are selected
this.availableCategories = []; // Available categories, it is a two dimensional array which holds categorized icons
this.unCategorizedKey = null; // Key of the uncategorized category
// Initialize plugin
this.init();
}
Plugin.prototype = {
/**
* Init
*/
init: function () {
// Add the theme CSS to the iconPicker
this.iconPicker.addClass(this.settings.theme);
// To properly calculate iconPicker height and width
// We will first append it to body (with left: -9999px so that it is not visible)
this.iconPicker.css({
left: -9999
}).appendTo('body');
var iconPickerHeight = this.iconPicker.outerHeight(),
iconPickerWidth = this.iconPicker.outerWidth();
// Now reset the iconPicker CSS
this.iconPicker.css({
left: ''
});
// Add the icon picker after the select
this.element.before(this.iconPicker);
// Hide source element
// Instead of doing a display:none, we would rather
// make the element invisible
// and adjust the margin
this.element.css({
visibility: 'hidden',
top: 0,
position: 'relative',
zIndex: '-1',
left: '-' + iconPickerWidth + 'px',
display: 'inline-block',
height: iconPickerHeight + 'px',
width: iconPickerWidth + 'px',
// Reset all margin, border and padding
padding: '0',
margin: '0 -' + iconPickerWidth + 'px 0 0', // Left margin adjustment to account for dangling space
border: '0 none',
verticalAlign: 'top'
});
// Set the trigger event
if ( ! this.element.is('select') ) {
// Determine the event that is fired when user change the field value
// Most modern browsers supports input event except IE 7, 8.
// IE 9 supports input event but the event is still not fired if I press the backspace key.
// Get IE version
// https://gist.github.com/padolsey/527683/#comment-7595
var ieVersion = (function() {
var v = 3, div = document.createElement('div'), a = div.all || [];
while (div.innerHTML = '', a[0]);
return v > 4 ? v : !v;
}());
var el = document.createElement('div');
this.triggerEvent = (ieVersion === 9 || !('oninput' in el)) ? ['keyup'] : ['input', 'keyup']; // Let's keep the keyup event for scripts that listens to it
}
// If current element is SELECT populate settings.source
if (!this.settings.source && this.element.is('select')) {
// Reset the source and searchSource
// These will be populated according to the available options
this.settings.source = [];
this.settings.searchSource = [];
// Check if optgroup is present within the select
// If it is present then the source has to be grouped
if ( this.element.find('optgroup').length ) {
// Set the categorized to true
this.isCategorized = true;
this.element.find('optgroup').each($.proxy(function(i, el) {
// Get the key of the new category array
var thisCategoryKey = this.availableCategories.length,
// Create the new option for the selectCategory SELECT field
categoryOption = $('');
// Set the value to this categorykey
categoryOption.attr('value', thisCategoryKey);
// Set the label
categoryOption.html($(el).attr('label'));
// Append to the DOM
this.selectCategory.append(categoryOption);
// Init the availableCategories array
this.availableCategories[thisCategoryKey] = [];
this.availableCategoriesSearch[thisCategoryKey] = [];
// Now loop through it's option elements and add the icons
$(el).find('option').each($.proxy(function(i, cel) {
var newIconValue = $(cel).val(),
newIconLabel = $(cel).html();
// Check if the option element has value and this value does not equal to the empty value
if (newIconValue && newIconValue !== this.settings.emptyIconValue) {
// Push to the source, because at first all icons are selected
this.settings.source.push(newIconValue);
// Push to the availableCategories child array
this.availableCategories[thisCategoryKey].push(newIconValue);
// Push to the search values
this.searchValues.push(newIconLabel);
this.availableCategoriesSearch[thisCategoryKey].push(newIconLabel);
}
}, this));
}, this));
// Additionally check for any first label option child
if ( this.element.find('> option').length ) {
this.element.find('> option').each($.proxy(function(i, el) {
var newIconValue = $(el).val(),
newIconLabel = $(el).html();
// Don't do anything if the new icon value is empty
if ( !newIconValue || newIconValue === '' || newIconValue == this.settings.emptyIconValue ) {
return true;
}
// Set the uncategorized key if not set already
if ( this.unCategorizedKey === null ) {
this.unCategorizedKey = this.availableCategories.length;
this.availableCategories[this.unCategorizedKey] = [];
this.availableCategoriesSearch[this.unCategorizedKey] = [];
// Create an option and append to the category selector
$('').attr('value', this.unCategorizedKey).html(this.settings.unCategorizedText).appendTo(this.selectCategory);
}
// Push the icon to the category
this.settings.source.push(newIconValue);
this.availableCategories[this.unCategorizedKey].push(newIconValue);
// Push the icon to the search
this.searchValues.push(newIconLabel);
this.availableCategoriesSearch[this.unCategorizedKey].push(newIconLabel);
}, this));
}
// Not categorized
} else {
this.element.find('option').each($.proxy(function (i, el) {
var newIconValue = $(el).val(),
newIconLabel = $(el).html();
if (newIconValue) {
this.settings.source.push(newIconValue);
this.searchValues.push(newIconLabel);
}
}, this));
}
// Clone and backup the original source and search
this.backupSource = this.settings.source.slice(0);
this.backupSearch = this.searchValues.slice(0);
// load the categories
this.loadCategories();
// Normalize the given source
} else {
this.initSourceIndex();
// No need to call loadCategories or take backups because these are called from the initSourceIndex
}
// Load icons
this.loadIcons();
/**
* Category changer
*/
this.selectCategory.on('change keyup', $.proxy(function(e) {
// Don't do anything if not categorized
if ( this.isCategorized === false ) {
return false;
}
var targetSelect = $(e.currentTarget),
currentCategory = targetSelect.val();
// Check if all categories are selected
if (targetSelect.val() === 'all') {
// Restore from the backups
// @note These backups must be rebuild on source change, otherwise it will lead to error
this.settings.source = this.backupSource;
this.searchValues = this.backupSearch;
// No? So there is a specified category
} else {
var key = parseInt(currentCategory, 10);
if (this.availableCategories[key]) {
this.settings.source = this.availableCategories[key];
this.searchValues = this.availableCategoriesSearch[key];
}
}
this.resetSearch();
this.loadIcons();
}, this));
/**
* On down arrow click
*/
this.iconPicker.find('.selector-button').click($.proxy(function () {
// Open/Close the icon picker
this.toggleIconSelector();
}, this));
/**
* Next page
*/
this.iconPicker.find('.selector-arrow-right').click($.proxy(function (e) {
if (this.currentPage < this.totalPage) {
this.iconPicker.find('.selector-arrow-left').show();
this.currentPage = this.currentPage + 1;
this.renderIconContainer();
}
if (this.currentPage === this.totalPage) {
$(e.currentTarget).hide();
}
}, this));
/**
* Prev page
*/
this.iconPicker.find('.selector-arrow-left').click($.proxy(function (e) {
if (this.currentPage > 1) {
this.iconPicker.find('.selector-arrow-right').show();
this.currentPage = this.currentPage - 1;
this.renderIconContainer();
}
if (this.currentPage === 1) {
$(e.currentTarget).hide();
}
}, this));
/**
* Realtime Icon Search
*/
this.iconPicker.find('.icons-search-input').keyup($.proxy(function (e) {
// Get the search string
var searchString = $(e.currentTarget).val();
// If the string is not empty
if (searchString === '') {
this.resetSearch();
return;
}
// Set icon search to X to reset search
this.searchIcon.removeClass('fip-icon-search');
this.searchIcon.addClass('fip-icon-cancel');
// Set this as a search
this.isSearch = true;
// Reset current page
this.currentPage = 1;
// Actual search
// This has been modified to search the searchValues instead
// Then return the value from the source if match is found
this.iconsSearched = [];
$.grep(this.searchValues, $.proxy(function (n, i) {
if (n.toLowerCase().search(searchString.toLowerCase()) >= 0) {
this.iconsSearched[this.iconsSearched.length] = this.settings.source[i];
return true;
}
}, this));
// Render icon list
this.renderIconContainer();
}, this));
/**
* Quit search
*/
this.iconPicker.find('.selector-search').on('click', '.fip-icon-cancel', $.proxy(function () {
this.iconPicker.find('.icons-search-input').focus();
this.resetSearch();
}, this));
/**
* On icon selected
*/
this.iconContainer.on('click', '.fip-box', $.proxy(function (e) {
this.setSelectedIcon($(e.currentTarget).find('i').attr('data-fip-value'));
this.toggleIconSelector();
}, this));
/**
* Stop click propagation on iconpicker
*/
this.iconPicker.click(function (event) {
event.stopPropagation();
return false;
});
/**
* On click out
*/
$('html').click($.proxy(function () {
if (this.open) {
this.toggleIconSelector();
}
}, this));
},
/**
* Init the source & search index from the current settings
* @return {void}
*/
initSourceIndex: function() {
// First check for any sorts of errors
if ( typeof(this.settings.source) !== 'object' ) {
return;
}
// We are going to check if the passed source is an array or an object
// If it is an array, then don't do anything
// otherwise it has to be an object and therefore is it a categorized icon set
if ($.isArray(this.settings.source)) {
// This is not categorized since it is 1D array
this.isCategorized = false;
this.selectCategory.html('').hide();
// We are going to convert the source items to string
// This is necessary because passed source might not be "strings" for attribute related icons
this.settings.source = $.map(this.settings.source, function(e, i) {
if ( typeof(e.toString) == 'function' ) {
return e.toString();
} else {
return e;
}
});
// Now update the search
// First check if the search is given by user
if ( $.isArray(this.settings.searchSource) ) {
// Convert everything inside the searchSource to string
this.searchValues = $.map(this.settings.searchSource, function(e, i) {
if ( typeof(e.toString) == 'function' ) {
return e.toString();
} else {
return e;
}
}); // Clone the searchSource
// Not given so use the source instead
} else {
this.searchValues = this.settings.source.slice(0); // Clone the source
}
// Categorized icon set
} else {
var originalSource = $.extend(true, {}, this.settings.source);
// Reset the source
this.settings.source = [];
// Reset other variables
this.searchValues = [];
this.availableCategoriesSearch = [];
this.selectedCategory = false;
this.availableCategories = [];
this.unCategorizedKey = null;
// Set the categorized to true and reset the HTML
this.isCategorized = true;
this.selectCategory.html('');
// Now loop through the source and add to the list
for (var categoryLabel in originalSource) {
// Get the key of the new category array
var thisCategoryKey = this.availableCategories.length,
// Create the new option for the selectCategory SELECT field
categoryOption = $('');
// Set the value to this categorykey
categoryOption.attr('value', thisCategoryKey);
// Set the label
categoryOption.html(categoryLabel);
// Append to the DOM
this.selectCategory.append(categoryOption);
// Init the availableCategories array
this.availableCategories[thisCategoryKey] = [];
this.availableCategoriesSearch[thisCategoryKey] = [];
// Now loop through it's icons and add to the list
for ( var newIconKey in originalSource[categoryLabel] ) {
// Get the new icon value
var newIconValue = originalSource[categoryLabel][newIconKey];
// Get the label either from the searchSource if set, otherwise from the source itself
var newIconLabel = (this.settings.searchSource && this.settings.searchSource[categoryLabel] && this.settings.searchSource[categoryLabel][newIconKey]) ?
this.settings.searchSource[categoryLabel][newIconKey] : newIconValue;
// Try to convert to the source value string
// This is to avoid attribute related icon sets
// Where hexadecimal or decimal numbers might be passed
if ( typeof(newIconValue.toString) == 'function' ) {
newIconValue = newIconValue.toString();
}
// Check if the option element has value and this value does not equal to the empty value
if (newIconValue && newIconValue !== this.settings.emptyIconValue) {
// Push to the source, because at first all icons are selected
this.settings.source.push(newIconValue);
// Push to the availableCategories child array
this.availableCategories[thisCategoryKey].push(newIconValue);
// Push to the search values
this.searchValues.push(newIconLabel);
this.availableCategoriesSearch[thisCategoryKey].push(newIconLabel);
}
}
}
}
// Clone and backup the original source and search
this.backupSource = this.settings.source.slice(0);
this.backupSearch = this.searchValues.slice(0);
// Call the loadCategories
this.loadCategories();
},
/**
* Load Categories
* @return {void}
*/
loadCategories: function() {
// Dont do anything if it is not categorized
if ( this.isCategorized === false ) {
return;
}
// Now append all to the category selector
$('').prependTo(this.selectCategory);
// Show it and set default value to all categories
this.selectCategory.show().val('all').trigger('change');
},
/**
* Load icons
*/
loadIcons: function () {
// Set the content of the popup as loading
this.iconContainer.html('');
// If source is set
if (this.settings.source instanceof Array) {
// Render icons
this.renderIconContainer();
}
},
/**
* Render icons inside the popup
*/
renderIconContainer: function () {
var offset, iconsPaged = [];
// Set a temporary array for icons
if (this.isSearch) {
iconsPaged = this.iconsSearched;
} else {
iconsPaged = this.settings.source;
}
// Count elements
this.iconsCount = iconsPaged.length;
// Calculate total page number
this.totalPage = Math.ceil(this.iconsCount / this.settings.iconsPerPage);
// Hide footer if no pagination is needed
if (this.totalPage > 1) {
this.iconPicker.find('.selector-footer').show();
} else {
this.iconPicker.find('.selector-footer').hide();
}
// Set the text for page number index and total icons
this.iconPicker.find('.selector-pages').html(this.currentPage + '/' + this.totalPage + ' (' + this.iconsCount + ')');
// Set the offset for slice
offset = (this.currentPage - 1) * this.settings.iconsPerPage;
// Should empty icon be shown?
if (this.settings.emptyIcon) {
// Reset icon container HTML and prepend empty icon
this.iconContainer.html('');
// If not show an error when no icons are found
} else if (iconsPaged.length < 1) {
this.iconContainer.html('');
return;
// else empty the container
} else {
this.iconContainer.html('');
}
// Set an array of current page icons
iconsPaged = iconsPaged.slice(offset, offset + this.settings.iconsPerPage);
// List icons
for (var i = 0, item; item = iconsPaged[i++];) {
// Set the icon title
var flipBoxTitle = item;
$.grep(this.settings.source, $.proxy(function(e, i) {
if ( e === item ) {
flipBoxTitle = this.searchValues[i];
return true;
}
return false;
}, this));
// Set the icon box
$('', {
html: '',
'class': 'fip-box',
title: flipBoxTitle
}).appendTo(this.iconContainer);
}
// If no empty icon is allowed and no current value is set or current value is not inside the icon set
if (!this.settings.emptyIcon && (!this.element.val() || $.inArray(this.element.val(), this.settings.source) === -1)) {
// Get the first icon
this.setSelectedIcon(iconsPaged[0]);
} else if ($.inArray(this.element.val(), this.settings.source) === -1) {
// Set empty
this.setSelectedIcon();
} else {
// Set the default selected icon even if not set
this.setSelectedIcon(this.element.val());
}
},
/**
* Set Highlighted icon
*/
setHighlightedIcon: function () {
this.iconContainer.find('.current-icon').removeClass('current-icon');
if (this.currentIcon) {
this.iconContainer.find('[data-fip-value="' + this.currentIcon + '"]').parent('span').addClass('current-icon');
}
},
/**
* Set selected icon
*
* @param {string} theIcon
*/
setSelectedIcon: function (theIcon) {
if (theIcon === 'fip-icon-block') {
theIcon = '';
}
// Check if attribute is to be used
if ( this.settings.useAttribute ) {
if ( theIcon ) {
this.iconPicker.find('.selected-icon').html('' );
} else {
this.iconPicker.find('.selected-icon').html('');
}
// Use class
} else {
this.iconPicker.find('.selected-icon').html('');
this.element.val(theIcon);
}
// Set the value of the element and trigger change event
this.element.val((theIcon === '' ? this.settings.emptyIconValue : theIcon )).trigger('change');
if ( this.triggerEvent !== null ) {
// Trigger other events
for ( var eventKey in this.triggerEvent ) {
this.element.trigger(this.triggerEvent[eventKey]);
}
}
this.currentIcon = theIcon;
this.setHighlightedIcon();
},
/**
* Open/close popup (toggle)
*/
toggleIconSelector: function () {
this.open = (!this.open) ? 1 : 0;
this.iconPicker.find('.selector-popup').slideToggle(300);
this.iconPicker.find('.selector-button i').toggleClass('fip-icon-down-dir');
this.iconPicker.find('.selector-button i').toggleClass('fip-icon-up-dir');
if (this.open) {
this.iconPicker.find('.icons-search-input').focus().select();
}
},
/**
* Reset search
*/
resetSearch: function () {
// Empty input
this.iconPicker.find('.icons-search-input').val('');
// Reset search icon class
this.searchIcon.removeClass('fip-icon-cancel');
this.searchIcon.addClass('fip-icon-search');
// Go back to page 1 and remove back arrow
this.iconPicker.find('.selector-arrow-left').hide();
this.currentPage = 1;
this.isSearch = false;
// Rerender icons
this.renderIconContainer();
// Restore pagination if needed
if (this.totalPage > 1) {
this.iconPicker.find('.selector-arrow-right').show();
}
}
};
// Lightweight plugin wrapper
$.fn.fontIconPicker = function (options) {
// Instantiate the plugin
this.each(function () {
if (!$.data(this, "fontIconPicker")) {
$.data(this, "fontIconPicker", new Plugin(this, options));
}
});
// setIcons method
this.setIcons = $.proxy(function (newIcons, iconSearch) {
if ( undefined === newIcons ) {
newIcons = false;
}
if ( undefined === iconSearch ) {
iconSearch = false;
}
this.each(function () {
$.data(this, "fontIconPicker").settings.source = newIcons;
$.data(this, "fontIconPicker").settings.searchSource = iconSearch;
$.data(this, "fontIconPicker").initSourceIndex();
$.data(this, "fontIconPicker").resetSearch();
$.data(this, "fontIconPicker").loadIcons();
});
}, this);
// destroy method
this.destroyPicker = $.proxy(function() {
this.each(function() {
if (!$.data(this, "fontIconPicker")) {
return;
}
// Remove the iconPicker
$.data(this, "fontIconPicker").iconPicker.remove();
// Reset the CSS
$.data(this, "fontIconPicker").element.css({
visibility: '',
top: '',
position: '',
zIndex: '',
left: '',
display: '',
height: '',
width: '',
padding: '',
margin: '',
border: '',
verticalAlign: ''
});
// destroy data
$.removeData(this, "fontIconPicker");
});
}, this);
// reInit method
this.refreshPicker = $.proxy(function(newOptions) {
if ( ! newOptions ) {
newOptions = options;
}
// First destroy
this.destroyPicker();
// Now reset
this.each(function() {
if (!$.data(this, "fontIconPicker")) {
$.data(this, "fontIconPicker", new Plugin(this, newOptions));
}
});
}, this);
return this;
};
})(jQuery);
Conveyance Fee should be paid in three installments according to the Fare stage opted for.
Students availing school bus service should register their names by making the
Payment of first installment : 15 days before the commencement of the conveyance service.
Payment of second installment : Before 25th of August
Payment of third installment : Before 25th of November
School bus service applicants should contact the office in person for information regarding the annual conveyance fee tariff.
School buses will leave the school at 03:05pm.
Parents are hereby informed that no request over phone for any minor or major change (s) in the conveyance of your ward (to and from school) is entertained.
All students using school bus should reach the bus stop at least 5 minutes before the expected time of arrival of the bus. The bus shall not wait for late comers.
Students using their Own Conveyance should reach school between 08:10am and 08:20am and leave the school between 03:15pm and 03:30pm.
Parents are solely responsible if their ward (s) is using independent means of conveyance to attend the school.