mirror of https://github.com/django/django.git
Fixed #22463 -- Added code style guide and JavaScript linting (EditorConfig and ESLint)
This commit is contained in:
parent
1e63652e44
commit
ec4f219ecb
|
@ -0,0 +1,37 @@
|
||||||
|
# http://editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
# Use 2 spaces for the HTML files
|
||||||
|
[*.html]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# The JSON files contain newlines inconsistently
|
||||||
|
[*.json]
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = ignore
|
||||||
|
|
||||||
|
[**/admin/js/vendor/**]
|
||||||
|
indent_style = ignore
|
||||||
|
indent_size = ignore
|
||||||
|
|
||||||
|
# Minified JavaScript files shouldn't be changed
|
||||||
|
[**.min.js]
|
||||||
|
indent_style = ignore
|
||||||
|
insert_final_newline = ignore
|
||||||
|
|
||||||
|
# Makefiles always use tabs for indentation
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
# Batch files use tabs for indentation
|
||||||
|
[*.bat]
|
||||||
|
indent_style = tab
|
|
@ -0,0 +1,3 @@
|
||||||
|
**/{*.min,jquery}.js
|
||||||
|
django/contrib/gis/templates/**/*.js
|
||||||
|
node_modules/**.js
|
|
@ -0,0 +1,51 @@
|
||||||
|
{
|
||||||
|
"rules": {
|
||||||
|
"camelcase": [1, {"properties": "always"}],
|
||||||
|
"comma-spacing": [1, {"before": false, "after": true}],
|
||||||
|
"dot-notation": [1, {"allowKeywords": true}],
|
||||||
|
"curly": [1, "all"],
|
||||||
|
"indent": [
|
||||||
|
2,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"key-spacing": [1, {
|
||||||
|
"beforeColon": false,
|
||||||
|
"afterColon": true
|
||||||
|
}],
|
||||||
|
"new-cap": [1, {"newIsCap": true, "capIsNew": true}],
|
||||||
|
"no-alert": [0],
|
||||||
|
"no-eval": [1],
|
||||||
|
"no-extend-native": [2, {"exceptions": ["Date", "String"]}],
|
||||||
|
"no-multi-spaces": [1],
|
||||||
|
"no-octal-escape": [1],
|
||||||
|
"no-underscore-dangle": [1],
|
||||||
|
"no-unused-vars": [2, {"vars": "local", "args": "none"}],
|
||||||
|
"no-script-url": [1],
|
||||||
|
"no-shadow": [1, {"hoist": "functions"}],
|
||||||
|
"quotes": [
|
||||||
|
1,
|
||||||
|
"single"
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
2,
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"semi": [
|
||||||
|
2,
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"space-before-blocks": [2, "always"],
|
||||||
|
"space-before-function-paren": [1, {"anonymous": "always", "named": "never"}],
|
||||||
|
"space-infix-ops": [
|
||||||
|
1,
|
||||||
|
{"int32Hint": false}
|
||||||
|
],
|
||||||
|
"strict": [1, "function"]
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"browser": true
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"django": false
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ MANIFEST
|
||||||
dist/
|
dist/
|
||||||
docs/_build/
|
docs/_build/
|
||||||
docs/locale/
|
docs/locale/
|
||||||
|
node_modules/
|
||||||
tests/coverage_html/
|
tests/coverage_html/
|
||||||
tests/.coverage
|
tests/.coverage
|
||||||
build/
|
build/
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
/*eslint no-cond-assign:1*/
|
||||||
var SelectBox = {
|
var SelectBox = {
|
||||||
cache: new Object(),
|
cache: {},
|
||||||
init: function(id) {
|
init: function(id) {
|
||||||
var box = document.getElementById(id);
|
var box = document.getElementById(id);
|
||||||
var node;
|
var node;
|
||||||
SelectBox.cache[id] = new Array();
|
SelectBox.cache[id] = [];
|
||||||
var cache = SelectBox.cache[id];
|
var cache = SelectBox.cache[id];
|
||||||
for (var i = 0; (node = box.options[i]); i++) {
|
for (var i = 0; (node = box.options[i]); i++) {
|
||||||
cache.push({value: node.value, text: node.text, displayed: 1});
|
cache.push({value: node.value, text: node.text, displayed: 1});
|
||||||
|
@ -31,7 +32,7 @@ var SelectBox = {
|
||||||
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
||||||
node.displayed = 1;
|
node.displayed = 1;
|
||||||
for (var j = 0; (token = tokens[j]); j++) {
|
for (var j = 0; (token = tokens[j]); j++) {
|
||||||
if (node.text.toLowerCase().indexOf(token) == -1) {
|
if (node.text.toLowerCase().indexOf(token) === -1) {
|
||||||
node.displayed = 0;
|
node.displayed = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,13 +42,13 @@ var SelectBox = {
|
||||||
delete_from_cache: function(id, value) {
|
delete_from_cache: function(id, value) {
|
||||||
var node, delete_index = null;
|
var node, delete_index = null;
|
||||||
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
||||||
if (node.value == value) {
|
if (node.value === value) {
|
||||||
delete_index = i;
|
delete_index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var j = SelectBox.cache[id].length - 1;
|
var j = SelectBox.cache[id].length - 1;
|
||||||
for (var i = delete_index; i < j; i++) {
|
for (i = delete_index; i < j; i++) {
|
||||||
SelectBox.cache[id][i] = SelectBox.cache[id][i+1];
|
SelectBox.cache[id][i] = SelectBox.cache[id][i+1];
|
||||||
}
|
}
|
||||||
SelectBox.cache[id].length--;
|
SelectBox.cache[id].length--;
|
||||||
|
@ -59,7 +60,7 @@ var SelectBox = {
|
||||||
// Check if an item is contained in the cache
|
// Check if an item is contained in the cache
|
||||||
var node;
|
var node;
|
||||||
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
|
||||||
if (node.value == value) {
|
if (node.value === value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +68,6 @@ var SelectBox = {
|
||||||
},
|
},
|
||||||
move: function(from, to) {
|
move: function(from, to) {
|
||||||
var from_box = document.getElementById(from);
|
var from_box = document.getElementById(from);
|
||||||
var to_box = document.getElementById(to);
|
|
||||||
var option;
|
var option;
|
||||||
for (var i = 0; (option = from_box.options[i]); i++) {
|
for (var i = 0; (option = from_box.options[i]); i++) {
|
||||||
if (option.selected && SelectBox.cache_contains(from, option.value)) {
|
if (option.selected && SelectBox.cache_contains(from, option.value)) {
|
||||||
|
@ -80,7 +80,6 @@ var SelectBox = {
|
||||||
},
|
},
|
||||||
move_all: function(from, to) {
|
move_all: function(from, to) {
|
||||||
var from_box = document.getElementById(from);
|
var from_box = document.getElementById(from);
|
||||||
var to_box = document.getElementById(to);
|
|
||||||
var option;
|
var option;
|
||||||
for (var i = 0; (option = from_box.options[i]); i++) {
|
for (var i = 0; (option = from_box.options[i]); i++) {
|
||||||
if (SelectBox.cache_contains(from, option.value)) {
|
if (SelectBox.cache_contains(from, option.value)) {
|
||||||
|
@ -111,4 +110,4 @@ var SelectBox = {
|
||||||
box.options[i].selected = 'selected';
|
box.options[i].selected = 'selected';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,196 +1,197 @@
|
||||||
|
/*global SelectBox, addEvent, gettext, interpolate, quickElement, SelectFilter*/
|
||||||
/*
|
/*
|
||||||
SelectFilter2 - Turns a multiple-select box into a filter interface.
|
SelectFilter2 - Turns a multiple-select box into a filter interface.
|
||||||
|
|
||||||
Requires core.js, SelectBox.js and addevent.js.
|
Requires core.js, SelectBox.js and addevent.js.
|
||||||
*/
|
*/
|
||||||
(function($) {
|
(function($) {
|
||||||
function findForm(node) {
|
function findForm(node) {
|
||||||
// returns the node of the form containing the given node
|
// returns the node of the form containing the given node
|
||||||
if (node.tagName.toLowerCase() != 'form') {
|
if (node.tagName.toLowerCase() !== 'form') {
|
||||||
return findForm(node.parentNode);
|
return findForm(node.parentNode);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.SelectFilter = {
|
window.SelectFilter = {
|
||||||
init: function(field_id, field_name, is_stacked) {
|
init: function(field_id, field_name, is_stacked) {
|
||||||
if (field_id.match(/__prefix__/)){
|
if (field_id.match(/__prefix__/)) {
|
||||||
// Don't initialize on empty forms.
|
// Don't initialize on empty forms.
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
var from_box = document.getElementById(field_id);
|
|
||||||
from_box.id += '_from'; // change its ID
|
|
||||||
from_box.className = 'filtered';
|
|
||||||
|
|
||||||
var ps = from_box.parentNode.getElementsByTagName('p');
|
|
||||||
for (var i=0; i<ps.length; i++) {
|
|
||||||
if (ps[i].className.indexOf("info") != -1) {
|
|
||||||
// Remove <p class="info">, because it just gets in the way.
|
|
||||||
from_box.parentNode.removeChild(ps[i]);
|
|
||||||
} else if (ps[i].className.indexOf("help") != -1) {
|
|
||||||
// Move help text up to the top so it isn't below the select
|
|
||||||
// boxes or wrapped off on the side to the right of the add
|
|
||||||
// button:
|
|
||||||
from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild);
|
|
||||||
}
|
}
|
||||||
}
|
var from_box = document.getElementById(field_id);
|
||||||
|
from_box.id += '_from'; // change its ID
|
||||||
|
from_box.className = 'filtered';
|
||||||
|
|
||||||
// <div class="selector"> or <div class="selector stacked">
|
var ps = from_box.parentNode.getElementsByTagName('p');
|
||||||
var selector_div = quickElement('div', from_box.parentNode);
|
for (var i=0; i<ps.length; i++) {
|
||||||
selector_div.className = is_stacked ? 'selector stacked' : 'selector';
|
if (ps[i].className.indexOf("info") !== -1) {
|
||||||
|
// Remove <p class="info">, because it just gets in the way.
|
||||||
// <div class="selector-available">
|
from_box.parentNode.removeChild(ps[i]);
|
||||||
var selector_available = quickElement('div', selector_div);
|
} else if (ps[i].className.indexOf("help") !== -1) {
|
||||||
selector_available.className = 'selector-available';
|
// Move help text up to the top so it isn't below the select
|
||||||
var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));
|
// boxes or wrapped off on the side to the right of the add
|
||||||
quickElement(
|
// button:
|
||||||
'span', title_available, '',
|
from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild);
|
||||||
'class', 'help help-tooltip help-icon',
|
}
|
||||||
'title', interpolate(
|
|
||||||
gettext(
|
|
||||||
'This is the list of available %s. You may choose some by ' +
|
|
||||||
'selecting them in the box below and then clicking the ' +
|
|
||||||
'"Choose" arrow between the two boxes.'
|
|
||||||
),
|
|
||||||
[field_name]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');
|
|
||||||
filter_p.className = 'selector-filter';
|
|
||||||
|
|
||||||
var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input");
|
|
||||||
|
|
||||||
var search_selector_img = quickElement(
|
|
||||||
'span', search_filter_label, '',
|
|
||||||
'class', 'help-tooltip search-label-icon',
|
|
||||||
'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])
|
|
||||||
);
|
|
||||||
|
|
||||||
filter_p.appendChild(document.createTextNode(' '));
|
|
||||||
|
|
||||||
var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter"));
|
|
||||||
filter_input.id = field_id + '_input';
|
|
||||||
|
|
||||||
selector_available.appendChild(from_box);
|
|
||||||
var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript:void(0);', 'id', field_id + '_add_all_link');
|
|
||||||
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), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript:void(0);', 'id', field_id + '_add_link');
|
|
||||||
add_link.className = 'selector-add';
|
|
||||||
var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript:void(0);', 'id', field_id + '_remove_link');
|
|
||||||
remove_link.className = 'selector-remove';
|
|
||||||
|
|
||||||
// <div class="selector-chosen">
|
|
||||||
var selector_chosen = quickElement('div', selector_div);
|
|
||||||
selector_chosen.className = 'selector-chosen';
|
|
||||||
var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
|
|
||||||
quickElement(
|
|
||||||
'span', title_chosen, '',
|
|
||||||
'class', 'help help-tooltip help-icon',
|
|
||||||
'title', interpolate(
|
|
||||||
gettext(
|
|
||||||
'This is the list of chosen %s. You may remove some by ' +
|
|
||||||
'selecting them in the box below and then clicking the ' +
|
|
||||||
'"Remove" arrow between the two boxes.'
|
|
||||||
),
|
|
||||||
[field_name]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
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, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript:void(0);', 'id', field_id + '_remove_all_link');
|
|
||||||
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(choose_all, 'click', function() { SelectBox.move_all(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
|
|
||||||
addEvent(add_link, 'click', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
|
|
||||||
addEvent(remove_link, 'click', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
|
|
||||||
addEvent(clear_all, 'click', function() { SelectBox.move_all(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
|
|
||||||
addEvent(filter_input, 'keypress', function(e) { SelectFilter.filter_key_press(e, field_id); });
|
|
||||||
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, 'change', function(e) { SelectFilter.refresh_icons(field_id) });
|
|
||||||
addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) });
|
|
||||||
addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
|
|
||||||
addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
|
|
||||||
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');
|
|
||||||
|
|
||||||
if (!is_stacked) {
|
|
||||||
// In horizontal mode, give the same height to the two boxes.
|
|
||||||
var j_from_box = $(from_box);
|
|
||||||
var j_to_box = $(to_box);
|
|
||||||
var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); }
|
|
||||||
if (j_from_box.outerHeight() > 0) {
|
|
||||||
resize_filters(); // This fieldset is already open. Resize now.
|
|
||||||
} else {
|
|
||||||
// This fieldset is probably collapsed. Wait for its 'show' event.
|
|
||||||
j_to_box.closest('fieldset').one('show.fieldset', resize_filters);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Initial icon refresh
|
// <div class="selector"> or <div class="selector stacked">
|
||||||
SelectFilter.refresh_icons(field_id);
|
var selector_div = quickElement('div', from_box.parentNode);
|
||||||
},
|
selector_div.className = is_stacked ? 'selector stacked' : 'selector';
|
||||||
refresh_icons: function(field_id) {
|
|
||||||
var from = $('#' + field_id + '_from');
|
// <div class="selector-available">
|
||||||
var to = $('#' + field_id + '_to');
|
var selector_available = quickElement('div', selector_div);
|
||||||
var is_from_selected = from.find('option:selected').length > 0;
|
selector_available.className = 'selector-available';
|
||||||
var is_to_selected = to.find('option:selected').length > 0;
|
var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));
|
||||||
// Active if at least one item is selected
|
quickElement(
|
||||||
$('#' + field_id + '_add_link').toggleClass('active', is_from_selected);
|
'span', title_available, '',
|
||||||
$('#' + field_id + '_remove_link').toggleClass('active', is_to_selected);
|
'class', 'help help-tooltip help-icon',
|
||||||
// Active if the corresponding box isn't empty
|
'title', interpolate(
|
||||||
$('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0);
|
gettext(
|
||||||
$('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0);
|
'This is the list of available %s. You may choose some by ' +
|
||||||
},
|
'selecting them in the box below and then clicking the ' +
|
||||||
filter_key_press: function(event, field_id) {
|
'"Choose" arrow between the two boxes.'
|
||||||
var from = document.getElementById(field_id + '_from');
|
),
|
||||||
// don't submit form if user pressed Enter
|
[field_name]
|
||||||
if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
|
)
|
||||||
from.selectedIndex = 0;
|
);
|
||||||
|
|
||||||
|
var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');
|
||||||
|
filter_p.className = 'selector-filter';
|
||||||
|
|
||||||
|
var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input');
|
||||||
|
|
||||||
|
quickElement(
|
||||||
|
'span', search_filter_label, '',
|
||||||
|
'class', 'help-tooltip search-label-icon',
|
||||||
|
'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])
|
||||||
|
);
|
||||||
|
|
||||||
|
filter_p.appendChild(document.createTextNode(' '));
|
||||||
|
|
||||||
|
var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter"));
|
||||||
|
filter_input.id = field_id + '_input';
|
||||||
|
|
||||||
|
selector_available.appendChild(from_box);
|
||||||
|
var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript:void(0);', 'id', field_id + '_add_all_link');
|
||||||
|
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), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript:void(0);', 'id', field_id + '_add_link');
|
||||||
|
add_link.className = 'selector-add';
|
||||||
|
var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript:void(0);', 'id', field_id + '_remove_link');
|
||||||
|
remove_link.className = 'selector-remove';
|
||||||
|
|
||||||
|
// <div class="selector-chosen">
|
||||||
|
var selector_chosen = quickElement('div', selector_div);
|
||||||
|
selector_chosen.className = 'selector-chosen';
|
||||||
|
var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
|
||||||
|
quickElement(
|
||||||
|
'span', title_chosen, '',
|
||||||
|
'class', 'help help-tooltip help-icon',
|
||||||
|
'title', interpolate(
|
||||||
|
gettext(
|
||||||
|
'This is the list of chosen %s. You may remove some by ' +
|
||||||
|
'selecting them in the box below and then clicking the ' +
|
||||||
|
'"Remove" arrow between the two boxes.'
|
||||||
|
),
|
||||||
|
[field_name]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
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, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript:void(0);', 'id', field_id + '_remove_all_link');
|
||||||
|
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(choose_all, 'click', function() { SelectBox.move_all(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
|
||||||
|
addEvent(add_link, 'click', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
|
||||||
|
addEvent(remove_link, 'click', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
|
||||||
|
addEvent(clear_all, 'click', function() { SelectBox.move_all(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
|
||||||
|
addEvent(filter_input, 'keypress', function(e) { SelectFilter.filter_key_press(e, field_id); });
|
||||||
|
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, 'change', function(e) { SelectFilter.refresh_icons(field_id); });
|
||||||
|
addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id); });
|
||||||
|
addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
|
||||||
|
addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
|
||||||
|
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');
|
SelectBox.move(field_id + '_from', field_id + '_to');
|
||||||
from.selectedIndex = 0;
|
|
||||||
event.preventDefault()
|
if (!is_stacked) {
|
||||||
return false;
|
// In horizontal mode, give the same height to the two boxes.
|
||||||
|
var j_from_box = $(from_box);
|
||||||
|
var j_to_box = $(to_box);
|
||||||
|
var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); };
|
||||||
|
if (j_from_box.outerHeight() > 0) {
|
||||||
|
resize_filters(); // This fieldset is already open. Resize now.
|
||||||
|
} else {
|
||||||
|
// This fieldset is probably collapsed. Wait for its 'show' event.
|
||||||
|
j_to_box.closest('fieldset').one('show.fieldset', resize_filters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial icon refresh
|
||||||
|
SelectFilter.refresh_icons(field_id);
|
||||||
|
},
|
||||||
|
refresh_icons: function(field_id) {
|
||||||
|
var from = $('#' + field_id + '_from');
|
||||||
|
var to = $('#' + field_id + '_to');
|
||||||
|
var is_from_selected = from.find('option:selected').length > 0;
|
||||||
|
var is_to_selected = to.find('option:selected').length > 0;
|
||||||
|
// Active if at least one item is selected
|
||||||
|
$('#' + field_id + '_add_link').toggleClass('active', is_from_selected);
|
||||||
|
$('#' + field_id + '_remove_link').toggleClass('active', is_to_selected);
|
||||||
|
// Active if the corresponding box isn't empty
|
||||||
|
$('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0);
|
||||||
|
$('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0);
|
||||||
|
},
|
||||||
|
filter_key_press: function(event, field_id) {
|
||||||
|
var 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;
|
||||||
|
event.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filter_key_up: function(event, field_id) {
|
||||||
|
var from = document.getElementById(field_id + '_from');
|
||||||
|
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) {
|
||||||
|
var 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;
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
filter_key_up: function(event, field_id) {
|
|
||||||
var from = document.getElementById(field_id + '_from');
|
|
||||||
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) {
|
|
||||||
var 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})(django.jQuery);
|
})(django.jQuery);
|
||||||
|
|
|
@ -1,144 +1,145 @@
|
||||||
|
/*global _actions_icnt, gettext, interpolate, ngettext*/
|
||||||
(function($) {
|
(function($) {
|
||||||
var lastChecked;
|
var lastChecked;
|
||||||
|
|
||||||
$.fn.actions = function(opts) {
|
$.fn.actions = function(opts) {
|
||||||
var options = $.extend({}, $.fn.actions.defaults, opts);
|
var options = $.extend({}, $.fn.actions.defaults, opts);
|
||||||
var actionCheckboxes = $(this);
|
var actionCheckboxes = $(this);
|
||||||
var list_editable_changed = false;
|
var list_editable_changed = false;
|
||||||
var checker = function(checked) {
|
var showQuestion = function() {
|
||||||
if (checked) {
|
$(options.acrossClears).hide();
|
||||||
showQuestion();
|
$(options.acrossQuestions).show();
|
||||||
} else {
|
$(options.allContainer).hide();
|
||||||
reset();
|
},
|
||||||
}
|
showClear = function() {
|
||||||
$(actionCheckboxes).prop("checked", checked)
|
$(options.acrossClears).show();
|
||||||
.parent().parent().toggleClass(options.selectedClass, checked);
|
$(options.acrossQuestions).hide();
|
||||||
},
|
$(options.actionContainer).toggleClass(options.selectedClass);
|
||||||
updateCounter = function() {
|
$(options.allContainer).show();
|
||||||
var sel = $(actionCheckboxes).filter(":checked").length;
|
$(options.counterContainer).hide();
|
||||||
// _actions_icnt is defined in the generated HTML
|
},
|
||||||
// and contains the total amount of objects in the queryset
|
reset = function() {
|
||||||
$(options.counterContainer).html(interpolate(
|
$(options.acrossClears).hide();
|
||||||
ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
|
$(options.acrossQuestions).hide();
|
||||||
sel: sel,
|
$(options.allContainer).hide();
|
||||||
cnt: _actions_icnt
|
$(options.counterContainer).show();
|
||||||
}, true));
|
},
|
||||||
$(options.allToggle).prop("checked", function() {
|
clearAcross = function() {
|
||||||
var value;
|
reset();
|
||||||
if (sel == actionCheckboxes.length) {
|
$(options.acrossInput).val(0);
|
||||||
value = true;
|
$(options.actionContainer).removeClass(options.selectedClass);
|
||||||
showQuestion();
|
},
|
||||||
} else {
|
checker = function(checked) {
|
||||||
value = false;
|
if (checked) {
|
||||||
clearAcross();
|
showQuestion();
|
||||||
}
|
} else {
|
||||||
return value;
|
reset();
|
||||||
});
|
}
|
||||||
},
|
$(actionCheckboxes).prop("checked", checked)
|
||||||
showQuestion = function() {
|
.parent().parent().toggleClass(options.selectedClass, checked);
|
||||||
$(options.acrossClears).hide();
|
},
|
||||||
$(options.acrossQuestions).show();
|
updateCounter = function() {
|
||||||
$(options.allContainer).hide();
|
var sel = $(actionCheckboxes).filter(":checked").length;
|
||||||
},
|
// _actions_icnt is defined in the generated HTML
|
||||||
showClear = function() {
|
// and contains the total amount of objects in the queryset
|
||||||
$(options.acrossClears).show();
|
$(options.counterContainer).html(interpolate(
|
||||||
$(options.acrossQuestions).hide();
|
ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
|
||||||
$(options.actionContainer).toggleClass(options.selectedClass);
|
sel: sel,
|
||||||
$(options.allContainer).show();
|
cnt: _actions_icnt
|
||||||
$(options.counterContainer).hide();
|
}, true));
|
||||||
},
|
$(options.allToggle).prop("checked", function() {
|
||||||
reset = function() {
|
var value;
|
||||||
$(options.acrossClears).hide();
|
if (sel === actionCheckboxes.length) {
|
||||||
$(options.acrossQuestions).hide();
|
value = true;
|
||||||
$(options.allContainer).hide();
|
showQuestion();
|
||||||
$(options.counterContainer).show();
|
} else {
|
||||||
},
|
value = false;
|
||||||
clearAcross = function() {
|
clearAcross();
|
||||||
reset();
|
}
|
||||||
$(options.acrossInput).val(0);
|
return value;
|
||||||
$(options.actionContainer).removeClass(options.selectedClass);
|
});
|
||||||
};
|
};
|
||||||
// Show counter by default
|
// Show counter by default
|
||||||
$(options.counterContainer).show();
|
$(options.counterContainer).show();
|
||||||
// Check state of checkboxes and reinit state if needed
|
// Check state of checkboxes and reinit state if needed
|
||||||
$(this).filter(":checked").each(function(i) {
|
$(this).filter(":checked").each(function(i) {
|
||||||
$(this).parent().parent().toggleClass(options.selectedClass);
|
$(this).parent().parent().toggleClass(options.selectedClass);
|
||||||
updateCounter();
|
updateCounter();
|
||||||
if ($(options.acrossInput).val() == 1) {
|
if ($(options.acrossInput).val() === 1) {
|
||||||
showClear();
|
showClear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$(options.allToggle).show().click(function() {
|
$(options.allToggle).show().click(function() {
|
||||||
checker($(this).prop("checked"));
|
checker($(this).prop("checked"));
|
||||||
updateCounter();
|
updateCounter();
|
||||||
});
|
});
|
||||||
$("a", options.acrossQuestions).click(function(event) {
|
$("a", options.acrossQuestions).click(function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$(options.acrossInput).val(1);
|
$(options.acrossInput).val(1);
|
||||||
showClear();
|
showClear();
|
||||||
});
|
});
|
||||||
$("a", options.acrossClears).click(function(event) {
|
$("a", options.acrossClears).click(function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$(options.allToggle).prop("checked", false);
|
$(options.allToggle).prop("checked", false);
|
||||||
clearAcross();
|
clearAcross();
|
||||||
checker(0);
|
checker(0);
|
||||||
updateCounter();
|
updateCounter();
|
||||||
});
|
});
|
||||||
lastChecked = null;
|
lastChecked = null;
|
||||||
$(actionCheckboxes).click(function(event) {
|
$(actionCheckboxes).click(function(event) {
|
||||||
if (!event) { event = window.event; }
|
if (!event) { event = window.event; }
|
||||||
var target = event.target ? event.target : event.srcElement;
|
var target = event.target ? event.target : event.srcElement;
|
||||||
if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) {
|
if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) {
|
||||||
var inrange = false;
|
var inrange = false;
|
||||||
$(lastChecked).prop("checked", target.checked)
|
$(lastChecked).prop("checked", target.checked)
|
||||||
.parent().parent().toggleClass(options.selectedClass, target.checked);
|
.parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||||
$(actionCheckboxes).each(function() {
|
$(actionCheckboxes).each(function() {
|
||||||
if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) {
|
if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) {
|
||||||
inrange = (inrange) ? false : true;
|
inrange = (inrange) ? false : true;
|
||||||
}
|
}
|
||||||
if (inrange) {
|
if (inrange) {
|
||||||
$(this).prop("checked", target.checked)
|
$(this).prop("checked", target.checked)
|
||||||
.parent().parent().toggleClass(options.selectedClass, target.checked);
|
.parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$(target).parent().parent().toggleClass(options.selectedClass, target.checked);
|
$(target).parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||||
lastChecked = target;
|
lastChecked = target;
|
||||||
updateCounter();
|
updateCounter();
|
||||||
});
|
});
|
||||||
$('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
|
$('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
|
||||||
list_editable_changed = true;
|
list_editable_changed = true;
|
||||||
});
|
});
|
||||||
$('form#changelist-form button[name="index"]').click(function(event) {
|
$('form#changelist-form button[name="index"]').click(function(event) {
|
||||||
if (list_editable_changed) {
|
if (list_editable_changed) {
|
||||||
return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
|
return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('form#changelist-form input[name="_save"]').click(function(event) {
|
$('form#changelist-form input[name="_save"]').click(function(event) {
|
||||||
var action_changed = false;
|
var action_changed = false;
|
||||||
$('select option:selected', options.actionContainer).each(function() {
|
$('select option:selected', options.actionContainer).each(function() {
|
||||||
if ($(this).val()) {
|
if ($(this).val()) {
|
||||||
action_changed = true;
|
action_changed = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (action_changed) {
|
if (action_changed) {
|
||||||
if (list_editable_changed) {
|
if (list_editable_changed) {
|
||||||
return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
|
return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
|
||||||
} else {
|
} else {
|
||||||
return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."));
|
return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
/* Setup plugin defaults */
|
/* Setup plugin defaults */
|
||||||
$.fn.actions.defaults = {
|
$.fn.actions.defaults = {
|
||||||
actionContainer: "div.actions",
|
actionContainer: "div.actions",
|
||||||
counterContainer: "span.action-counter",
|
counterContainer: "span.action-counter",
|
||||||
allContainer: "div.actions span.all",
|
allContainer: "div.actions span.all",
|
||||||
acrossInput: "div.actions input.select-across",
|
acrossInput: "div.actions input.select-across",
|
||||||
acrossQuestions: "div.actions span.question",
|
acrossQuestions: "div.actions span.question",
|
||||||
acrossClears: "div.actions span.clear",
|
acrossClears: "div.actions span.clear",
|
||||||
allToggle: "#action-toggle",
|
allToggle: "#action-toggle",
|
||||||
selectedClass: "selected"
|
selectedClass: "selected"
|
||||||
};
|
};
|
||||||
})(django.jQuery);
|
})(django.jQuery);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*global addEvent, Calendar, cancelEventPropagation, findPosX, findPosY, getStyle, get_format, gettext, interpolate, ngettext, quickElement, removeEvent*/
|
||||||
// Inserts shortcut buttons after all of the following:
|
// Inserts shortcut buttons after all of the following:
|
||||||
// <input type="text" class="vDateField">
|
// <input type="text" class="vDateField">
|
||||||
// <input type="text" class="vTimeField">
|
// <input type="text" class="vTimeField">
|
||||||
|
@ -17,20 +18,20 @@ var DateTimeShortcuts = {
|
||||||
timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
|
timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
|
||||||
timezoneOffset: 0,
|
timezoneOffset: 0,
|
||||||
init: function() {
|
init: function() {
|
||||||
if (window.__admin_utc_offset__ != undefined) {
|
if (window.__admin_utc_offset__ !== undefined) {
|
||||||
var serverOffset = window.__admin_utc_offset__;
|
var serverOffset = window.__admin_utc_offset__;
|
||||||
var localOffset = new Date().getTimezoneOffset() * -60;
|
var localOffset = new Date().getTimezoneOffset() * -60;
|
||||||
DateTimeShortcuts.timezoneOffset = localOffset - serverOffset;
|
DateTimeShortcuts.timezoneOffset = localOffset - serverOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputs = document.getElementsByTagName('input');
|
var inputs = document.getElementsByTagName('input');
|
||||||
for (i=0; i<inputs.length; i++) {
|
for (var i=0; i<inputs.length; i++) {
|
||||||
var inp = inputs[i];
|
var inp = inputs[i];
|
||||||
if (inp.getAttribute('type') == 'text' && inp.className.match(/vTimeField/)) {
|
if (inp.getAttribute('type') === 'text' && inp.className.match(/vTimeField/)) {
|
||||||
DateTimeShortcuts.addClock(inp);
|
DateTimeShortcuts.addClock(inp);
|
||||||
DateTimeShortcuts.addTimezoneWarning(inp);
|
DateTimeShortcuts.addTimezoneWarning(inp);
|
||||||
}
|
}
|
||||||
else if (inp.getAttribute('type') == 'text' && inp.className.match(/vDateField/)) {
|
else if (inp.getAttribute('type') === 'text' && inp.className.match(/vDateField/)) {
|
||||||
DateTimeShortcuts.addCalendar(inp);
|
DateTimeShortcuts.addCalendar(inp);
|
||||||
DateTimeShortcuts.addTimezoneWarning(inp);
|
DateTimeShortcuts.addTimezoneWarning(inp);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +39,7 @@ var DateTimeShortcuts = {
|
||||||
},
|
},
|
||||||
// Return the current time while accounting for the server timezone.
|
// Return the current time while accounting for the server timezone.
|
||||||
now: function() {
|
now: function() {
|
||||||
if (window.__admin_utc_offset__ != undefined) {
|
if (window.__admin_utc_offset__ !== undefined) {
|
||||||
var serverOffset = window.__admin_utc_offset__;
|
var serverOffset = window.__admin_utc_offset__;
|
||||||
var localNow = new Date();
|
var localNow = new Date();
|
||||||
var localOffset = localNow.getTimezoneOffset() * -60;
|
var localOffset = localNow.getTimezoneOffset() * -60;
|
||||||
|
@ -71,7 +72,7 @@ var DateTimeShortcuts = {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
timezoneOffset *= -1
|
timezoneOffset *= -1;
|
||||||
message = ngettext(
|
message = ngettext(
|
||||||
'Note: You are %s hour behind server time.',
|
'Note: You are %s hour behind server time.',
|
||||||
'Note: You are %s hours behind server time.',
|
'Note: You are %s hours behind server time.',
|
||||||
|
@ -86,7 +87,7 @@ var DateTimeShortcuts = {
|
||||||
|
|
||||||
$(inp).parent()
|
$(inp).parent()
|
||||||
.append($('<br>'))
|
.append($('<br>'))
|
||||||
.append($warning)
|
.append($warning);
|
||||||
},
|
},
|
||||||
// Add clock widget to a given field
|
// Add clock widget to a given field
|
||||||
addClock: function(inp) {
|
addClock: function(inp) {
|
||||||
|
@ -150,7 +151,7 @@ var DateTimeShortcuts = {
|
||||||
cancel_p.className = 'calendar-cancel';
|
cancel_p.className = 'calendar-cancel';
|
||||||
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');');
|
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');');
|
||||||
django.jQuery(document).bind('keyup', function(event) {
|
django.jQuery(document).bind('keyup', function(event) {
|
||||||
if (event.which == 27) {
|
if (event.which === 27) {
|
||||||
// ESC key closes popup
|
// ESC key closes popup
|
||||||
DateTimeShortcuts.dismissClock(num);
|
DateTimeShortcuts.dismissClock(num);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -158,12 +159,12 @@ var DateTimeShortcuts = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
openClock: function(num) {
|
openClock: function(num) {
|
||||||
var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num)
|
var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num);
|
||||||
var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName+num)
|
var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName+num);
|
||||||
|
|
||||||
// Recalculate the clockbox position
|
// Recalculate the clockbox position
|
||||||
// is it left-to-right or right-to-left layout ?
|
// is it left-to-right or right-to-left layout ?
|
||||||
if (getStyle(document.body,'direction')!='rtl') {
|
if (getStyle(document.body,'direction')!=='rtl') {
|
||||||
clock_box.style.left = findPosX(clock_link) + 17 + 'px';
|
clock_box.style.left = findPosX(clock_link) + 17 + 'px';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -180,20 +181,20 @@ var DateTimeShortcuts = {
|
||||||
addEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]);
|
addEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]);
|
||||||
},
|
},
|
||||||
dismissClock: function(num) {
|
dismissClock: function(num) {
|
||||||
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';
|
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';
|
||||||
removeEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]);
|
removeEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]);
|
||||||
},
|
},
|
||||||
handleClockQuicklink: function(num, val) {
|
handleClockQuicklink: function(num, val) {
|
||||||
var d;
|
var d;
|
||||||
if (val == -1) {
|
if (val === -1) {
|
||||||
d = DateTimeShortcuts.now();
|
d = DateTimeShortcuts.now();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
d = new Date(1970, 1, 1, val, 0, 0, 0)
|
d = new Date(1970, 1, 1, val, 0, 0, 0);
|
||||||
}
|
}
|
||||||
DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]);
|
DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]);
|
||||||
DateTimeShortcuts.clockInputs[num].focus();
|
DateTimeShortcuts.clockInputs[num].focus();
|
||||||
DateTimeShortcuts.dismissClock(num);
|
DateTimeShortcuts.dismissClock(num);
|
||||||
},
|
},
|
||||||
// Add calendar widget to a given field.
|
// Add calendar widget to a given field.
|
||||||
addCalendar: function(inp) {
|
addCalendar: function(inp) {
|
||||||
|
@ -274,7 +275,7 @@ var DateTimeShortcuts = {
|
||||||
cancel_p.className = 'calendar-cancel';
|
cancel_p.className = 'calendar-cancel';
|
||||||
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
|
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
|
||||||
django.jQuery(document).bind('keyup', function(event) {
|
django.jQuery(document).bind('keyup', function(event) {
|
||||||
if (event.which == 27) {
|
if (event.which === 27) {
|
||||||
// ESC key closes popup
|
// ESC key closes popup
|
||||||
DateTimeShortcuts.dismissCalendar(num);
|
DateTimeShortcuts.dismissCalendar(num);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -282,8 +283,8 @@ var DateTimeShortcuts = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
openCalendar: function(num) {
|
openCalendar: function(num) {
|
||||||
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
|
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num);
|
||||||
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
|
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num);
|
||||||
var inp = DateTimeShortcuts.calendarInputs[num];
|
var inp = DateTimeShortcuts.calendarInputs[num];
|
||||||
|
|
||||||
// Determine if the current value in the input has a valid date.
|
// Determine if the current value in the input has a valid date.
|
||||||
|
@ -293,7 +294,7 @@ var DateTimeShortcuts = {
|
||||||
var selected = inp.value.strptime(format);
|
var selected = inp.value.strptime(format);
|
||||||
var year = selected.getFullYear();
|
var year = selected.getFullYear();
|
||||||
var month = selected.getMonth() + 1;
|
var month = selected.getMonth() + 1;
|
||||||
var re = /\d{4}/
|
var re = /\d{4}/;
|
||||||
if (re.test(year.toString()) && month >= 1 && month <= 12) {
|
if (re.test(year.toString()) && month >= 1 && month <= 12) {
|
||||||
DateTimeShortcuts.calendars[num].drawDate(month, year, selected);
|
DateTimeShortcuts.calendars[num].drawDate(month, year, selected);
|
||||||
}
|
}
|
||||||
|
@ -301,7 +302,7 @@ var DateTimeShortcuts = {
|
||||||
|
|
||||||
// Recalculate the clockbox position
|
// Recalculate the clockbox position
|
||||||
// is it left-to-right or right-to-left layout ?
|
// is it left-to-right or right-to-left layout ?
|
||||||
if (getStyle(document.body,'direction')!='rtl') {
|
if (getStyle(document.body,'direction')!=='rtl') {
|
||||||
cal_box.style.left = findPosX(cal_link) + 17 + 'px';
|
cal_box.style.left = findPosX(cal_link) + 17 + 'px';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -345,12 +346,12 @@ var DateTimeShortcuts = {
|
||||||
").style.display='none';}"].join('');
|
").style.display='none';}"].join('');
|
||||||
},
|
},
|
||||||
handleCalendarQuickLink: function(num, offset) {
|
handleCalendarQuickLink: function(num, offset) {
|
||||||
var d = DateTimeShortcuts.now();
|
var d = DateTimeShortcuts.now();
|
||||||
d.setDate(d.getDate() + offset)
|
d.setDate(d.getDate() + offset);
|
||||||
DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);
|
DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);
|
||||||
DateTimeShortcuts.calendarInputs[num].focus();
|
DateTimeShortcuts.calendarInputs[num].focus();
|
||||||
DateTimeShortcuts.dismissCalendar(num);
|
DateTimeShortcuts.dismissCalendar(num);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
addEvent(window, 'load', DateTimeShortcuts.init);
|
addEvent(window, 'load', DateTimeShortcuts.init);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*global SelectBox, interpolate*/
|
||||||
// Handles related-objects functionality: lookup link for raw_id_fields
|
// Handles related-objects functionality: lookup link for raw_id_fields
|
||||||
// and Add Another links.
|
// and Add Another links.
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ function showAdminPopup(triggeringLink, name_regexp, add_popup) {
|
||||||
name = id_to_windowname(name);
|
name = id_to_windowname(name);
|
||||||
var href = triggeringLink.href;
|
var href = triggeringLink.href;
|
||||||
if (add_popup) {
|
if (add_popup) {
|
||||||
if (href.indexOf('?') == -1) {
|
if (href.indexOf('?') === -1) {
|
||||||
href += '?_popup=1';
|
href += '?_popup=1';
|
||||||
} else {
|
} else {
|
||||||
href += '&_popup=1';
|
href += '&_popup=1';
|
||||||
|
@ -50,7 +51,7 @@ function showRelatedObjectLookupPopup(triggeringLink) {
|
||||||
function dismissRelatedLookupPopup(win, chosenId) {
|
function dismissRelatedLookupPopup(win, chosenId) {
|
||||||
var name = windowname_to_id(win.name);
|
var name = windowname_to_id(win.name);
|
||||||
var elem = document.getElementById(name);
|
var elem = document.getElementById(name);
|
||||||
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
|
if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) {
|
||||||
elem.value += ',' + chosenId;
|
elem.value += ',' + chosenId;
|
||||||
} else {
|
} else {
|
||||||
document.getElementById(name).value = chosenId;
|
document.getElementById(name).value = chosenId;
|
||||||
|
@ -86,10 +87,10 @@ function dismissAddRelatedObjectPopup(win, newId, newRepr) {
|
||||||
var elem = document.getElementById(name);
|
var elem = document.getElementById(name);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
var elemName = elem.nodeName.toUpperCase();
|
var elemName = elem.nodeName.toUpperCase();
|
||||||
if (elemName == 'SELECT') {
|
if (elemName === 'SELECT') {
|
||||||
elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
|
elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
|
||||||
} else if (elemName == 'INPUT') {
|
} else if (elemName === 'INPUT') {
|
||||||
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
|
if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) {
|
||||||
elem.value += ',' + newId;
|
elem.value += ',' + newId;
|
||||||
} else {
|
} else {
|
||||||
elem.value = newId;
|
elem.value = newId;
|
||||||
|
@ -113,13 +114,13 @@ function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
|
||||||
var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
|
var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
|
||||||
var selects = django.jQuery(selectsSelector);
|
var selects = django.jQuery(selectsSelector);
|
||||||
selects.find('option').each(function() {
|
selects.find('option').each(function() {
|
||||||
if (this.value == objId) {
|
if (this.value === objId) {
|
||||||
this.innerHTML = newRepr;
|
this.innerHTML = newRepr;
|
||||||
this.value = newId;
|
this.value = newId;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
win.close();
|
win.close();
|
||||||
};
|
}
|
||||||
|
|
||||||
function dismissDeleteRelatedObjectPopup(win, objId) {
|
function dismissDeleteRelatedObjectPopup(win, objId) {
|
||||||
objId = html_unescape(objId);
|
objId = html_unescape(objId);
|
||||||
|
@ -127,13 +128,13 @@ function dismissDeleteRelatedObjectPopup(win, objId) {
|
||||||
var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
|
var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
|
||||||
var selects = django.jQuery(selectsSelector);
|
var selects = django.jQuery(selectsSelector);
|
||||||
selects.find('option').each(function() {
|
selects.find('option').each(function() {
|
||||||
if (this.value == objId) {
|
if (this.value === objId) {
|
||||||
django.jQuery(this).remove();
|
django.jQuery(this).remove();
|
||||||
}
|
}
|
||||||
}).trigger('change');
|
}).trigger('change');
|
||||||
win.close();
|
win.close();
|
||||||
};
|
}
|
||||||
|
|
||||||
// Kept for backward compatibility
|
// Kept for backward compatibility
|
||||||
showAddAnotherPopup = showRelatedObjectPopup;
|
var showAddAnotherPopup = showRelatedObjectPopup;
|
||||||
dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
|
var dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*global gettext, get_format, quickElement, removeChildren*/
|
||||||
/*
|
/*
|
||||||
calendar.js - Calendar functions by Adrian Holovaty
|
calendar.js - Calendar functions by Adrian Holovaty
|
||||||
depends on core.js for utility functions like removeChildren or quickElement
|
depends on core.js for utility functions like removeChildren or quickElement
|
||||||
|
@ -9,17 +10,17 @@ var CalendarNamespace = {
|
||||||
daysOfWeek: gettext('S M T W T F S').split(' '),
|
daysOfWeek: gettext('S M T W T F S').split(' '),
|
||||||
firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
|
firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
|
||||||
isLeapYear: function(year) {
|
isLeapYear: function(year) {
|
||||||
return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0));
|
return (((year % 4)===0) && ((year % 100)!==0) || ((year % 400)===0));
|
||||||
},
|
},
|
||||||
getDaysInMonth: function(month,year) {
|
getDaysInMonth: function(month,year) {
|
||||||
var days;
|
var days;
|
||||||
if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
|
if (month===1 || month===3 || month===5 || month===7 || month===8 || month===10 || month===12) {
|
||||||
days = 31;
|
days = 31;
|
||||||
}
|
}
|
||||||
else if (month==4 || month==6 || month==9 || month==11) {
|
else if (month===4 || month===6 || month===9 || month===11) {
|
||||||
days = 30;
|
days = 30;
|
||||||
}
|
}
|
||||||
else if (month==2 && CalendarNamespace.isLeapYear(year)) {
|
else if (month===2 && CalendarNamespace.isLeapYear(year)) {
|
||||||
days = 29;
|
days = 29;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -46,8 +47,8 @@ var CalendarNamespace = {
|
||||||
// The day variable above will be 1 instead of 2 in, say, US Pacific time
|
// The day variable above will be 1 instead of 2 in, say, US Pacific time
|
||||||
// zone.
|
// zone.
|
||||||
var isSelectedMonth = false;
|
var isSelectedMonth = false;
|
||||||
if (typeof selected != 'undefined') {
|
if (typeof selected !== 'undefined') {
|
||||||
isSelectedMonth = (selected.getUTCFullYear() == year && (selected.getUTCMonth()+1) == month);
|
isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth()+1) === month);
|
||||||
}
|
}
|
||||||
|
|
||||||
month = parseInt(month);
|
month = parseInt(month);
|
||||||
|
@ -67,28 +68,30 @@ var CalendarNamespace = {
|
||||||
var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
|
var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
|
||||||
var days = CalendarNamespace.getDaysInMonth(month, year);
|
var days = CalendarNamespace.getDaysInMonth(month, year);
|
||||||
|
|
||||||
|
var _cell;
|
||||||
|
|
||||||
// Draw blanks before first of month
|
// Draw blanks before first of month
|
||||||
tableRow = quickElement('tr', tableBody);
|
tableRow = quickElement('tr', tableBody);
|
||||||
for (var i = 0; i < startingPos; i++) {
|
for (i = 0; i < startingPos; i++) {
|
||||||
var _cell = quickElement('td', tableRow, ' ');
|
_cell = quickElement('td', tableRow, ' ');
|
||||||
_cell.className = "nonday";
|
_cell.className = "nonday";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw days of month
|
// Draw days of month
|
||||||
var currentDay = 1;
|
var currentDay = 1;
|
||||||
for (var i = startingPos; currentDay <= days; i++) {
|
for (i = startingPos; currentDay <= days; i++) {
|
||||||
if (i%7 == 0 && currentDay != 1) {
|
if (i%7 === 0 && currentDay !== 1) {
|
||||||
tableRow = quickElement('tr', tableBody);
|
tableRow = quickElement('tr', tableBody);
|
||||||
}
|
}
|
||||||
if ((currentDay==todayDay) && (month==todayMonth) && (year==todayYear)) {
|
if ((currentDay===todayDay) && (month===todayMonth) && (year===todayYear)) {
|
||||||
todayClass='today';
|
todayClass='today';
|
||||||
} else {
|
} else {
|
||||||
todayClass='';
|
todayClass='';
|
||||||
}
|
}
|
||||||
|
|
||||||
// use UTC function; see above for explanation.
|
// use UTC function; see above for explanation.
|
||||||
if (isSelectedMonth && currentDay == selected.getUTCDate()) {
|
if (isSelectedMonth && currentDay === selected.getUTCDate()) {
|
||||||
if (todayClass != '') todayClass += " ";
|
if (todayClass !== '') todayClass += " ";
|
||||||
todayClass += "selected";
|
todayClass += "selected";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,13 +103,13 @@ var CalendarNamespace = {
|
||||||
|
|
||||||
// Draw blanks after end of month (optional, but makes for valid code)
|
// Draw blanks after end of month (optional, but makes for valid code)
|
||||||
while (tableRow.childNodes.length < 7) {
|
while (tableRow.childNodes.length < 7) {
|
||||||
var _cell = quickElement('td', tableRow, ' ');
|
_cell = quickElement('td', tableRow, ' ');
|
||||||
_cell.className = "nonday";
|
_cell.className = "nonday";
|
||||||
}
|
}
|
||||||
|
|
||||||
calDiv.appendChild(calTable);
|
calDiv.appendChild(calTable);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Calendar -- A calendar instance
|
// Calendar -- A calendar instance
|
||||||
function Calendar(div_id, callback, selected) {
|
function Calendar(div_id, callback, selected) {
|
||||||
|
@ -120,7 +123,7 @@ function Calendar(div_id, callback, selected) {
|
||||||
this.today = new Date();
|
this.today = new Date();
|
||||||
this.currentMonth = this.today.getMonth() + 1;
|
this.currentMonth = this.today.getMonth() + 1;
|
||||||
this.currentYear = this.today.getFullYear();
|
this.currentYear = this.today.getFullYear();
|
||||||
if (typeof selected != 'undefined') {
|
if (typeof selected !== 'undefined') {
|
||||||
this.selected = selected;
|
this.selected = selected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +142,7 @@ Calendar.prototype = {
|
||||||
this.drawCurrent();
|
this.drawCurrent();
|
||||||
},
|
},
|
||||||
drawPreviousMonth: function() {
|
drawPreviousMonth: function() {
|
||||||
if (this.currentMonth == 1) {
|
if (this.currentMonth === 1) {
|
||||||
this.currentMonth = 12;
|
this.currentMonth = 12;
|
||||||
this.currentYear--;
|
this.currentYear--;
|
||||||
}
|
}
|
||||||
|
@ -149,7 +152,7 @@ Calendar.prototype = {
|
||||||
this.drawCurrent();
|
this.drawCurrent();
|
||||||
},
|
},
|
||||||
drawNextMonth: function() {
|
drawNextMonth: function() {
|
||||||
if (this.currentMonth == 12) {
|
if (this.currentMonth === 12) {
|
||||||
this.currentMonth = 1;
|
this.currentMonth = 1;
|
||||||
this.currentYear++;
|
this.currentYear++;
|
||||||
}
|
}
|
||||||
|
@ -166,4 +169,4 @@ Calendar.prototype = {
|
||||||
this.currentYear++;
|
this.currentYear++;
|
||||||
this.drawCurrent();
|
this.drawCurrent();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
|
/*global gettext*/
|
||||||
(function($) {
|
(function($) {
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Add anchor tag for Show/Hide link
|
// Add anchor tag for Show/Hide link
|
||||||
$("fieldset.collapse").each(function(i, elem) {
|
$("fieldset.collapse").each(function(i, elem) {
|
||||||
// Don't hide if fields in this fieldset have errors
|
// Don't hide if fields in this fieldset have errors
|
||||||
if ($(elem).find("div.errors").length == 0) {
|
if ($(elem).find("div.errors").length === 0) {
|
||||||
$(elem).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser' +
|
$(elem).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser' +
|
||||||
i +'" class="collapse-toggle" href="#">' + gettext("Show") +
|
i +'" class="collapse-toggle" href="#">' + gettext("Show") +
|
||||||
'</a>)');
|
'</a>)');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Add toggle to anchor tag
|
// Add toggle to anchor tag
|
||||||
$("fieldset.collapse a.collapse-toggle").click(function(ev) {
|
$("fieldset.collapse a.collapse-toggle").click(function(ev) {
|
||||||
if ($(this).closest("fieldset").hasClass("collapsed")) {
|
if ($(this).closest("fieldset").hasClass("collapsed")) {
|
||||||
// Show
|
// Show
|
||||||
$(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]);
|
$(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]);
|
||||||
} else {
|
} else {
|
||||||
// Hide
|
// Hide
|
||||||
$(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]);
|
$(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(django.jQuery);
|
})(django.jQuery);
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){a(b).find("div.errors").length==0&&a(b).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser'+c+'" class="collapse-toggle" href="#">'+gettext("Show")+"</a>)")});a("fieldset.collapse a.collapse-toggle").click(function(){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset",
|
(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(b,c){0===a(c).find("div.errors").length&&a(c).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser'+b+'" class="collapse-toggle" href="#">'+gettext("Show")+"</a>)")});a("fieldset.collapse a.collapse-toggle").click(function(b){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset",
|
||||||
[a(this).attr("id")]);return false})})})(django.jQuery);
|
[a(this).attr("id")]);return!1})})})(django.jQuery);
|
||||||
|
|
|
@ -74,8 +74,8 @@ var xmlhttp;
|
||||||
@else
|
@else
|
||||||
xmlhttp = false;
|
xmlhttp = false;
|
||||||
@end @*/
|
@end @*/
|
||||||
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
|
if (!xmlhttp && typeof XMLHttpRequest !== 'undefined') {
|
||||||
xmlhttp = new XMLHttpRequest();
|
xmlhttp = new XMLHttpRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -90,7 +90,7 @@ function findPosX(obj) {
|
||||||
obj = obj.offsetParent;
|
obj = obj.offsetParent;
|
||||||
}
|
}
|
||||||
// IE offsetParent does not include the top-level
|
// IE offsetParent does not include the top-level
|
||||||
if (isIE && obj.parentElement){
|
if (isIE && obj.parentElement) {
|
||||||
curleft += obj.offsetLeft - obj.scrollLeft;
|
curleft += obj.offsetLeft - obj.scrollLeft;
|
||||||
}
|
}
|
||||||
} else if (obj.x) {
|
} else if (obj.x) {
|
||||||
|
@ -107,7 +107,7 @@ function findPosY(obj) {
|
||||||
obj = obj.offsetParent;
|
obj = obj.offsetParent;
|
||||||
}
|
}
|
||||||
// IE offsetParent does not include the top-level
|
// IE offsetParent does not include the top-level
|
||||||
if (isIE && obj.parentElement){
|
if (isIE && obj.parentElement) {
|
||||||
curtop += obj.offsetTop - obj.scrollTop;
|
curtop += obj.offsetTop - obj.scrollTop;
|
||||||
}
|
}
|
||||||
} else if (obj.y) {
|
} else if (obj.y) {
|
||||||
|
@ -121,46 +121,46 @@ function findPosY(obj) {
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
Date.prototype.getTwelveHours = function() {
|
Date.prototype.getTwelveHours = function() {
|
||||||
hours = this.getHours();
|
var hours = this.getHours();
|
||||||
if (hours == 0) {
|
if (hours === 0) {
|
||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return hours <= 12 ? hours : hours-12
|
return hours <= 12 ? hours : hours-12;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.getTwoDigitMonth = function() {
|
Date.prototype.getTwoDigitMonth = function() {
|
||||||
return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1);
|
return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1);
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.getTwoDigitDate = function() {
|
Date.prototype.getTwoDigitDate = function() {
|
||||||
return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();
|
return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.getTwoDigitTwelveHour = function() {
|
Date.prototype.getTwoDigitTwelveHour = function() {
|
||||||
return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours();
|
return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours();
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.getTwoDigitHour = function() {
|
Date.prototype.getTwoDigitHour = function() {
|
||||||
return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();
|
return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.getTwoDigitMinute = function() {
|
Date.prototype.getTwoDigitMinute = function() {
|
||||||
return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
|
return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.getTwoDigitSecond = function() {
|
Date.prototype.getTwoDigitSecond = function() {
|
||||||
return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
|
return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.getHourMinute = function() {
|
Date.prototype.getHourMinute = function() {
|
||||||
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
|
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.getHourMinuteSecond = function() {
|
Date.prototype.getHourMinuteSecond = function() {
|
||||||
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond();
|
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond();
|
||||||
}
|
};
|
||||||
|
|
||||||
Date.prototype.strftime = function(format) {
|
Date.prototype.strftime = function(format) {
|
||||||
var fields = {
|
var fields = {
|
||||||
|
@ -191,7 +191,7 @@ Date.prototype.strftime = function(format) {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// String object extensions
|
// String object extensions
|
||||||
|
@ -202,42 +202,43 @@ String.prototype.pad_left = function(pad_length, pad_string) {
|
||||||
new_string = pad_string + new_string;
|
new_string = pad_string + new_string;
|
||||||
}
|
}
|
||||||
return new_string;
|
return new_string;
|
||||||
}
|
};
|
||||||
|
|
||||||
String.prototype.strptime = function(format) {
|
String.prototype.strptime = function(format) {
|
||||||
var split_format = format.split(/[.\-/]/);
|
var split_format = format.split(/[.\-/]/);
|
||||||
var date = this.split(/[.\-/]/);
|
var date = this.split(/[.\-/]/);
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
var day, month, year;
|
||||||
while (i < split_format.length) {
|
while (i < split_format.length) {
|
||||||
switch (split_format[i]) {
|
switch (split_format[i]) {
|
||||||
case "%d":
|
case "%d":
|
||||||
var day = date[i];
|
day = date[i];
|
||||||
break;
|
break;
|
||||||
case "%m":
|
case "%m":
|
||||||
var month = date[i] - 1;
|
month = date[i] - 1;
|
||||||
break;
|
break;
|
||||||
case "%Y":
|
case "%Y":
|
||||||
var year = date[i];
|
year = date[i];
|
||||||
break;
|
break;
|
||||||
case "%y":
|
case "%y":
|
||||||
var year = date[i];
|
year = date[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
};
|
}
|
||||||
return new Date(year, month, day);
|
return new Date(year, month, day);
|
||||||
}
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Get the computed style for and element
|
// Get the computed style for and element
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
function getStyle(oElm, strCssRule){
|
function getStyle(oElm, strCssRule) {
|
||||||
var strValue = "";
|
var strValue = "";
|
||||||
if(document.defaultView && document.defaultView.getComputedStyle){
|
if(document.defaultView && document.defaultView.getComputedStyle) {
|
||||||
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
|
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
|
||||||
}
|
}
|
||||||
else if(oElm.currentStyle){
|
else if(oElm.currentStyle) {
|
||||||
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
|
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1) {
|
||||||
return p1.toUpperCase();
|
return p1.toUpperCase();
|
||||||
});
|
});
|
||||||
strValue = oElm.currentStyle[strCssRule];
|
strValue = oElm.currentStyle[strCssRule];
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*global DateTimeShortcuts, SelectFilter*/
|
||||||
/**
|
/**
|
||||||
* Django admin inlines
|
* Django admin inlines
|
||||||
*
|
*
|
||||||
|
@ -15,258 +16,260 @@
|
||||||
* See: http://www.opensource.org/licenses/bsd-license.php
|
* See: http://www.opensource.org/licenses/bsd-license.php
|
||||||
*/
|
*/
|
||||||
(function($) {
|
(function($) {
|
||||||
$.fn.formset = function(opts) {
|
$.fn.formset = function(opts) {
|
||||||
var options = $.extend({}, $.fn.formset.defaults, opts);
|
var options = $.extend({}, $.fn.formset.defaults, opts);
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
var $parent = $this.parent();
|
var $parent = $this.parent();
|
||||||
var updateElementIndex = function(el, prefix, ndx) {
|
var updateElementIndex = function(el, prefix, ndx) {
|
||||||
var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))");
|
var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))");
|
||||||
var replacement = prefix + "-" + ndx;
|
var replacement = prefix + "-" + ndx;
|
||||||
if ($(el).prop("for")) {
|
if ($(el).prop("for")) {
|
||||||
$(el).prop("for", $(el).prop("for").replace(id_regex, replacement));
|
$(el).prop("for", $(el).prop("for").replace(id_regex, replacement));
|
||||||
}
|
}
|
||||||
if (el.id) {
|
if (el.id) {
|
||||||
el.id = el.id.replace(id_regex, replacement);
|
el.id = el.id.replace(id_regex, replacement);
|
||||||
}
|
}
|
||||||
if (el.name) {
|
if (el.name) {
|
||||||
el.name = el.name.replace(id_regex, replacement);
|
el.name = el.name.replace(id_regex, replacement);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off");
|
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off");
|
||||||
var nextIndex = parseInt(totalForms.val(), 10);
|
var nextIndex = parseInt(totalForms.val(), 10);
|
||||||
var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off");
|
var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off");
|
||||||
// only show the add button if we are allowed to add more items,
|
// only show the add button if we are allowed to add more items,
|
||||||
// note that max_num = None translates to a blank string.
|
// note that max_num = None translates to a blank string.
|
||||||
var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0;
|
var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0;
|
||||||
$this.each(function(i) {
|
$this.each(function(i) {
|
||||||
$(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
|
$(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
|
||||||
});
|
|
||||||
if ($this.length && showAddButton) {
|
|
||||||
var addButton;
|
|
||||||
if ($this.prop("tagName") == "TR") {
|
|
||||||
// If forms are laid out as table rows, insert the
|
|
||||||
// "add" button in a new table row:
|
|
||||||
var numCols = this.eq(-1).children().length;
|
|
||||||
$parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="javascript:void(0)">' + options.addText + "</a></tr>");
|
|
||||||
addButton = $parent.find("tr:last a");
|
|
||||||
} else {
|
|
||||||
// Otherwise, insert it immediately after the last form:
|
|
||||||
$this.filter(":last").after('<div class="' + options.addCssClass + '"><a href="javascript:void(0)">' + options.addText + "</a></div>");
|
|
||||||
addButton = $this.filter(":last").next().find("a");
|
|
||||||
}
|
|
||||||
addButton.click(function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS");
|
|
||||||
var template = $("#" + options.prefix + "-empty");
|
|
||||||
var row = template.clone(true);
|
|
||||||
row.removeClass(options.emptyCssClass)
|
|
||||||
.addClass(options.formCssClass)
|
|
||||||
.attr("id", options.prefix + "-" + nextIndex);
|
|
||||||
if (row.is("tr")) {
|
|
||||||
// If the forms are laid out in table rows, insert
|
|
||||||
// the remove button into the last table cell:
|
|
||||||
row.children(":last").append('<div><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></div>");
|
|
||||||
} else if (row.is("ul") || row.is("ol")) {
|
|
||||||
// If they're laid out as an ordered/unordered list,
|
|
||||||
// insert an <li> after the last list item:
|
|
||||||
row.append('<li><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></li>");
|
|
||||||
} else {
|
|
||||||
// Otherwise, just insert the remove button as the
|
|
||||||
// last child element of the form's container:
|
|
||||||
row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText + "</a></span>");
|
|
||||||
}
|
|
||||||
row.find("*").each(function() {
|
|
||||||
updateElementIndex(this, options.prefix, totalForms.val());
|
|
||||||
});
|
});
|
||||||
// Insert the new form when it has been fully edited
|
if ($this.length && showAddButton) {
|
||||||
row.insertBefore($(template));
|
var addButton;
|
||||||
// Update number of total forms
|
if ($this.prop("tagName") === "TR") {
|
||||||
$(totalForms).val(parseInt(totalForms.val(), 10) + 1);
|
// If forms are laid out as table rows, insert the
|
||||||
nextIndex += 1;
|
// "add" button in a new table row:
|
||||||
// Hide add button in case we've hit the max, except we want to add infinitely
|
var numCols = this.eq(-1).children().length;
|
||||||
if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) {
|
$parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="javascript:void(0)">' + options.addText + "</a></tr>");
|
||||||
addButton.parent().hide();
|
addButton = $parent.find("tr:last a");
|
||||||
}
|
} else {
|
||||||
// The delete button of each row triggers a bunch of other things
|
// Otherwise, insert it immediately after the last form:
|
||||||
row.find("a." + options.deleteCssClass).click(function(e) {
|
$this.filter(":last").after('<div class="' + options.addCssClass + '"><a href="javascript:void(0)">' + options.addText + "</a></div>");
|
||||||
e.preventDefault();
|
addButton = $this.filter(":last").next().find("a");
|
||||||
// Remove the parent form containing this button:
|
}
|
||||||
var row = $(this).parents("." + options.formCssClass);
|
addButton.click(function(e) {
|
||||||
row.remove();
|
e.preventDefault();
|
||||||
nextIndex -= 1;
|
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS");
|
||||||
// If a post-delete callback was provided, call it with the deleted form:
|
var template = $("#" + options.prefix + "-empty");
|
||||||
if (options.removed) {
|
var row = template.clone(true);
|
||||||
options.removed(row);
|
row.removeClass(options.emptyCssClass)
|
||||||
}
|
.addClass(options.formCssClass)
|
||||||
// Update the TOTAL_FORMS form count.
|
.attr("id", options.prefix + "-" + nextIndex);
|
||||||
var forms = $("." + options.formCssClass);
|
if (row.is("tr")) {
|
||||||
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
|
// If the forms are laid out in table rows, insert
|
||||||
// Show add button again once we drop below max
|
// the remove button into the last table cell:
|
||||||
if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) {
|
row.children(":last").append('<div><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></div>");
|
||||||
addButton.parent().show();
|
} else if (row.is("ul") || row.is("ol")) {
|
||||||
}
|
// If they're laid out as an ordered/unordered list,
|
||||||
// Also, update names and ids for all remaining form controls
|
// insert an <li> after the last list item:
|
||||||
// so they remain in sequence:
|
row.append('<li><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></li>");
|
||||||
for (var i=0, formCount=forms.length; i<formCount; i++)
|
} else {
|
||||||
{
|
// Otherwise, just insert the remove button as the
|
||||||
updateElementIndex($(forms).get(i), options.prefix, i);
|
// last child element of the form's container:
|
||||||
$(forms.get(i)).find("*").each(function() {
|
row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText + "</a></span>");
|
||||||
updateElementIndex(this, options.prefix, i);
|
}
|
||||||
|
row.find("*").each(function() {
|
||||||
|
updateElementIndex(this, options.prefix, totalForms.val());
|
||||||
|
});
|
||||||
|
// Insert the new form when it has been fully edited
|
||||||
|
row.insertBefore($(template));
|
||||||
|
// Update number of total forms
|
||||||
|
$(totalForms).val(parseInt(totalForms.val(), 10) + 1);
|
||||||
|
nextIndex += 1;
|
||||||
|
// Hide add button in case we've hit the max, except we want to add infinitely
|
||||||
|
if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) {
|
||||||
|
addButton.parent().hide();
|
||||||
|
}
|
||||||
|
// The delete button of each row triggers a bunch of other things
|
||||||
|
row.find("a." + options.deleteCssClass).click(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// Remove the parent form containing this button:
|
||||||
|
var row = $(this).parents("." + options.formCssClass);
|
||||||
|
row.remove();
|
||||||
|
nextIndex -= 1;
|
||||||
|
// If a post-delete callback was provided, call it with the deleted form:
|
||||||
|
if (options.removed) {
|
||||||
|
options.removed(row);
|
||||||
|
}
|
||||||
|
// Update the TOTAL_FORMS form count.
|
||||||
|
var forms = $("." + options.formCssClass);
|
||||||
|
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
|
||||||
|
// Show add button again once we drop below max
|
||||||
|
if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) {
|
||||||
|
addButton.parent().show();
|
||||||
|
}
|
||||||
|
// Also, update names and ids for all remaining form controls
|
||||||
|
// so they remain in sequence:
|
||||||
|
var i, formCount;
|
||||||
|
var updateElementCallback = function() {
|
||||||
|
updateElementIndex(this, options.prefix, i);
|
||||||
|
};
|
||||||
|
for (i=0, formCount=forms.length; i<formCount; i++)
|
||||||
|
{
|
||||||
|
updateElementIndex($(forms).get(i), options.prefix, i);
|
||||||
|
$(forms.get(i)).find("*").each(updateElementCallback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// If a post-add callback was supplied, call it with the added form:
|
||||||
|
if (options.added) {
|
||||||
|
options.added(row);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
// If a post-add callback was supplied, call it with the added form:
|
|
||||||
if (options.added) {
|
|
||||||
options.added(row);
|
|
||||||
}
|
}
|
||||||
});
|
return this;
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Setup plugin defaults */
|
|
||||||
$.fn.formset.defaults = {
|
|
||||||
prefix: "form", // The form prefix for your django formset
|
|
||||||
addText: "add another", // Text for the add link
|
|
||||||
deleteText: "remove", // Text for the delete link
|
|
||||||
addCssClass: "add-row", // CSS class applied to the add link
|
|
||||||
deleteCssClass: "delete-row", // CSS class applied to the delete link
|
|
||||||
emptyCssClass: "empty-row", // CSS class applied to the empty row
|
|
||||||
formCssClass: "dynamic-form", // CSS class applied to each form in a formset
|
|
||||||
added: null, // Function called each time a new form is added
|
|
||||||
removed: null // Function called each time a form is deleted
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Tabular inlines ---------------------------------------------------------
|
|
||||||
$.fn.tabularFormset = function(options) {
|
|
||||||
var $rows = $(this);
|
|
||||||
var alternatingRows = function(row) {
|
|
||||||
$($rows.selector).not(".add-row").removeClass("row1 row2")
|
|
||||||
.filter(":even").addClass("row1").end()
|
|
||||||
.filter(":odd").addClass("row2");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var reinitDateTimeShortCuts = function() {
|
/* Setup plugin defaults */
|
||||||
// Reinitialize the calendar and clock widgets by force
|
$.fn.formset.defaults = {
|
||||||
if (typeof DateTimeShortcuts != "undefined") {
|
prefix: "form", // The form prefix for your django formset
|
||||||
$(".datetimeshortcuts").remove();
|
addText: "add another", // Text for the add link
|
||||||
DateTimeShortcuts.init();
|
deleteText: "remove", // Text for the delete link
|
||||||
}
|
addCssClass: "add-row", // CSS class applied to the add link
|
||||||
|
deleteCssClass: "delete-row", // CSS class applied to the delete link
|
||||||
|
emptyCssClass: "empty-row", // CSS class applied to the empty row
|
||||||
|
formCssClass: "dynamic-form", // CSS class applied to each form in a formset
|
||||||
|
added: null, // Function called each time a new form is added
|
||||||
|
removed: null // Function called each time a form is deleted
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateSelectFilter = function() {
|
|
||||||
// If any SelectFilter widgets are a part of the new form,
|
// Tabular inlines ---------------------------------------------------------
|
||||||
// instantiate a new SelectFilter instance for it.
|
$.fn.tabularFormset = function(options) {
|
||||||
if (typeof SelectFilter != 'undefined'){
|
var $rows = $(this);
|
||||||
$('.selectfilter').each(function(index, value){
|
var alternatingRows = function(row) {
|
||||||
var namearr = value.name.split('-');
|
$($rows.selector).not(".add-row").removeClass("row1 row2")
|
||||||
SelectFilter.init(value.id, namearr[namearr.length-1], false);
|
.filter(":even").addClass("row1").end()
|
||||||
|
.filter(":odd").addClass("row2");
|
||||||
|
};
|
||||||
|
|
||||||
|
var reinitDateTimeShortCuts = function() {
|
||||||
|
// Reinitialize the calendar and clock widgets by force
|
||||||
|
if (typeof DateTimeShortcuts !== "undefined") {
|
||||||
|
$(".datetimeshortcuts").remove();
|
||||||
|
DateTimeShortcuts.init();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateSelectFilter = function() {
|
||||||
|
// If any SelectFilter widgets are a part of the new form,
|
||||||
|
// instantiate a new SelectFilter instance for it.
|
||||||
|
if (typeof SelectFilter !== 'undefined') {
|
||||||
|
$('.selectfilter').each(function(index, value) {
|
||||||
|
var namearr = value.name.split('-');
|
||||||
|
SelectFilter.init(value.id, namearr[namearr.length-1], false);
|
||||||
|
});
|
||||||
|
$('.selectfilterstacked').each(function(index, value) {
|
||||||
|
var namearr = value.name.split('-');
|
||||||
|
SelectFilter.init(value.id, namearr[namearr.length-1], true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var initPrepopulatedFields = function(row) {
|
||||||
|
row.find('.prepopulated_field').each(function() {
|
||||||
|
var field = $(this),
|
||||||
|
input = field.find('input, select, textarea'),
|
||||||
|
dependency_list = input.data('dependency_list') || [],
|
||||||
|
dependencies = [];
|
||||||
|
$.each(dependency_list, function(i, field_name) {
|
||||||
|
dependencies.push('#' + row.find('.field-' + field_name).find('input, select, textarea').attr('id'));
|
||||||
|
});
|
||||||
|
if (dependencies.length) {
|
||||||
|
input.prepopulate(dependencies, input.attr('maxlength'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$rows.formset({
|
||||||
|
prefix: options.prefix,
|
||||||
|
addText: options.addText,
|
||||||
|
formCssClass: "dynamic-" + options.prefix,
|
||||||
|
deleteCssClass: "inline-deletelink",
|
||||||
|
deleteText: options.deleteText,
|
||||||
|
emptyCssClass: "empty-form",
|
||||||
|
removed: alternatingRows,
|
||||||
|
added: function(row) {
|
||||||
|
initPrepopulatedFields(row);
|
||||||
|
reinitDateTimeShortCuts();
|
||||||
|
updateSelectFilter();
|
||||||
|
alternatingRows(row);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
$('.selectfilterstacked').each(function(index, value){
|
|
||||||
var namearr = value.name.split('-');
|
return $rows;
|
||||||
SelectFilter.init(value.id, namearr[namearr.length-1], true);
|
};
|
||||||
|
|
||||||
|
// Stacked inlines ---------------------------------------------------------
|
||||||
|
$.fn.stackedFormset = function(options) {
|
||||||
|
var $rows = $(this);
|
||||||
|
var updateInlineLabel = function(row) {
|
||||||
|
$($rows.selector).find(".inline_label").each(function(i) {
|
||||||
|
var count = i + 1;
|
||||||
|
$(this).html($(this).html().replace(/(#\d+)/g, "#" + count));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var reinitDateTimeShortCuts = function() {
|
||||||
|
// Reinitialize the calendar and clock widgets by force, yuck.
|
||||||
|
if (typeof DateTimeShortcuts !== "undefined") {
|
||||||
|
$(".datetimeshortcuts").remove();
|
||||||
|
DateTimeShortcuts.init();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateSelectFilter = function() {
|
||||||
|
// If any SelectFilter widgets were added, instantiate a new instance.
|
||||||
|
if (typeof SelectFilter !== "undefined") {
|
||||||
|
$(".selectfilter").each(function(index, value) {
|
||||||
|
var namearr = value.name.split('-');
|
||||||
|
SelectFilter.init(value.id, namearr[namearr.length-1], false);
|
||||||
|
});
|
||||||
|
$(".selectfilterstacked").each(function(index, value) {
|
||||||
|
var namearr = value.name.split('-');
|
||||||
|
SelectFilter.init(value.id, namearr[namearr.length-1], true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var initPrepopulatedFields = function(row) {
|
||||||
|
row.find('.prepopulated_field').each(function() {
|
||||||
|
var field = $(this),
|
||||||
|
input = field.find('input, select, textarea'),
|
||||||
|
dependency_list = input.data('dependency_list') || [],
|
||||||
|
dependencies = [];
|
||||||
|
$.each(dependency_list, function(i, field_name) {
|
||||||
|
dependencies.push('#' + row.find('.form-row .field-' + field_name).find('input, select, textarea').attr('id'));
|
||||||
|
});
|
||||||
|
if (dependencies.length) {
|
||||||
|
input.prepopulate(dependencies, input.attr('maxlength'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$rows.formset({
|
||||||
|
prefix: options.prefix,
|
||||||
|
addText: options.addText,
|
||||||
|
formCssClass: "dynamic-" + options.prefix,
|
||||||
|
deleteCssClass: "inline-deletelink",
|
||||||
|
deleteText: options.deleteText,
|
||||||
|
emptyCssClass: "empty-form",
|
||||||
|
removed: updateInlineLabel,
|
||||||
|
added: function(row) {
|
||||||
|
initPrepopulatedFields(row);
|
||||||
|
reinitDateTimeShortCuts();
|
||||||
|
updateSelectFilter();
|
||||||
|
updateInlineLabel(row);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
return $rows;
|
||||||
};
|
};
|
||||||
|
|
||||||
var initPrepopulatedFields = function(row) {
|
|
||||||
row.find('.prepopulated_field').each(function() {
|
|
||||||
var field = $(this),
|
|
||||||
input = field.find('input, select, textarea'),
|
|
||||||
dependency_list = input.data('dependency_list') || [],
|
|
||||||
dependencies = [];
|
|
||||||
$.each(dependency_list, function(i, field_name) {
|
|
||||||
dependencies.push('#' + row.find('.field-' + field_name).find('input, select, textarea').attr('id'));
|
|
||||||
});
|
|
||||||
if (dependencies.length) {
|
|
||||||
input.prepopulate(dependencies, input.attr('maxlength'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$rows.formset({
|
|
||||||
prefix: options.prefix,
|
|
||||||
addText: options.addText,
|
|
||||||
formCssClass: "dynamic-" + options.prefix,
|
|
||||||
deleteCssClass: "inline-deletelink",
|
|
||||||
deleteText: options.deleteText,
|
|
||||||
emptyCssClass: "empty-form",
|
|
||||||
removed: alternatingRows,
|
|
||||||
added: function(row) {
|
|
||||||
initPrepopulatedFields(row);
|
|
||||||
reinitDateTimeShortCuts();
|
|
||||||
updateSelectFilter();
|
|
||||||
alternatingRows(row);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return $rows;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Stacked inlines ---------------------------------------------------------
|
|
||||||
$.fn.stackedFormset = function(options) {
|
|
||||||
var $rows = $(this);
|
|
||||||
var updateInlineLabel = function(row) {
|
|
||||||
$($rows.selector).find(".inline_label").each(function(i) {
|
|
||||||
var count = i + 1;
|
|
||||||
$(this).html($(this).html().replace(/(#\d+)/g, "#" + count));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var reinitDateTimeShortCuts = function() {
|
|
||||||
// Reinitialize the calendar and clock widgets by force, yuck.
|
|
||||||
if (typeof DateTimeShortcuts != "undefined") {
|
|
||||||
$(".datetimeshortcuts").remove();
|
|
||||||
DateTimeShortcuts.init();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var updateSelectFilter = function() {
|
|
||||||
// If any SelectFilter widgets were added, instantiate a new instance.
|
|
||||||
if (typeof SelectFilter != "undefined"){
|
|
||||||
$(".selectfilter").each(function(index, value){
|
|
||||||
var namearr = value.name.split('-');
|
|
||||||
SelectFilter.init(value.id, namearr[namearr.length-1], false);
|
|
||||||
});
|
|
||||||
$(".selectfilterstacked").each(function(index, value){
|
|
||||||
var namearr = value.name.split('-');
|
|
||||||
SelectFilter.init(value.id, namearr[namearr.length-1], true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var initPrepopulatedFields = function(row) {
|
|
||||||
row.find('.prepopulated_field').each(function() {
|
|
||||||
var field = $(this),
|
|
||||||
input = field.find('input, select, textarea'),
|
|
||||||
dependency_list = input.data('dependency_list') || [],
|
|
||||||
dependencies = [];
|
|
||||||
$.each(dependency_list, function(i, field_name) {
|
|
||||||
dependencies.push('#' + row.find('.form-row .field-' + field_name).find('input, select, textarea').attr('id'));
|
|
||||||
});
|
|
||||||
if (dependencies.length) {
|
|
||||||
input.prepopulate(dependencies, input.attr('maxlength'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$rows.formset({
|
|
||||||
prefix: options.prefix,
|
|
||||||
addText: options.addText,
|
|
||||||
formCssClass: "dynamic-" + options.prefix,
|
|
||||||
deleteCssClass: "inline-deletelink",
|
|
||||||
deleteText: options.deleteText,
|
|
||||||
emptyCssClass: "empty-form",
|
|
||||||
removed: updateInlineLabel,
|
|
||||||
added: (function(row) {
|
|
||||||
initPrepopulatedFields(row);
|
|
||||||
reinitDateTimeShortCuts();
|
|
||||||
updateSelectFilter();
|
|
||||||
updateInlineLabel(row);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
return $rows;
|
|
||||||
};
|
|
||||||
})(django.jQuery);
|
})(django.jQuery);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
(function(c){c.fn.formset=function(b){var a=c.extend({},c.fn.formset.defaults,b),d=c(this);b=d.parent();var k=function(a,f,l){var h=new RegExp("("+f+"-(\\d+|__prefix__))");f=f+"-"+l;c(a).prop("for")&&c(a).prop("for",c(a).prop("for").replace(h,f));a.id&&(a.id=a.id.replace(h,f));a.name&&(a.name=a.name.replace(h,f))},e=c("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(e.val(),10),f=c("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),e=""===f.val()||0<f.val()-e.val();
|
(function(c){c.fn.formset=function(b){var a=c.extend({},c.fn.formset.defaults,b),d=c(this);b=d.parent();var k=function(a,g,l){var h=new RegExp("("+g+"-(\\d+|__prefix__))");g=g+"-"+l;c(a).prop("for")&&c(a).prop("for",c(a).prop("for").replace(h,g));a.id&&(a.id=a.id.replace(h,g));a.name&&(a.name=a.name.replace(h,g))},f=c("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(f.val(),10),g=c("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),f=""===g.val()||0<g.val()-f.val();
|
||||||
d.each(function(f){c(this).not("."+a.emptyCssClass).addClass(a.formCssClass)});if(d.length&&e){var h;"TR"==d.prop("tagName")?(d=this.eq(-1).children().length,b.append('<tr class="'+a.addCssClass+'"><td colspan="'+d+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),h=b.find("tr:last a")):(d.filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),h=d.filter(":last").next().find("a"));h.click(function(b){b.preventDefault();var d=c("#id_"+a.prefix+
|
d.each(function(g){c(this).not("."+a.emptyCssClass).addClass(a.formCssClass)});if(d.length&&f){var h;"TR"==d.prop("tagName")?(d=this.eq(-1).children().length,b.append('<tr class="'+a.addCssClass+'"><td colspan="'+d+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),h=b.find("tr:last a")):(d.filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),h=d.filter(":last").next().find("a"));h.click(function(b){b.preventDefault();var d=c("#id_"+a.prefix+
|
||||||
"-TOTAL_FORMS");b=c("#"+a.prefix+"-empty");var g=b.clone(!0);g.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);g.is("tr")?g.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):g.is("ul")||g.is("ol")?g.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):g.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+
|
"-TOTAL_FORMS");b=c("#"+a.prefix+"-empty");var e=b.clone(!0);e.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);e.is("tr")?e.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):e.is("ul")||e.is("ol")?e.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):e.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+
|
||||||
"</a></span>");g.find("*").each(function(){k(this,a.prefix,d.val())});g.insertBefore(c(b));c(d).val(parseInt(d.val(),10)+1);l+=1;""!==f.val()&&0>=f.val()-d.val()&&h.parent().hide();g.find("a."+a.deleteCssClass).click(function(b){b.preventDefault();b=c(this).parents("."+a.formCssClass);b.remove();--l;a.removed&&a.removed(b);b=c("."+a.formCssClass);c("#id_"+a.prefix+"-TOTAL_FORMS").val(b.length);(""===f.val()||0<f.val()-b.length)&&h.parent().show();for(var d=0,g=b.length;d<g;d++)k(c(b).get(d),a.prefix,
|
"</a></span>");e.find("*").each(function(){k(this,a.prefix,d.val())});e.insertBefore(c(b));c(d).val(parseInt(d.val(),10)+1);l+=1;""!==g.val()&&0>=g.val()-d.val()&&h.parent().hide();e.find("a."+a.deleteCssClass).click(function(b){b.preventDefault();b=c(this).parents("."+a.formCssClass);b.remove();--l;a.removed&&a.removed(b);b=c("."+a.formCssClass);c("#id_"+a.prefix+"-TOTAL_FORMS").val(b.length);(""===g.val()||0<g.val()-b.length)&&h.parent().show();for(var d=function(){k(this,a.prefix,e)},e=0,f=b.length;e<
|
||||||
d),c(b.get(d)).find("*").each(function(){k(this,a.prefix,d)})});a.added&&a.added(g)})}return this};c.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null};c.fn.tabularFormset=function(b){var a=c(this),d=function(b){c(a.selector).not(".add-row").removeClass("row1 row2").filter(":even").addClass("row1").end().filter(":odd").addClass("row2")},k=function(){"undefined"!=
|
f;e++)k(c(b).get(e),a.prefix,e),c(b.get(e)).find("*").each(d)});a.added&&a.added(e)})}return this};c.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null};c.fn.tabularFormset=function(b){var a=c(this),d=function(b){c(a.selector).not(".add-row").removeClass("row1 row2").filter(":even").addClass("row1").end().filter(":odd").addClass("row2")},k=function(){"undefined"!=
|
||||||
typeof SelectFilter&&(c(".selectfilter").each(function(a,c){var b=c.name.split("-");SelectFilter.init(c.id,b[b.length-1],!1)}),c(".selectfilterstacked").each(function(a,c){var b=c.name.split("-");SelectFilter.init(c.id,b[b.length-1],!0)}))},e=function(a){a.find(".prepopulated_field").each(function(){var b=c(this).find("input, select, textarea"),d=b.data("dependency_list")||[],e=[];c.each(d,function(c,b){e.push("#"+a.find(".field-"+b).find("input, select, textarea").attr("id"))});e.length&&b.prepopulate(e,
|
typeof SelectFilter&&(c(".selectfilter").each(function(a,c){var b=c.name.split("-");SelectFilter.init(c.id,b[b.length-1],!1)}),c(".selectfilterstacked").each(function(a,c){var b=c.name.split("-");SelectFilter.init(c.id,b[b.length-1],!0)}))},f=function(a){a.find(".prepopulated_field").each(function(){var b=c(this).find("input, select, textarea"),d=b.data("dependency_list")||[],f=[];c.each(d,function(c,b){f.push("#"+a.find(".field-"+b).find("input, select, textarea").attr("id"))});f.length&&b.prepopulate(f,
|
||||||
b.attr("maxlength"))})};a.formset({prefix:b.prefix,addText:b.addText,formCssClass:"dynamic-"+b.prefix,deleteCssClass:"inline-deletelink",deleteText:b.deleteText,emptyCssClass:"empty-form",removed:d,added:function(a){e(a);"undefined"!=typeof DateTimeShortcuts&&(c(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();d(a)}});return a};c.fn.stackedFormset=function(b){var a=c(this),d=function(b){c(a.selector).find(".inline_label").each(function(a){a+=1;c(this).html(c(this).html().replace(/(#\d+)/g,
|
b.attr("maxlength"))})};a.formset({prefix:b.prefix,addText:b.addText,formCssClass:"dynamic-"+b.prefix,deleteCssClass:"inline-deletelink",deleteText:b.deleteText,emptyCssClass:"empty-form",removed:d,added:function(a){f(a);"undefined"!=typeof DateTimeShortcuts&&(c(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();d(a)}});return a};c.fn.stackedFormset=function(b){var a=c(this),d=function(b){c(a.selector).find(".inline_label").each(function(a){a+=1;c(this).html(c(this).html().replace(/(#\d+)/g,
|
||||||
"#"+a))})},k=function(){"undefined"!=typeof SelectFilter&&(c(".selectfilter").each(function(a,c){var b=c.name.split("-");SelectFilter.init(c.id,b[b.length-1],!1)}),c(".selectfilterstacked").each(function(a,c){var b=c.name.split("-");SelectFilter.init(c.id,b[b.length-1],!0)}))},e=function(a){a.find(".prepopulated_field").each(function(){var b=c(this).find("input, select, textarea"),d=b.data("dependency_list")||[],e=[];c.each(d,function(b,c){e.push("#"+a.find(".form-row .field-"+c).find("input, select, textarea").attr("id"))});
|
"#"+a))})},k=function(){"undefined"!=typeof SelectFilter&&(c(".selectfilter").each(function(a,c){var b=c.name.split("-");SelectFilter.init(c.id,b[b.length-1],!1)}),c(".selectfilterstacked").each(function(a,c){var b=c.name.split("-");SelectFilter.init(c.id,b[b.length-1],!0)}))},f=function(a){a.find(".prepopulated_field").each(function(){var b=c(this).find("input, select, textarea"),d=b.data("dependency_list")||[],f=[];c.each(d,function(b,c){f.push("#"+a.find(".form-row .field-"+c).find("input, select, textarea").attr("id"))});
|
||||||
e.length&&b.prepopulate(e,b.attr("maxlength"))})};a.formset({prefix:b.prefix,addText:b.addText,formCssClass:"dynamic-"+b.prefix,deleteCssClass:"inline-deletelink",deleteText:b.deleteText,emptyCssClass:"empty-form",removed:d,added:function(a){e(a);"undefined"!=typeof DateTimeShortcuts&&(c(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();d(a)}});return a}})(django.jQuery);
|
f.length&&b.prepopulate(f,b.attr("maxlength"))})};a.formset({prefix:b.prefix,addText:b.addText,formCssClass:"dynamic-"+b.prefix,deleteCssClass:"inline-deletelink",deleteText:b.deleteText,emptyCssClass:"empty-form",removed:d,added:function(a){f(a);"undefined"!=typeof DateTimeShortcuts&&(c(".datetimeshortcuts").remove(),DateTimeShortcuts.init());k();d(a)}});return a}})(django.jQuery);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*global django:true, jQuery:false*/
|
||||||
/* Puts the included jQuery into our own namespace using noConflict and passing
|
/* Puts the included jQuery into our own namespace using noConflict and passing
|
||||||
* it 'true'. This ensures that the included jQuery doesn't pollute the global
|
* it 'true'. This ensures that the included jQuery doesn't pollute the global
|
||||||
* namespace (i.e. this preserves pre-existing values for both window.$ and
|
* namespace (i.e. this preserves pre-existing values for both window.$ and
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*global URLify*/
|
||||||
(function($) {
|
(function($) {
|
||||||
$.fn.prepopulate = function(dependencies, maxLength) {
|
$.fn.prepopulate = function(dependencies, maxLength) {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
(function(b){b.fn.prepopulate=function(e,g){return this.each(function(){var a=b(this),d=function(){if(!a.data("_changed")){var f=[];b.each(e,function(h,c){c=b(c);c.val().length>0&&f.push(c.val())});a.val(URLify(f.join(" "),g))}};a.data("_changed",false);a.change(function(){a.data("_changed",true)});a.val()||b(e.join(",")).keyup(d).change(d).focus(d)})}})(django.jQuery);
|
(function(c){c.fn.prepopulate=function(e,f){return this.each(function(){var a=c(this),b=function(){if(!a.data("_changed")){var b=[];c.each(e,function(a,d){d=c(d);0<d.val().length&&b.push(d.val())});a.val(URLify(b.join(" "),f))}};a.data("_changed",!1);a.change(function(){a.data("_changed",!0)});a.val()||c(e.join(",")).keyup(b).change(b).focus(b)})}})(django.jQuery);
|
||||||
|
|
|
@ -2,7 +2,7 @@ var timeParsePatterns = [
|
||||||
// 9
|
// 9
|
||||||
{ re: /^\d{1,2}$/i,
|
{ re: /^\d{1,2}$/i,
|
||||||
handler: function(bits) {
|
handler: function(bits) {
|
||||||
if (bits[0].length == 1) {
|
if (bits[0].length === 1) {
|
||||||
return '0' + bits[0] + ':00';
|
return '0' + bits[0] + ':00';
|
||||||
} else {
|
} else {
|
||||||
return bits[0] + ':00';
|
return bits[0] + ':00';
|
||||||
|
@ -25,11 +25,11 @@ var timeParsePatterns = [
|
||||||
{ re: /^(\d+)\s*([ap])(?:.?m.?)?$/i,
|
{ re: /^(\d+)\s*([ap])(?:.?m.?)?$/i,
|
||||||
handler: function(bits) {
|
handler: function(bits) {
|
||||||
var hour = parseInt(bits[1]);
|
var hour = parseInt(bits[1]);
|
||||||
if (hour == 12) {
|
if (hour === 12) {
|
||||||
hour = 0;
|
hour = 0;
|
||||||
}
|
}
|
||||||
if (bits[2].toLowerCase() == 'p') {
|
if (bits[2].toLowerCase() === 'p') {
|
||||||
if (hour == 12) {
|
if (hour === 12) {
|
||||||
hour = 0;
|
hour = 0;
|
||||||
}
|
}
|
||||||
return (hour + 12) + ':00';
|
return (hour + 12) + ':00';
|
||||||
|
@ -50,11 +50,11 @@ var timeParsePatterns = [
|
||||||
if (mins < 10) {
|
if (mins < 10) {
|
||||||
mins = '0' + mins;
|
mins = '0' + mins;
|
||||||
}
|
}
|
||||||
if (hour == 12) {
|
if (hour === 12) {
|
||||||
hour = 0;
|
hour = 0;
|
||||||
}
|
}
|
||||||
if (bits[3].toLowerCase() == 'p') {
|
if (bits[3].toLowerCase() === 'p') {
|
||||||
if (hour == 12) {
|
if (hour === 12) {
|
||||||
hour = 0;
|
hour = 0;
|
||||||
}
|
}
|
||||||
return (hour + 12) + ':' + mins;
|
return (hour + 12) + ':' + mins;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
/*global OpenLayers*/
|
||||||
|
/*eslint indent:1*/
|
||||||
(function() {
|
(function() {
|
||||||
/**
|
/**
|
||||||
* Transforms an array of features to a single feature with the merged
|
* Transforms an array of features to a single feature with the merged
|
||||||
* geometry of geom_type
|
* geometry of geom_type
|
||||||
*/
|
*/
|
||||||
OpenLayers.Util.properFeatures = function(features, geom_type) {
|
OpenLayers.Util.properFeatures = function(features, geom_type) {
|
||||||
if (features.constructor == Array) {
|
if (features.constructor === Array) {
|
||||||
var geoms = [];
|
var geoms = [];
|
||||||
for (var i=0; i<features.length; i++) {
|
for (var i=0; i<features.length; i++) {
|
||||||
geoms.push(features[i].geometry);
|
geoms.push(features[i].geometry);
|
||||||
|
@ -13,7 +15,7 @@ OpenLayers.Util.properFeatures = function(features, geom_type) {
|
||||||
features = new OpenLayers.Feature.Vector(geom);
|
features = new OpenLayers.Feature.Vector(geom);
|
||||||
}
|
}
|
||||||
return features;
|
return features;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @requires OpenLayers/Format/WKT.js
|
* @requires OpenLayers/Format/WKT.js
|
||||||
|
@ -128,7 +130,7 @@ OpenLayers.Format.DjangoWKT = OpenLayers.Class(OpenLayers.Format.WKT, {
|
||||||
geometry = geometry.clone();
|
geometry = geometry.clone();
|
||||||
geometry.transform(this.internalProjection, this.externalProjection);
|
geometry.transform(this.internalProjection, this.externalProjection);
|
||||||
}
|
}
|
||||||
var wktType = type == 'collection' ? 'GEOMETRYCOLLECTION' : type.toUpperCase();
|
var wktType = type === 'collection' ? 'GEOMETRYCOLLECTION' : type.toUpperCase();
|
||||||
var data = wktType + '(' + this.extract[type].apply(this, [geometry]) + ')';
|
var data = wktType + '(' + this.extract[type].apply(this, [geometry]) + ')';
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
@ -138,8 +140,8 @@ OpenLayers.Format.DjangoWKT = OpenLayers.Class(OpenLayers.Format.WKT, {
|
||||||
* geometrycollections.
|
* geometrycollections.
|
||||||
*/
|
*/
|
||||||
write: function(features) {
|
write: function(features) {
|
||||||
var collection, geometry, type, data, isCollection;
|
var collection, isCollection;
|
||||||
isCollection = features.geometry.CLASS_NAME == "OpenLayers.Geometry.Collection";
|
isCollection = features.geometry.CLASS_NAME === "OpenLayers.Geometry.Collection";
|
||||||
var pieces = [];
|
var pieces = [];
|
||||||
if (isCollection) {
|
if (isCollection) {
|
||||||
collection = features.geometry.components;
|
collection = features.geometry.components;
|
||||||
|
@ -168,8 +170,8 @@ function MapWidget(options) {
|
||||||
this.wkt_f = new OpenLayers.Format.DjangoWKT();
|
this.wkt_f = new OpenLayers.Format.DjangoWKT();
|
||||||
|
|
||||||
// Mapping from OGRGeomType name to OpenLayers.Geometry name
|
// Mapping from OGRGeomType name to OpenLayers.Geometry name
|
||||||
if (options['geom_name'] == 'Unknown') options['geom_type'] = OpenLayers.Geometry;
|
if (options['geom_name'] === 'Unknown') options['geom_type'] = OpenLayers.Geometry;
|
||||||
else if (options['geom_name'] == 'GeometryCollection') options['geom_type'] = OpenLayers.Geometry.Collection;
|
else if (options['geom_name'] === 'GeometryCollection') options['geom_type'] = OpenLayers.Geometry.Collection;
|
||||||
else options['geom_type'] = eval('OpenLayers.Geometry.' + options['geom_name']);
|
else options['geom_type'] = eval('OpenLayers.Geometry.' + options['geom_name']);
|
||||||
|
|
||||||
// Default options
|
// Default options
|
||||||
|
@ -204,7 +206,7 @@ function MapWidget(options) {
|
||||||
'fillOpacity': this.options.opacity,
|
'fillOpacity': this.options.opacity,
|
||||||
'strokeColor': '#' + this.options.color
|
'strokeColor': '#' + this.options.color
|
||||||
};
|
};
|
||||||
if (this.options.geom_name == 'LineString') {
|
if (this.options.geom_name === 'LineString') {
|
||||||
defaults_style['strokeWidth'] = 3;
|
defaults_style['strokeWidth'] = 3;
|
||||||
}
|
}
|
||||||
var styleMap = new OpenLayers.StyleMap({'default': OpenLayers.Util.applyDefaults(defaults_style, OpenLayers.Feature.Vector.style['default'])});
|
var styleMap = new OpenLayers.StyleMap({'default': OpenLayers.Util.applyDefaults(defaults_style, OpenLayers.Feature.Vector.style['default'])});
|
||||||
|
@ -222,7 +224,7 @@ function MapWidget(options) {
|
||||||
this.layers.vector.addFeatures([feat]);
|
this.layers.vector.addFeatures([feat]);
|
||||||
}
|
}
|
||||||
this.map.zoomToExtent(feat.geometry.getBounds());
|
this.map.zoomToExtent(feat.geometry.getBounds());
|
||||||
if (this.options.geom_name == 'Point') {
|
if (this.options.geom_name === 'Point') {
|
||||||
this.map.zoomTo(this.options.point_zoom);
|
this.map.zoomTo(this.options.point_zoom);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -262,7 +264,7 @@ MapWidget.prototype.create_map = function() {
|
||||||
if (this.options.base_layer) this.layers.base = this.options.base_layer;
|
if (this.options.base_layer) this.layers.base = this.options.base_layer;
|
||||||
else this.layers.base = new OpenLayers.Layer.WMS('OpenLayers WMS', 'http://vmap0.tiles.osgeo.org/wms/vmap0', {layers: 'basic'});
|
else this.layers.base = new OpenLayers.Layer.WMS('OpenLayers WMS', 'http://vmap0.tiles.osgeo.org/wms/vmap0', {layers: 'basic'});
|
||||||
map.addLayer(this.layers.base);
|
map.addLayer(this.layers.base);
|
||||||
return map
|
return map;
|
||||||
};
|
};
|
||||||
|
|
||||||
MapWidget.prototype.get_ewkt = function(feat) {
|
MapWidget.prototype.get_ewkt = function(feat) {
|
||||||
|
@ -270,7 +272,7 @@ MapWidget.prototype.get_ewkt = function(feat) {
|
||||||
};
|
};
|
||||||
|
|
||||||
MapWidget.prototype.read_wkt = function(wkt) {
|
MapWidget.prototype.read_wkt = function(wkt) {
|
||||||
var prefix = 'SRID=' + this.options.map_srid + ';'
|
var prefix = 'SRID=' + this.options.map_srid + ';';
|
||||||
if (wkt.indexOf(prefix) === 0) {
|
if (wkt.indexOf(prefix) === 0) {
|
||||||
wkt = wkt.slice(prefix.length);
|
wkt = wkt.slice(prefix.length);
|
||||||
}
|
}
|
||||||
|
@ -296,7 +298,7 @@ MapWidget.prototype.add_wkt = function(event) {
|
||||||
this.write_wkt(feat);
|
this.write_wkt(feat);
|
||||||
} else {
|
} else {
|
||||||
if (this.layers.vector.features.length > 1) {
|
if (this.layers.vector.features.length > 1) {
|
||||||
old_feats = [this.layers.vector.features[0]];
|
var old_feats = [this.layers.vector.features[0]];
|
||||||
this.layers.vector.removeFeatures(old_feats);
|
this.layers.vector.removeFeatures(old_feats);
|
||||||
this.layers.vector.destroyFeatures(old_feats);
|
this.layers.vector.destroyFeatures(old_feats);
|
||||||
}
|
}
|
||||||
|
@ -306,7 +308,7 @@ MapWidget.prototype.add_wkt = function(event) {
|
||||||
|
|
||||||
MapWidget.prototype.modify_wkt = function(event) {
|
MapWidget.prototype.modify_wkt = function(event) {
|
||||||
if (this.options.is_collection) {
|
if (this.options.is_collection) {
|
||||||
if (this.options.geom_name == 'MultiPoint') {
|
if (this.options.geom_name === 'MultiPoint') {
|
||||||
this.add_wkt(event);
|
this.add_wkt(event);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -359,13 +361,13 @@ MapWidget.prototype.getControls = function(layer) {
|
||||||
this.controls = [new OpenLayers.Control.Navigation()];
|
this.controls = [new OpenLayers.Control.Navigation()];
|
||||||
if (!this.options.modifiable && layer.features.length)
|
if (!this.options.modifiable && layer.features.length)
|
||||||
return;
|
return;
|
||||||
if (this.options.geom_name.indexOf('LineString') >= 0 || this.options.geom_name == 'GeometryCollection' || this.options.geom_name == 'Unknown') {
|
if (this.options.geom_name.indexOf('LineString') >= 0 || this.options.geom_name === 'GeometryCollection' || this.options.geom_name === 'Unknown') {
|
||||||
this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}));
|
this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}));
|
||||||
}
|
}
|
||||||
if (this.options.geom_name.indexOf('Polygon') >= 0 || this.options.geom_name == 'GeometryCollection' || this.options.geom_name == 'Unknown') {
|
if (this.options.geom_name.indexOf('Polygon') >= 0 || this.options.geom_name === 'GeometryCollection' || this.options.geom_name === 'Unknown') {
|
||||||
this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}));
|
this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}));
|
||||||
}
|
}
|
||||||
if (this.options.geom_name.indexOf('Point') >= 0 || this.options.geom_name == 'GeometryCollection' || this.options.geom_name == 'Unknown') {
|
if (this.options.geom_name.indexOf('Point') >= 0 || this.options.geom_name === 'GeometryCollection' || this.options.geom_name === 'Unknown') {
|
||||||
this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}));
|
this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}));
|
||||||
}
|
}
|
||||||
if (this.options.modifiable) {
|
if (this.options.modifiable) {
|
||||||
|
|
|
@ -12,98 +12,98 @@ OpenLayers.Projection.addTransform("EPSG:4326", "EPSG:3857", OpenLayers.Layer.Sp
|
||||||
{{ module }}.is_point = {{ is_point|yesno:"true,false" }};
|
{{ module }}.is_point = {{ is_point|yesno:"true,false" }};
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{{ module }}.get_ewkt = function(feat){
|
{{ module }}.get_ewkt = function(feat){
|
||||||
return 'SRID={{ srid|unlocalize }};' + {{ module }}.wkt_f.write(feat);
|
return 'SRID={{ srid|unlocalize }};' + {{ module }}.wkt_f.write(feat);
|
||||||
};
|
};
|
||||||
{{ module }}.read_wkt = function(wkt){
|
{{ module }}.read_wkt = function(wkt){
|
||||||
// OpenLayers cannot handle EWKT -- we make sure to strip it out.
|
// OpenLayers cannot handle EWKT -- we make sure to strip it out.
|
||||||
// EWKT is only exposed to OL if there's a validation error in the admin.
|
// EWKT is only exposed to OL if there's a validation error in the admin.
|
||||||
var match = {{ module }}.re.exec(wkt);
|
var match = {{ module }}.re.exec(wkt);
|
||||||
if (match){wkt = match[1];}
|
if (match){wkt = match[1];}
|
||||||
return {{ module }}.wkt_f.read(wkt);
|
return {{ module }}.wkt_f.read(wkt);
|
||||||
};
|
};
|
||||||
{{ module }}.write_wkt = function(feat){
|
{{ module }}.write_wkt = function(feat){
|
||||||
if ({{ module }}.is_collection){ {{ module }}.num_geom = feat.geometry.components.length;}
|
if ({{ module }}.is_collection){ {{ module }}.num_geom = feat.geometry.components.length;}
|
||||||
else { {{ module }}.num_geom = 1;}
|
else { {{ module }}.num_geom = 1;}
|
||||||
document.getElementById('{{ id }}').value = {{ module }}.get_ewkt(feat);
|
document.getElementById('{{ id }}').value = {{ module }}.get_ewkt(feat);
|
||||||
};
|
};
|
||||||
{{ module }}.add_wkt = function(event){
|
{{ module }}.add_wkt = function(event){
|
||||||
// This function will sync the contents of the `vector` layer with the
|
// This function will sync the contents of the `vector` layer with the
|
||||||
// WKT in the text field.
|
// WKT in the text field.
|
||||||
if ({{ module }}.is_collection){
|
if ({{ module }}.is_collection){
|
||||||
var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());
|
var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());
|
||||||
for (var i = 0; i < {{ module }}.layers.vector.features.length; i++){
|
for (var i = 0; i < {{ module }}.layers.vector.features.length; i++){
|
||||||
feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]);
|
feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]);
|
||||||
|
}
|
||||||
|
{{ module }}.write_wkt(feat);
|
||||||
|
} else {
|
||||||
|
// Make sure to remove any previously added features.
|
||||||
|
if ({{ module }}.layers.vector.features.length > 1){
|
||||||
|
old_feats = [{{ module }}.layers.vector.features[0]];
|
||||||
|
{{ module }}.layers.vector.removeFeatures(old_feats);
|
||||||
|
{{ module }}.layers.vector.destroyFeatures(old_feats);
|
||||||
|
}
|
||||||
|
{{ module }}.write_wkt(event.feature);
|
||||||
}
|
}
|
||||||
{{ module }}.write_wkt(feat);
|
|
||||||
} else {
|
|
||||||
// Make sure to remove any previously added features.
|
|
||||||
if ({{ module }}.layers.vector.features.length > 1){
|
|
||||||
old_feats = [{{ module }}.layers.vector.features[0]];
|
|
||||||
{{ module }}.layers.vector.removeFeatures(old_feats);
|
|
||||||
{{ module }}.layers.vector.destroyFeatures(old_feats);
|
|
||||||
}
|
|
||||||
{{ module }}.write_wkt(event.feature);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
{{ module }}.modify_wkt = function(event){
|
{{ module }}.modify_wkt = function(event){
|
||||||
if ({{ module }}.is_collection){
|
if ({{ module }}.is_collection){
|
||||||
if ({{ module }}.is_point){
|
if ({{ module }}.is_point){
|
||||||
{{ module }}.add_wkt(event);
|
{{ module }}.add_wkt(event);
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
// When modifying the selected components are added to the
|
||||||
|
// vector layer so we only increment to the `num_geom` value.
|
||||||
|
var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());
|
||||||
|
for (var i = 0; i < {{ module }}.num_geom; i++){
|
||||||
|
feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]);
|
||||||
|
}
|
||||||
|
{{ module }}.write_wkt(feat);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// When modifying the selected components are added to the
|
{{ module }}.write_wkt(event.feature);
|
||||||
// vector layer so we only increment to the `num_geom` value.
|
|
||||||
var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());
|
|
||||||
for (var i = 0; i < {{ module }}.num_geom; i++){
|
|
||||||
feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]);
|
|
||||||
}
|
|
||||||
{{ module }}.write_wkt(feat);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
{{ module }}.write_wkt(event.feature);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
// Function to clear vector features and purge wkt from div
|
// Function to clear vector features and purge wkt from div
|
||||||
{{ module }}.deleteFeatures = function(){
|
{{ module }}.deleteFeatures = function(){
|
||||||
{{ module }}.layers.vector.removeFeatures({{ module }}.layers.vector.features);
|
{{ module }}.layers.vector.removeFeatures({{ module }}.layers.vector.features);
|
||||||
{{ module }}.layers.vector.destroyFeatures();
|
{{ module }}.layers.vector.destroyFeatures();
|
||||||
};
|
};
|
||||||
{{ module }}.clearFeatures = function (){
|
{{ module }}.clearFeatures = function (){
|
||||||
{{ module }}.deleteFeatures();
|
{{ module }}.deleteFeatures();
|
||||||
document.getElementById('{{ id }}').value = '';
|
document.getElementById('{{ id }}').value = '';
|
||||||
{% localize off %}
|
{% localize off %}
|
||||||
{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});
|
{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});
|
||||||
{% endlocalize %}
|
{% endlocalize %}
|
||||||
};
|
};
|
||||||
// Add Select control
|
// Add Select control
|
||||||
{{ module }}.addSelectControl = function(){
|
{{ module }}.addSelectControl = function(){
|
||||||
var select = new OpenLayers.Control.SelectFeature({{ module }}.layers.vector, {'toggle' : true, 'clickout' : true});
|
var select = new OpenLayers.Control.SelectFeature({{ module }}.layers.vector, {'toggle' : true, 'clickout' : true});
|
||||||
{{ module }}.map.addControl(select);
|
{{ module }}.map.addControl(select);
|
||||||
select.activate();
|
select.activate();
|
||||||
};
|
};
|
||||||
{{ module }}.enableDrawing = function(){
|
{{ module }}.enableDrawing = function(){
|
||||||
{{ module }}.map.getControlsByClass('OpenLayers.Control.DrawFeature')[0].activate();
|
{{ module }}.map.getControlsByClass('OpenLayers.Control.DrawFeature')[0].activate();
|
||||||
};
|
};
|
||||||
{{ module }}.enableEditing = function(){
|
{{ module }}.enableEditing = function(){
|
||||||
{{ module }}.map.getControlsByClass('OpenLayers.Control.ModifyFeature')[0].activate();
|
{{ module }}.map.getControlsByClass('OpenLayers.Control.ModifyFeature')[0].activate();
|
||||||
};
|
};
|
||||||
// Create an array of controls based on geometry type
|
// Create an array of controls based on geometry type
|
||||||
{{ module }}.getControls = function(lyr){
|
{{ module }}.getControls = function(lyr){
|
||||||
{{ module }}.panel = new OpenLayers.Control.Panel({'displayClass': 'olControlEditingToolbar'});
|
{{ module }}.panel = new OpenLayers.Control.Panel({'displayClass': 'olControlEditingToolbar'});
|
||||||
{{ module }}.controls = [new OpenLayers.Control.Navigation()];
|
{{ module }}.controls = [new OpenLayers.Control.Navigation()];
|
||||||
if (!{{ module }}.modifiable && lyr.features.length) return;
|
if (!{{ module }}.modifiable && lyr.features.length) return;
|
||||||
if ({{ module }}.is_linestring || {{ module }}.is_generic){
|
if ({{ module }}.is_linestring || {{ module }}.is_generic){
|
||||||
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}));
|
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}));
|
||||||
}
|
}
|
||||||
if ({{ module }}.is_polygon || {{ module }}.is_generic){
|
if ({{ module }}.is_polygon || {{ module }}.is_generic){
|
||||||
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}));
|
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}));
|
||||||
}
|
}
|
||||||
if ({{ module }}.is_point || {{ module }}.is_generic){
|
if ({{ module }}.is_point || {{ module }}.is_generic){
|
||||||
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}));
|
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}));
|
||||||
}
|
}
|
||||||
if ({{ module }}.modifiable){
|
if ({{ module }}.modifiable){
|
||||||
{{ module }}.controls.push(new OpenLayers.Control.ModifyFeature(lyr, {'displayClass': 'olControlModifyFeature'}));
|
{{ module }}.controls.push(new OpenLayers.Control.ModifyFeature(lyr, {'displayClass': 'olControlModifyFeature'}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
{{ module }}.init = function(){
|
{{ module }}.init = function(){
|
||||||
{% block map_options %}// The options hash, w/ zoom, resolution, and projection settings.
|
{% block map_options %}// The options hash, w/ zoom, resolution, and projection settings.
|
||||||
|
@ -124,28 +124,28 @@ OpenLayers.Projection.addTransform("EPSG:4326", "EPSG:3857", OpenLayers.Layer.Sp
|
||||||
// Read WKT from the text field.
|
// Read WKT from the text field.
|
||||||
var wkt = document.getElementById('{{ id }}').value;
|
var wkt = document.getElementById('{{ id }}').value;
|
||||||
if (wkt){
|
if (wkt){
|
||||||
// After reading into geometry, immediately write back to
|
// After reading into geometry, immediately write back to
|
||||||
// WKT <textarea> as EWKT (so that SRID is included).
|
// WKT <textarea> as EWKT (so that SRID is included).
|
||||||
var admin_geom = {{ module }}.read_wkt(wkt);
|
var admin_geom = {{ module }}.read_wkt(wkt);
|
||||||
{{ module }}.write_wkt(admin_geom);
|
{{ module }}.write_wkt(admin_geom);
|
||||||
if ({{ module }}.is_collection){
|
if ({{ module }}.is_collection){
|
||||||
// If geometry collection, add each component individually so they may be
|
// If geometry collection, add each component individually so they may be
|
||||||
// edited individually.
|
// edited individually.
|
||||||
for (var i = 0; i < {{ module }}.num_geom; i++){
|
for (var i = 0; i < {{ module }}.num_geom; i++){
|
||||||
{{ module }}.layers.vector.addFeatures([new OpenLayers.Feature.Vector(admin_geom.geometry.components[i].clone())]);
|
{{ module }}.layers.vector.addFeatures([new OpenLayers.Feature.Vector(admin_geom.geometry.components[i].clone())]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
{{ module }}.layers.vector.addFeatures([admin_geom]);
|
||||||
|
}
|
||||||
|
// Zooming to the bounds.
|
||||||
|
{{ module }}.map.zoomToExtent(admin_geom.geometry.getBounds());
|
||||||
|
if ({{ module }}.is_point){
|
||||||
|
{{ module }}.map.zoomTo({{ point_zoom }});
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
{{ module }}.layers.vector.addFeatures([admin_geom]);
|
|
||||||
}
|
|
||||||
// Zooming to the bounds.
|
|
||||||
{{ module }}.map.zoomToExtent(admin_geom.geometry.getBounds());
|
|
||||||
if ({{ module }}.is_point){
|
|
||||||
{{ module }}.map.zoomTo({{ point_zoom }});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
{% localize off %}
|
{% localize off %}
|
||||||
{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});
|
{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});
|
||||||
{% endlocalize %}
|
{% endlocalize %}
|
||||||
}
|
}
|
||||||
// This allows editing of the geographic fields -- the modified WKT is
|
// This allows editing of the geographic fields -- the modified WKT is
|
||||||
// written back to the content field (as EWKT, so that the ORM will know
|
// written back to the content field (as EWKT, so that the ORM will know
|
||||||
|
@ -167,10 +167,10 @@ OpenLayers.Projection.addTransform("EPSG:4326", "EPSG:3857", OpenLayers.Layer.Sp
|
||||||
{% if not scrollable %}{{ module }}.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();{% endif %}
|
{% if not scrollable %}{{ module }}.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
if (wkt){
|
if (wkt){
|
||||||
if ({{ module }}.modifiable){
|
if ({{ module }}.modifiable){
|
||||||
{{ module }}.enableEditing();
|
{{ module }}.enableEditing();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
{{ module }}.enableDrawing();
|
{{ module }}.enableDrawing();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,11 @@ Please follow these coding standards when writing code for inclusion in Django.
|
||||||
Python style
|
Python style
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
* Please conform to the indentation style dictated in the ``.editorconfig``
|
||||||
|
file. We recommend using a text editor with `EditorConfig`_ support to avoid
|
||||||
|
indentation and whitespace issues. The Python files use 4 spaces for
|
||||||
|
indentation and the HTML files use 2 spaces.
|
||||||
|
|
||||||
* Unless otherwise specified, follow :pep:`8`.
|
* Unless otherwise specified, follow :pep:`8`.
|
||||||
|
|
||||||
Use `flake8`_ to check for problems in this area. Note that our ``setup.cfg``
|
Use `flake8`_ to check for problems in this area. Note that our ``setup.cfg``
|
||||||
|
@ -286,4 +291,11 @@ Miscellaneous
|
||||||
change to the ``AUTHORS`` file in your patch if you make more than a
|
change to the ``AUTHORS`` file in your patch if you make more than a
|
||||||
single trivial change.
|
single trivial change.
|
||||||
|
|
||||||
|
JavaScript style
|
||||||
|
----------------
|
||||||
|
|
||||||
|
For details about the JavaScript code style used by Django, see
|
||||||
|
:doc:`javascript`.
|
||||||
|
|
||||||
|
.. _editorconfig: http://editorconfig.org/
|
||||||
.. _flake8: https://pypi.python.org/pypi/flake8
|
.. _flake8: https://pypi.python.org/pypi/flake8
|
||||||
|
|
|
@ -13,3 +13,4 @@ chances to be included in Django core:
|
||||||
unit-tests
|
unit-tests
|
||||||
submitting-patches
|
submitting-patches
|
||||||
working-with-git
|
working-with-git
|
||||||
|
javascript
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
==========
|
||||||
|
JavaScript
|
||||||
|
==========
|
||||||
|
|
||||||
|
While most of Django core is Python, the ``admin`` and ``gis`` contrib apps
|
||||||
|
contain JavaScript code.
|
||||||
|
|
||||||
|
Please follow these coding standards when writing JavaScript code for inclusion
|
||||||
|
in Django.
|
||||||
|
|
||||||
|
Code style
|
||||||
|
----------
|
||||||
|
|
||||||
|
* Please conform to the indentation style dictated in the ``.editorconfig``
|
||||||
|
file. We recommend using a text editor with `EditorConfig`_ support to avoid
|
||||||
|
indentation and whitespace issues. Most of the JavaScript files use 4 spaces
|
||||||
|
for indentation, but there are some exceptions.
|
||||||
|
|
||||||
|
* When naming variables, use ``camelCase`` instead of ``underscore_case``.
|
||||||
|
Different JavaScript files sometimes use a different code style. Please try to
|
||||||
|
conform to the code style of each file.
|
||||||
|
|
||||||
|
* Use the `JSHint`_ code linter to check your code for bugs and style errors.
|
||||||
|
JSHint will be run when you run the JavaScript tests. We also recommended
|
||||||
|
installing a JSHint plugin in your text editor.
|
||||||
|
|
||||||
|
.. _javascript-patches:
|
||||||
|
|
||||||
|
JavaScript patches
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Django's admin system leverages the jQuery framework to increase the
|
||||||
|
capabilities of the admin interface. In conjunction, there is an emphasis on
|
||||||
|
admin JavaScript performance and minimizing overall admin media file size.
|
||||||
|
Serving compressed or "minified" versions of JavaScript files is considered
|
||||||
|
best practice in this regard.
|
||||||
|
|
||||||
|
To that end, patches for JavaScript files should include both the original
|
||||||
|
code for future development (e.g. ``foo.js``), and a compressed version for
|
||||||
|
production use (e.g. ``foo.min.js``). Any links to the file in the codebase
|
||||||
|
should point to the compressed version.
|
||||||
|
|
||||||
|
Compressing JavaScript
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
To simplify the process of providing optimized JavaScript code, Django
|
||||||
|
includes a handy Python script which should be used to create a "minified"
|
||||||
|
version. To run it::
|
||||||
|
|
||||||
|
python django/contrib/admin/bin/compress.py
|
||||||
|
|
||||||
|
Behind the scenes, ``compress.py`` is a front-end for Google's
|
||||||
|
`Closure Compiler`_ which is written in Java. However, the Closure Compiler
|
||||||
|
library is not bundled with Django directly, so those wishing to contribute
|
||||||
|
complete JavaScript patches will need to download and install the library
|
||||||
|
independently. The Closure Compiler library requires `Java`_ 7 or higher.
|
||||||
|
|
||||||
|
Please don't forget to run ``compress.py`` and include the ``diff`` of the
|
||||||
|
minified scripts when submitting patches for Django's JavaScript.
|
||||||
|
|
||||||
|
.. _Closure Compiler: https://developers.google.com/closure/compiler/
|
||||||
|
.. _EditorConfig: http://editorconfig.org/
|
||||||
|
.. _Java: https://www.java.com
|
||||||
|
.. _jshint: http://jshint.com/
|
|
@ -145,6 +145,8 @@ Regardless of the way you submit your work, follow these steps.
|
||||||
obvious that the ticket includes a patch, and it will add the ticket to
|
obvious that the ticket includes a patch, and it will add the ticket to
|
||||||
the `list of tickets with patches`_.
|
the `list of tickets with patches`_.
|
||||||
|
|
||||||
|
.. _list of tickets with patches: https://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority
|
||||||
|
.. _ticket tracker: https://code.djangoproject.com/newticket
|
||||||
|
|
||||||
Non-trivial patches
|
Non-trivial patches
|
||||||
-------------------
|
-------------------
|
||||||
|
@ -245,39 +247,8 @@ the new version are removed.
|
||||||
JavaScript patches
|
JavaScript patches
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Django's admin system leverages the jQuery framework to increase the
|
For information on JavaScript patches, see the :ref:`javascript-patches`
|
||||||
capabilities of the admin interface. In conjunction, there is an emphasis on
|
documentation.
|
||||||
admin JavaScript performance and minimizing overall admin media file size.
|
|
||||||
Serving compressed or "minified" versions of JavaScript files is considered
|
|
||||||
best practice in this regard.
|
|
||||||
|
|
||||||
To that end, patches for JavaScript files should include both the original
|
|
||||||
code for future development (e.g. ``foo.js``), and a compressed version for
|
|
||||||
production use (e.g. ``foo.min.js``). Any links to the file in the codebase
|
|
||||||
should point to the compressed version.
|
|
||||||
|
|
||||||
Compressing JavaScript
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
To simplify the process of providing optimized JavaScript code, Django
|
|
||||||
includes a handy Python script which should be used to create a "minified"
|
|
||||||
version. To run it::
|
|
||||||
|
|
||||||
python django/contrib/admin/bin/compress.py
|
|
||||||
|
|
||||||
Behind the scenes, ``compress.py`` is a front-end for Google's
|
|
||||||
`Closure Compiler`_ which is written in Java. However, the Closure Compiler
|
|
||||||
library is not bundled with Django directly, so those wishing to contribute
|
|
||||||
complete JavaScript patches will need to download and install the library
|
|
||||||
independently. The Closure Compiler library requires `Java`_ 7 or higher.
|
|
||||||
|
|
||||||
Please don't forget to run ``compress.py`` and include the ``diff`` of the
|
|
||||||
minified scripts when submitting patches for Django's JavaScript.
|
|
||||||
|
|
||||||
.. _Closure Compiler: https://developers.google.com/closure/compiler/
|
|
||||||
.. _list of tickets with patches: https://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority
|
|
||||||
.. _ticket tracker: https://code.djangoproject.com/newticket
|
|
||||||
.. _Java: https://www.java.com
|
|
||||||
|
|
||||||
.. _patch-review-checklist:
|
.. _patch-review-checklist:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"name": "Django",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"pretest": "eslint django/"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^0.22.1"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue