增加定时器功能

Conflicts:
	src/main/webapp/WEB-INF/views/cfg/ipaddr/ipList.jsp
This commit is contained in:
zhangwei
2019-01-26 18:02:44 +06:00
parent 5c63f85483
commit 9d6e3a3d4a
41 changed files with 5184 additions and 335 deletions

View File

@@ -0,0 +1 @@
Shawn Chin <shawn.chin__AT__(GEE)mail.com>

View File

@@ -0,0 +1,20 @@
Copyright (c) 2010 Shawn Chin
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,40 @@
# jQuery plugin: cron
jquery-cron is a [jQuery] plugin for
presenting a simplified interface for users to specify cron entries.
Check out the [jquery-cron] website for more information.
There is much to be done on the flexibility and robustness front,
and we welcome contributions and bug fixes. Feel free to fork
and send us pull requests!
## Dependencies
* [jQuery]
* [jquery-gentleSelect] (optional)
## Usage
To use this plugin, one simply needs to load [jQuery]
and the JS/CSS scripts for jquery-cron, then attach it an empty `<DIV>`
on DOM ready:
$(document).ready(function() {
$('#selector').cron();
});
</script>
For more options, see the [jquery-cron] website.
## Others
Copyright (c) 2010-2013, Shawn Chin.
This project is licensed under the [MIT license].
[jQuery]: http://jquery.com "jQuery"
[jquery-cron]: http://shawnchin.github.com/jquery-cron "jquery-cron"
[jquery-gentleSelect]: http://shawnchin.github.com/jquery-gentleSelect "jquery-gentleSelect"
[MIT License]: http://www.opensource.org/licenses/mit-license.php "MIT License"

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
.cron-button {
height: 16px;
padding-left: 20px;
margin-left: 5px;
background-repeat: no-repeat;
background-position: center center;
cursor: pointer;
}
.cron-button-save {
background-image: url('img/disk.png');
}
.cron-changed {
padding-top: 5px;
padding-bottom: 5px;
background-color: #fdd;
}
.cron-controls {
margin-left: 10px;
color: #c77;
font-size: 0.9em;
}
.cron-controls > span.cron-loading {
background-image: url('img/loading.gif');
}

View File

@@ -0,0 +1,512 @@
/*
* jQuery gentleSelect plugin (version 0.1.4.1)
* http://shawnchin.github.com/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)
* <div id='cron'></div>
*
* 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 -------
// 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 += "<option value='"+i+"'>" + j + i + "</option>\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 += "<option value='"+i+"'>" + j + i + "</option>\n";
}
// options for days of month
var str_opt_dom = "";
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 += "<option value='"+i+"'>" + i + suffix + "</option>\n";
}
// options for months
var str_opt_month = "";
var months = ["January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"];
for (var i = 0; i < months.length; i++) {
str_opt_month += "<option value='"+(i+1)+"'>" + months[i] + "</option>\n";
}
// options for day of week
var str_opt_dow = "";
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday"];
for (var i = 0; i < days.length; i++) {
str_opt_dow += "<option value='"+i+"'>" + days[i] + "</option>\n";
}
// options for period
var str_opt_period = "";
//var periods = ["minute", "hour", "day", "week", "month", "year"];
var periods = ["day", "week", "month", "year"];
for (var i = 0; i < periods.length; i++) {
str_opt_period += "<option value='"+periods[i]+"'>" + periods[i] + "</option>\n";
}
// display matrix
var toDisplay = {
"minute" : [],
"hour" : ["mins"],
"day" : ["time"],
"week" : ["dow", "time"],
"month" : ["dom", "time"],
"year" : ["dom", "month", "time"]
};
var combinations = {
"minute" : /^(\*\s){4}\*$/, // "* * * * *"
"hour" : /^\d{1,2}\s(\*\s){3}\*$/, // "? * * * *"
"day" : /^(\d{1,2}\s){2}(\*\s){2}\*$/, // "? ? * * *"
"week" : /^(\d{1,2}\s){2}(\*\s){2}\d{1,2}$/, // "? ? * * ?"
"month" : /^(\d{1,2}\s){3}\*\s\*$/, // "? ? ? * *"
"year" : /^(\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 b = c.data("block");
var min = hour = day = month = dow = "*";
var selectedPeriod = b["period"].find("select").val();
switch (selectedPeriod) {
case "minute":
break;
case "hour":
min = b["mins"].find("select").val();
break;
case "day":
min = b["time"].find("select.cron-time-min").val();
hour = b["time"].find("select.cron-time-hour").val();
break;
case "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();
break;
case "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();
break;
case "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();
break;
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)
});
// 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 += "<option value='" + cv[key] + "'>" + key + "</option>\n";
}
}
block["period"] = $("<span class='cron-period'>"
+ "Every <select name='cron-period'>" + custom_periods
+ str_opt_period + "</select> </span>")
.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"] = $("<span class='cron-block cron-block-dom'>"
+ " on the <select name='cron-dom'>" + str_opt_dom
+ "</select> </span>")
.appendTo(this)
.data("root", this);
select = block["dom"].find("select").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.domOpts);
block["month"] = $("<span class='cron-block cron-block-month'>"
+ " of <select name='cron-month'>" + str_opt_month
+ "</select> </span>")
.appendTo(this)
.data("root", this);
select = block["month"].find("select").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.monthOpts);
block["mins"] = $("<span class='cron-block cron-block-mins'>"
+ " at <select name='cron-mins'>" + str_opt_mih
+ "</select> minutes past the hour </span>")
.appendTo(this)
.data("root", this);
select = block["mins"].find("select").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.minuteOpts);
block["dow"] = $("<span class='cron-block cron-block-dow'>"
+ " on <select name='cron-dow'>" + str_opt_dow
+ "</select> </span>")
.appendTo(this)
.data("root", this);
select = block["dow"].find("select").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.dowOpts);
block["time"] = $("<span class='cron-block cron-block-time'>"
+ " at <select name='cron-time-hour' class='cron-time-hour'>" + str_opt_hid
+ "</select>:<select name='cron-time-min' class='cron-time-min'>" + str_opt_mih
+ " </span>")
.appendTo(this)
.data("root", this);
select = block["time"].find("select.cron-time-hour").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.timeHourOpts);
select = block["time"].find("select.cron-time-min").data("root", this);
if (o.useGentleSelect) select.gentleSelect(o.timeMinuteOpts);
block["controls"] = $("<span class='cron-controls'>&laquo; save "
+ "<span class='cron-button cron-button-save'></span>"
+ " </span>")
.appendTo(this)
.data("root", this)
.find("span.cron-button-save")
.bind("click.cron", event_handlers.saveClicked)
.data("root", this)
.end();
this.find("select").bind("change.cron-callback", event_handlers.somethingChanged);
this.data("options", o).data("block", block); // store options and block pointer
this.data("current_value", o.initial); // remember base value to detect changes
return methods["value"].call(this, o.initial); // set initial value
},
value : function(cron_str) {
// when no args, act as getter
if (!cron_str) { return getCurrentValue(this); }
var o = this.data('options');
var block = this.data("block");
var useGentleSelect = o.useGentleSelect;
var t = getCronType(cron_str, o);
if (!defined(t)) { return false; }
if (defined(o.customValues) && o.customValues.hasOwnProperty(t)) {
t = o.customValues[t];
} else {
var d = cron_str.split(" ");
var v = {
"mins" : d[0],
"hour" : d[1],
"dom" : d[2],
"month" : d[3],
"dow" : d[4]
};
// update appropriate select boxes
var targets = toDisplay[t];
for (var i = 0; i < targets.length; i++) {
var tgt = targets[i];
if (tgt == "time") {
var btgt = block[tgt].find("select.cron-time-hour").val(v["hour"]);
if (useGentleSelect) btgt.gentleSelect("update");
btgt = block[tgt].find("select.cron-time-min").val(v["mins"]);
if (useGentleSelect) btgt.gentleSelect("update");
} else {;
var btgt = block[tgt].find("select").val(v[tgt]);
if (useGentleSelect) btgt.gentleSelect("update");
}
}
}
// trigger change event
var bp = block["period"].find("select").val(t);
if (useGentleSelect) bp.gentleSelect("update");
bp.trigger("change");
return this;
}
};
var event_handlers = {
periodChanged : function() {
var root = $(this).data("root");
var block = root.data("block"),
opt = root.data("options");
var period = $(this).val();
root.find("span.cron-block").hide(); // first, hide all blocks
if (toDisplay.hasOwnProperty(period)) { // not custom value
var b = toDisplay[$(this).val()];
for (var i = 0; i < b.length; i++) {
block[b[i]].show();
}
}
},
somethingChanged : function() {
root = $(this).data("root");
// if AJAX url defined, show "save"/"reset" button
if (defined(root.data("options").url_set)) {
if (methods.value.call(root) != root.data("current_value")) { // if changed
root.addClass("cron-changed");
root.data("block")["controls"].fadeIn();
} else { // values manually reverted
root.removeClass("cron-changed");
root.data("block")["controls"].fadeOut();
}
} else {
root.data("block")["controls"].hide();
}
// chain in user defined event handler, if specified
var oc = root.data("options").onChange;
if (defined(oc) && $.isFunction(oc)) {
oc.call(root);
}
},
saveClicked : function() {
var btn = $(this);
var root = btn.data("root");
var cron_str = methods.value.call(root);
if (btn.hasClass("cron-loading")) { return; } // in progress
btn.addClass("cron-loading");
$.ajax({
type : "POST",
url : root.data("options").url_set,
data : { "cron" : cron_str },
success : function() {
root.data("current_value", cron_str);
btn.removeClass("cron-loading");
// data changed since "save" clicked?
if (cron_str == methods.value.call(root)) {
root.removeClass("cron-changed");
root.data("block").controls.fadeOut();
}
},
error : function() {
alert("An error occured when submitting your request. Try again?");
btn.removeClass("cron-loading");
}
});
}
};
$.fn.cron = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || ! method) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.cron' );
}
};
})(jQuery);

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,68 @@
.gentleselect-data { display: none; }
.gentleselect-label {
padding: 1px 20px 1px 20px;
background-color: #eee;
border: 2px solid #ddd;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
background-repeat: no-repeat;
background-position: center right;
cursor: pointer;
color: #555;
white-space: nowrap;
}
.gentleselect-label-highlight {
border: 2px solid #aaa;
background-image: url('img/expand.png');
}
.gentleselect-dialog {
position: absolute;
z-index: 500;
display: none;
background-color: #fff;
border: 2px solid #999;
-moz-box-shadow: 0px 0px 12px #555;
-webkit-box-shadow: 0px 0px 12px #555;
box-shadow: 0px 0px 12px #555;
margin: 0; padding: 0;
}
.gentleselect-dialog > ul { padding: 0; margin: 0; list-style: none; }
.gentleselect-dialog > ul > li {
margin: 0;
padding: 3px 20px 3px 25px;
cursor: pointer;
}
.gentleselect-dialog > ul > li.selected {
font-weight: bold;
color: #369;
background-color: #eee;
}
.gentleselect-dialog > ul > li.gentleselect-dummy:hover { background-color: #fff; }
.gentleselect-dialog > ul > li:hover {
background-color: #69c;
color: #fff;
}
.gentleselect-dialog > .gentleselect-title {
display: block;
text-align: center;
margin: 0;
padding: 2px;
background-color: #ddd;
font-size: 0.8em;
color: #666;
overflow: hidden;
}

View File

@@ -0,0 +1,300 @@
/*
* jQuery gentleSelect plugin
* http://shawnchin.github.com/jquery-gentleSelect
*
* Copyright (c) 2010 Shawn Chin.
* Licensed under the MIT license.
*
* Usage:
* (JS)
*
* $('#myselect').gentleSelect(); // default. single column
*
* $('#myselect').gentleSelect({ // 3 columns, 150px wide each
* itemWidth : 150,
* columns : 3,
* });
*
* (HTML)
* <select id='myselect'><options> .... </options></select>
*
*/
(function($) {
var defaults = {
minWidth : 100, // only applies if columns and itemWidth not set
itemWidth : undefined,
columns : undefined,
rows : undefined,
title : undefined,
prompt : "Make A Selection",
maxDisplay: 0, // set to 0 for unlimited
openSpeed : 400,
closeSpeed : 400,
openEffect : "slide",
closeEffect : "slide",
hideOnMouseOut : true
}
function defined(obj) {
if (typeof obj == "undefined") { return false; }
else { return true; }
}
function hasError(c, o) {
if (defined(o.columns) && defined(o.rows)) {
$.error("gentleSelect: You cannot supply both 'rows' and 'columns'");
return true;
}
if (defined(o.columns) && !defined(o.itemWidth)) {
$.error("gentleSelect: itemWidth must be supplied if 'columns' is specified");
return true;
}
if (defined(o.rows) && !defined(o.itemWidth)) {
$.error("gentleSelect: itemWidth must be supplied if 'rows' is specified");
return true;
}
if (!defined(o.openSpeed) || typeof o.openSpeed != "number" &&
(typeof o.openSpeed == "string" && (o.openSpeed != "slow" && o.openSpeed != "fast"))) {
$.error("gentleSelect: openSpeed must be an integer or \"slow\" or \"fast\"");
return true;
}
if (!defined(o.closeSpeed) || typeof o.closeSpeed != "number" &&
(typeof o.closeSpeed == "string" && (o.closeSpeed != "slow" && o.closeSpeed != "fast"))) {
$.error("gentleSelect: closeSpeed must be an integer or \"slow\" or \"fast\"");
return true;
}
if (!defined(o.openEffect) || (o.openEffect != "fade" && o.openEffect != "slide")) {
$.error("gentleSelect: openEffect must be either 'fade' or 'slide'!");
return true;
}
if (!defined(o.closeEffect)|| (o.closeEffect != "fade" && o.closeEffect != "slide")) {
$.error("gentleSelect: closeEffect must be either 'fade' or 'slide'!");
return true;
}
if (!defined(o.hideOnMouseOut) || (typeof o.hideOnMouseOut != "boolean")) {
$.error("gentleSelect: hideOnMouseOut must be supplied and either \"true\" or \"false\"!");
return true;
}
return false;
}
function optionOverrides(c, o) {
if (c.attr("multiple")) {
o.hideOnMouseOut = true; // must be true or dialog will never hide
}
}
function getSelectedAsText(elemList, opts) {
// If no items selected, return prompt
if (elemList.length < 1) { return opts.prompt; }
// Truncate if exceed maxDisplay
if (opts.maxDisplay != 0 && elemList.length > opts.maxDisplay) {
var arr = elemList.slice(0, opts.maxDisplay).map(function(){return $(this).text();});
arr.push("...");
} else {
var arr = elemList.map(function(){return $(this).text();});
}
return arr.get().join(", ");
}
var methods = {
init : function(options) {
var o = $.extend({}, defaults, options);
if (hasError(this, o)) { return this; }; // check for errors
optionOverrides(this, o); //
this.hide(); // hide original select box
// initialise <span> to replace select box
label_text = getSelectedAsText(this.find(":selected"), o);
var label = $("<span class='gentleselect-label'>" + label_text + "</span>")
.insertBefore(this)
.bind("mouseenter.gentleselect", event_handlers.labelHoverIn)
.bind("mouseleave.gentleselect", event_handlers.labelHoverOut)
.bind("click.gentleselect", event_handlers.labelClick)
.data("root", this);
this.data("label", label)
.data("options", o);
// generate list of options
var ul = $("<ul></ul>");
this.find("option").each(function() {
var li = $("<li>" + $(this).text() + "</li>")
.data("value", $(this).attr("value"))
.data("name", $(this).text())
.appendTo(ul);
if ($(this).attr("selected")) { li.addClass("selected"); }
});
// build dialog box
var dialog = $("<div class='gentleselect-dialog'></div>")
.append(ul)
.insertAfter(label)
.bind("click.gentleselect", event_handlers.dialogClick)
.bind("mouseleave.gentleselect", event_handlers.dialogHoverOut)
.data("label", label)
.data("root", this);
this.data("dialog", dialog);
// if to be displayed in columns
if (defined(o.columns) || defined(o.rows)) {
// Update CSS
ul.css("float", "left")
.find("li").width(o.itemWidth).css("float","left");
var f = ul.find("li:first");
var actualWidth = o.itemWidth
+ parseInt(f.css("padding-left"))
+ parseInt(f.css("padding-right"));
var elemCount = ul.find("li").length;
if (defined(o.columns)) {
var cols = parseInt(o.columns);
var rows = Math.ceil(elemCount / cols);
} else {
var rows = parseInt(o.rows);
var cols = Math.ceil(elemCount / rows);
}
dialog.width(actualWidth * cols);
// add padding
for (var i = 0; i < (rows * cols) - elemCount; i++) {
$("<li style='float:left' class='gentleselect-dummy'><span>&nbsp;</span></li>").appendTo(ul);
}
// reorder elements
var ptr = [];
var idx = 0;
ul.find("li").each(function() {
if (idx < rows) {
ptr[idx] = $(this);
} else {
var p = idx % rows;
$(this).insertAfter(ptr[p]);
ptr[p] = $(this);
}
idx++;
});
} else if (typeof o.minWidth == "number") {
dialog.css("min-width", o.minWidth);
}
if (defined(o.title)) {
$("<div class='gentleselect-title'>" + o.title + "</div>").prependTo(dialog);
}
// ESC key should hide all dialog boxes
$(document).bind("keyup.gentleselect", event_handlers.keyUp);
return this;
},
// if select box was updated externally, we need to bring everything
// else up to speed.
update : function() {
var opts = this.data("options");
// Update li with selected data
var v = (this.attr("multiple")) ? this.val() : [this.val()];
$("li", this.data("dialog")).each(function() {
var $li = $(this);
var isSelected = ($.inArray($li.data("value"), v) != -1);
$li.toggleClass("selected", isSelected);
});
// Update label
var label = getSelectedAsText(this.find(":selected"), opts);
this.data("label").text(label);
return this;
}
};
var event_handlers = {
labelHoverIn : function() {
$(this).addClass('gentleselect-label-highlight');
},
labelHoverOut : function() {
$(this).removeClass('gentleselect-label-highlight');
},
labelClick : function() {
var $this = $(this);
var pos = $this.position();
var root = $this.data("root");
var opts = root.data("options");
var dialog = root.data("dialog")
.css("top", pos.top + $this.height())
.css("left", pos.left + 1);
if (opts.openEffect == "fade") {
dialog.fadeIn(opts.openSpeed);
} else {
dialog.slideDown(opts.openSpeed);
}
},
dialogHoverOut : function() {
var $this = $(this);
if ($this.data("root").data("options").hideOnMouseOut) {
$this.hide();
}
},
dialogClick : function(e) {
var clicked = $(e.target);
var $this = $(this);
var root = $this.data("root");
var opts = root.data("options");
if (!root.attr("multiple")) {
if (opts.closeEffect == "fade") {
$this.fadeOut(opts.closeSpeed);
} else {
$this.slideUp(opts.closeSpeed);
}
}
if (clicked.is("li") && !clicked.hasClass("gentleselect-dummy")) {
var value = clicked.data("value");
var name = clicked.data("name");
var label = $this.data("label")
if ($this.data("root").attr("multiple")) {
clicked.toggleClass("selected");
var s = $this.find("li.selected");
label.text(getSelectedAsText(s, opts));
var v = s.map(function(){ return $(this).data("value"); });
// update actual selectbox and trigger change event
root.val(v.get()).trigger("change");
} else {
$this.find("li.selected").removeClass("selected");
clicked.addClass("selected");
label.text(clicked.data("name"));
// update actual selectbox and trigger change event
root.val(value).trigger("change");
}
}
},
keyUp : function(e) {
if (e.keyCode == 27 ) { // ESC
$(".gentleselect-dialog").hide();
}
}
};
$.fn.gentleSelect = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || ! method) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.gentleSelect' );
}
};
})(jQuery);

