merb-admin 0.8.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. data/.gitignore +29 -27
  2. data/Gemfile +24 -22
  3. data/Gemfile.lock +86 -0
  4. data/LICENSE +20 -20
  5. data/README.rdoc +54 -58
  6. data/Rakefile +11 -44
  7. data/app/controllers/application.rb +6 -6
  8. data/app/controllers/main.rb +191 -191
  9. data/app/helpers/application_helper.rb +64 -64
  10. data/app/helpers/main_helper.rb +167 -167
  11. data/app/models/.gitkeep +0 -0
  12. data/app/views/layout/_message.html.erb +10 -10
  13. data/app/views/layout/dashboard.html.erb +34 -34
  14. data/app/views/layout/form.html.erb +48 -48
  15. data/app/views/layout/list.html.erb +42 -42
  16. data/app/views/main/_belongs_to.html.erb +29 -29
  17. data/app/views/main/_big_decimal.html.erb +12 -12
  18. data/app/views/main/_boolean.html.erb +7 -7
  19. data/app/views/main/_date.html.erb +12 -12
  20. data/app/views/main/_datetime.html.erb +12 -12
  21. data/app/views/main/_float.html.erb +12 -12
  22. data/app/views/main/_has_many.html.erb +16 -16
  23. data/app/views/main/_has_one.html.erb +30 -30
  24. data/app/views/main/_integer.html.erb +12 -12
  25. data/app/views/main/_properties.html.erb +18 -18
  26. data/app/views/main/_string.html.erb +15 -15
  27. data/app/views/main/_text.html.erb +11 -11
  28. data/app/views/main/_time.html.erb +12 -12
  29. data/app/views/main/_timestamp.html.erb +12 -12
  30. data/app/views/main/delete.html.erb +28 -28
  31. data/app/views/main/edit.html.erb +19 -19
  32. data/app/views/main/index.html.erb +22 -22
  33. data/app/views/main/list.html.erb +93 -93
  34. data/app/views/main/new.html.erb +16 -16
  35. data/config/init.rb +30 -0
  36. data/config/router.rb +4 -0
  37. data/lib/abstract_model.rb +84 -86
  38. data/lib/active_record_support.rb +147 -147
  39. data/lib/datamapper_support.rb +139 -140
  40. data/lib/generic_support.rb +13 -13
  41. data/lib/merb-admin.rb +99 -99
  42. data/lib/merb-admin/merbtasks.rb +103 -103
  43. data/lib/merb-admin/slicetasks.rb +174 -174
  44. data/lib/merb-admin/spectasks.rb +55 -55
  45. data/lib/merb-admin/version.rb +3 -0
  46. data/lib/sequel_support.rb +275 -275
  47. data/merb-admin.gemspec +42 -232
  48. data/public/javascripts/CollapsedFieldsets.js +85 -85
  49. data/public/javascripts/DateTimeShortcuts.js +255 -255
  50. data/public/javascripts/RelatedObjectLookups.js +96 -96
  51. data/public/javascripts/SelectBox.js +111 -111
  52. data/public/javascripts/SelectFilter2.js +113 -113
  53. data/public/javascripts/actions.js +39 -39
  54. data/public/javascripts/calendar.js +143 -143
  55. data/public/javascripts/core.js +176 -176
  56. data/public/javascripts/dateparse.js +233 -233
  57. data/public/javascripts/getElementsBySelector.js +167 -167
  58. data/public/javascripts/i18n.js +33 -33
  59. data/public/javascripts/ordering.js +137 -137
  60. data/public/javascripts/timeparse.js +94 -94
  61. data/public/javascripts/urlify.js +140 -140
  62. data/public/stylesheets/base.css +746 -746
  63. data/public/stylesheets/changelists.css +269 -269
  64. data/public/stylesheets/dashboard.css +24 -24
  65. data/public/stylesheets/forms.css +327 -327
  66. data/public/stylesheets/global.css +142 -142
  67. data/public/stylesheets/ie.css +50 -50
  68. data/public/stylesheets/layout.css +29 -29
  69. data/public/stylesheets/login.css +54 -54
  70. data/public/stylesheets/master.css +1 -1
  71. data/public/stylesheets/patch-iewin.css +7 -7
  72. data/public/stylesheets/rtl.css +206 -206
  73. data/public/stylesheets/widgets.css +506 -506
  74. data/screenshots/create.png +0 -0
  75. data/screenshots/delete.png +0 -0
  76. data/screenshots/edit.png +0 -0
  77. data/screenshots/index.png +0 -0
  78. data/screenshots/list.png +0 -0
  79. data/screenshots/new.png +0 -0
  80. data/spec/controllers/main_spec.rb +25 -25
  81. data/spec/migrations/activerecord/001_create_divisions_migration.rb +13 -13
  82. data/spec/migrations/activerecord/002_create_drafts_migration.rb +19 -19
  83. data/spec/migrations/activerecord/003_create_leagues_migration.rb +12 -12
  84. data/spec/migrations/activerecord/004_create_players_migration.rb +19 -20
  85. data/spec/migrations/activerecord/005_create_teams_migration.rb +22 -22
  86. data/spec/migrations/sequel/001_create_divisions_migration.rb +15 -15
  87. data/spec/migrations/sequel/002_create_drafts_migration.rb +21 -21
  88. data/spec/migrations/sequel/003_create_leagues_migration.rb +14 -14
  89. data/spec/migrations/sequel/004_create_players_migration.rb +21 -22
  90. data/spec/migrations/sequel/005_create_teams_migration.rb +24 -24
  91. data/spec/models/activerecord/division.rb +7 -7
  92. data/spec/models/activerecord/draft.rb +11 -11
  93. data/spec/models/activerecord/league.rb +6 -6
  94. data/spec/models/activerecord/player.rb +8 -8
  95. data/spec/models/activerecord/team.rb +13 -13
  96. data/spec/models/datamapper/division.rb +12 -12
  97. data/spec/models/datamapper/draft.rb +18 -18
  98. data/spec/models/datamapper/league.rb +11 -11
  99. data/spec/models/datamapper/player.rb +20 -21
  100. data/spec/models/datamapper/team.rb +22 -22
  101. data/spec/models/sequel/division.rb +15 -15
  102. data/spec/models/sequel/draft.rb +19 -19
  103. data/spec/models/sequel/league.rb +14 -14
  104. data/spec/models/sequel/player.rb +18 -18
  105. data/spec/models/sequel/team.rb +21 -21
  106. data/spec/requests/main_spec.rb +763 -763
  107. data/spec/spec_helper.rb +113 -112
  108. metadata +247 -41
  109. data/VERSION +0 -1
