/* * jQuery gentleSelect plugin (version 0.1.4.1) * http://shawnchin.git.spacen.net/jquery-cron * * Copyright (c) 2010-2013 Shawn Chin. * Dual licensed under the MIT or GPL Version 2 licenses. * * Requires: * - jQuery * * Usage: * (JS) * * // initialise like this * var c = $('#cron').cron({ * initial: '9 10 * * *', # Initial value. default = "* * * * *" * url_set: '/set/', # POST expecting {"cron": "12 10 * * 6"} * }); * * // you can update values later * c.cron("value", "1 2 3 4 *"); * * // you can also get the current value using the "value" option * alert(c.cron("value")); * * (HTML) *
* * Notes: * At this stage, we only support a subset of possible cron options. * For example, each cron entry can only be digits or "*", no commas * to denote multiple entries. We also limit the allowed combinations: * - Every minute : * * * * * * - Every hour : ? * * * * * - Every day : ? ? * * * * - Every week : ? ? * * ? * - Every month : ? ? ? * * * - Every year : ? ? ? ? * */ (function($) { var defaults = { initial : "* * * * *", minuteOpts : { minWidth : 100, // only applies if columns and itemWidth not set itemWidth : 30, columns : 4, rows : undefined, title : "Minutes Past the Hour" }, timeHourOpts : { minWidth : 100, // only applies if columns and itemWidth not set itemWidth : 20, columns : 2, rows : undefined, title : "Time: Hour" }, domOpts : { minWidth : 100, // only applies if columns and itemWidth not set itemWidth : 30, columns : undefined, rows : 10, title : "Day of Month" }, monthOpts : { minWidth : 100, // only applies if columns and itemWidth not set itemWidth : 100, columns : 2, rows : undefined, title : undefined }, dowOpts : { minWidth : 100, // only applies if columns and itemWidth not set itemWidth : undefined, columns : undefined, rows : undefined, title : undefined }, timeMinuteOpts : { minWidth : 100, // only applies if columns and itemWidth not set itemWidth : 20, columns : 4, rows : undefined, title : "Time: Minute" }, effectOpts : { openSpeed : 400, closeSpeed : 400, openEffect : "slide", closeEffect : "slide", hideOnMouseOut : true }, url_set : undefined, customValues : undefined, onChange: undefined, // callback function each time value changes useGentleSelect: false }; // ------- build some static data ------- var str_opt_dom = ""; var str_opt_month = ""; var str_opt_dow = ""; var str_opt_period = ""; var toDisplay = {}; var combinations = {}; // options for minutes in an hour var str_opt_mih = ""; for (var i = 0; i < 60; i++) { var j = (i < 10)? "0":""; str_opt_mih += "\n"; } // options for hours in a day var str_opt_hid = ""; for (var i = 0; i < 24; i++) { var j = (i < 10)? "0":""; str_opt_hid += "\n"; } function buildSelects(options) { options = options || {}; // options for days of month if (options.dom){ for (var i = 1; i < 32; i++) { str_opt_dom += "\n"; } } else { for (var i = 1; i < 32; i++) { if (i == 1 || i == 21 || i == 31) { var suffix = "st"; } else if (i == 2 || i == 22) { var suffix = "nd"; } else if (i == 3 || i == 23) { var suffix = "rd"; } else { var suffix = "th"; } str_opt_dom += "\n"; } } // options for months var months = options.months || ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; for (var i = 0; i < months.length; i++) { str_opt_month += "\n"; } // options for day of week var days = options.days || ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; for (var i = 0; i < days.length; i++) { str_opt_dow += "\n"; } // options for period options.periods = options.periods || ["minute", "hour", "day", "week", "month", "year"]; for (var i = 0; i < options.periods.length; i++) { str_opt_period += "\n"; } // display matrix toDisplay = {}; toDisplay[options.periods[0]] = []; // minute toDisplay[options.periods[1]] = ["mins"]; // hour toDisplay[options.periods[2]] = ["time"]; // day toDisplay[options.periods[3]] = ["dow", "time"]; // week toDisplay[options.periods[4]] = ["dom", "time"]; // month toDisplay[options.periods[5]] = ["dom", "month", "time"]; // year combinations = {}; combinations[options.periods[0]] = /^(\*\s){4}\*$/, // "* * * * *" combinations[options.periods[1]] = /^\d{1,2}\s(\*\s){3}\*$/, // "? * * * *" combinations[options.periods[2]] = /^(\d{1,2}\s){2}(\*\s){2}\*$/, // "? ? * * *" combinations[options.periods[3]] = /^(\d{1,2}\s){2}(\*\s){2}\d{1,2}$/, // "? ? * * ?" combinations[options.periods[4]] = /^(\d{1,2}\s){3}\*\s\*$/, // "? ? ? * *" combinations[options.periods[5]] = /^(\d{1,2}\s){4}\*$/ // "? ? ? ? *" } // ------------------ internal functions --------------- function defined(obj) { if (typeof obj == "undefined") { return false; } else { return true; } } function undefinedOrObject(obj) { return (!defined(obj) || typeof obj == "object") } function getCronType(cron_str, opts) { // if customValues defined, check for matches there first if (defined(opts.customValues)) { for (key in opts.customValues) { if (cron_str == opts.customValues[key]) { return key; } } } // check format of initial cron value var valid_cron = /^((\d{1,2}|\*)\s){4}(\d{1,2}|\*)$/ if (typeof cron_str != "string" || !valid_cron.test(cron_str)) { $.error("cron: invalid initial value"); return undefined; } // check actual cron values var d = cron_str.split(" "); // mm, hh, DD, MM, DOW var minval = [ 0, 0, 1, 1, 0]; var maxval = [59, 23, 31, 12, 6]; for (var i = 0; i < d.length; i++) { if (d[i] == "*") continue; var v = parseInt(d[i]); if (defined(v) && v <= maxval[i] && v >= minval[i]) continue; $.error("cron: invalid value found (col "+(i+1)+") in " + o.initial); return undefined; } // determine combination for (var t in combinations) { if (combinations[t].test(cron_str)) { return t; } } // unknown combination $.error("cron: valid but unsupported cron format. sorry."); return undefined; } function hasError(c, o) { if (!defined(getCronType(o.initial, o))) { return true; } if (!undefinedOrObject(o.customValues)) { return true; } // ensure that customValues keys do not coincide with existing fields if (defined(o.customValues)) { for (key in o.customValues) { if (combinations.hasOwnProperty(key)) { $.error("cron: reserved keyword '" + key + "' should not be used as customValues key."); return true; } } } return false; } function getCurrentValue(c) { var o = c.data('options'); var b = c.data("block"); var min = hour = day = month = dow = "*"; var selectedPeriod = b["period"].find("select").val(); if (selectedPeriod == o.periods[0]) { // minute } else if (selectedPeriod == o.periods[1]) { //hour min = b["mins"].find("select").val(); } else if (selectedPeriod == o.periods[2]) { //day min = b["time"].find("select.cron-time-min").val(); hour = b["time"].find("select.cron-time-hour").val(); } else if (selectedPeriod == o.periods[3]) { //week min = b["time"].find("select.cron-time-min").val(); hour = b["time"].find("select.cron-time-hour").val(); dow = b["dow"].find("select").val(); } else if (selectedPeriod == o.periods[4]) { //month min = b["time"].find("select.cron-time-min").val(); hour = b["time"].find("select.cron-time-hour").val(); day = b["dom"].find("select").val(); } else if (selectedPeriod == o.periods[5]) { //year min = b["time"].find("select.cron-time-min").val(); hour = b["time"].find("select.cron-time-hour").val(); day = b["dom"].find("select").val(); month = b["month"].find("select").val(); } else { // default // we assume this only happens when customValues is set return selectedPeriod; } return [min, hour, day, month, dow].join(" "); } // ------------------- PUBLIC METHODS ----------------- var methods = { init : function(opts) { // init options var options = opts ? opts : {}; /* default to empty obj */ var o = $.extend([], defaults, options); var eo = $.extend({}, defaults.effectOpts, options.effectOpts); $.extend(o, { minuteOpts : $.extend({}, defaults.minuteOpts, eo, options.minuteOpts), domOpts : $.extend({}, defaults.domOpts, eo, options.domOpts), monthOpts : $.extend({}, defaults.monthOpts, eo, options.monthOpts), dowOpts : $.extend({}, defaults.dowOpts, eo, options.dowOpts), timeHourOpts : $.extend({}, defaults.timeHourOpts, eo, options.timeHourOpts), timeMinuteOpts : $.extend({}, defaults.timeMinuteOpts, eo, options.timeMinuteOpts) }); buildSelects(o); // error checking if (hasError(this, o)) { return this; } // ---- define select boxes in the right order ----- var block = [], custom_periods = "", cv = o.customValues; if (defined(cv)) { // prepend custom values if specified for (var key in cv) { custom_periods += "\n"; } } block["period"] = $("" + (o.every || "Every") + " ") .appendTo(this) .data("root", this); var select = block["period"].find("select"); select.bind("change.cron", event_handlers.periodChanged) .data("root", this); if (o.useGentleSelect) select.gentleSelect(eo); block["dom"] = $("" + " " + (o.onThe || "on the") + " ") .appendTo(this) .data("root", this); select = block["dom"].find("select").data("root", this); if (o.useGentleSelect) select.gentleSelect(o.domOpts); block["month"] = $("" + " " + (o.of || "of") + " ") .appendTo(this) .data("root", this); select = block["month"].find("select").data("root", this); if (o.useGentleSelect) select.gentleSelect(o.monthOpts); block["mins"] = $("" + " " + (o.at || "at") + " " + o.minuteOpts.title + " ") .appendTo(this) .data("root", this); select = block["mins"].find("select").data("root", this); if (o.useGentleSelect) select.gentleSelect(o.minuteOpts); block["dow"] = $("" + " " + (o.on || "on") + " ") .appendTo(this) .data("root", this); select = block["dow"].find("select").data("root", this); if (o.useGentleSelect) select.gentleSelect(o.dowOpts); block["time"] = $("" + " " + (o.at || "at") + " :