View File

@@ -0,0 +1,384 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>jquery-cron : a jQuery plugin</title>
<link type="text/css" href="gentleSelect/jquery-gentleSelect.css" rel="stylesheet" />
<link type="text/css" href="cron/jquery-cron.css" rel="stylesheet" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="gentleSelect/jquery-gentleSelect-min.js"></script>
<script type="text/javascript" src="cron/jquery-cron.js"></script>
<style>
* { margin: 0; padding: 0; }
body { font-family: Helvetica,Arial,sans-serif; color: #222; background-color: #ddd;line-height: 24px; }
ul { margin-left: 20px; }
ol { margin: 15px 0px 0px 20px; }
ol li { margin-top: 10px; }
h1 { margin: 30px; font-size: 2.5em; font-weight: bold; color: #000; text-align: center; }
h2 { border-bottom: 1px solid #999; margin: 30px 0 10px 0; font-size: 1.3em; color: #555; }
h3 { border-left: 20px solid #999; padding-left: 10px; line-height: 1.2; font-size: 1.1em; color: #333; margin: 30px 0 10px 0; }
p { line-height: 1.3; margin-top: 20px; }
pre { line-height: 1.3; background-color: #369; color: #fff; padding: 10px; margin-top: 20px;}
a { color: #369; font-weight: bold; text-decoration: none; }
a:hover { text-decoration: underline; }
.example { margin: 10px; border: 1px dashed #ccc; padding: 10px;}
.example-text { font-family: monospace; }
#content { margin: 0 auto; padding: 20px 20px 40px 20px; width: 760px; background-color: #fff; border: 1px solid #777; border-width: 0 1px 0px 1px; }
#footer { margin: 0 auto; padding: 20px; padding-top: 2px; width: 760px; font-size: 0.8em; text-align: center; color: #888; }
</style>
<script type="text/javascript">
$(document).ready(function() {
$('#example1').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example1-val').text($(this).cron("value"));
}
});
$('#example1b').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example1b-val').text($(this).cron("value"));
},
useGentleSelect: true
});
$('#example2').cron({
initial: "42 3 * * 5",
effectOpts: {
openEffect: "fade",
openSpeed: "slow"
},
useGentleSelect: true
});
$('#example3').cron({
initial: "*/5 * * * *",
onChange: function() {
$('#example3-val').text($(this).cron("value"));
},
customValues: {
"5 Minutes" : "*/5 * * * *",
"2 Hours on Weekends" : "0 */2 * * 5,6"
},
useGentleSelect: true
});
$('#example4').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example4-val').text($(this).cron("value"));
},
useGentleSelect: true
});
});
</script>
</head>
<body>
<div id="content">
<h1>jQuery plugin: cron</h1>
<h2 id='intro'>Introduction</h2>
<p>
jquery-cron is a <a href='http://jquery.com'>jQuery</a> plugin for
presenting a simplified interface for users to specify cron entries.
</p>
<p>
Instead of having to specify the five elements of a cron entry (minute,
hour, day of month, month, day of week), jquery-cron provides a simpler
interface for users to enter the more common combinations. For example:
</p>
<div class='example'>
<div id='example1'></div>
<p>Generated cron entry: <span class='example-text' id='example1-val'></span></p>
</div>
Or, with <a href='#option-useGentleSelect'>useGentleSelect</a> enabled:
<div class='example'>
<div id='example1b'></div>
<p>Generated cron entry: <span class='example-text' id='example1b-val'></span></p>
</div>
<p>
In addition, the <a href='#option-customvalues'><tt>customValues</tt></a>
option can be used to provide a list of canned cron entries. This allow users to
cater for common use cases as well as enable more complex cron entries.
</p>
<p>
There is much room for improvements and we welcome contributions
and bug fixes. Feel free to fork <a href='https://github.com/shawnchin/jquery-cron'>the project</a>
and send us pull requests!
</p>
<h2>Download</h2>
<ul>
<li>Latest Release : <a href='https://github.com/shawnchin/jquery-cron/zipball/v0.1.4.1'>jquery-cron v0.1.4.1</a></li>
<li>If you're feeling brave, download the <a href='https://github.com/shawnchin/jquery-cron/zipball/master'>Development Version</a></li>
</ul>
<h2>TODO</h2>
<ul>
<li>Support multiple entries per field</li>
<li>implement option to add CSS class (simplify customisation)</li>
<li>make the AJAX POST functionality more generic</li>
</ul>
<h2>Usage</h2>
<p>
To use this plugin, one simply needs to load <a href='http://jquery.com'>jQuery</a>
and the JS/CSS scripts for jquery-cron:
</p>
<pre>
&lt;script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="cron/jquery-cron.js"&gt;&lt;/script&gt;
&lt;link type="text/css" href="cron/jquery-cron.css" rel="stylesheet" /&gt;
</pre>
<p>If used with <a href="#option-useGentleSelect"><tt>useGentleSelect</tt></a> you'll also need:</p>
<pre>
&lt;script type="text/javascript" src="gentleSelect/jquery-gentleSelect.js"&gt;&lt;/script&gt;
&lt;link type="text/css" href="gentleSelect/jquery-gentleSelect.css" rel="stylesheet" /&gt;
</pre>
<p>
then attach it to an empty &lt;div&gt; on DOM ready:
</p>
<pre>
&lt;script type="text/javascript"&gt;
$(document).ready(function() {
$('#selector').cron(); // apply cron with default options
});
&lt;/script&gt;
&lt;!--- somewhere within &lt;body&gt; --&gt;
&lt;div id='selector'&gt;&lt;/div&gt;
</pre>
<p>
There are several ways one can utilise the generated cron entry:
<ol>
<li>
<strong>Interrogating the object</strong> :
See <a href="#method-value"><tt>value</tt></a> method and <a href="#option-onchange"><tt>onChange</tt></a> option.
</li>
<li>
<strong>AJAX POST</strong> :
See the <a href="#option-urlset"><tt>url_set</tt></a> option.
</li>
<li>
<strong>embed in existing form</strong> (not recommended) :
The UI is rendered as a series of &lt;select&gt; boxes within the &lt;div&gt;.
Therefore, one can (in theory) embed the whole &lt;div&gt; within a form and on submission
interrogate the appropriate fields. The generated fiels will have the names:
<ul>
<li><tt>cron-period</tt> : possible values are "minute, hour, day, week, month, year"</li>
<li><tt>cron-mins</tt> : only relevant when cron-period = "hour"</li>
<li><tt>cron-time-hour</tt> : only relevant when cron-period = "day, week, month, year" </li>
<li><tt>cron-time-min</tt> : only relevant when cron-period = "day, week, month, year" </li>
<li><tt>cron-dom</tt> : only relevant when cron-period = "month, year"</li>
<li><tt>cron-month</tt> : only relevant when cron-period = "year"</li>
<li><tt>cron-dow</tt> : only relevant when cron-period = "week"</li>
</ul>
</li>
</ol>
</p>
<h2>Options</h2>
<h3 id='option-initial'>initial</h3>
<p>
The <tt>initial</tt> option allows you the set the initial cron value. If an initialll value is not set,
a default value of <tt>"* * * * *"</tt> is used.
</p>
<p>
After the object has been set up, you can still update the value using
the <a href="#method-value"><tt>value</tt></a> method.
</p>
<h3 id='option-urlset'>url_set</h3>
<p>
You can asynchronously submit the current value to you backend script by specifying then
the URL using the <tt>url_set</tt> option.
</p>
<p>
If this option is set, a "save" icon will appear when changes are made allowing users
to submit their changes to the backend for processing.
</p>
<p>
jquery-cron will submit the values <tt>{"cron": ??}</tt> using a POST request via AJAX.
If a non-error HTTP response is received, the save is considered to be successfule and
the "save" icon will be hidden until the next change is made.
</p>
<h3 id='option-onchange'>onChange</h3>
<p>
You can set a callback function using the <tt>onChange</tt> option. The function will be called
each time the value changes.
For instance, the <a href='#intro'>example in the introduction</a> is implemented as using:
</p>
<pre>
$('#example1').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example1-val').text($(this).cron("value"));
}
});</pre>
<h3 id='option-useGentleSelect'>useGentleSelect</h3>
<p>Tells the plugin to use <a href='http://shawnchin.github.com/jquery-gentleSelect'>gentleSelect</a> to show dropdown options instead of the default select inputs.
</p>
<pre>
$('#example1').cron({
initial: "42 3 * * 5",
onChange: function() {
$('#example1-val').text($(this).cron("value"));
},
useGentleSelect: true // default: false
});</pre>
<div class='example'>
<div id='example4'></div>
<p>Generated cron entry: <span class='example-text' id='example4-val'></span></p>
</div>
<h3 id='option-effectopts'>effectOpts</h3>
<p>
You can change the effects used when displaying/hiding the selection menu by changing the
parameters in effectOpts. These values will be used as the default options for <tt>gentleSelect</tt>.
</p>
<p>
The following parameters can be set:
<ul>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-effect'>openEffect</a> (default: <tt>'slide'</tt>)</li>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-effect'>closeEffect</a> (default: <tt>'slide'</tt>)</li>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-speed'>openSpeed</a> (default: <tt>400</tt>)</li>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-speed'>closeSpeed</a> (default: <tt>400</tt>)</li>
<li><a href='http://shawnchin.github.com/jquery-gentleSelect/#option-mouseout'>hideOnMouseOut</a> (default: <tt>true</tt>)</li>
</ul>
</p>
<p>
For example, the following uses the <tt>fade</tt> effect with a slower animation speed:
</p>
<p>
<div id='example2'></div>
<pre>
$('#example2').cron({
initial: "42 3 * * 5",
effectOpts: {
openEffect: "fade",
openSpeed: "slow"
}
});</pre>
</p>
<h3 id='option-each-element'>Customising individual select boxes</h3>
<p>
It is possible to customise each of the generated select boxes by sending additional
options to its instance of <tt>gentleSelect</tt>.
All <a href='http://shawnchin.github.com/jquery-gentleSelect/#option-title'>attributes
support by jquery-gentleSelect</a> can be specified.
</p>
<p>
The following are the options to use for each select menu:
<ul>
<li><tt>minuteOpts</tt> - Minutes past the hour (hourly)</li>
<li><tt>timeMinuteOpts</tt> - Time:Minute (daily, weekly, monthly, yearly)</li>
<li><tt>timeHourOpts</tt> - Time:Hour (daily, weekly, monthly, yearly)</li>
<li><tt>dowOpts</tt> - Day of week (weekly)</li>
<li><tt>domOpts</tt> - Day of month (monthly, yearly)</li>
<li><tt>monthOpts</tt> - Month (yearly)</li>
</ul>
</p>
<p>
For example, to change the title of the "Day of Month" select box which appears for monthly and yearly crons:
<pre>
$('#selector').cron({
initial: "42 3 * * 5",
domOpts: {
title: "N-th day of the month"
}
});
</pre>
</p>
<h3 id='option-customvalues'>Adding custom values</h3>
<p>
Additional entries can be included in the period selection using the <tt>customValues</tt>
option. This allows you to specify more complex cron entries that is not currently expressible
using the current setup.
</p>
<p>
For example, the following adds two additional entries to the selection:
<pre>
$('#selector').cron({
initial: "*/5 * * * *",
customValues: {
"5 Minutes" : "*/5 * * * *",
"2 Hours on Weekends" : "0 */2 * * 5,6"
}
});
</pre>
</p>
<div class='example'>
<div id='example3'></div>
<p>Generated cron entry: <span class='example-text' id='example3-val'></span></p>
</div>
<p>
<b>Caveats:</b>
<ul>
<li>
At present, cron entries specified in <tt>customValues</tt> are not validated.
It is down to the implementer to ensure that provided values are as required.
</li>
<li>
The <a href='#method-value'><tt>value</tt></a> method can be used to retrieve
custom cron values. However, it cannot be used to set custom values.
</li>
</ul>
</p>
<h2>Methods</h2>
<h3 id='method-value'>value</h3>
<p>
The <tt>value</tt> method enables you to set/get the current cron value.
</p>
<pre>
// Initialise a cron objecy
var cron_field = $('#selector').cron();
// Updating the value of an existing cron object
cron_field.cron("value", "12 23 * * *");
// calling the method with the extra argument returns the current value
var current_value = cron_field.cron("value")
</pre>
</div>
<div id='footer'>
Copyright &copy; 2010-2013 <a href='http://github.com/shawnchin'>Shawn Chin</a>
(Licensed under the <a href='http://www.opensource.org/licenses/mit-license.php'>MIT License</a>)
</div>
<a href="http://github.com/shawnchin/jquery-cron"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub" /></a>
</body>
</html>