@@ -1,96 +1,96 @@
1
- // Handles related-objects functionality: lookup link for raw_id_fields
2
- // and Add Another links.
3
-
4
- function html_unescape(text) {
5
- // Unescape a string that was escaped using django.utils.html.escape.
6
- text = text.replace(/&lt;/g, '<');
7
- text = text.replace(/&gt;/g, '>');
8
- text = text.replace(/&quot;/g, '"');
9
- text = text.replace(/&#39;/g, "'");
10
- text = text.replace(/&amp;/g, '&');
11
- return text;
12
- }
13
-
14
- // IE doesn't accept periods or dashes in the window name, but the element IDs
15
- // we use to generate popup window names may contain them, therefore we map them
16
- // to allowed characters in a reversible way so that we can locate the correct
17
- // element when the popup window is dismissed.
18
- function id_to_windowname(text) {
19
- text = text.replace(/\./g, '__dot__');
20
- text = text.replace(/\-/g, '__dash__');
21
- return text;
22
- }
23
-
24
- function windowname_to_id(text) {
25
- text = text.replace(/__dot__/g, '.');
26
- text = text.replace(/__dash__/g, '-');
27
- return text;
28
- }
29
-
30
- function showRelatedObjectLookupPopup(triggeringLink) {
31
- var name = triggeringLink.id.replace(/^lookup_/, '');
32
- name = id_to_windowname(name);
33
- var href;
34
- if (triggeringLink.href.search(/\?/) >= 0) {
35
- href = triggeringLink.href + '&pop=1';
36
- } else {
37
- href = triggeringLink.href + '?pop=1';
38
- }
39
- var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
40
- win.focus();
41
- return false;
42
- }
43
-
44
- function dismissRelatedLookupPopup(win, chosenId) {
45
- var name = windowname_to_id(win.name);
46
- var elem = document.getElementById(name);
47
- if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
48
- elem.value += ',' + chosenId;
49
- } else {
50
- document.getElementById(name).value = chosenId;
51
- }
52
- win.close();
53
- }
54
-
55
- function showAddAnotherPopup(triggeringLink) {
56
- var name = triggeringLink.id.replace(/^add_/, '');
57
- name = id_to_windowname(name);
58
- href = triggeringLink.href
59
- if (href.indexOf('?') == -1) {
60
- href += '?_popup=1';
61
- } else {
62
- href += '&_popup=1';
63
- }
64
- var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
65
- win.focus();
66
- return false;
67
- }
68
-
69
- function dismissAddAnotherPopup(win, newId, newRepr) {
70
- // newId and newRepr are expected to have previously been escaped by
71
- // django.utils.html.escape.
72
- newId = html_unescape(newId);
73
- newRepr = html_unescape(newRepr);
74
- var name = windowname_to_id(win.name);
75
- var elem = document.getElementById(name);
76
- if (elem) {
77
- if (elem.nodeName == 'SELECT') {
78
- var o = new Option(newRepr, newId);
79
- elem.options[elem.options.length] = o;
80
- o.selected = true;
81
- } else if (elem.nodeName == 'INPUT') {
82
- if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
83
- elem.value += ',' + newId;
84
- } else {
85
- elem.value = newId;
86
- }
87
- }
88
- } else {
89
- var toId = name + "_to";
90
- elem = document.getElementById(toId);
91
- var o = new Option(newRepr, newId);
92
- SelectBox.add_to_cache(toId, o);
93
- SelectBox.redisplay(toId);
94
- }
95
- win.close();
96
- }
1
+ // Handles related-objects functionality: lookup link for raw_id_fields
2
+ // and Add Another links.
3
+
4
+ function html_unescape(text) {
5
+ // Unescape a string that was escaped using django.utils.html.escape.
6
+ text = text.replace(/&lt;/g, '<');
7
+ text = text.replace(/&gt;/g, '>');
8
+ text = text.replace(/&quot;/g, '"');
9
+ text = text.replace(/&#39;/g, "'");
10
+ text = text.replace(/&amp;/g, '&');
11
+ return text;
12
+ }
13
+
14
+ // IE doesn't accept periods or dashes in the window name, but the element IDs
15
+ // we use to generate popup window names may contain them, therefore we map them
16
+ // to allowed characters in a reversible way so that we can locate the correct
17
+ // element when the popup window is dismissed.
18
+ function id_to_windowname(text) {
19
+ text = text.replace(/\./g, '__dot__');
20
+ text = text.replace(/\-/g, '__dash__');
21
+ return text;
22
+ }
23
+
24
+ function windowname_to_id(text) {
25
+ text = text.replace(/__dot__/g, '.');
26
+ text = text.replace(/__dash__/g, '-');
27
+ return text;
28
+ }
29
+
30
+ function showRelatedObjectLookupPopup(triggeringLink) {
31
+ var name = triggeringLink.id.replace(/^lookup_/, '');
32
+ name = id_to_windowname(name);
33
+ var href;
34
+ if (triggeringLink.href.search(/\?/) >= 0) {
35
+ href = triggeringLink.href + '&pop=1';
36
+ } else {
37
+ href = triggeringLink.href + '?pop=1';
38
+ }
39
+ var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
40
+ win.focus();
41
+ return false;
42
+ }
43
+
44
+ function dismissRelatedLookupPopup(win, chosenId) {
45
+ var name = windowname_to_id(win.name);
46
+ var elem = document.getElementById(name);
47
+ if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
48
+ elem.value += ',' + chosenId;
49
+ } else {
50
+ document.getElementById(name).value = chosenId;
51
+ }
52
+ win.close();
53
+ }
54
+
55
+ function showAddAnotherPopup(triggeringLink) {
56
+ var name = triggeringLink.id.replace(/^add_/, '');
57
+ name = id_to_windowname(name);
58
+ href = triggeringLink.href
59
+ if (href.indexOf('?') == -1) {
60
+ href += '?_popup=1';
61
+ } else {
62
+ href += '&_popup=1';
63
+ }
64
+ var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
65
+ win.focus();
66
+ return false;
67
+ }
68
+
69
+ function dismissAddAnotherPopup(win, newId, newRepr) {
70
+ // newId and newRepr are expected to have previously been escaped by
71
+ // django.utils.html.escape.
72
+ newId = html_unescape(newId);
73
+ newRepr = html_unescape(newRepr);
74
+ var name = windowname_to_id(win.name);
75
+ var elem = document.getElementById(name);
76
+ if (elem) {
77
+ if (elem.nodeName == 'SELECT') {
78
+ var o = new Option(newRepr, newId);
79
+ elem.options[elem.options.length] = o;
80
+ o.selected = true;
81
+ } else if (elem.nodeName == 'INPUT') {
82
+ if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
83
+ elem.value += ',' + newId;
84
+ } else {
85
+ elem.value = newId;
86
+ }
87
+ }
88
+ } else {
89
+ var toId = name + "_to";
90
+ elem = document.getElementById(toId);
91
+ var o = new Option(newRepr, newId);
92
+ SelectBox.add_to_cache(toId, o);
93
+ SelectBox.redisplay(toId);
94
+ }
95
+ win.close();
96
+ }
@@ -1,111 +1,111 @@
1
- var SelectBox = {
2
- cache: new Object(),
3
- init: function(id) {
4
- var box = document.getElementById(id);
5
- var node;
6
- SelectBox.cache[id] = new Array();
7
- var cache = SelectBox.cache[id];
8
- for (var i = 0; (node = box.options[i]); i++) {
9
- cache.push({value: node.value, text: node.text, displayed: 1});
10
- }
11
- },
12
- redisplay: function(id) {
13
- // Repopulate HTML select box from cache
14
- var box = document.getElementById(id);
15
- box.options.length = 0; // clear all options
16
- for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) {
17
- var node = SelectBox.cache[id][i];
18
- if (node.displayed) {
19
- box.options[box.options.length] = new Option(node.text, node.value, false, false);
20
- }
21
- }
22
- },
23
- filter: function(id, text) {
24
- // Redisplay the HTML select box, displaying only the choices containing ALL
25
- // the words in text. (It's an AND search.)
26
- var tokens = text.toLowerCase().split(/\s+/);
27
- var node, token;
28
- for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
29
- node.displayed = 1;
30
- for (var j = 0; (token = tokens[j]); j++) {
31
- if (node.text.toLowerCase().indexOf(token) == -1) {
32
- node.displayed = 0;
33
- }
34
- }
35
- }
36
- SelectBox.redisplay(id);
37
- },
38
- delete_from_cache: function(id, value) {
39
- var node, delete_index = null;
40
- for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
41
- if (node.value == value) {
42
- delete_index = i;
43
- break;
44
- }
45
- }
46
- var j = SelectBox.cache[id].length - 1;
47
- for (var i = delete_index; i < j; i++) {
48
- SelectBox.cache[id][i] = SelectBox.cache[id][i+1];
49
- }
50
- SelectBox.cache[id].length--;
51
- },
52
- add_to_cache: function(id, option) {
53
- SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1});
54
- },
55
- cache_contains: function(id, value) {
56
- // Check if an item is contained in the cache
57
- var node;
58
- for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
59
- if (node.value == value) {
60
- return true;
61
- }
62
- }
63
- return false;
64
- },
65
- move: function(from, to) {
66
- var from_box = document.getElementById(from);
67
- var to_box = document.getElementById(to);
68
- var option;
69
- for (var i = 0; (option = from_box.options[i]); i++) {
70
- if (option.selected && SelectBox.cache_contains(from, option.value)) {
71
- SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1});
72
- SelectBox.delete_from_cache(from, option.value);
73
- }
74
- }
75
- SelectBox.redisplay(from);
76
- SelectBox.redisplay(to);
77
- },
78
- move_all: function(from, to) {
79
- var from_box = document.getElementById(from);
80
- var to_box = document.getElementById(to);
81
- var option;
82
- for (var i = 0; (option = from_box.options[i]); i++) {
83
- if (SelectBox.cache_contains(from, option.value)) {
84
- SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1});
85
- SelectBox.delete_from_cache(from, option.value);
86
- }
87
- }
88
- SelectBox.redisplay(from);
89
- SelectBox.redisplay(to);
90
- },
91
- sort: function(id) {
92
- SelectBox.cache[id].sort( function(a, b) {
93
- a = a.text.toLowerCase();
94
- b = b.text.toLowerCase();
95
- try {
96
- if (a > b) return 1;
97
- if (a < b) return -1;
98
- }
99
- catch (e) {
100
- // silently fail on IE 'unknown' exception
101
- }
102
- return 0;
103
- } );
104
- },
105
- select_all: function(id) {
106
- var box = document.getElementById(id);
107
- for (var i = 0; i < box.options.length; i++) {
108
- box.options[i].selected = 'selected';
109
- }
110
- }
111
- }
1
+ var SelectBox = {
2
+ cache: new Object(),
3
+ init: function(id) {
4
+ var box = document.getElementById(id);
5
+ var node;
6
+ SelectBox.cache[id] = new Array();
7
+ var cache = SelectBox.cache[id];
8
+ for (var i = 0; (node = box.options[i]); i++) {
9
+ cache.push({value: node.value, text: node.text, displayed: 1});
10
+ }
11
+ },
12
+ redisplay: function(id) {
13
+ // Repopulate HTML select box from cache
14
+ var box = document.getElementById(id);
15
+ box.options.length = 0; // clear all options
16
+ for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) {
17
+ var node = SelectBox.cache[id][i];
18
+ if (node.displayed) {
19
+ box.options[box.options.length] = new Option(node.text, node.value, false, false);
20
+ }
21
+ }
22
+ },
23
+ filter: function(id, text) {
24
+ // Redisplay the HTML select box, displaying only the choices containing ALL
25
+ // the words in text. (It's an AND search.)
26
+ var tokens = text.toLowerCase().split(/\s+/);
27
+ var node, token;
28
+ for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
29
+ node.displayed = 1;
30
+ for (var j = 0; (token = tokens[j]); j++) {
31
+ if (node.text.toLowerCase().indexOf(token) == -1) {
32
+ node.displayed = 0;
33
+ }
34
+ }
35
+ }
36
+ SelectBox.redisplay(id);
37
+ },
38
+ delete_from_cache: function(id, value) {
39
+ var node, delete_index = null;
40
+ for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
41
+ if (node.value == value) {
42
+ delete_index = i;
43
+ break;
44
+ }
45
+ }
46
+ var j = SelectBox.cache[id].length - 1;
47
+ for (var i = delete_index; i < j; i++) {
48
+ SelectBox.cache[id][i] = SelectBox.cache[id][i+1];
49
+ }
50
+ SelectBox.cache[id].length--;
51
+ },
52
+ add_to_cache: function(id, option) {
53
+ SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1});
54
+ },
55
+ cache_contains: function(id, value) {
56
+ // Check if an item is contained in the cache
57
+ var node;
58
+ for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
59
+ if (node.value == value) {
60
+ return true;
61
+ }
62
+ }
63
+ return false;
64
+ },
65
+ move: function(from, to) {
66
+ var from_box = document.getElementById(from);
67
+ var to_box = document.getElementById(to);
68
+ var option;
69
+ for (var i = 0; (option = from_box.options[i]); i++) {
70
+ if (option.selected && SelectBox.cache_contains(from, option.value)) {
71
+ SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1});
72
+ SelectBox.delete_from_cache(from, option.value);
73
+ }
74
+ }
75
+ SelectBox.redisplay(from);
76
+ SelectBox.redisplay(to);
77
+ },
78
+ move_all: function(from, to) {
79
+ var from_box = document.getElementById(from);
80
+ var to_box = document.getElementById(to);
81
+ var option;
82
+ for (var i = 0; (option = from_box.options[i]); i++) {
83
+ if (SelectBox.cache_contains(from, option.value)) {
84
+ SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1});
85
+ SelectBox.delete_from_cache(from, option.value);
86
+ }
87
+ }
88
+ SelectBox.redisplay(from);
89
+ SelectBox.redisplay(to);
90
+ },
91
+ sort: function(id) {
92
+ SelectBox.cache[id].sort( function(a, b) {
93
+ a = a.text.toLowerCase();
94
+ b = b.text.toLowerCase();
95
+ try {
96
+ if (a > b) return 1;
97
+ if (a < b) return -1;
98
+ }
99
+ catch (e) {
100
+ // silently fail on IE 'unknown' exception
101
+ }
102
+ return 0;
103
+ } );
104
+ },
105
+ select_all: function(id) {
106
+ var box = document.getElementById(id);
107
+ for (var i = 0; i < box.options.length; i++) {
108
+ box.options[i].selected = 'selected';
109
+ }
110
+ }
111
+ }
@@ -1,113 +1,113 @@
1
- /*
2
- SelectFilter2 - Turns a multiple-select box into a filter interface.
3
-
4
- Different than SelectFilter because this is coupled to the admin framework.
5
-
6
- Requires core.js, SelectBox.js and addevent.js.
7
- */
8
-
9
- function findForm(node) {
10
- // returns the node of the form containing the given node
11
- if (node.tagName.toLowerCase() != 'form') {
12
- return findForm(node.parentNode);
13
- }
14
- return node;
15
- }
16
-
17
- var SelectFilter = {
18
- init: function(field_id, field_name, is_stacked, admin_media_prefix) {
19
- var from_box = document.getElementById(field_id);
20
- from_box.id += '_from'; // change its ID
21
- from_box.className = 'filtered';
22
-
23
- // Remove <p class="info">, because it just gets in the way.
24
- var ps = from_box.parentNode.getElementsByTagName('p');
25
- for (var i=0; i<ps.length; i++) {
26
- from_box.parentNode.removeChild(ps[i]);
27
- }
28
-
29
- // <div class="selector"> or <div class="selector stacked">
30
- var selector_div = quickElement('div', from_box.parentNode);
31
- selector_div.className = is_stacked ? 'selector stacked' : 'selector';
32
-
33
- // <div class="selector-available">
34
- var selector_available = quickElement('div', selector_div, '');
35
- selector_available.className = 'selector-available';
36
- quickElement('h2', selector_available, interpolate(gettext('Available %s'), [field_name]));
37
- var filter_p = quickElement('p', selector_available, '');
38
- filter_p.className = 'selector-filter';
39
- quickElement('img', filter_p, '', 'src', admin_media_prefix + '/selector-search.gif');
40
- filter_p.appendChild(document.createTextNode(' '));
41
- var filter_input = quickElement('input', filter_p, '', 'type', 'text');
42
- filter_input.id = field_id + '_input';
43
- selector_available.appendChild(from_box);
44
- var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()');
45
- choose_all.className = 'selector-chooseall';
46
-
47
- // <ul class="selector-chooser">
48
- var selector_chooser = quickElement('ul', selector_div, '');
49
- selector_chooser.className = 'selector-chooser';
50
- var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Add'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()');
51
- add_link.className = 'selector-add';
52
- var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()');
53
- remove_link.className = 'selector-remove';
54
-
55
- // <div class="selector-chosen">
56
- var selector_chosen = quickElement('div', selector_div, '');
57
- selector_chosen.className = 'selector-chosen';
58
- quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
59
- var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
60
- selector_filter.className = 'selector-filter';
61
- quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? '/selector_stacked-add.gif':'/selector-add.gif'), 'alt', 'Add');
62
- var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
63
- to_box.className = 'filtered';
64
- var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
65
- clear_all.className = 'selector-clearall';
66
-
67
- from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
68
-
69
- // Set up the JavaScript event handlers for the select box filter interface
70
- addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
71
- addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
72
- addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); });
73
- addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); });
74
- addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
75
- SelectBox.init(field_id + '_from');
76
- SelectBox.init(field_id + '_to');
77
- // Move selected from_box options to to_box
78
- SelectBox.move(field_id + '_from', field_id + '_to');
79
- },
80
- filter_key_up: function(event, field_id) {
81
- from = document.getElementById(field_id + '_from');
82
- // don't submit form if user pressed Enter
83
- if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
84
- from.selectedIndex = 0;
85
- SelectBox.move(field_id + '_from', field_id + '_to');
86
- from.selectedIndex = 0;
87
- return false;
88
- }
89
- var temp = from.selectedIndex;
90
- SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
91
- from.selectedIndex = temp;
92
- return true;
93
- },
94
- filter_key_down: function(event, field_id) {
95
- from = document.getElementById(field_id + '_from');
96
- // right arrow -- move across
97
- if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
98
- var old_index = from.selectedIndex;
99
- SelectBox.move(field_id + '_from', field_id + '_to');
100
- from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
101
- return false;
102
- }
103
- // down arrow -- wrap around
104
- if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
105
- from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
106
- }
107
- // up arrow -- wrap around
108
- if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
109
- from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
110
- }
111
- return true;
112
- }
113
- }
1
+ /*
2
+ SelectFilter2 - Turns a multiple-select box into a filter interface.
3
+
4
+ Different than SelectFilter because this is coupled to the admin framework.
5
+
6
+ Requires core.js, SelectBox.js and addevent.js.
7
+ */
8
+
9
+ function findForm(node) {
10
+ // returns the node of the form containing the given node
11
+ if (node.tagName.toLowerCase() != 'form') {
12
+ return findForm(node.parentNode);
13
+ }
14
+ return node;
15
+ }
16
+
17
+ var SelectFilter = {
18
+ init: function(field_id, field_name, is_stacked, admin_media_prefix) {
19
+ var from_box = document.getElementById(field_id);
20
+ from_box.id += '_from'; // change its ID
21
+ from_box.className = 'filtered';
22
+
23
+ // Remove <p class="info">, because it just gets in the way.
24
+ var ps = from_box.parentNode.getElementsByTagName('p');
25
+ for (var i=0; i<ps.length; i++) {
26
+ from_box.parentNode.removeChild(ps[i]);
27
+ }
28
+
29
+ // <div class="selector"> or <div class="selector stacked">
30
+ var selector_div = quickElement('div', from_box.parentNode);
31
+ selector_div.className = is_stacked ? 'selector stacked' : 'selector';
32
+
33
+ // <div class="selector-available">
34
+ var selector_available = quickElement('div', selector_div, '');
35
+ selector_available.className = 'selector-available';
36
+ quickElement('h2', selector_available, interpolate(gettext('Available %s'), [field_name]));
37
+ var filter_p = quickElement('p', selector_available, '');
38
+ filter_p.className = 'selector-filter';
39
+ quickElement('img', filter_p, '', 'src', admin_media_prefix + '/selector-search.gif');
40
+ filter_p.appendChild(document.createTextNode(' '));
41
+ var filter_input = quickElement('input', filter_p, '', 'type', 'text');
42
+ filter_input.id = field_id + '_input';
43
+ selector_available.appendChild(from_box);
44
+ var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()');
45
+ choose_all.className = 'selector-chooseall';
46
+
47
+ // <ul class="selector-chooser">
48
+ var selector_chooser = quickElement('ul', selector_div, '');
49
+ selector_chooser.className = 'selector-chooser';
50
+ var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Add'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()');
51
+ add_link.className = 'selector-add';
52
+ var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()');
53
+ remove_link.className = 'selector-remove';
54
+
55
+ // <div class="selector-chosen">
56
+ var selector_chosen = quickElement('div', selector_div, '');
57
+ selector_chosen.className = 'selector-chosen';
58
+ quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
59
+ var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
60
+ selector_filter.className = 'selector-filter';
61
+ quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? '/selector_stacked-add.gif':'/selector-add.gif'), 'alt', 'Add');
62
+ var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
63
+ to_box.className = 'filtered';
64
+ var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
65
+ clear_all.className = 'selector-clearall';
66
+
67
+ from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
68
+
69
+ // Set up the JavaScript event handlers for the select box filter interface
70
+ addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
71
+ addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
72
+ addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); });
73
+ addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); });
74
+ addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
75
+ SelectBox.init(field_id + '_from');
76
+ SelectBox.init(field_id + '_to');
77
+ // Move selected from_box options to to_box
78
+ SelectBox.move(field_id + '_from', field_id + '_to');
79
+ },
80
+ filter_key_up: function(event, field_id) {
81
+ from = document.getElementById(field_id + '_from');
82
+ // don't submit form if user pressed Enter
83
+ if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
84
+ from.selectedIndex = 0;
85
+ SelectBox.move(field_id + '_from', field_id + '_to');
86
+ from.selectedIndex = 0;
87
+ return false;
88
+ }
89
+ var temp = from.selectedIndex;
90
+ SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
91
+ from.selectedIndex = temp;
92
+ return true;
93
+ },
94
+ filter_key_down: function(event, field_id) {
95
+ from = document.getElementById(field_id + '_from');
96
+ // right arrow -- move across
97
+ if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
98
+ var old_index = from.selectedIndex;
99
+ SelectBox.move(field_id + '_from', field_id + '_to');
100
+ from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
101
+ return false;
102
+ }
103
+ // down arrow -- wrap around
104
+ if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
105
+ from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
106
+ }
107
+ // up arrow -- wrap around
108
+ if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
109
+ from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
110
+ }
111
+ return true;
112
+ }
113
+ }