Added admin media to the Django distribution
git-svn-id: http://code.djangoproject.com/svn/django/trunk@96 bcc190cf-cafb-0310-a4f2-bffc1f526a37
3
media/css/base.css
Normal file
@ -0,0 +1,3 @@
|
||||
@import url('global.css');
|
||||
@import url('changelists.css');
|
||||
|
59
media/css/changelists.css
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
______________________________
|
||||
WORLD ONLINE PUBLISHING SYSTEM
|
||||
Admin Changelist Styles
|
||||
|
||||
Extends global.css
|
||||
|
||||
by World Online, Copyright 2004
|
||||
|
||||
645 New Hampshire
|
||||
Lawrence, KS 66044
|
||||
|
||||
webmaster@ljworld.com
|
||||
|
||||
*/
|
||||
|
||||
#changelist {position:relative; width:100%;}
|
||||
#changelist table {width:100%;}
|
||||
.change-list .filtered table { border-right:1px solid #ddd; }
|
||||
.change-list .filtered {min-height:400px; _height:400px;}
|
||||
.change-list .filtered {background:white url(../img/admin/changelist-bg.gif) top right repeat-y !important;}
|
||||
.change-list .filtered table, .filtered .paginator, .filtered #toolbar, .filtered div.xfull {margin-right:160px !important; width:auto !important; }
|
||||
.change-list .filtered table tbody th {padding-right:10px;}
|
||||
#changelist .toplinks {border-bottom:1px solid #ccc !important;}
|
||||
#changelist .paginator { color:#666; border-top:1px solid #eee; border-bottom:1px solid #eee; background:white url(../img/admin/nav-bg.gif) 0 180% repeat-x; overflow:hidden;}
|
||||
.change-list .filtered .paginator { border-right:1px solid #ddd; }
|
||||
|
||||
/* CHANGELIST TABLES */
|
||||
|
||||
#changelist table thead th {white-space:nowrap;}
|
||||
#changelist table tbody td {border-left: 1px solid #ddd;}
|
||||
#changelist table tfoot {color: #666;}
|
||||
|
||||
/* TOOLBAR */
|
||||
|
||||
#changelist #toolbar {padding:3px; border-bottom:1px solid #ddd; background:#e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; color:#666;}
|
||||
#changelist #toolbar form input {font-size:11px; padding:1px 2px;}
|
||||
#changelist #toolbar form #searchbar {padding:2px;}
|
||||
#changelist #changelist-search img {vertical-align:middle;}
|
||||
|
||||
/* FILTER COLUMN */
|
||||
|
||||
#changelist-filter {position:absolute; top:0; right:0; z-index:1000; width:160px; border-left:1px solid #ddd; background:#efefef; margin:0;}
|
||||
#changelist-filter h2 {font-size:11px; padding:2px 5px; border-bottom:1px solid #ddd;}
|
||||
#changelist-filter h3 {font-size:12px; margin-bottom:0;}
|
||||
#changelist-filter ul {padding-left:0;margin-left:10px;_margin-right:-10px;}
|
||||
#changelist-filter li {list-style-type:none; margin-left:0; padding-left:0;}
|
||||
#changelist-filter a {color:#999;}
|
||||
#changelist-filter a:hover {color:#036;}
|
||||
#changelist-filter li.selected {border-left:5px solid #ccc; padding-left:5px;margin-left:-10px;}
|
||||
#changelist-filter li.selected a {color:#5b80b2 !important;}
|
||||
|
||||
/* DATE DRILLDOWN */
|
||||
|
||||
.change-list ul.toplinks {display:block; background:white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; border-top:1px solid white; float:left; padding:0 !important; margin:0 !important; width:100%;}
|
||||
.change-list ul.toplinks li {float: left; width: 9em; padding:3px 6px; font-weight: bold; list-style-type:none;}
|
||||
.change-list ul.toplinks .date-back a {color:#999;}
|
||||
.change-list ul.toplinks .date-back a:hover {color:#036;}
|
||||
|
398
media/css/global.css
Normal file
@ -0,0 +1,398 @@
|
||||
/*
|
||||
______________________________
|
||||
DJANGO
|
||||
Admin Master Styles
|
||||
|
||||
Extends base.css
|
||||
|
||||
by World Online
|
||||
Copyright 2004-2005
|
||||
|
||||
645 New Hampshire
|
||||
Lawrence, KS 66044
|
||||
|
||||
webmaster@ljworld.com
|
||||
|
||||
______________________________
|
||||
SITE DIMENSIONS
|
||||
|
||||
Site Width: 768px
|
||||
Content Width: 750px
|
||||
Main Column: 580px
|
||||
Sidebar: 220px
|
||||
|
||||
______________________________
|
||||
COLORS
|
||||
|
||||
Blue #5b80b2
|
||||
Dark Blue #036
|
||||
|
||||
*/
|
||||
|
||||
body { margin:0; padding:0; font-family:"Lucida Grande","Bitstream Vera Sans",Verdana,Arial,sans-serif; color:#333; }
|
||||
|
||||
/* LINKS */
|
||||
|
||||
a:link, a:visited { color: #5b80b2; text-decoration:none; }
|
||||
a:hover { color: #036; }
|
||||
a img { border:none; }
|
||||
|
||||
/* GLOBAL DEFAULTS */
|
||||
|
||||
p, ol, ul, dl { margin:.2em 0 .8em 0; font-size:12px; }
|
||||
p { padding:0; line-height:140%; }
|
||||
|
||||
h1,h2,h3,h4,h5 { font-weight:bold; }
|
||||
h1 { font-size:18px; color:#666; padding:0 6px 0 0; margin:0 0 .2em 0; }
|
||||
h2 { font-size:16px; margin:1em 0 .5em 0; }
|
||||
h2.subhead { font-weight:normal;margin-top:0; }
|
||||
h3 { font-size:14px; margin:.8em 0 .3em 0; color:#666; font-weight:bold; }
|
||||
h4 { font-size:12px; margin:1em 0 .8em 0; padding-bottom:3px; }
|
||||
h5 { font-size:10px; margin:1.5em 0 .5em 0; color:#666; text-transform:uppercase; letter-spacing:1px; }
|
||||
|
||||
ul li { list-style-type:square; padding:1px 0; }
|
||||
ul.plainlist { margin-left:0 !important; }
|
||||
ul.plainlist li { list-style-type:none; }
|
||||
li ul { margin-bottom:0; }
|
||||
li, dt, dd { font-size:11px; line-height:14px; }
|
||||
dt { font-weight:bold; margin-top:4px; }
|
||||
dd { margin-left:0; }
|
||||
|
||||
form { margin:0; padding:0; }
|
||||
fieldset { margin:0; padding:0; }
|
||||
|
||||
blockquote { font-size:11px; color:#777; margin-left:2px; padding-left:10px; border-left:5px solid #ddd; }
|
||||
code, pre { font-family:"Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; background:inherit; color:#666; font-size:11px; }
|
||||
pre.literal-block { margin:10px; background:#eee; padding:6px 8px; }
|
||||
code strong { color:#930; }
|
||||
hr { clear:both; color:#eee; background-color:#eee; height:1px; border:none; margin:0; padding:0; font-size:1px; line-height:1px; }
|
||||
|
||||
/* PAGE STRUCTURE */
|
||||
|
||||
#container { position:relative; width:100%; min-width:720px; }
|
||||
#header { text-align:left; min-height:55px; _height:55px; }
|
||||
#content { margin:10px 15px; }
|
||||
#content-main { float:left; }
|
||||
#content-related { float:right; }
|
||||
#footer { clear:both; padding:10px; }
|
||||
|
||||
/* COLUMN TYPES */
|
||||
/*
|
||||
colM = Main | M |
|
||||
colMS = Main, Sidebar | M |S|
|
||||
colSM = Sidebar, Main |S| M |
|
||||
flex = single-column, liquid width
|
||||
superwide = single-column, extra-wide fixed width
|
||||
*/
|
||||
.colMS, .colM, .colSM, .colM #content-main, .colM #content-main .xfull { width:758px; } /* master site width for fixed-width pages */
|
||||
.colMS #content-main, .colSM #content-main, .colMS #content-main .xfull, .colSM #content-main .xfull { width:519px; } /* main column width for 2-column pages */
|
||||
.colMS #content-related, .colSM #content-related, .colSMS #content-related { width:220px; } /* sidebar column width */
|
||||
.colSM #content-related { float:left; } .colSM #content-main { float:right; } /* swaps left and right columns */
|
||||
.colSMS #content-main { width:298px; }
|
||||
.popup .colM { width:95%; }
|
||||
.popup #content-main, .flex #content-main, .flex .xfull { width:100% !important; } /* main column width for liquid-width pages */
|
||||
.popup .flex #content-main, .popup .colM #content-main { width:100% !important; }
|
||||
.subcol { float:left; width:46%; margin-right:15px; }
|
||||
|
||||
/* WIDTHS */
|
||||
|
||||
.x50 { width:50px; }
|
||||
.x75 { width:75px; }
|
||||
.x100 { width:100px; }
|
||||
.x150 { width:150px; }
|
||||
.x200 { width:200px; }
|
||||
.x250 { width:250px; }
|
||||
.x300 { width:300px; }
|
||||
.x400 { width:400px; }
|
||||
.x500 { width:500px; }
|
||||
|
||||
/* HEADER */
|
||||
|
||||
#header { background:#417690; color:#ffc; }
|
||||
#header a:link, #header a:visited { color:white; }
|
||||
#header a:hover { text-decoration:underline; }
|
||||
#branding { float:left; width:480px; }
|
||||
#branding h1 /* client name */ { padding:8px 0 0 10px; margin:0; font-size:18px; font-weight:normal; color:#f4f379; }
|
||||
#branding h2 /* site name */ { font-size:14px; padding:0 0 8px 10px; margin:0; font-weight:normal; color:#ffc; }
|
||||
#user-tools { font-size:11px; padding:8px 8px 0 5px; text-align:right; }
|
||||
|
||||
|
||||
/* SIDEBAR */
|
||||
|
||||
#content-related h3 { font-size:12px; color:#666; margin-bottom:3px; }
|
||||
#content-related h4 { font-size:11px; }
|
||||
|
||||
/* TABLES */
|
||||
|
||||
table { border-collapse:collapse; border-color:#ccc; }
|
||||
td, th { font-size:11px; line-height:13px; border-bottom:1px solid #eee; vertical-align:top; padding:5px; font-family:"Lucida Grande", Verdana, Arial, sans-serif; }
|
||||
th { text-align:left; font-size:12px; }
|
||||
thead th { font-weight:bold; color:#666; padding:2px 5px; font-size:11px; background:#e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; border-left:1px solid #ddd; border-bottom:1px solid #ddd; }
|
||||
thead th:first-child { border-left:none !important; }
|
||||
.superwide table th, .superwide table td, .superwide table input, .superwide table select { font-size:10px; }
|
||||
.module table { border-collapse: collapse; }
|
||||
thead th.optional { font-weight:normal !important; }
|
||||
#home-page table.module tr:hover { background:#EDF3FE; }
|
||||
fieldset table { border-right:1px solid #eee; }
|
||||
tr.row-label td { font-size:9px; padding-top:2px; padding-bottom:0; border-bottom:none; color:#666; margin-top:-1px; }
|
||||
tr.alt { background:#f6f6f6; }
|
||||
.row1 { background:#EDF3FE; }
|
||||
.row2 { background:white; }
|
||||
table#change-history { width:100%; }
|
||||
table#change-history tbody th { width:16em; }
|
||||
|
||||
/* TABLE SORTING */
|
||||
|
||||
thead th a:link, thead th a:visited { color:#666; display:block; }
|
||||
table thead th.sorted { background-position:bottom left !important; }
|
||||
table thead th.sorted a { padding-right:13px; }
|
||||
table thead th.ascending a { background:url(../img/admin/arrow-down.gif) right .4em no-repeat; }
|
||||
table thead th.descending a { background:url(../img/admin/arrow-up.gif) right .4em no-repeat; }
|
||||
|
||||
/* MODULES */
|
||||
|
||||
.module { border:1px solid #ccc; margin-bottom:5px; background:white; }
|
||||
.module p, .module ul, .module h3, .module h4, .module dl, .module pre { padding-left:10px; padding-right:10px; }
|
||||
.module blockquote { margin-left:12px; }
|
||||
.module ul, .module ol { margin-left:1.5em; }
|
||||
.module h2, .module caption { margin:0; padding:2px 5px 3px 5px; font-size:11px; text-align:left; font-weight:bold; color:#666; }
|
||||
.module caption { border:1px solid #ccc; border-bottom:none; }
|
||||
.module h2, .module caption { background:#7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x; color:white; }
|
||||
.module h3 { margin-top:.6em; }
|
||||
#content-related .module h2 { background:#eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; }
|
||||
#content-main .verbose .actionlist { float:right; font-size:10px; width:17em; position:relative; top:-1.6em; margin:0 8px; }
|
||||
.dashboard .module table { width:100%; }
|
||||
|
||||
/* RECENT ACTIONS MODULE */
|
||||
|
||||
.module ul.actionlist { margin-left:0; }
|
||||
ul.actionlist li { list-style-type:none; }
|
||||
|
||||
/* FORM DEFAULTS */
|
||||
|
||||
input, textarea, select { margin:2px 0; padding:2px 3px; vertical-align:middle; border:1px solid #ccc; font-family:"Lucida Grande", Verdana, Arial, sans-serif; font-weight:normal; font-size:11px; }
|
||||
textarea { vertical-align:top !important; }
|
||||
input[type=checkbox], input[type=radio] { border:none; }
|
||||
|
||||
/* FORM BUTTONS */
|
||||
|
||||
input[type=submit], input[type=button], .submit-row input { background:white url(../img/admin/nav-bg.gif) bottom repeat-x; }
|
||||
input[type=submit]:active, input[type=button]:active { background-image:url(../img/admin/nav-bg-reverse.gif); background-position:top; }
|
||||
input[type=submit].default, .submit-row input.default { border:2px solid #5b80b2; padding:3px; background:white url(../img/admin/default-bg.gif) bottom repeat-x; font-weight:bold; color:white; }
|
||||
input[type=submit].default:active { background-image:url(../img/admin/default-bg-reverse.gif); background-position:top; }
|
||||
.submit-row { padding:5px 7px; text-align:right; background:#ffc; border:1px solid #ccc; margin:5px 0; }
|
||||
.submit-row input { margin:0 0 0 5px; }
|
||||
|
||||
/* FORM ROWS */
|
||||
|
||||
.form-row { clear:both; padding:8px 12px; font-size:11px; }
|
||||
html>body .form-row { border-bottom:1px solid #eee; }
|
||||
.form-row:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
|
||||
.form-row img, .form-row input { vertical-align:middle; }
|
||||
form .form-row p { padding-left:0; font-size:11px; }
|
||||
|
||||
/* FORM LABELS */
|
||||
|
||||
form h4 { margin:0 !important; padding:0 !important; border:none !important; }
|
||||
label { font-weight:normal !important; color:#666; font-size:12px; }
|
||||
label.inline { margin-left:20px; }
|
||||
.required label, label.required { font-weight:bold !important; color:#333 !important; }
|
||||
|
||||
/* RADIO BUTTONS */
|
||||
|
||||
form ul.radiolist li { list-style-type:none; }
|
||||
form ul.radiolist label { float:none; display:inline; }
|
||||
form ul.inline { margin-left:0; padding:0; }
|
||||
form ul.inline li { float:left; padding-right:7px; }
|
||||
|
||||
/* ALIGNED FIELDSETS */
|
||||
|
||||
.aligned label { display:block; padding:0 1em 3px 0; float:left; text-align:left; width:8em; }
|
||||
.aligned label.inline { display:inline; float:none; }
|
||||
.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { width:350px; }
|
||||
form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; }
|
||||
form .aligned table p { margin-left:0; padding-left:0; }
|
||||
form .aligned p.help { padding-left:38px; }
|
||||
.aligned .vCheckboxLabel { float:none !important; display:inline; }
|
||||
.colM .aligned .vLargeTextField, colM .aligned .vXMLLargeTextField { width:610px; }
|
||||
.checkbox-row p.help { margin-left:0; padding-left:0 !important; }
|
||||
|
||||
/* WIDE FIELDSETS */
|
||||
|
||||
.wide label { width:15em !important; }
|
||||
form .wide p { margin-left:15em; }
|
||||
form .wide p.help { padding-left:38px; }
|
||||
.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { width:450px; }
|
||||
|
||||
/* COLLAPSED FIELDSETS */
|
||||
|
||||
fieldset.collapsed * { display:none; }
|
||||
fieldset.collapsed h2, fieldset.collapsed .collapse-toggle { display:block !important; }
|
||||
fieldset.collapsed h2 { background-image:url(../img/admin/nav-bg.gif); background-position:bottom left; color:#999; }
|
||||
fieldset.collapsed .collapse-toggle { padding:3px 5px !important; background:#efefef; }
|
||||
fieldset.collapsed .collapse-toggle a { display:inline !important; }
|
||||
|
||||
/* MESSAGES & ERRORS */
|
||||
|
||||
ul.messagelist { padding:0 0 5px 0; margin:0; }
|
||||
ul.messagelist li { font-size:12px; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border-bottom:1px solid #ddd; color:#666; background:#ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat; }
|
||||
.errornote { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:red;background:#ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; }
|
||||
ul.errorlist { margin:0 !important; padding:0 !important; }
|
||||
.errorlist li { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:white; background:red url(../img/admin/icon_alert.gif) 5px .3em no-repeat; }
|
||||
td ul.errorlist { margin:0 !important; padding:0 !important; }
|
||||
td ul.errorlist li { margin:0 !important; }
|
||||
.error { background:#ffc; }
|
||||
.error input, .error select { border:1px solid red; }
|
||||
|
||||
/* ACTION ICONS */
|
||||
|
||||
.addlink { padding-left:12px; background:url(../img/admin/icon_addlink.gif) 0 .2em no-repeat; }
|
||||
.changelink { padding-left:12px; background:url(../img/admin/icon_changelink.gif) 0 .2em no-repeat; }
|
||||
.deletelink { padding-left:12px; background:url(../img/admin/icon_deletelink.gif) 0 50% no-repeat; }
|
||||
a.deletelink:link, a.deletelink:visited { color:#CC3434; }
|
||||
a.deletelink:hover { color:#993333; }
|
||||
|
||||
/* OBJECT TOOLS */
|
||||
|
||||
.object-tools { font-size:10px; font-weight:bold; font-family:Arial,Helvetica,sans-serif; padding-left:0; margin-bottom:5px; float:right; position:relative; margin-top:-2.4em; margin-bottom:-2em; }
|
||||
.form-row .object-tools { margin-top:0; margin-bottom:0; }
|
||||
.object-tools li { display:block; float:left; background:url(../img/admin/tool-left.gif) 0 0 no-repeat; padding:0 0 0 8px; margin-left:2px; height:16px; }
|
||||
.object-tools li:hover { background:url(../img/admin/tool-left_over.gif) 0 0 no-repeat; }
|
||||
.object-tools a:link, .object-tools a:visited { display:block; float:left; color:white; padding:.1em 14px .1em 8px; height:14px; background:#999 url(../img/admin/tool-right.gif) 100% 0 no-repeat; }
|
||||
.object-tools a:hover, .object-tools li:hover a { background:#5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat; }
|
||||
.object-tools a.viewsitelink, .object-tools a.golink { background:#999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat; padding-right:28px; }
|
||||
.object-tools a.viewsitelink:hover, .object-tools a.golink:hover { background:#5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat; }
|
||||
.object-tools a.addlink { background:#999 url(../img/admin/tooltag-add.gif) top right no-repeat; padding-right:28px; }
|
||||
.object-tools a.addlink:hover { background:#5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat; }
|
||||
|
||||
/* INLINE CONTROLS */
|
||||
|
||||
#inline-controls { font-weight:bold; font-size:12px; }
|
||||
#inline-specific-controls { margin-left:6px; padding:0 8px; border-left:6px solid #ccc; }
|
||||
|
||||
/* BREADCRUMBS */
|
||||
|
||||
p.breadcrumbs { font-size:11px; color:#ccc;text-align:left; } /* old breadcrumbs style */
|
||||
div.breadcrumbs { background:white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; padding:2px 8px 3px 8px; font-size:11px; color:#999; border-top:1px solid white; border-bottom:1px solid #ccc; text-align:left; }
|
||||
|
||||
/* SELECTOR (FILTER INTERFACE) */
|
||||
|
||||
.selector { width:580px; float:left; }
|
||||
.selector select { width:270px; height:170px; }
|
||||
.selector-available, .selector-chosen { float:left; width:270px; text-align:center; margin-bottom:5px; }
|
||||
.selector-available h2, .selector-chosen h2 { border:1px solid #ccc; }
|
||||
.selector .selector-available h2 { background:white url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; }
|
||||
.selector .selector-filter { background:white; border:1px solid #ccc; border-width:0 1px; padding:3px; color:#999; font-size:10px; margin:0; text-align:left; }
|
||||
.selector .selector-chosen .selector-filter { padding:4px 5px; }
|
||||
.selector .selector-available input { width:230px; }
|
||||
.selector ul.selector-chooser { float:left; width:22px; height:50px; background:url(../img/admin/chooser-bg.gif) top center no-repeat; margin:13% 3px 0 3px; padding:0; }
|
||||
.selector-chooser li { margin:0; padding:3px; list-style-type:none; }
|
||||
.selector select { margin-bottom:5px; margin-top:0; }
|
||||
.selector-add, .selector-remove { width:16px; height:16px; display:block; text-indent:-3000px; }
|
||||
.selector-add { background:url(../img/admin/selector-add.gif) top center no-repeat; margin-bottom:2px; }
|
||||
.selector-remove { background:url(../img/admin/selector-remove.gif) top center no-repeat; }
|
||||
a.selector-chooseall, a.selector-clearall { display:block; width:6em; text-align:left; margin-left:auto; margin-right:auto; font-weight:bold; color:#666; padding:3px 0 3px 18px; }
|
||||
a.selector-chooseall:hover, a.selector-clearall:hover { color:#036; }
|
||||
a.selector-chooseall { width:7em; background:url(../img/admin/selector-addall.gif) left center no-repeat; }
|
||||
a.selector-clearall { background:url(../img/admin/selector-removeall.gif) left center no-repeat; }
|
||||
|
||||
/* Stacked selectors for long items */
|
||||
|
||||
.stacked { float:left; width:500px; }
|
||||
.stacked select { width:480px; height:100px; }
|
||||
.stacked .selector-available, .stacked .selector-chosen { width:480px; }
|
||||
.stacked .selector-available { margin-bottom:0; }
|
||||
.stacked .selector-available input { width:442px; }
|
||||
.stacked ul.selector-chooser { height:22px; width:50px; margin:0 0 3px 40%; background:url(../img/admin/chooser_stacked-bg.gif) top center no-repeat; }
|
||||
.stacked .selector-chooser li { float:left; padding:3px 3px 3px 5px; }
|
||||
.stacked .selector-chooseall, .stacked .selector-clearall { display:none; }
|
||||
.stacked .selector-add { background-image:url(../img/admin/selector_stacked-add.gif); }
|
||||
.stacked .selector-remove { background-image:url(../img/admin/selector_stacked-remove.gif); }
|
||||
|
||||
/* DATE AND TIME */
|
||||
|
||||
p.datetime { line-height:20px; margin:0; padding:0; color:#666; font-size:11px; font-weight:bold; }
|
||||
.datetime span { font-size:11px; font-weight:normal; white-space:nowrap; }
|
||||
.vDateField { margin-left:4px; }
|
||||
table p.datetime { font-size:10px; margin-left:0; padding-left:0; }
|
||||
|
||||
/* FILE UPLOADS */
|
||||
|
||||
p.file-upload { line-height:20px; margin:0; padding:0; color:#666; font-size:11px; font-weight:bold; }
|
||||
.file-upload a { font-weight:normal; }
|
||||
.file-upload .deletelink { margin-left:5px; }
|
||||
|
||||
/* CALENDARS & CLOCKS */
|
||||
|
||||
.calendarbox, .clockbox { margin:5px auto; width: 10em; text-align: center; background:white; position:relative; }
|
||||
.clockbox { width:6em; }
|
||||
.calendar { margin:0; padding: 0; }
|
||||
.calendar table { margin: 0; padding: 0; border-collapse:collapse; background:white; width:99%; }
|
||||
.calendar caption, .calendarbox h2 { margin: 0; font-size:11px; text-align:center; border-top:none; }
|
||||
.calendar th { font-size:10px; color:#666; padding:2px 3px; text-align:center; background:#e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-bottom:1px solid #ddd; }
|
||||
.calendar td { font-size:11px; text-align: center; padding: 0; border-top:1px solid #eee; border-bottom:none; }
|
||||
.calendar td.selected a { background: #C9DBED; }
|
||||
.calendar td.nonday { background:#efefef; }
|
||||
.calendar td.today a { background:#ffc; }
|
||||
.calendar td a, .timelist a { display: block; font-weight:bold; padding:4px; text-decoration: none; color:#444; }
|
||||
.calendar td a:hover, .timelist a:hover { background: #5b80b2; color:white; }
|
||||
.calendar td a:active, .timelist a:active { background: #036; color:white; }
|
||||
.calendarnav { font-size:10px; text-align: center; color:#ccc; margin:0; padding:1px 3px; }
|
||||
.calendarnav a:link, #calendarnav a:visited, #calendarnav a:hover { color: #999; }
|
||||
.calendar-shortcuts { background:white; font-size:10px; line-height:11px; border-top:1px solid #eee; padding:3px 0 4px; color:#ccc; }
|
||||
.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { display:block; position:absolute; font-weight:bold; font-size:12px; background:#C9DBED url(../img/admin/default-bg.gif) bottom left repeat-x; padding:1px 4px 2px 4px; color:white; }
|
||||
.calendarnav-previous:hover, .calendarnav-next:hover { background:#036; }
|
||||
.calendarnav-previous { top:0; left:0; }
|
||||
.calendarnav-next { top:0; right:0; }
|
||||
.calendar-cancel { margin:0 !important; padding:0; font-size:10px; background:#e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-top:1px solid #ddd; }
|
||||
.calendar-cancel a { padding:2px; color:#999; }
|
||||
ul.timelist, .timelist li { list-style-type:none; margin:0; padding:0; }
|
||||
.timelist a { padding:2px; }
|
||||
|
||||
/* OLD ORDERING WIDGET */
|
||||
|
||||
ul#orderthese { padding:0; margin:0; list-style-type:none; }
|
||||
ul#orderthese li { list-style-type:none; display:block; padding:0; margin:6px 0; width:214px; background:#f6f6f6; white-space:nowrap; overflow:hidden; }
|
||||
ul#orderthese li span { display:block; border:1px solid #e7e7e7; background:transparent url(../img/admin/nav-bg-grabber.gif) top left repeat-y; font-size:10px !important; padding:4px 6px 4px 12px; }
|
||||
ul#orderthese span:hover { background-color:#efefef; }
|
||||
|
||||
/* PAGINATOR */
|
||||
|
||||
.paginator { font-size:11px; padding-top:10px; padding-bottom:10px; line-height:22px; margin:0; border-top:1px solid #ddd; }
|
||||
.paginator a:link, .paginator a:visited { padding:2px 6px; border:solid 1px #ccc; background:white; text-decoration:none; }
|
||||
.paginator a.showall { padding:0 !important; border:none !important; }
|
||||
.paginator a.showall:hover { color:#036 !important; background:transparent !important; }
|
||||
.paginator .end { border-width:2px !important; margin-right:6px; }
|
||||
.paginator .this-page { padding:2px 6px; font-weight:bold; font-size:13px; vertical-align:top; }
|
||||
.paginator a:hover { color:white; background:#5b80b2; border-color:#036; }
|
||||
|
||||
/* TEXT STYLES & MODIFIERS */
|
||||
|
||||
.small { font-size:11px; }
|
||||
.tiny { font-size:10px; }
|
||||
p.tiny { margin-top:-2px; }
|
||||
.mini { font-size:9px; }
|
||||
p.mini { margin-top:-3px; }
|
||||
.help, p.help { font-size:10px !important; color:#999; }
|
||||
p img, h1 img, h2 img, h3 img, h4 img, td img { vertical-align:middle; }
|
||||
.quiet, a.quiet:link, a.quiet:visited { color:#999 !important;font-weight:normal !important; }
|
||||
.quiet strong { font-weight:bold !important; }
|
||||
.float-right { float:right; }
|
||||
.float-left { float:left; }
|
||||
.clear { clear:both; }
|
||||
.align-left { text-align:left; }
|
||||
.align-right { text-align:right; }
|
||||
.example { margin:10px 0; padding:5px 10px; background:#efefef; }
|
||||
.nowrap { white-space:nowrap; }
|
||||
|
||||
/* CUSTOM FORM FIELDS */
|
||||
|
||||
.vSelectMultipleField { vertical-align:top !important; }
|
||||
.vCheckboxField { border:none; }
|
||||
.vDateField, .vTimeField { margin-right:2px; }
|
||||
.vFileUploadField { border:none; }
|
||||
.vURLField { width:380px; }
|
||||
.vLargeTextField, .vXMLLargeTextField { width:480px; }
|
||||
.colM .vLargeTextField, .colM .vXMLLargeTextField { width:720px; }
|
||||
body.core-flatfile #id_content { height: 400px; }
|
||||
.module table .vPositiveSmallIntegerField { width: 22px; }
|
BIN
media/img/calendar.gif
Normal file
After Width: | Height: | Size: 192 B |
BIN
media/img/changelist-bg.gif
Normal file
After Width: | Height: | Size: 58 B |
BIN
media/img/chooser-bg.gif
Normal file
After Width: | Height: | Size: 199 B |
BIN
media/img/chooser_stacked-bg.gif
Normal file
After Width: | Height: | Size: 212 B |
BIN
media/img/default-bg-reverse.gif
Normal file
After Width: | Height: | Size: 843 B |
BIN
media/img/default-bg.gif
Normal file
After Width: | Height: | Size: 844 B |
BIN
media/img/icon-no.gif
Normal file
After Width: | Height: | Size: 176 B |
BIN
media/img/icon-yes.gif
Normal file
After Width: | Height: | Size: 299 B |
BIN
media/img/icon_addlink.gif
Normal file
After Width: | Height: | Size: 119 B |
BIN
media/img/icon_alert.gif
Normal file
After Width: | Height: | Size: 145 B |
BIN
media/img/icon_calendar.gif
Normal file
After Width: | Height: | Size: 192 B |
BIN
media/img/icon_changelink.gif
Normal file
After Width: | Height: | Size: 119 B |
BIN
media/img/icon_clock.gif
Normal file
After Width: | Height: | Size: 390 B |
BIN
media/img/icon_deletelink.gif
Normal file
After Width: | Height: | Size: 181 B |
BIN
media/img/icon_error.gif
Normal file
After Width: | Height: | Size: 319 B |
BIN
media/img/icon_searchbox.gif
Normal file
After Width: | Height: | Size: 681 B |
BIN
media/img/icon_success.gif
Normal file
After Width: | Height: | Size: 342 B |
BIN
media/img/nav-bg-grabber.gif
Normal file
After Width: | Height: | Size: 116 B |
BIN
media/img/nav-bg-grabber2.gif
Normal file
After Width: | Height: | Size: 268 B |
BIN
media/img/nav-bg-reverse.gif
Normal file
After Width: | Height: | Size: 186 B |
BIN
media/img/nav-bg.gif
Normal file
After Width: | Height: | Size: 273 B |
BIN
media/img/selector-add.gif
Normal file
After Width: | Height: | Size: 606 B |
BIN
media/img/selector-addall.gif
Normal file
After Width: | Height: | Size: 358 B |
BIN
media/img/selector-remove.gif
Normal file
After Width: | Height: | Size: 398 B |
BIN
media/img/selector-removeall.gif
Normal file
After Width: | Height: | Size: 355 B |
BIN
media/img/selector-search.gif
Normal file
After Width: | Height: | Size: 552 B |
BIN
media/img/selector_stacked-add.gif
Normal file
After Width: | Height: | Size: 612 B |
BIN
media/img/selector_stacked-remove.gif
Normal file
After Width: | Height: | Size: 401 B |
BIN
media/img/tool-left.gif
Normal file
After Width: | Height: | Size: 197 B |
BIN
media/img/tool-left_over.gif
Normal file
After Width: | Height: | Size: 203 B |
BIN
media/img/tool-right.gif
Normal file
After Width: | Height: | Size: 198 B |
BIN
media/img/tool-right_over.gif
Normal file
After Width: | Height: | Size: 200 B |
BIN
media/img/tooltag-add.gif
Normal file
After Width: | Height: | Size: 932 B |
BIN
media/img/tooltag-add_over.gif
Normal file
After Width: | Height: | Size: 336 B |
BIN
media/img/tooltag-arrowright.gif
Normal file
After Width: | Height: | Size: 351 B |
BIN
media/img/tooltag-arrowright_over.gif
Normal file
After Width: | Height: | Size: 354 B |
110
media/js/SelectBox.js
Normal file
@ -0,0 +1,110 @@
|
||||
var SelectBox = {
|
||||
cache: new Object(),
|
||||
init: function(id) {
|
||||
var box = document.getElementById(id);
|
||||
var node;
|
||||
SelectBox.cache[id] = new Array();
|
||||
var cache = SelectBox.cache[id];
|
||||
for (var i = 0; (node = box.options[i]); i++) {
|
||||
cache.push({ value: node.value, text: node.text, displayed: 1 });
|
||||
}
|
||||
},
|
||||
redisplay: function(id) {
|
||||
// Repopulate HTML select box from cache
|
||||
var box = document.getElementById(id);
|
||||
box.options.length = 0; // clear all options
|
||||
for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) {
|
||||
var node = SelectBox.cache[id][i];
|
||||
if (node.displayed) {
|
||||
box.options[box.options.length] = new Option(node.text, node.value, false, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
filter: function(id, text) {
|
||||
// Redisplay the HTML select box, displaying only the choices containing ALL
|
||||
// the words in text. (It's an AND search.)
|
||||
var tokens = text.toLowerCase().split(/\s+/);
|
||||
var node, token;
|
||||
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
||||
node.displayed = 1;
|
||||
for (var j = 0; (token = tokens[j]); j++) {
|
||||
if (node.text.toLowerCase().indexOf(token) == -1) {
|
||||
node.displayed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
SelectBox.redisplay(id);
|
||||
},
|
||||
delete_from_cache: function(id, value) {
|
||||
var node, delete_index = null;
|
||||
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
||||
if (node.value == value) {
|
||||
delete_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var j = SelectBox.cache[id].length - 1;
|
||||
for (var i = delete_index; i < j; i++) {
|
||||
SelectBox.cache[id][i] = SelectBox.cache[id][i+1];
|
||||
}
|
||||
SelectBox.cache[id].length--;
|
||||
},
|
||||
add_to_cache: function(id, option) {
|
||||
SelectBox.cache[id].push({ value: option.value, text: option.text, displayed: 1 });
|
||||
// SelectBox.sort(id) // Commented out for performance. Can this be deleted?
|
||||
},
|
||||
cache_contains: function(id, value) {
|
||||
// Check if an item is contained in the cache
|
||||
var node;
|
||||
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
||||
if (node.value == value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
move: function(from, to) {
|
||||
var from_box = document.getElementById(from);
|
||||
var to_box = document.getElementById(to);
|
||||
var option;
|
||||
for (var i = 0; (option = from_box.options[i]); i++) {
|
||||
if (option.selected && SelectBox.cache_contains(from, option.value)) {
|
||||
SelectBox.add_to_cache(to, { value: option.value, text: option.text, displayed: 1 });
|
||||
SelectBox.delete_from_cache(from, option.value);
|
||||
}
|
||||
}
|
||||
SelectBox.redisplay(from);
|
||||
SelectBox.redisplay(to);
|
||||
},
|
||||
move_all: function(from, to) {
|
||||
var from_box = document.getElementById(from);
|
||||
var to_box = document.getElementById(to);
|
||||
var option;
|
||||
for (var i = 0; (option = from_box.options[i]); i++) {
|
||||
SelectBox.add_to_cache(to, { value: option.value, text: option.text, displayed: 1 });
|
||||
SelectBox.delete_from_cache(from, option.value);
|
||||
}
|
||||
SelectBox.redisplay(from);
|
||||
SelectBox.redisplay(to);
|
||||
},
|
||||
sort: function(id) {
|
||||
SelectBox.cache[id].sort( function(a, b) {
|
||||
a = a.text.toLowerCase();
|
||||
b = b.text.toLowerCase();
|
||||
try {
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
}
|
||||
catch (e) {
|
||||
// silently fail on IE 'unknown' exception
|
||||
}
|
||||
return 0;
|
||||
} );
|
||||
},
|
||||
select_all: function(id) {
|
||||
var box = document.getElementById(id);
|
||||
for (var i = 0; i < box.options.length; i++) {
|
||||
box.options[i].selected = 'selected';
|
||||
}
|
||||
}
|
||||
}
|
81
media/js/SelectFilter.js
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
SelectFilter - Turns a multiple-select box into a filter interface.
|
||||
|
||||
Requires SelectBox.js and addevent.js.
|
||||
*/
|
||||
|
||||
function findForm(node) {
|
||||
// returns the node of the form containing the given node
|
||||
if (node.tagName.toLowerCase() != 'form') {
|
||||
return findForm(node.parentNode);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
var SelectFilter = {
|
||||
init: function(field_id) {
|
||||
var from_box = document.getElementById(field_id);
|
||||
from_box.id += '_from'; // change its ID
|
||||
// Create the INPUT input box
|
||||
var input_box = document.createElement('input');
|
||||
input_box.id = field_id + '_input';
|
||||
input_box.setAttribute('type', 'text');
|
||||
from_box.parentNode.insertBefore(input_box, from_box);
|
||||
from_box.parentNode.insertBefore(document.createElement('br'), input_box.nextSibling);
|
||||
// Create the TO box
|
||||
var to_box = document.createElement('select');
|
||||
to_box.id = field_id + '_to';
|
||||
to_box.setAttribute('multiple', 'multiple');
|
||||
to_box.setAttribute('size', from_box.size);
|
||||
from_box.parentNode.insertBefore(to_box, from_box.nextSibling);
|
||||
to_box.setAttribute('name', from_box.getAttribute('name'));
|
||||
from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
|
||||
// Give the filters a CSS hook
|
||||
from_box.setAttribute('class', 'filtered');
|
||||
to_box.setAttribute('class', 'filtered');
|
||||
// Set up the JavaScript event handlers for the select box filter interface
|
||||
addEvent(input_box, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
|
||||
addEvent(input_box, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
|
||||
addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); });
|
||||
addEvent(from_box, 'focus', function() { input_box.focus(); });
|
||||
addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); });
|
||||
addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
|
||||
SelectBox.init(field_id + '_from');
|
||||
SelectBox.init(field_id + '_to');
|
||||
// Move selected from_box options to to_box
|
||||
SelectBox.move(field_id + '_from', field_id + '_to');
|
||||
},
|
||||
filter_key_up: function(event, field_id) {
|
||||
from = document.getElementById(field_id + '_from');
|
||||
// don't submit form if user pressed Enter
|
||||
if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
|
||||
from.selectedIndex = 0;
|
||||
SelectBox.move(field_id + '_from', field_id + '_to');
|
||||
from.selectedIndex = 0;
|
||||
return false;
|
||||
}
|
||||
var temp = from.selectedIndex;
|
||||
SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
|
||||
from.selectedIndex = temp;
|
||||
return true;
|
||||
},
|
||||
filter_key_down: function(event, field_id) {
|
||||
from = document.getElementById(field_id + '_from');
|
||||
// right arrow -- move across
|
||||
if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
|
||||
var old_index = from.selectedIndex;
|
||||
SelectBox.move(field_id + '_from', field_id + '_to');
|
||||
from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
|
||||
return false;
|
||||
}
|
||||
// down arrow -- wrap around
|
||||
if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
|
||||
from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
|
||||
}
|
||||
// up arrow -- wrap around
|
||||
if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
|
||||
from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
129
media/js/SelectFilter2.js
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
SelectFilter2 - Turns a multiple-select box into a filter interface.
|
||||
|
||||
Different than SelectFilter because this is coupled to the admin framework.
|
||||
|
||||
Requires SelectBox.js and addevent.js.
|
||||
*/
|
||||
|
||||
// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]);
|
||||
function quickElement() {
|
||||
var obj = document.createElement(arguments[0]);
|
||||
if (arguments[2] != '' && arguments[2] != null) {
|
||||
var textNode = document.createTextNode(arguments[2]);
|
||||
obj.appendChild(textNode);
|
||||
}
|
||||
var len = arguments.length;
|
||||
for (var i = 3; i < len; i += 2) {
|
||||
obj.setAttribute(arguments[i], arguments[i+1]);
|
||||
}
|
||||
arguments[1].appendChild(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
function findForm(node) {
|
||||
// returns the node of the form containing the given node
|
||||
if (node.tagName.toLowerCase() != 'form') {
|
||||
return findForm(node.parentNode);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
var SelectFilter = {
|
||||
init: function(field_id, field_name, is_stacked) {
|
||||
var from_box = document.getElementById(field_id);
|
||||
from_box.id += '_from'; // change its ID
|
||||
from_box.className = 'filtered';
|
||||
|
||||
// Remove <p class="info">, because it just gets in the way.
|
||||
var ps = from_box.parentNode.getElementsByTagName('p');
|
||||
for (var i=0; i<ps.length; i++) {
|
||||
from_box.parentNode.removeChild(ps[i]);
|
||||
}
|
||||
|
||||
// <div class="selector"> or <div class="selector stacked">
|
||||
var selector_div = quickElement('div', from_box.parentNode);
|
||||
selector_div.className = is_stacked ? 'selector stacked' : 'selector';
|
||||
|
||||
// <div class="selector-available">
|
||||
var selector_available = quickElement('div', selector_div, '');
|
||||
selector_available.className = 'selector-available';
|
||||
quickElement('h2', selector_available, 'Available ' + field_name);
|
||||
var filter_p = quickElement('p', selector_available, '');
|
||||
filter_p.className = 'selector-filter';
|
||||
quickElement('img', filter_p, '', 'src', 'http://media.ljworld.com/img/admin/selector-search.gif');
|
||||
filter_p.appendChild(document.createTextNode(' '));
|
||||
var filter_input = quickElement('input', filter_p, '', 'type', 'text');
|
||||
filter_input.id = field_id + '_input';
|
||||
selector_available.appendChild(from_box);
|
||||
var choose_all = quickElement('a', selector_available, 'Choose all', 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()');
|
||||
choose_all.className = 'selector-chooseall';
|
||||
|
||||
// <ul class="selector-chooser">
|
||||
var selector_chooser = quickElement('ul', selector_div, '');
|
||||
selector_chooser.className = 'selector-chooser';
|
||||
var add_link = quickElement('a', quickElement('li', selector_chooser, ''), 'Add', 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()');
|
||||
add_link.className = 'selector-add';
|
||||
var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), 'Remove', 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()');
|
||||
remove_link.className = 'selector-remove';
|
||||
|
||||
// <div class="selector-chosen">
|
||||
var selector_chosen = quickElement('div', selector_div, '');
|
||||
selector_chosen.className = 'selector-chosen';
|
||||
quickElement('h2', selector_chosen, 'Chosen ' + field_name);
|
||||
var selector_filter = quickElement('p', selector_chosen, 'Select your choice(s) and click ');
|
||||
selector_filter.className = 'selector-filter';
|
||||
quickElement('img', selector_filter, '', 'src', 'http://media.ljworld.com/img/admin/selector-add.gif', 'alt', 'Add');
|
||||
var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
|
||||
to_box.className = 'filtered';
|
||||
var clear_all = quickElement('a', selector_chosen, 'Clear all', 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
|
||||
clear_all.className = 'selector-clearall';
|
||||
|
||||
from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
|
||||
|
||||
// Set up the JavaScript event handlers for the select box filter interface
|
||||
addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
|
||||
addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
|
||||
addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); });
|
||||
addEvent(from_box, 'focus', function() { filter_input.focus(); });
|
||||
addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); });
|
||||
addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
|
||||
SelectBox.init(field_id + '_from');
|
||||
SelectBox.init(field_id + '_to');
|
||||
// Move selected from_box options to to_box
|
||||
SelectBox.move(field_id + '_from', field_id + '_to');
|
||||
},
|
||||
filter_key_up: function(event, field_id) {
|
||||
from = document.getElementById(field_id + '_from');
|
||||
// don't submit form if user pressed Enter
|
||||
if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
|
||||
from.selectedIndex = 0;
|
||||
SelectBox.move(field_id + '_from', field_id + '_to');
|
||||
from.selectedIndex = 0;
|
||||
return false;
|
||||
}
|
||||
var temp = from.selectedIndex;
|
||||
SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
|
||||
from.selectedIndex = temp;
|
||||
return true;
|
||||
},
|
||||
filter_key_down: function(event, field_id) {
|
||||
from = document.getElementById(field_id + '_from');
|
||||
// right arrow -- move across
|
||||
if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
|
||||
var old_index = from.selectedIndex;
|
||||
SelectBox.move(field_id + '_from', field_id + '_to');
|
||||
from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
|
||||
return false;
|
||||
}
|
||||
// down arrow -- wrap around
|
||||
if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
|
||||
from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
|
||||
}
|
||||
// up arrow -- wrap around
|
||||
if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
|
||||
from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
82
media/js/admin/CollapsedFieldsets.js
Normal file
@ -0,0 +1,82 @@
|
||||
// Finds all fieldsets with class="collapse", collapses them, and gives each
|
||||
// one a "Show foo" link that uncollapses it.
|
||||
|
||||
function findForm(node) {
|
||||
// returns the node of the form containing the given node
|
||||
if (node.tagName.toLowerCase() != 'form') {
|
||||
return findForm(node.parentNode);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
var CollapsedFieldsets = {
|
||||
collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with.
|
||||
collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden.
|
||||
collapsed_class: 'collapsed',
|
||||
init: function() {
|
||||
var fieldsets = document.getElementsByTagName('fieldset');
|
||||
var collapsed_seen = false;
|
||||
for (var i=0; i<fieldsets.length; i++) {
|
||||
var fs = fieldsets[i];
|
||||
// Collapse this fieldset if it has the correct class, and if it
|
||||
// doesn't have any errors. (Collapsing shouldn't apply in the case
|
||||
// of error messages.)
|
||||
if (fs.className.match(CollapsedFieldsets.collapse_re) && !CollapsedFieldsets.fieldset_has_errors(fs)) {
|
||||
|
||||
collapsed_seen = true;
|
||||
|
||||
// Give it an additional class, used by CSS to hide it.
|
||||
fs.className += ' ' + CollapsedFieldsets.collapsed_class;
|
||||
|
||||
// Get plural verbose name of object.
|
||||
var verbose_name = fs.getElementsByTagName('h2')[0].innerHTML;
|
||||
|
||||
// <div class="form-row collapse-toggle" id="fieldsetcollapser1">
|
||||
// <a href="javascript:toggleDisplay;">Show section priorities…</a>
|
||||
// </div>
|
||||
var div = document.createElement('div');
|
||||
|
||||
// Give it a hook so we can remove it later.
|
||||
div.id = 'fieldsetcollapser' + i;
|
||||
|
||||
div.className = 'form-row collapse-toggle'; // CSS hook
|
||||
var collapse_link = document.createElement('a');
|
||||
collapse_link.setAttribute('href', 'javascript:CollapsedFieldsets.display(' + i + ');');
|
||||
collapse_link.appendChild(document.createTextNode('Show ' + verbose_name));
|
||||
div.appendChild(collapse_link);
|
||||
fs.appendChild(div);
|
||||
}
|
||||
}
|
||||
if (collapsed_seen) {
|
||||
// Expand all collapsed fieldsets when form is submitted.
|
||||
addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); });
|
||||
}
|
||||
},
|
||||
fieldset_has_errors: function(fs) {
|
||||
// Returns true if any fields in the fieldset have validation errors.
|
||||
var divs = fs.getElementsByTagName('div');
|
||||
for (var i=0; i<divs.length; i++) {
|
||||
if (divs[i].className.match(/\berror\b/)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
display: function(fieldset_index) {
|
||||
var fs = document.getElementsByTagName('fieldset')[fieldset_index];
|
||||
// Remove the class name that causes the "display: none".
|
||||
fs.className = fs.className.replace(CollapsedFieldsets.collapsed_re, '');
|
||||
// Remove the "Show foo" link.
|
||||
fs.removeChild(document.getElementById('fieldsetcollapser' + fieldset_index));
|
||||
},
|
||||
uncollapse_all: function() {
|
||||
var fieldsets = document.getElementsByTagName('fieldset');
|
||||
for (var i=0; i<fieldsets.length; i++) {
|
||||
if (fieldsets[i].className.match(CollapsedFieldsets.collapsed_re)) {
|
||||
CollapsedFieldsets.display(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addEvent(window, 'load', CollapsedFieldsets.init);
|
204
media/js/admin/DateTimeShortcuts.js
Normal file
@ -0,0 +1,204 @@
|
||||
// Inserts shortcut buttons after all of the following:
|
||||
// <input type="text" class="vDateField">
|
||||
// <input type="text" class="vTimeField">
|
||||
|
||||
var DateTimeShortcuts = {
|
||||
calendars: [],
|
||||
calendarInputs: [],
|
||||
clockInputs: [],
|
||||
calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
|
||||
calendarDivName2: 'calendarin', // name of <div> that contains calendar
|
||||
clockDivName: 'clockbox', // name of clock <div> that gets toggled
|
||||
|
||||
init: function() {
|
||||
var inputs = document.getElementsByTagName('input');
|
||||
for (var i=0; i<inputs.length; i++) {
|
||||
var inp = inputs[i];
|
||||
if (inp.getAttribute('type') == 'text' && inp.className.match(/vTimeField/)) {
|
||||
DateTimeShortcuts.addClock(inp);
|
||||
}
|
||||
else if (inp.getAttribute('type') == 'text' && inp.className.match(/vDateField/)) {
|
||||
DateTimeShortcuts.addCalendar(inp);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Add clock widget to a given field
|
||||
addClock: function(inp) {
|
||||
var num = DateTimeShortcuts.clockInputs.length;
|
||||
DateTimeShortcuts.clockInputs[num] = inp;
|
||||
|
||||
// Shortcut links (clock icon and "Now" link)
|
||||
var shortcuts_span = document.createElement('span');
|
||||
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
||||
var now_link = document.createElement('a');
|
||||
now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinute());");
|
||||
now_link.appendChild(document.createTextNode('Now'));
|
||||
var clock_link = document.createElement('a');
|
||||
clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');');
|
||||
quickElement('img', clock_link, '', 'src', 'http://media.ljworld.com/img/admin/icon_clock.gif', 'alt', 'Clock');
|
||||
shortcuts_span.appendChild(document.createTextNode('\240'));
|
||||
shortcuts_span.appendChild(now_link);
|
||||
shortcuts_span.appendChild(document.createTextNode('\240|\240'));
|
||||
shortcuts_span.appendChild(clock_link);
|
||||
|
||||
// Create clock link div
|
||||
//
|
||||
// Markup looks like:
|
||||
// <div id="clockbox1" class="clockbox module">
|
||||
// <h2>Choose a time</h2>
|
||||
// <ul class="timelist">
|
||||
// <li><a href="#">Now</a></li>
|
||||
// <li><a href="#">Midnight</a></li>
|
||||
// <li><a href="#">6 a.m.</a></li>
|
||||
// <li><a href="#">Noon</a></li>
|
||||
// </ul>
|
||||
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
||||
// </div>
|
||||
|
||||
var clock_box = document.createElement('div');
|
||||
clock_box.style.display = 'none';
|
||||
clock_box.style.position = 'absolute';
|
||||
clock_box.style.left = findPosX(clock_link) + 17 + 'px';
|
||||
clock_box.style.top = findPosY(clock_link) - 30 + 'px';
|
||||
clock_box.className = 'clockbox module';
|
||||
clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num);
|
||||
document.body.appendChild(clock_box);
|
||||
addEvent(clock_box, 'click', DateTimeShortcuts.cancelEventPropagation);
|
||||
|
||||
quickElement('h2', clock_box, 'Choose a time');
|
||||
time_list = quickElement('ul', clock_box, '', 'class', 'timelist');
|
||||
quickElement("a", quickElement("li", time_list, ""), "Now", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinute());")
|
||||
quickElement("a", quickElement("li", time_list, ""), "Midnight", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '00:00');")
|
||||
quickElement("a", quickElement("li", time_list, ""), "6 a.m.", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '06:00');")
|
||||
quickElement("a", quickElement("li", time_list, ""), "Noon", "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '12:00');")
|
||||
|
||||
cancel_p = quickElement('p', clock_box, '', 'class', 'calendar-cancel');
|
||||
quickElement('a', cancel_p, 'Cancel', 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
|
||||
},
|
||||
|
||||
openClock: function(num) {
|
||||
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'block';
|
||||
addEvent(window, 'click', function() { DateTimeShortcuts.dismissClock(num); return true; });
|
||||
},
|
||||
|
||||
dismissClock: function(num) {
|
||||
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';
|
||||
window.onclick = null;
|
||||
},
|
||||
|
||||
handleClockQuicklink: function(num, val) {
|
||||
DateTimeShortcuts.clockInputs[num].value = val;
|
||||
DateTimeShortcuts.dismissClock(num);
|
||||
},
|
||||
|
||||
// Add calendar widget to a given field.
|
||||
addCalendar: function(inp) {
|
||||
var num = DateTimeShortcuts.calendars.length;
|
||||
|
||||
DateTimeShortcuts.calendarInputs[num] = inp;
|
||||
|
||||
// Shortcut links (calendar icon and "Today" link)
|
||||
var shortcuts_span = document.createElement('span');
|
||||
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
||||
var today_link = document.createElement('a');
|
||||
today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);');
|
||||
today_link.appendChild(document.createTextNode('Today'));
|
||||
var cal_link = document.createElement('a');
|
||||
cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');');
|
||||
quickElement('img', cal_link, '', 'src', 'http://media.ljworld.com/img/admin/icon_calendar.gif', 'alt', 'Calendar');
|
||||
shortcuts_span.appendChild(document.createTextNode('\240'));
|
||||
shortcuts_span.appendChild(today_link);
|
||||
shortcuts_span.appendChild(document.createTextNode('\240|\240'));
|
||||
shortcuts_span.appendChild(cal_link);
|
||||
|
||||
// Create calendarbox div.
|
||||
//
|
||||
// Markup looks like:
|
||||
//
|
||||
// <div id="calendarbox3" class="calendarbox module">
|
||||
// <h2>
|
||||
// <a href="#" class="link-previous">‹</a>
|
||||
// <a href="#" class="link-next">›</a> February 2003
|
||||
// </h2>
|
||||
// <div class="calendar" id="calendarin3">
|
||||
// <!-- (cal) -->
|
||||
// </div>
|
||||
// <div class="calendar-shortcuts">
|
||||
// <a href="#">Yesterday</a> | <a href="#">Today</a> | <a href="#">Tomorrow</a>
|
||||
// </div>
|
||||
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
||||
// </div>
|
||||
var cal_box = document.createElement('div');
|
||||
cal_box.style.display = 'none';
|
||||
cal_box.style.position = 'absolute';
|
||||
cal_box.style.left = findPosX(cal_link) + 17 + 'px';
|
||||
cal_box.style.top = findPosY(cal_link) - 75 + 'px';
|
||||
cal_box.className = 'calendarbox module';
|
||||
cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num);
|
||||
document.body.appendChild(cal_box);
|
||||
addEvent(cal_box, 'click', DateTimeShortcuts.cancelEventPropagation);
|
||||
|
||||
// next-prev links
|
||||
var cal_nav = quickElement('div', cal_box, '');
|
||||
quickElement('a', cal_nav, '<', 'class', 'calendarnav-previous', 'href', 'javascript:DateTimeShortcuts.drawPrev('+num+');');
|
||||
quickElement('a', cal_nav, '>', 'class', 'calendarnav-next', 'href', 'javascript:DateTimeShortcuts.drawNext('+num+');');
|
||||
cal_box.appendChild(cal_nav);
|
||||
|
||||
// main box
|
||||
var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
|
||||
cal_main.className = 'calendar';
|
||||
DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));
|
||||
DateTimeShortcuts.calendars[num].drawCurrent();
|
||||
|
||||
// calendar shortcuts
|
||||
var shortcuts = quickElement('div', cal_box, '', 'class', 'calendar-shortcuts');
|
||||
quickElement('a', shortcuts, 'Yesterday', 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);');
|
||||
shortcuts.appendChild(document.createTextNode('\240|\240'));
|
||||
quickElement('a', shortcuts, 'Today', 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);');
|
||||
shortcuts.appendChild(document.createTextNode('\240|\240'));
|
||||
quickElement('a', shortcuts, 'Tomorrow', 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);');
|
||||
|
||||
// cancel bar
|
||||
var cancel_p = quickElement('p', cal_box, '', 'class', 'calendar-cancel');
|
||||
quickElement('a', cancel_p, 'Cancel', 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
|
||||
},
|
||||
|
||||
openCalendar: function(num) {
|
||||
document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'block';
|
||||
addEvent(window, 'click', function() { DateTimeShortcuts.dismissCalendar(num); return true; });
|
||||
},
|
||||
|
||||
dismissCalendar: function(num) {
|
||||
document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'none';
|
||||
window.onclick = null;
|
||||
},
|
||||
|
||||
drawPrev: function(num) {
|
||||
DateTimeShortcuts.calendars[num].drawPreviousMonth();
|
||||
},
|
||||
|
||||
drawNext: function(num) {
|
||||
DateTimeShortcuts.calendars[num].drawNextMonth();
|
||||
},
|
||||
|
||||
handleCalendarCallback: function(num) {
|
||||
return "function(y, m, d) { DateTimeShortcuts.calendarInputs["+num+"].value = y+'-'+m+'-'+d; document.getElementById(DateTimeShortcuts.calendarDivName1+"+num+").style.display='none';}";
|
||||
},
|
||||
|
||||
handleCalendarQuickLink: function(num, offset) {
|
||||
var d = new Date();
|
||||
d.setDate(d.getDate() + offset)
|
||||
DateTimeShortcuts.calendarInputs[num].value = d.getISODate();
|
||||
DateTimeShortcuts.dismissCalendar(num);
|
||||
},
|
||||
|
||||
cancelEventPropagation: function(e) {
|
||||
if (!e) var e = window.event;
|
||||
e.cancelBubble = true;
|
||||
if (e.stripPropagation) e.stopPropagation();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addEvent(window, 'load', DateTimeShortcuts.init);
|
33
media/js/admin/RelatedObjectLookups.js
Normal file
@ -0,0 +1,33 @@
|
||||
// Handles related-objects functionality: lookup link for raw_id_admin=True
|
||||
// and Add Another links.
|
||||
|
||||
function showRelatedObjectLookupPopup(triggeringLink) {
|
||||
var name = triggeringLink.id.replace(/^lookup_/, '');
|
||||
var win = window.open(triggeringLink.href + '?pop=1', name, 'height=500,width=740,resizable=yes,scrollbars=yes');
|
||||
win.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
function dismissRelatedLookupPopup(win, chosenId) {
|
||||
document.getElementById(win.name).value = chosenId;
|
||||
win.close();
|
||||
}
|
||||
|
||||
function showAddAnotherPopup(triggeringLink) {
|
||||
var name = triggeringLink.id.replace(/^add_/, '');
|
||||
var win = window.open(triggeringLink.href + '?_popup=1', name, 'height=500,width=800,resizable=yes,scrollbars=yes');
|
||||
win.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
function dismissAddAnotherPopup(win, newId, newRepr) {
|
||||
var elem = document.getElementById(win.name);
|
||||
if (elem.nodeName == 'SELECT') {
|
||||
var o = new Option(newRepr, newId);
|
||||
elem.appendChild(o);
|
||||
elem.selectedIndex = elem.length - 1;
|
||||
} else if (elem.nodeName == 'INPUT') {
|
||||
elem.value = newId;
|
||||
}
|
||||
win.close();
|
||||
}
|
158
media/js/admin/add_calendars.js
Normal file
@ -0,0 +1,158 @@
|
||||
// Finds all <input type="text" class="vDateField"> and inserts a calendar after them
|
||||
|
||||
// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]);
|
||||
function quickElement() {
|
||||
var obj = document.createElement(arguments[0]);
|
||||
if (arguments[2] != '' && arguments[2] != null) {
|
||||
var textNode = document.createTextNode(arguments[2]);
|
||||
obj.appendChild(textNode);
|
||||
}
|
||||
for (var i = 3; i < arguments.length; i += 2) {
|
||||
obj.setAttribute(arguments[i], arguments[i+1]);
|
||||
}
|
||||
arguments[1].appendChild(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
// findPosX / findPosY: see http://www.quirksmode.org/js/findpos.html
|
||||
function findPosX(obj)
|
||||
{
|
||||
var curleft = 0;
|
||||
if (obj.offsetParent)
|
||||
{
|
||||
while (obj.offsetParent)
|
||||
{
|
||||
curleft += obj.offsetLeft
|
||||
obj = obj.offsetParent;
|
||||
}
|
||||
}
|
||||
else if (obj.x)
|
||||
curleft += obj.x;
|
||||
return curleft;
|
||||
}
|
||||
|
||||
function findPosY(obj)
|
||||
{
|
||||
var curtop = 0;
|
||||
if (obj.offsetParent)
|
||||
{
|
||||
while (obj.offsetParent)
|
||||
{
|
||||
curtop += obj.offsetTop
|
||||
obj = obj.offsetParent;
|
||||
}
|
||||
}
|
||||
else if (obj.y)
|
||||
curtop += obj.y;
|
||||
return curtop;
|
||||
}
|
||||
|
||||
var AddCal = {
|
||||
cals: [],
|
||||
inps: [],
|
||||
divname1: 'calendarbox', // name of <div> that gets toggled
|
||||
divname2: 'calendarin', // name of <div> that contains calendar
|
||||
init: function() {
|
||||
var inputs = document.getElementsByTagName('input');
|
||||
for (var i=0; i < inputs.length; i++) {
|
||||
var inp = inputs[i];
|
||||
if (inp.getAttribute('type') == 'text' && inp.className.match(/vDateField/)) {
|
||||
var num = AddCal.cals.length;
|
||||
|
||||
AddCal.inps[num] = inp;
|
||||
|
||||
// <a href="javascript:AddCal.toggle()">Calendar</a>
|
||||
var cal_link = document.createElement('a');
|
||||
cal_link.setAttribute('href', 'javascript:AddCal.toggle(' + num + ');');
|
||||
quickElement('img', cal_link, '', 'src', 'http://media.ljworld.com/img/admin/icon_calendar.gif', 'alt', 'Calendar');
|
||||
inp.parentNode.insertBefore(cal_link, inp.nextSibling);
|
||||
|
||||
// Markup looks like:
|
||||
//
|
||||
// <div id="calendarbox3" class="calendarbox module">
|
||||
// <h2>
|
||||
// <a href="#" class="link-previous">‹</a>
|
||||
// <a href="#" class="link-next">›</a> February 2003
|
||||
// </h2>
|
||||
// <div class="calendar" id="calendarin3">
|
||||
// <!-- (cal) -->
|
||||
// </div>
|
||||
// <div class="calendar-shortcuts">
|
||||
// <a href="#">Yesterday</a> | <a href="#">Today</a> | <a href="#">Tomorrow</a>
|
||||
// </div>
|
||||
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
||||
// </div>
|
||||
var cal_box = document.createElement('div');
|
||||
cal_box.style.display = 'none';
|
||||
cal_box.style.position = 'absolute';
|
||||
cal_box.style.left = findPosX(cal_link) + 17 + 'px';
|
||||
cal_box.style.top = findPosY(cal_link) - 75 + 'px';
|
||||
cal_box.className = 'calendarbox module';
|
||||
cal_box.setAttribute('id', AddCal.divname1 + num);
|
||||
|
||||
// next-prev links
|
||||
var cal_nav = quickElement('div', cal_box, '');
|
||||
quickElement('a', cal_nav, '<', 'class', 'calendarnav-previous', 'href', 'javascript:AddCal.drawPrev('+num+');');
|
||||
quickElement('a', cal_nav, '>', 'class', 'calendarnav-next', 'href', 'javascript:AddCal.drawNext('+num+');');
|
||||
cal_box.appendChild(cal_nav);
|
||||
|
||||
// main box
|
||||
var cal_main = quickElement('div', cal_box, '', 'id', AddCal.divname2 + num);
|
||||
cal_main.className = 'calendar';
|
||||
document.body.appendChild(cal_box);
|
||||
AddCal.cals[num] = new Calendar(AddCal.divname2 + num, AddCal.handleCallback(num));
|
||||
AddCal.cals[num].drawCurrent();
|
||||
|
||||
// calendar shortcuts
|
||||
var shortcuts = quickElement('div', cal_box, '', 'class', 'calendar-shortcuts');
|
||||
quickElement('a', shortcuts, 'Yesterday', 'href', 'javascript:AddCal.handleQuickLink(' + num + ', -1);');
|
||||
shortcuts.appendChild(document.createTextNode('\240|\240'));
|
||||
quickElement('a', shortcuts, 'Today', 'href', 'javascript:AddCal.handleQuickLink(' + num + ', 0);');
|
||||
shortcuts.appendChild(document.createTextNode('\240|\240'));
|
||||
quickElement('a', shortcuts, 'Tomorrow', 'href', 'javascript:AddCal.handleQuickLink(' + num + ', +1);');
|
||||
|
||||
// cancel bar
|
||||
var cancel_p = quickElement('p', cal_box, '', 'class', 'calendar-cancel');
|
||||
quickElement('a', cancel_p, 'Cancel', 'href', 'javascript:AddCal.toggle(' + num + ');');
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
toggle: function(num) {
|
||||
var box = document.getElementById(AddCal.divname1+num);
|
||||
box.style.display = (box.style.display == 'none') ? 'block' : 'none';
|
||||
/*
|
||||
if (box.style.display = 'block') {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
if (!e) var e = window.event;
|
||||
if (e.pageX || e.pageY) {
|
||||
x = e.pageX;
|
||||
y = e.pageY;
|
||||
} else if (e.clientX || e.clientY) {
|
||||
x = e.clientX + document.body.scrollLeft;
|
||||
y = e.clientY + document.body.scrollTop;
|
||||
}
|
||||
box.style.left = x;
|
||||
box.style.top = y;
|
||||
}
|
||||
*/
|
||||
},
|
||||
drawPrev: function(num) {
|
||||
AddCal.cals[num].drawPreviousMonth();
|
||||
},
|
||||
drawNext: function(num) {
|
||||
AddCal.cals[num].drawNextMonth();
|
||||
},
|
||||
handleCallback: function(num) {
|
||||
return "function(y, m, d) { AddCal.inps["+num+"].value = y+'-'+m+'-'+d; document.getElementById(AddCal.divname1+"+num+").style.display='none';}";
|
||||
},
|
||||
handleQuickLink: function(num, offset) {
|
||||
var d = new Date();
|
||||
d.setDate(d.getDate() + offset)
|
||||
AddCal.inps[num].value = d.getISODate();
|
||||
AddCal.toggle(num);
|
||||
}
|
||||
}
|
||||
addEvent(window, 'load', AddCal.init);
|
137
media/js/admin/ordering.js
Normal file
@ -0,0 +1,137 @@
|
||||
addEvent(window, 'load', reorder_init);
|
||||
|
||||
var lis;
|
||||
var top = 90;
|
||||
var left = 545;
|
||||
var height = 30;
|
||||
|
||||
function reorder_init() {
|
||||
lis = document.getElementsBySelector('ul#orderthese li');
|
||||
var input = document.getElementsBySelector('input[name=order_]')[0];
|
||||
setOrder(input.value.split(','));
|
||||
input.disabled = true;
|
||||
draw();
|
||||
// Now initialise the dragging behaviour
|
||||
var limit = (lis.length - 1) * height;
|
||||
for (var i = 0; i < lis.length; i++) {
|
||||
var li = lis[i];
|
||||
var img = document.getElementById('handle'+li.id);
|
||||
li.style.zIndex = 1;
|
||||
Drag.init(img, li, left + 10, left + 10, top + 10, top + 10 + limit);
|
||||
li.onDragStart = startDrag;
|
||||
li.onDragEnd = endDrag;
|
||||
img.style.cursor = 'move';
|
||||
}
|
||||
}
|
||||
|
||||
function submitOrderForm() {
|
||||
var inputOrder = document.getElementsBySelector('input[name=order_]')[0];
|
||||
inputOrder.value = getOrder();
|
||||
inputOrder.disabled=false;
|
||||
}
|
||||
|
||||
function startDrag() {
|
||||
this.style.zIndex = '10';
|
||||
this.className = 'dragging';
|
||||
}
|
||||
|
||||
function endDrag(x, y) {
|
||||
this.style.zIndex = '1';
|
||||
this.className = '';
|
||||
// Work out how far along it has been dropped, using x co-ordinate
|
||||
var oldIndex = this.index;
|
||||
var newIndex = Math.round((y - 10 - top) / height);
|
||||
// 'Snap' to the correct position
|
||||
this.style.top = (10 + top + newIndex * height) + 'px';
|
||||
this.index = newIndex;
|
||||
moveItem(oldIndex, newIndex);
|
||||
}
|
||||
|
||||
function moveItem(oldIndex, newIndex) {
|
||||
// Swaps two items, adjusts the index and left co-ord for all others
|
||||
if (oldIndex == newIndex) {
|
||||
return; // Nothing to swap;
|
||||
}
|
||||
var direction, lo, hi;
|
||||
if (newIndex > oldIndex) {
|
||||
lo = oldIndex;
|
||||
hi = newIndex;
|
||||
direction = -1;
|
||||
} else {
|
||||
direction = 1;
|
||||
hi = oldIndex;
|
||||
lo = newIndex;
|
||||
}
|
||||
var lis2 = new Array(); // We will build the new order in this array
|
||||
for (var i = 0; i < lis.length; i++) {
|
||||
if (i < lo || i > hi) {
|
||||
// Position of items not between the indexes is unaffected
|
||||
lis2[i] = lis[i];
|
||||
continue;
|
||||
} else if (i == newIndex) {
|
||||
lis2[i] = lis[oldIndex];
|
||||
continue;
|
||||
} else {
|
||||
// Item is between the two indexes - move it along 1
|
||||
lis2[i] = lis[i - direction];
|
||||
}
|
||||
}
|
||||
// Re-index everything
|
||||
reIndex(lis2);
|
||||
lis = lis2;
|
||||
draw();
|
||||
// document.getElementById('hiddenOrder').value = getOrder();
|
||||
document.getElementsBySelector('input[name=order_]')[0].value = getOrder();
|
||||
}
|
||||
|
||||
function reIndex(lis) {
|
||||
for (var i = 0; i < lis.length; i++) {
|
||||
lis[i].index = i;
|
||||
}
|
||||
}
|
||||
|
||||
function draw() {
|
||||
for (var i = 0; i < lis.length; i++) {
|
||||
var li = lis[i];
|
||||
li.index = i;
|
||||
li.style.position = 'absolute';
|
||||
li.style.left = (10 + left) + 'px';
|
||||
li.style.top = (10 + top + (i * height)) + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
function getOrder() {
|
||||
var order = new Array(lis.length);
|
||||
for (var i = 0; i < lis.length; i++) {
|
||||
order[i] = lis[i].id.substring(1, 100);
|
||||
}
|
||||
return order.join(',');
|
||||
}
|
||||
|
||||
function setOrder(id_list) {
|
||||
/* Set the current order to match the lsit of IDs */
|
||||
var temp_lis = new Array();
|
||||
for (var i = 0; i < id_list.length; i++) {
|
||||
var id = 'p' + id_list[i];
|
||||
temp_lis[temp_lis.length] = document.getElementById(id);
|
||||
}
|
||||
reIndex(temp_lis);
|
||||
lis = temp_lis;
|
||||
draw();
|
||||
}
|
||||
|
||||
function addEvent(elm, evType, fn, useCapture)
|
||||
// addEvent and removeEvent
|
||||
// cross-browser event handling for IE5+, NS6 and Mozilla
|
||||
// By Scott Andrew
|
||||
{
|
||||
if (elm.addEventListener){
|
||||
elm.addEventListener(evType, fn, useCapture);
|
||||
return true;
|
||||
} else if (elm.attachEvent){
|
||||
var r = elm.attachEvent("on"+evType, fn);
|
||||
return r;
|
||||
} else {
|
||||
elm['on'+evType] = fn;
|
||||
}
|
||||
}
|
139
media/js/calendar.js
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
calendar.js - Calendar functions by Adrian Holovaty
|
||||
*/
|
||||
|
||||
function removeChildren(a) { // "a" is reference to an object
|
||||
while (a.hasChildNodes()) a.removeChild(a.lastChild);
|
||||
}
|
||||
|
||||
// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]);
|
||||
function quickElement() {
|
||||
var obj = document.createElement(arguments[0]);
|
||||
if (arguments[2] != '' && arguments[2] != null) {
|
||||
var textNode = document.createTextNode(arguments[2]);
|
||||
obj.appendChild(textNode);
|
||||
}
|
||||
var len = arguments.length;
|
||||
for (var i = 3; i < len; i += 2) {
|
||||
obj.setAttribute(arguments[i], arguments[i+1]);
|
||||
}
|
||||
arguments[1].appendChild(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
// CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
|
||||
var CalendarNamespace = {
|
||||
monthsOfYear: 'January February March April May June July August September October November December'.split(' '),
|
||||
daysOfWeek: 'S M T W T F S'.split(' '),
|
||||
isLeapYear: function(year) {
|
||||
return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0));
|
||||
},
|
||||
getDaysInMonth: function(month,year) {
|
||||
var days;
|
||||
if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
|
||||
days = 31;
|
||||
}
|
||||
else if (month==4 || month==6 || month==9 || month==11) {
|
||||
days = 30;
|
||||
}
|
||||
else if (month==2 && CalendarNamespace.isLeapYear(year)) {
|
||||
days = 29;
|
||||
}
|
||||
else {
|
||||
days = 28;
|
||||
}
|
||||
return days;
|
||||
},
|
||||
draw: function(month, year, div_id, callback) { // month = 1-12, year = 1-9999
|
||||
month = parseInt(month);
|
||||
year = parseInt(year);
|
||||
var calDiv = document.getElementById(div_id);
|
||||
removeChildren(calDiv);
|
||||
var calTable = document.createElement('table');
|
||||
quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month-1] + ' ' + year);
|
||||
var tableBody = quickElement('tbody', calTable);
|
||||
|
||||
// Draw days-of-week header
|
||||
var tableRow = quickElement('tr', tableBody);
|
||||
for (var i = 0; i < 7; i++) {
|
||||
quickElement('th', tableRow, CalendarNamespace.daysOfWeek[i]);
|
||||
}
|
||||
|
||||
var startingPos = new Date(year, month-1, 1).getDay();
|
||||
var days = CalendarNamespace.getDaysInMonth(month, year);
|
||||
|
||||
// Draw blanks before first of month
|
||||
tableRow = quickElement('tr', tableBody);
|
||||
for (var i = 0; i < startingPos; i++) {
|
||||
quickElement('td', tableRow, ' ', 'bgcolor','#f3f3f3');
|
||||
}
|
||||
|
||||
// Draw days of month
|
||||
var currentDay = 1;
|
||||
for (var i = startingPos; currentDay <= days; i++) {
|
||||
if (i%7 == 0 && currentDay != 1) {
|
||||
tableRow = quickElement('tr', tableBody);
|
||||
}
|
||||
var cell = quickElement('td', tableRow, '');
|
||||
quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));');
|
||||
currentDay++;
|
||||
}
|
||||
|
||||
// Draw blanks after end of month (optional, but makes for valid code)
|
||||
while (tableRow.childNodes.length < 7) {
|
||||
quickElement('td', tableRow, ' ', 'bgcolor','#f3f3f3');
|
||||
}
|
||||
|
||||
calDiv.appendChild(calTable);
|
||||
}
|
||||
}
|
||||
|
||||
// Calendar -- A calendar instance
|
||||
function Calendar(div_id, callback) {
|
||||
// div_id (string) is the ID of the element in which the calendar will
|
||||
// be displayed
|
||||
// callback (string) is the name of a JavaScript function that will be
|
||||
// called with the parameters (year, month, day) when a day in the
|
||||
// calendar is clicked
|
||||
this.div_id = div_id;
|
||||
this.callback = callback;
|
||||
this.today = new Date();
|
||||
this.currentMonth = this.today.getMonth() + 1;
|
||||
this.currentYear = this.today.getFullYear();
|
||||
this.drawCurrent = function() {
|
||||
CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback);
|
||||
}
|
||||
this.drawDate = function(month, year) {
|
||||
this.currentMonth = month;
|
||||
this.currentYear = year;
|
||||
this.drawCurrent();
|
||||
}
|
||||
this.drawPreviousMonth = function() {
|
||||
if (this.currentMonth == 1) {
|
||||
this.currentMonth = 12;
|
||||
this.currentYear--;
|
||||
}
|
||||
else {
|
||||
this.currentMonth--;
|
||||
}
|
||||
this.drawCurrent();
|
||||
}
|
||||
this.drawNextMonth = function() {
|
||||
if (this.currentMonth == 12) {
|
||||
this.currentMonth = 1;
|
||||
this.currentYear++;
|
||||
}
|
||||
else {
|
||||
this.currentMonth++;
|
||||
}
|
||||
this.drawCurrent();
|
||||
}
|
||||
this.drawPreviousYear = function() {
|
||||
this.currentYear--;
|
||||
this.drawCurrent();
|
||||
}
|
||||
this.drawNextYear = function() {
|
||||
this.currentYear++;
|
||||
this.drawCurrent();
|
||||
}
|
||||
}
|
138
media/js/core.js
Normal file
@ -0,0 +1,138 @@
|
||||
// Core javascript helper functions
|
||||
|
||||
// Cross-browser event handlers.
|
||||
function addEvent(obj, evType, fn) {
|
||||
if (obj.addEventListener) {
|
||||
obj.addEventListener(evType, fn, false);
|
||||
return true;
|
||||
} else if (obj.attachEvent) {
|
||||
var r = obj.attachEvent("on" + evType, fn);
|
||||
return r;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function removeEvent(obj, evType, fn) {
|
||||
if (obj.removeEventListener) {
|
||||
obj.removeEventListener(evType, fn, false);
|
||||
return true;
|
||||
} else if (obj.detachEvent) {
|
||||
obj.detachEvent("on" + evType, fn);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]);
|
||||
function quickElement() {
|
||||
var obj = document.createElement(arguments[0]);
|
||||
if (arguments[2] != '' && arguments[2] != null) {
|
||||
var textNode = document.createTextNode(arguments[2]);
|
||||
obj.appendChild(textNode);
|
||||
}
|
||||
var len = arguments.length;
|
||||
for (var i = 3; i < len; i += 2) {
|
||||
obj.setAttribute(arguments[i], arguments[i+1]);
|
||||
}
|
||||
arguments[1].appendChild(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Cross-browser xmlhttp object
|
||||
// from http://jibbering.com/2002/4/httprequest.html
|
||||
// ----------------------------------------------------------------------------
|
||||
var xmlhttp;
|
||||
/*@cc_on @*/
|
||||
/*@if (@_jscript_version >= 5)
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||
} catch (e) {
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch (E) {
|
||||
xmlhttp = false;
|
||||
}
|
||||
}
|
||||
@else
|
||||
xmlhttp = false;
|
||||
@end @*/
|
||||
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
|
||||
xmlhttp = new XMLHttpRequest();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Find-position functions by PPK
|
||||
// See http://www.xs4all.nl/~ppk/js/index.html?/~ppk/js/findpos.html
|
||||
// ----------------------------------------------------------------------------
|
||||
function findPosX(obj) {
|
||||
var curleft = 0;
|
||||
if (obj.offsetParent) {
|
||||
while (obj.offsetParent) {
|
||||
curleft += obj.offsetLeft
|
||||
obj = obj.offsetParent;
|
||||
}
|
||||
} else if (obj.x) {
|
||||
curleft += obj.x;
|
||||
}
|
||||
return curleft;
|
||||
}
|
||||
|
||||
function findPosY(obj) {
|
||||
var curtop = 0;
|
||||
if (obj.offsetParent) {
|
||||
while (obj.offsetParent) {
|
||||
curtop += obj.offsetTop
|
||||
obj = obj.offsetParent;
|
||||
}
|
||||
} else if (obj.y) {
|
||||
curtop += obj.y;
|
||||
}
|
||||
return curtop;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Date object extensions
|
||||
// ----------------------------------------------------------------------------
|
||||
Date.prototype.getCorrectYear = function() {
|
||||
// Date.getYear() is unreliable --
|
||||
// see http://www.quirksmode.org/js/introdate.html#year
|
||||
var y = this.getYear() % 100;
|
||||
return (y < 38) ? y + 2000 : y + 1900;
|
||||
}
|
||||
|
||||
Date.prototype.getTwoDigitMonth = function() {
|
||||
return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1);
|
||||
}
|
||||
|
||||
Date.prototype.getTwoDigitDate = function() {
|
||||
return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();
|
||||
}
|
||||
|
||||
Date.prototype.getTwoDigitHour = function() {
|
||||
return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();
|
||||
}
|
||||
|
||||
Date.prototype.getTwoDigitMinute = function() {
|
||||
return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
|
||||
}
|
||||
|
||||
Date.prototype.getISODate = function() {
|
||||
return this.getCorrectYear() + '-' + this.getTwoDigitMonth() + '-' + this.getTwoDigitDate();
|
||||
}
|
||||
|
||||
Date.prototype.getHourMinute = function() {
|
||||
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// String object extensions
|
||||
// ----------------------------------------------------------------------------
|
||||
String.prototype.pad_left = function(pad_length, pad_string) {
|
||||
new_string = this;
|
||||
for (var i = 0; new_string.length < pad_length; i++) {
|
||||
new_string = pad_string + new_string;
|
||||
}
|
||||
return new_string;
|
||||
}
|
227
media/js/dateparse.js
Normal file
@ -0,0 +1,227 @@
|
||||
/* 'Magic' date parsing, by Simon Willison (6th October 2003)
|
||||
http://simon.incutio.com/archive/2003/10/06/betterDateInput
|
||||
Adapted for 6newslawrence.com, 28th January 2004
|
||||
*/
|
||||
|
||||
/* Finds the index of the first occurence of item in the array, or -1 if not found */
|
||||
Array.prototype.indexOf = function(item) {
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (this[i] == item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
/* Returns an array of items judged 'true' by the passed in test function */
|
||||
Array.prototype.filter = function(test) {
|
||||
var matches = [];
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (test(this[i])) {
|
||||
matches[matches.length] = this[i];
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
};
|
||||
|
||||
var monthNames = "January February March April May June July August September October November December".split(" ");
|
||||
var weekdayNames = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" ");
|
||||
|
||||
/* Takes a string, returns the index of the month matching that string, throws
|
||||
an error if 0 or more than 1 matches
|
||||
*/
|
||||
function parseMonth(month) {
|
||||
var matches = monthNames.filter(function(item) {
|
||||
return new RegExp("^" + month, "i").test(item);
|
||||
});
|
||||
if (matches.length == 0) {
|
||||
throw new Error("Invalid month string");
|
||||
}
|
||||
if (matches.length > 1) {
|
||||
throw new Error("Ambiguous month");
|
||||
}
|
||||
return monthNames.indexOf(matches[0]);
|
||||
}
|
||||
/* Same as parseMonth but for days of the week */
|
||||
function parseWeekday(weekday) {
|
||||
var matches = weekdayNames.filter(function(item) {
|
||||
return new RegExp("^" + weekday, "i").test(item);
|
||||
});
|
||||
if (matches.length == 0) {
|
||||
throw new Error("Invalid day string");
|
||||
}
|
||||
if (matches.length > 1) {
|
||||
throw new Error("Ambiguous weekday");
|
||||
}
|
||||
return weekdayNames.indexOf(matches[0]);
|
||||
}
|
||||
|
||||
/* Array of objects, each has 're', a regular expression and 'handler', a
|
||||
function for creating a date from something that matches the regular
|
||||
expression. Handlers may throw errors if string is unparseable.
|
||||
*/
|
||||
var dateParsePatterns = [
|
||||
// Today
|
||||
{ re: /^tod/i,
|
||||
handler: function() {
|
||||
return new Date();
|
||||
}
|
||||
},
|
||||
// Tomorrow
|
||||
{ re: /^tom/i,
|
||||
handler: function() {
|
||||
var d = new Date();
|
||||
d.setDate(d.getDate() + 1);
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// Yesterday
|
||||
{ re: /^yes/i,
|
||||
handler: function() {
|
||||
var d = new Date();
|
||||
d.setDate(d.getDate() - 1);
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// 4th
|
||||
{ re: /^(\d{1,2})(st|nd|rd|th)?$/i,
|
||||
handler: function(bits) {
|
||||
var d = new Date();
|
||||
d.setDate(parseInt(bits[1], 10));
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// 4th Jan
|
||||
{ re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+)$/i,
|
||||
handler: function(bits) {
|
||||
var d = new Date();
|
||||
d.setDate(parseInt(bits[1], 10));
|
||||
d.setMonth(parseMonth(bits[2]));
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// 4th Jan 2003
|
||||
{ re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+),? (\d{4})$/i,
|
||||
handler: function(bits) {
|
||||
var d = new Date();
|
||||
d.setDate(parseInt(bits[1], 10));
|
||||
d.setMonth(parseMonth(bits[2]));
|
||||
d.setYear(bits[3]);
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// Jan 4th
|
||||
{ re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i,
|
||||
handler: function(bits) {
|
||||
var d = new Date();
|
||||
d.setDate(parseInt(bits[2], 10));
|
||||
d.setMonth(parseMonth(bits[1]));
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// Jan 4th 2003
|
||||
{ re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{4})$/i,
|
||||
handler: function(bits) {
|
||||
var d = new Date();
|
||||
d.setDate(parseInt(bits[2], 10));
|
||||
d.setMonth(parseMonth(bits[1]));
|
||||
d.setYear(bits[3]);
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// next Tuesday - this is suspect due to weird meaning of "next"
|
||||
{ re: /^next (\w+)$/i,
|
||||
handler: function(bits) {
|
||||
var d = new Date();
|
||||
var day = d.getDay();
|
||||
var newDay = parseWeekday(bits[1]);
|
||||
var addDays = newDay - day;
|
||||
if (newDay <= day) {
|
||||
addDays += 7;
|
||||
}
|
||||
d.setDate(d.getDate() + addDays);
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// last Tuesday
|
||||
{ re: /^last (\w+)$/i,
|
||||
handler: function(bits) {
|
||||
throw new Error("Not yet implemented");
|
||||
}
|
||||
},
|
||||
// mm/dd/yyyy (American style)
|
||||
{ re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/,
|
||||
handler: function(bits) {
|
||||
var d = new Date();
|
||||
d.setYear(bits[3]);
|
||||
d.setDate(parseInt(bits[2], 10));
|
||||
d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0
|
||||
return d;
|
||||
}
|
||||
},
|
||||
// yyyy-mm-dd (ISO style)
|
||||
{ re: /(\d{4})-(\d{1,2})-(\d{1,2})/,
|
||||
handler: function(bits) {
|
||||
var d = new Date();
|
||||
d.setYear(parseInt(bits[1]));
|
||||
d.setDate(parseInt(bits[3], 10));
|
||||
d.setMonth(parseInt(bits[2], 10) - 1);
|
||||
return d;
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
function parseDateString(s) {
|
||||
for (var i = 0; i < dateParsePatterns.length; i++) {
|
||||
var re = dateParsePatterns[i].re;
|
||||
var handler = dateParsePatterns[i].handler;
|
||||
var bits = re.exec(s);
|
||||
if (bits) {
|
||||
return handler(bits);
|
||||
}
|
||||
}
|
||||
throw new Error("Invalid date string");
|
||||
}
|
||||
|
||||
function fmt00(x) {
|
||||
// fmt00: Tags leading zero onto numbers 0 - 9.
|
||||
// Particularly useful for displaying results from Date methods.
|
||||
//
|
||||
if (Math.abs(parseInt(x)) < 10){
|
||||
x = "0"+ Math.abs(x);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
function parseDateStringISO(s) {
|
||||
try {
|
||||
var d = parseDateString(s);
|
||||
return d.getFullYear() + '-' + (fmt00(d.getMonth() + 1)) + '-' + fmt00(d.getDate())
|
||||
}
|
||||
catch (e) { return s; }
|
||||
}
|
||||
function magicDate(input) {
|
||||
var messagespan = input.id + 'Msg';
|
||||
try {
|
||||
var d = parseDateString(input.value);
|
||||
input.value = d.getFullYear() + '-' + (fmt00(d.getMonth() + 1)) + '-' +
|
||||
fmt00(d.getDate());
|
||||
input.className = '';
|
||||
// Human readable date
|
||||
if (document.getElementById(messagespan)) {
|
||||
document.getElementById(messagespan).firstChild.nodeValue = d.toDateString();
|
||||
document.getElementById(messagespan).className = 'normal';
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
input.className = 'error';
|
||||
var message = e.message;
|
||||
// Fix for IE6 bug
|
||||
if (message.indexOf('is null or not an object') > -1) {
|
||||
message = 'Invalid date string';
|
||||
}
|
||||
if (document.getElementById(messagespan)) {
|
||||
document.getElementById(messagespan).firstChild.nodeValue = message;
|
||||
document.getElementById(messagespan).className = 'error';
|
||||
}
|
||||
}
|
||||
}
|
167
media/js/getElementsBySelector.js
Normal file
@ -0,0 +1,167 @@
|
||||
/* document.getElementsBySelector(selector)
|
||||
- returns an array of element objects from the current document
|
||||
matching the CSS selector. Selectors can contain element names,
|
||||
class names and ids and can be nested. For example:
|
||||
|
||||
elements = document.getElementsBySelect('div#main p a.external')
|
||||
|
||||
Will return an array of all 'a' elements with 'external' in their
|
||||
class attribute that are contained inside 'p' elements that are
|
||||
contained inside the 'div' element which has id="main"
|
||||
|
||||
New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
|
||||
See http://www.w3.org/TR/css3-selectors/#attribute-selectors
|
||||
|
||||
Version 0.4 - Simon Willison, March 25th 2003
|
||||
-- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
|
||||
-- Opera 7 fails
|
||||
*/
|
||||
|
||||
function getAllChildren(e) {
|
||||
// Returns all children of element. Workaround required for IE5/Windows. Ugh.
|
||||
return e.all ? e.all : e.getElementsByTagName('*');
|
||||
}
|
||||
|
||||
document.getElementsBySelector = function(selector) {
|
||||
// Attempt to fail gracefully in lesser browsers
|
||||
if (!document.getElementsByTagName) {
|
||||
return new Array();
|
||||
}
|
||||
// Split selector in to tokens
|
||||
var tokens = selector.split(' ');
|
||||
var currentContext = new Array(document);
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
|
||||
if (token.indexOf('#') > -1) {
|
||||
// Token is an ID selector
|
||||
var bits = token.split('#');
|
||||
var tagName = bits[0];
|
||||
var id = bits[1];
|
||||
var element = document.getElementById(id);
|
||||
if (tagName && element.nodeName.toLowerCase() != tagName) {
|
||||
// tag with that ID not found, return false
|
||||
return new Array();
|
||||
}
|
||||
// Set currentContext to contain just this element
|
||||
currentContext = new Array(element);
|
||||
continue; // Skip to next token
|
||||
}
|
||||
if (token.indexOf('.') > -1) {
|
||||
// Token contains a class selector
|
||||
var bits = token.split('.');
|
||||
var tagName = bits[0];
|
||||
var className = bits[1];
|
||||
if (!tagName) {
|
||||
tagName = '*';
|
||||
}
|
||||
// Get elements matching tag, filter them for class selector
|
||||
var found = new Array;
|
||||
var foundCount = 0;
|
||||
for (var h = 0; h < currentContext.length; h++) {
|
||||
var elements;
|
||||
if (tagName == '*') {
|
||||
elements = getAllChildren(currentContext[h]);
|
||||
} else {
|
||||
try {
|
||||
elements = currentContext[h].getElementsByTagName(tagName);
|
||||
}
|
||||
catch(e) {
|
||||
elements = [];
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < elements.length; j++) {
|
||||
found[foundCount++] = elements[j];
|
||||
}
|
||||
}
|
||||
currentContext = new Array;
|
||||
var currentContextIndex = 0;
|
||||
for (var k = 0; k < found.length; k++) {
|
||||
if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
|
||||
currentContext[currentContextIndex++] = found[k];
|
||||
}
|
||||
}
|
||||
continue; // Skip to next token
|
||||
}
|
||||
// Code to deal with attribute selectors
|
||||
if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
|
||||
var tagName = RegExp.$1;
|
||||
var attrName = RegExp.$2;
|
||||
var attrOperator = RegExp.$3;
|
||||
var attrValue = RegExp.$4;
|
||||
if (!tagName) {
|
||||
tagName = '*';
|
||||
}
|
||||
// Grab all of the tagName elements within current context
|
||||
var found = new Array;
|
||||
var foundCount = 0;
|
||||
for (var h = 0; h < currentContext.length; h++) {
|
||||
var elements;
|
||||
if (tagName == '*') {
|
||||
elements = getAllChildren(currentContext[h]);
|
||||
} else {
|
||||
elements = currentContext[h].getElementsByTagName(tagName);
|
||||
}
|
||||
for (var j = 0; j < elements.length; j++) {
|
||||
found[foundCount++] = elements[j];
|
||||
}
|
||||
}
|
||||
currentContext = new Array;
|
||||
var currentContextIndex = 0;
|
||||
var checkFunction; // This function will be used to filter the elements
|
||||
switch (attrOperator) {
|
||||
case '=': // Equality
|
||||
checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
|
||||
break;
|
||||
case '~': // Match one of space seperated words
|
||||
checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
|
||||
break;
|
||||
case '|': // Match start with value followed by optional hyphen
|
||||
checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
|
||||
break;
|
||||
case '^': // Match starts with value
|
||||
checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
|
||||
break;
|
||||
case '$': // Match ends with value - fails with "Warning" in Opera 7
|
||||
checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
|
||||
break;
|
||||
case '*': // Match ends with value
|
||||
checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
|
||||
break;
|
||||
default :
|
||||
// Just test for existence of attribute
|
||||
checkFunction = function(e) { return e.getAttribute(attrName); };
|
||||
}
|
||||
currentContext = new Array;
|
||||
var currentContextIndex = 0;
|
||||
for (var k = 0; k < found.length; k++) {
|
||||
if (checkFunction(found[k])) {
|
||||
currentContext[currentContextIndex++] = found[k];
|
||||
}
|
||||
}
|
||||
// alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
|
||||
continue; // Skip to next token
|
||||
}
|
||||
// If we get here, token is JUST an element (not a class or ID selector)
|
||||
tagName = token;
|
||||
var found = new Array;
|
||||
var foundCount = 0;
|
||||
for (var h = 0; h < currentContext.length; h++) {
|
||||
var elements = currentContext[h].getElementsByTagName(tagName);
|
||||
for (var j = 0; j < elements.length; j++) {
|
||||
found[foundCount++] = elements[j];
|
||||
}
|
||||
}
|
||||
currentContext = found;
|
||||
}
|
||||
return currentContext;
|
||||
}
|
||||
|
||||
/* That revolting regular expression explained
|
||||
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
|
||||
\---/ \---/\-------------/ \-------/
|
||||
| | | |
|
||||
| | | The value
|
||||
| | ~,|,^,$,* or =
|
||||
| Attribute
|
||||
Tag
|
||||
*/
|
94
media/js/timeparse.js
Normal file
@ -0,0 +1,94 @@
|
||||
var timeParsePatterns = [
|
||||
// 9
|
||||
{ re: /^\d{1,2}$/i,
|
||||
handler: function(bits) {
|
||||
if (bits[0].length == 1) {
|
||||
return '0' + bits[0] + ':00';
|
||||
} else {
|
||||
return bits[0] + ':00';
|
||||
}
|
||||
}
|
||||
},
|
||||
// 13:00
|
||||
{ re: /^\d{2}[:.]\d{2}$/i,
|
||||
handler: function(bits) {
|
||||
return bits[0].replace('.', ':');
|
||||
}
|
||||
},
|
||||
// 9:00
|
||||
{ re: /^\d[:.]\d{2}$/i,
|
||||
handler: function(bits) {
|
||||
return '0' + bits[0].replace('.', ':');
|
||||
}
|
||||
},
|
||||
// 3 am / 3 a.m. / 3am
|
||||
{ re: /^(\d+)\s*([ap])(?:.?m.?)?$/i,
|
||||
handler: function(bits) {
|
||||
var hour = parseInt(bits[1]);
|
||||
if (hour == 12) {
|
||||
hour = 0;
|
||||
}
|
||||
if (bits[2].toLowerCase() == 'p') {
|
||||
if (hour == 12) {
|
||||
hour = 0;
|
||||
}
|
||||
return (hour + 12) + ':00';
|
||||
} else {
|
||||
if (hour < 10) {
|
||||
return '0' + hour + ':00';
|
||||
} else {
|
||||
return hour + ':00';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 3.30 am / 3:15 a.m. / 3.00am
|
||||
{ re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i,
|
||||
handler: function(bits) {
|
||||
var hour = parseInt(bits[1]);
|
||||
var mins = parseInt(bits[2]);
|
||||
if (mins < 10) {
|
||||
mins = '0' + mins;
|
||||
}
|
||||
if (hour == 12) {
|
||||
hour = 0;
|
||||
}
|
||||
if (bits[3].toLowerCase() == 'p') {
|
||||
if (hour == 12) {
|
||||
hour = 0;
|
||||
}
|
||||
return (hour + 12) + ':' + mins;
|
||||
} else {
|
||||
if (hour < 10) {
|
||||
return '0' + hour + ':' + mins;
|
||||
} else {
|
||||
return hour + ':' + mins;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// noon
|
||||
{ re: /^no/i,
|
||||
handler: function(bits) {
|
||||
return '12:00';
|
||||
}
|
||||
},
|
||||
// midnight
|
||||
{ re: /^mid/i,
|
||||
handler: function(bits) {
|
||||
return '00:00';
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function parseTimeString(s) {
|
||||
for (var i = 0; i < timeParsePatterns.length; i++) {
|
||||
var re = timeParsePatterns[i].re;
|
||||
var handler = timeParsePatterns[i].handler;
|
||||
var bits = re.exec(s);
|
||||
if (bits) {
|
||||
return handler(bits);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
16
media/js/urlify.js
Normal file
@ -0,0 +1,16 @@
|
||||
function URLify(s, num_chars) {
|
||||
// changes, e.g., "Petty theft" to "petty_theft"
|
||||
|
||||
// remove all these words from the string before urlifying
|
||||
removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from",
|
||||
"is", "in", "into", "like", "of", "off", "on", "onto", "per",
|
||||
"since", "than", "the", "this", "that", "to", "up", "via",
|
||||
"with"];
|
||||
r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi');
|
||||
s = s.replace(r, '');
|
||||
s = s.replace(/[^\w\s]/g, ''); // remove unneeded chars
|
||||
s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
|
||||
s = s.replace(/\s+/g, '_'); // convert spaces to underscores
|
||||
s = s.toLowerCase(); // convert to lowercase
|
||||
return s.substring(0, num_chars);// trim to first num_chars chars
|
||||
}
|