sufia 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +5 -2
  5. data/History.md +6 -0
  6. data/README.md +40 -0
  7. data/Rakefile +4 -0
  8. data/app/assets/javascripts/sufia.js +3 -115
  9. data/app/assets/javascripts/sufia/batch_select_all.js +179 -0
  10. data/app/assets/javascripts/sufia/edit_metadata.js +86 -0
  11. data/app/assets/javascripts/sufia/multiForm.js +57 -0
  12. data/app/assets/javascripts/terms_of_service.js +7 -0
  13. data/app/assets/stylesheets/audio-js.css +3 -0
  14. data/app/assets/stylesheets/dashboard.css.scss +51 -0
  15. data/app/assets/stylesheets/generic_files.css +36 -0
  16. data/app/assets/stylesheets/sufia.css.scss +2 -0
  17. data/app/controllers/batch_controller.rb +11 -0
  18. data/app/controllers/batch_edits_controller.rb +1 -77
  19. data/app/controllers/generic_files_controller.rb +1 -0
  20. data/app/controllers/mailbox_controller.rb +1 -1
  21. data/app/controllers/single_use_link_controller.rb +11 -7
  22. data/app/helpers/generic_file_helper.rb +11 -3
  23. data/app/helpers/sufia_helper.rb +13 -10
  24. data/app/models/batch.rb +1 -1
  25. data/app/models/datastreams/fits_datastream.rb +2 -2
  26. data/app/models/datastreams/generic_file_rdf_datastream.rb +22 -18
  27. data/app/models/datastreams/properties_datastream.rb +2 -2
  28. data/app/views/_user_util_links.html.erb +2 -2
  29. data/app/views/batch/_metadata.html.erb +82 -0
  30. data/app/views/batch/_more_metadata.html.erb +6 -0
  31. data/app/views/batch/edit.html.erb +1 -8
  32. data/app/views/batch_edits/_check_all.html.erb +0 -157
  33. data/app/views/batch_edits/edit.html.erb +0 -29
  34. data/app/views/catalog/_index_partials/_list_files.html.erb +8 -10
  35. data/app/views/catalog/_recent_document.html.erb +9 -18
  36. data/app/views/catalog/_results_pagination.html.erb +1 -1
  37. data/app/views/contact_form/new.html.erb +1 -1
  38. data/app/views/dashboard/_index_partials/_default_group.html.erb +1 -1
  39. data/app/views/dashboard/_index_partials/_list_files.html.erb +12 -14
  40. data/app/views/dashboard/_index_partials/_thumbnail_display.html.erb +9 -19
  41. data/app/views/dashboard/_results_pagination.html.erb +1 -1
  42. data/app/views/dashboard/index.html.erb +6 -82
  43. data/app/views/error/single_use_error.html.erb +35 -0
  44. data/app/views/generic_files/_descriptions.html.erb +2 -2
  45. data/app/views/generic_files/_extra_fields_modal.html.erb +1 -1
  46. data/app/views/generic_files/_field_form.html.erb +2 -5
  47. data/app/views/generic_files/_media_display.html.erb +8 -6
  48. data/app/views/generic_files/_permission.html.erb +2 -2
  49. data/app/views/generic_files/_rights_modal.html.erb +1 -1
  50. data/app/views/generic_files/_show_actions.html.erb +1 -1
  51. data/app/views/generic_files/_show_details.html.erb +11 -6
  52. data/app/views/generic_files/edit.html.erb +0 -8
  53. data/app/views/generic_files/edit_fields/_type.html.erb +1 -1
  54. data/app/views/generic_files/show.html.erb +5 -8
  55. data/app/views/generic_files/show_fields/_based_near.html.erb +4 -1
  56. data/app/views/generic_files/show_fields/_contributor.html.erb +4 -1
  57. data/app/views/generic_files/show_fields/_creator.html.erb +4 -1
  58. data/app/views/generic_files/show_fields/_date_created.html.erb +4 -1
  59. data/app/views/generic_files/show_fields/_description.html.erb +4 -1
  60. data/app/views/generic_files/show_fields/_language.html.erb +1 -1
  61. data/app/views/generic_files/show_fields/_publisher.html.erb +4 -1
  62. data/app/views/generic_files/show_fields/_related_url.html.erb +3 -1
  63. data/app/views/generic_files/show_fields/_resource_type.html.erb +1 -1
  64. data/app/views/generic_files/show_fields/_subject.html.erb +4 -1
  65. data/app/views/generic_files/show_fields/_tag.html.erb +1 -1
  66. data/app/views/generic_files/show_fields/_title.html.erb +4 -1
  67. data/app/views/layouts/error.html.erb +0 -4
  68. data/app/views/layouts/hydra-head.html.erb +2 -6
  69. data/app/views/single_use_link/show.html.erb +1 -1
  70. data/app/views/users/index.html.erb +1 -1
  71. data/app/views/users/show.html.erb +1 -1
  72. data/config/locales/sufia.en.yml +1 -0
  73. data/config/routes.rb +11 -4
  74. data/lib/generators/sufia/sufia_generator.rb +2 -1
  75. data/lib/generators/sufia/templates/catalog_controller.rb +143 -117
  76. data/lib/generators/sufia/templates/config/resque_admin.rb +10 -0
  77. data/lib/generators/sufia/templates/config/sufia.rb +8 -0
  78. data/lib/sufia.rb +4 -14
  79. data/lib/sufia/batch_edits_controller_behavior.rb +89 -0
  80. data/lib/sufia/controller.rb +7 -5
  81. data/lib/sufia/downloads_controller_behavior.rb +14 -19
  82. data/lib/sufia/file_content/extract_metadata.rb +11 -4
  83. data/lib/sufia/files_controller_behavior.rb +63 -44
  84. data/lib/sufia/generic_file.rb +29 -11
  85. data/lib/sufia/generic_file/audit.rb +1 -1
  86. data/lib/sufia/generic_file/thumbnail.rb +51 -26
  87. data/lib/sufia/id_service.rb +28 -11
  88. data/lib/sufia/jobs/batch_update_job.rb +2 -2
  89. data/lib/sufia/jobs/characterize_job.rb +11 -3
  90. data/lib/sufia/jobs/ffmpeg_transcode_job.rb +61 -0
  91. data/lib/sufia/jobs/resolrize_job.rb +1 -1
  92. data/lib/sufia/jobs/transcode_audio_job.rb +40 -0
  93. data/lib/sufia/jobs/transcode_video_job.rb +9 -49
  94. data/lib/sufia/queue/resque.rb +2 -2
  95. data/lib/sufia/single_use_error.rb +4 -0
  96. data/lib/sufia/solr_document_behavior.rb +108 -1
  97. data/lib/sufia/version.rb +1 -1
  98. data/solr_conf/conf/schema.xml +332 -652
  99. data/solr_conf/conf/solrconfig.xml +60 -196
  100. data/spec/controllers/batch_controller_spec.rb +4 -5
  101. data/spec/controllers/catalog_controller_spec.rb +13 -13
  102. data/spec/controllers/dashboard_controller_spec.rb +2 -2
  103. data/spec/controllers/downloads_controller_spec.rb +74 -62
  104. data/spec/controllers/generic_files_controller_spec.rb +10 -8
  105. data/spec/controllers/single_use_link_controller_spec.rb +12 -4
  106. data/spec/fixtures/Example.ogg +0 -0
  107. data/spec/fixtures/piano_note.wav +0 -0
  108. data/spec/fixtures/sufia_generic_stub.descMeta.txt +1 -1
  109. data/spec/helpers/sufia_helper_spec.rb +12 -0
  110. data/spec/models/characterize_job_spec.rb +89 -0
  111. data/spec/models/checksum_audit_log_spec.rb +1 -0
  112. data/spec/models/event_jobs_spec.rb +9 -9
  113. data/spec/models/file_content_datastream_spec.rb +16 -10
  114. data/spec/models/fits_datastream_spec.rb +2 -8
  115. data/spec/models/generic_file_spec.rb +131 -60
  116. data/spec/models/solr_document_spec.rb +21 -0
  117. data/spec/models/transcode_audio_job_spec.rb +81 -0
  118. data/spec/models/transcode_video_job_spec.rb +2 -2
  119. data/spec/models/unzip_job_spec.rb +3 -3
  120. data/spec/spec_helper.rb +21 -0
  121. data/spec/support/Gemfile +7 -3
  122. data/sufia.gemspec +8 -11
  123. data/tasks/cucumber.rake +1 -2
  124. data/tasks/sufia-dev.rake +13 -2
  125. data/tasks/sufia.rake +1 -1
  126. metadata +77 -118
  127. data/app/views/batch_edits/_metadata.html.erb +0 -180
  128. data/lib/generators/sufia/templates/config/hydra_config.rb +0 -32
  129. data/lib/kaminari/helpers/tag.rb +0 -11
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f58a172c978631ed2850516f2ab9502cd114d61a
4
+ data.tar.gz: 1fd149a51495e374d2b9dab1baca7b121521fe2a
5
+ SHA512:
6
+ metadata.gz: 57bc995e34962a7babd5c8c19e22ee51e96fdadefbbfc6c553b2d266183178df62b831f7c5fedee29309de2d4c5bbbeccbb06cd7678940f4f6a72e7b5eaee8c4
7
+ data.tar.gz: 34eb247bfe4bc0baf28dc6fcaecda85eac8b4025883b02ec85dc043be93b4cdc7e72403d20ed79d654dca114a2ef3be05061cf496071582a9529559d31fce626
data/.gitignore CHANGED
@@ -7,6 +7,10 @@ config/hydra-ldap.yml
7
7
  config/redis.yml
8
8
 
9
9
  # bad gem etiquette, man
10
+ .ruby-version
11
+ .ruby-gemset
12
+ ruby-version
13
+ ruby-gemset
10
14
  .rvmrc
11
15
  Gemfile.lock
12
16
 
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ notifications:
6
+ irc: "irc.freenode.org#scholarsphere"
data/Gemfile CHANGED
@@ -3,9 +3,11 @@ source 'http://rubygems.org'
3
3
  # Please see sufia.gemspec for dependency information.
4
4
  gemspec
5
5
 
6
- gem 'hydra-head', github: 'projecthydra/hydra-head'
7
- #gem 'mail_form', :git => 'git://github.com/psu-stewardship/mail_form.git', :ref => '50c00f0'
6
+ # Required for doing pagination inside an engine. See https://github.com/amatsuda/kaminari/pull/322
7
+ gem 'kaminari', github: 'harai/kaminari', branch: 'route_prefix_prototype'
8
+
8
9
  group :development, :test do
10
+ gem 'activerecord-import', '0.3.0'
9
11
  gem 'sqlite3'
10
12
  gem 'selenium-webdriver'
11
13
  gem 'rspec-rails', '~> 2.12.0'
@@ -16,4 +18,5 @@ group :development, :test do
16
18
  gem 'bcrypt-ruby'
17
19
  gem "jettywrapper"
18
20
  gem "factory_girl_rails", "~> 4.1.0"
21
+ gem "simplecov", :require => false
19
22
  end # (leave this comment here to catch a stray line inserted by blacklight!)
@@ -0,0 +1,6 @@
1
+ # History of Sufia releases
2
+
3
+ ## 1.0.0
4
+ * Initial API-stable release
5
+
6
+
data/README.md CHANGED
@@ -1,4 +1,44 @@
1
1
  # Sufia
2
+
3
+ ## Code Status
4
+
5
+ [![Build Status](https://travis-ci.org/curationexperts/sufia.png?branch=master)](https://travis-ci.org/curationexperts/sufia)
6
+ [![Dependencies Status](https://gemnasium.com/curationexperts/sufia.png)](https://gemnasium.com/curationexperts/sufia)
7
+
8
+ ## What is Sufia?
9
+ Sufia is a component that adds self-deposit institutional repository features to a Rails app.
10
+ Sufia is created with Ruby on Rails and builds on the Hydra Framework.
11
+
12
+ Sufia has the following features:
13
+
14
+ * Multiple file, or folder, upload
15
+ * Flexible user- and group-based access controls
16
+ * Transcoding of audio and video files
17
+ * Generation and validation of identifiers
18
+ * Fixity checking
19
+ * Version control
20
+ * Characterization of uploaded files
21
+ * Forms for batch editing metadata
22
+ * Faceted search and browse (based on Blacklight)
23
+ * Social media interaction
24
+ * User profiles
25
+ * User dashboard for file management
26
+ * Highlighted files on profile
27
+ * Sharing w/ groups and users
28
+ * User notifications
29
+ * Activity streams
30
+ * Background jobs
31
+ * Single-use links
32
+
33
+ Sufia needs the following software to work:
34
+ * Solr
35
+ * Fedora Commons
36
+ * A SQL RDBMS (MySQL, SQLite)
37
+ * Redis
38
+ * Ruby
39
+
40
+
41
+
2
42
  ## Creating an application
3
43
  ### Generate base Rails install
4
44
  ```rails new my_app```
data/Rakefile CHANGED
@@ -3,3 +3,7 @@
3
3
  require "bundler/gem_tasks"
4
4
  Dir.glob('tasks/*.rake').each { |r| import r }
5
5
 
6
+ desc 'Run CI tests in Travis environment'
7
+ task :travis => ['clean', 'ci']
8
+
9
+ task :default => [:travis]
@@ -41,6 +41,9 @@ limitations under the License.
41
41
  //= require sufia/permissions
42
42
  //= require sufia/tabs
43
43
  //= require sufia/trophy
44
+ //= require sufia/batch_select_all
45
+ //= require sufia/multiForm
46
+ //= require sufia/edit_metadata
44
47
 
45
48
  //over ride the blacklight default to submit
46
49
  //form when sort by or show per page change
@@ -86,121 +89,6 @@ $(function() {
86
89
  }
87
90
  });
88
91
  };
89
- // there are two levels of vocabulary auto complete.
90
- // currently we have this externally hosted vocabulary
91
- // for geonames. I'm not going to make these any easier
92
- // to implement for an external url (it's all hard coded)
93
- // because I'm guessing we'll get away from the hard coding
94
- var cities_autocomplete_opts = {
95
- source: function( request, response ) {
96
- $.ajax( {
97
- url: "http://ws.geonames.org/searchJSON",
98
- dataType: "jsonp",
99
- data: {
100
- featureClass: "P",
101
- style: "full",
102
- maxRows: 12,
103
- name_startsWith: request.term
104
- },
105
- success: function( data ) { response( $.map( data.geonames, function( item ) {
106
- return {
107
- label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
108
- value: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName
109
- };
110
- }));
111
- },
112
- });
113
- },
114
- minLength: 2
115
- };
116
- $("#generic_file_based_near").autocomplete(get_autocomplete_opts("location"));
117
-
118
-
119
- function get_autocomplete_opts(field) {
120
- var autocomplete_opts = {
121
- minLength: 2,
122
- source: function( request, response ) {
123
- $.getJSON( "/authorities/generic_files/" + field, {
124
- q: request.term
125
- }, response );
126
- },
127
- focus: function() {
128
- // prevent value inserted on focus
129
- return false;
130
- },
131
- complete: function(event) {
132
- $('.ui-autocomplete-loading').removeClass("ui-autocomplete-loading");
133
- }
134
- };
135
- return autocomplete_opts;
136
- }
137
-
138
- var autocomplete_vocab = new Object();
139
-
140
- autocomplete_vocab.url_var = ['subject', 'language']; // the url variable to pass to determine the vocab to attach to
141
- autocomplete_vocab.field_name = new Array(); // the form name to attach the event for autocomplete
142
- autocomplete_vocab.add_btn_id = new Array(); // the id of the button pressed when adding an additional form element
143
-
144
- // loop over the autocomplete fields and attach the
145
- // events for autocomplete and create other array values for autocomplete
146
- for (var i=0; i < autocomplete_vocab.url_var.length; i++) {
147
- autocomplete_vocab.field_name.push('generic_file_' + autocomplete_vocab.url_var[i]);
148
- autocomplete_vocab.add_btn_id.push('additional_' + autocomplete_vocab.url_var[i] + '_submit');
149
- // autocompletes
150
- $("#" + autocomplete_vocab.field_name[i])
151
- // don't navigate away from the field on tab when selecting an item
152
- .bind( "keydown", function( event ) {
153
- if ( event.keyCode === $.ui.keyCode.TAB &&
154
- $( this ).data( "autocomplete" ).menu.active ) {
155
- event.preventDefault();
156
- }
157
- })
158
- .autocomplete( get_autocomplete_opts(autocomplete_vocab.url_var[i]) );
159
-
160
- }
161
-
162
- /*
163
- * adds additional metadata elements
164
- */
165
- $('.adder').click(function() {
166
- var cloneId = this.id.replace("submit", "clone");
167
- var newId = this.id.replace("submit", "elements");
168
- var cloneElem = $('#'+cloneId).clone();
169
- // change the add button to a remove button
170
- var plusbttn = cloneElem.find('#'+this.id);
171
- plusbttn.html('-<span class="accessible-hidden">remove this '+ this.name.replace("_", " ") +'</span>');
172
- plusbttn.on('click',removeField);
173
-
174
- // remove the help tag on subsequent added fields
175
- cloneElem.find('.formHelp').remove();
176
- cloneElem.find('i').remove();
177
- cloneElem.find('.modal-div').remove();
178
-
179
- //clear out the value for the element being appended
180
- //so the new element has a blank value
181
- cloneElem.find('input[type=text]').attr("value", "");
182
- cloneElem.find('input[type=text]').attr("required", false);
183
-
184
- // should we attach an auto complete based on the input
185
- if (this.id == 'additional_based_near_submit') {
186
- cloneElem.find('input[type=text]').autocomplete(cities_autocomplete_opts);
187
- }
188
- else if ( (index = $.inArray(this.id, autocomplete_vocab.add_btn_id)) != -1 ) {
189
- cloneElem.find('input[type=text]').autocomplete(get_autocomplete_opts(autocomplete_vocab.url_var[index]));
190
- }
191
-
192
- $('#'+newId).append(cloneElem);
193
- cloneElem.find('input[type=text]').focus();
194
- return false;
195
- });
196
-
197
- $('.remover').click(removeField);
198
-
199
- function removeField () {
200
- // get parent and remove it
201
- $(this).parent().remove();
202
- return false;
203
- }
204
92
 
205
93
  // show/hide more information on the dashboard when clicking
206
94
  // plus/minus
@@ -0,0 +1,179 @@
1
+ // function to hide or show the batch update buttons based on how may items are checked
2
+ function toggleButtons(forceOn, otherPage ){
3
+ forceOn = typeof forceOn !== 'undefined' ? forceOn : false
4
+ otherPage = typeof otherPage !== 'undefined' ? otherPage : !window.batch_part_on_other_page;
5
+ var n = $(".batch_toggle:checked").length;
6
+ if ((n>0) || (forceOn)) {
7
+ $('.batch-select-all').show();
8
+ $('.button_to').show();
9
+ } else if ( otherPage){
10
+ $('.batch-select-all').hide();
11
+ $('.button_to').hide();
12
+ }
13
+ $("body").css("cursor", "auto");
14
+ }
15
+
16
+ function toggleState (obj, state) {
17
+ if (state == 'on'){
18
+ obj.attr("data-state", 'on');
19
+ obj.find('a i').addClass('icon-ok');
20
+ }else {
21
+ obj.attr("data-state", 'off');
22
+ obj.find('a i').removeClass('icon-ok');
23
+ }
24
+
25
+ }
26
+
27
+ function check_all_page(e) {
28
+ var checked = $("#check_all")[0]['checked'];
29
+
30
+ // only check the current page
31
+ var timeout = 0;
32
+ var timeoutInc = 60;
33
+
34
+ $("input[type='checkbox'].batch_toggle").each(function(index, value) {
35
+ // check each individual box
36
+ var ck = value['checked'];
37
+ console.log("status for ");
38
+ console.log(value);
39
+ // not the same state click the box
40
+ if (checked != ck) {
41
+ console.log("click it");
42
+ window.parent.setTimeout(function(){value.click();},timeout);
43
+ }
44
+ timeout+=timeoutInc;
45
+ });
46
+ window.parent.setTimeout(toggleButtons,timeout+500);
47
+ $("#check_all").attr('checked', checked);
48
+ }
49
+
50
+ function clear_batch () {
51
+ var url = '<%=clear_batch_edits_path %>';
52
+ var clearState = $.ajax({
53
+ headers: {
54
+ Accept : "application/javascript",
55
+ },
56
+ type: 'PUT',
57
+ url: url,
58
+ async: false,
59
+ });
60
+
61
+ }
62
+
63
+ function set_all_checkboxes(checked){
64
+ $("input[type='checkbox'].batch_toggle").each(function(){
65
+ $(this).attr('checked', checked);
66
+
67
+ // make sure the form is set correctly
68
+ form = $($(this).parent()[0]);
69
+ if (checked) {
70
+ form.find("input[name=_method]").val("delete");
71
+
72
+ } else {
73
+ form.find("input[name=_method]").val("put");
74
+ }
75
+ });
76
+
77
+ }
78
+
79
+
80
+ $(document).ready(function() {
81
+
82
+ $("[data-behavior='batch-edit-select-page']").bind('click', function(e) {
83
+ $("body").css("cursor", "progress");
84
+ e.preventDefault();
85
+ $("#check_all").attr('checked', true);
86
+ toggleState($(this),'on');
87
+ toggleState($("[data-behavior='batch-edit-select-all']"),'off');
88
+ toggleState($("[data-behavior='batch-edit-select-none']"),'off');
89
+ clear_batch();
90
+
91
+ // uncheck everything on the current page
92
+ set_all_checkboxes(false);
93
+
94
+ // check everything on the current page
95
+ check_all_page();
96
+
97
+ });
98
+
99
+ $("[data-behavior='batch-edit-select-all']").bind('click', function(e) {
100
+ $("body").css("cursor", "progress");
101
+ e.preventDefault();
102
+ $("#check_all").attr('checked', true);
103
+ toggleState($(this), 'on');
104
+ toggleState($("[data-behavior='batch-edit-select-page']"),'off');
105
+ toggleState($("[data-behavior='batch-edit-select-none']"),'off');
106
+ var url = '<%=all_batch_edits_path %>';
107
+ var clearState = $.ajax({
108
+ headers: {
109
+ Accept : "application/javascript",
110
+ },
111
+ type: 'PUT',
112
+ url: url,
113
+ async: false,
114
+ });
115
+
116
+ // show that update on the local screen
117
+ set_all_checkboxes(true)
118
+ $("body").css("cursor", "auto");
119
+ toggleButtons(true);
120
+ });
121
+
122
+ $("[data-behavior='batch-edit-select-none']").bind('click', function(e) {
123
+ $("body").css("cursor", "progress");
124
+ e.preventDefault();
125
+ $("#check_all").attr('checked', false);
126
+ toggleState($(this), 'on');
127
+ toggleState($("[data-behavior='batch-edit-select-page']"),'off');
128
+ toggleState($("[data-behavior='batch-edit-select-all']"),'off');
129
+ clear_batch();
130
+
131
+ // show that update on the local screen
132
+ set_all_checkboxes(false)
133
+ $("body").css("cursor", "auto");
134
+ toggleButtons(false, true);
135
+ });
136
+
137
+
138
+
139
+ // check all buttons
140
+ $("#check_all").bind('click', check_all_page);
141
+
142
+
143
+ $(".batch_toggle").bind('click', function(e) {
144
+
145
+ // if we are unchecking a box remove the group selections
146
+ if ($(e.currentTarget).attr('checked') != "checked") {
147
+ toggleState($("[data-behavior='batch-edit-select-all']"),'off');
148
+ toggleState($("[data-behavior='batch-edit-select-page']"),'off');
149
+ toggleState($("[data-behavior='batch-edit-select-none']"),'off');
150
+ $("#check_all").attr('checked', false);
151
+ }
152
+ // checking a single box see if we need to turn on one of the groups
153
+ else {
154
+ var n = $(".batch_toggle:checked").length;
155
+ if (n == window.document_list_count) {
156
+ $("#check_all").attr('checked', true);
157
+ if (!window.batch_part_on_other_page) {
158
+ toggleState($("[data-behavior='batch-edit-select-page']"),'on');
159
+ } else if ((n + window.batch_size_on_other_page) == window.result_set_size){
160
+ toggleState($("[data-behavior='batch-edit-select-all']"),'on');
161
+ }
162
+ } else {
163
+ if ((n + window.batch_size_on_other_page) == 0){
164
+ toggleState($("[data-behavior='batch-edit-select-none']"),'on');
165
+ }
166
+ }
167
+ }
168
+ });
169
+
170
+ });
171
+
172
+ // hide or show the batch update buttons file selections
173
+ function setup_buttontoggle(checkbox) {
174
+ checkbox.bind('click', function(e) {
175
+ e.preventDefault();
176
+ toggleButtons();
177
+ });
178
+ }
179
+
@@ -0,0 +1,86 @@
1
+ $(function() {
2
+ function get_autocomplete_opts(field) {
3
+ var autocomplete_opts = {
4
+ minLength: 2,
5
+ source: function( request, response ) {
6
+ $.getJSON( "/authorities/generic_files/" + field, {
7
+ q: request.term
8
+ }, response );
9
+ },
10
+ focus: function() {
11
+ // prevent value inserted on focus
12
+ return false;
13
+ },
14
+ complete: function(event) {
15
+ $('.ui-autocomplete-loading').removeClass("ui-autocomplete-loading");
16
+ }
17
+ };
18
+ return autocomplete_opts;
19
+ }
20
+
21
+ // there are two levels of vocabulary auto complete.
22
+ // currently we have this externally hosted vocabulary
23
+ // for geonames. I'm not going to make these any easier
24
+ // to implement for an external url (it's all hard coded)
25
+ // because I'm guessing we'll get away from the hard coding
26
+ var cities_autocomplete_opts = {
27
+ source: function( request, response ) {
28
+ $.ajax( {
29
+ url: "http://ws.geonames.org/searchJSON",
30
+ dataType: "jsonp",
31
+ data: {
32
+ featureClass: "P",
33
+ style: "full",
34
+ maxRows: 12,
35
+ name_startsWith: request.term
36
+ },
37
+ success: function( data ) { response( $.map( data.geonames, function( item ) {
38
+ return {
39
+ label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
40
+ value: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName
41
+ };
42
+ }));
43
+ },
44
+ });
45
+ },
46
+ minLength: 2
47
+ };
48
+ $("#generic_file_based_near").autocomplete(get_autocomplete_opts("location"));
49
+
50
+ var autocomplete_vocab = new Object();
51
+
52
+ autocomplete_vocab.url_var = ['subject', 'language']; // the url variable to pass to determine the vocab to attach to
53
+ autocomplete_vocab.field_name = new Array(); // the form name to attach the event for autocomplete
54
+ autocomplete_vocab.add_btn_id = new Array(); // the id of the button pressed when adding an additional form element
55
+
56
+ // loop over the autocomplete fields and attach the
57
+ // events for autocomplete and create other array values for autocomplete
58
+ for (var i=0; i < autocomplete_vocab.url_var.length; i++) {
59
+ autocomplete_vocab.field_name.push('generic_file_' + autocomplete_vocab.url_var[i]);
60
+ autocomplete_vocab.add_btn_id.push('additional_' + autocomplete_vocab.url_var[i] + '_submit');
61
+ // autocompletes
62
+ $("#" + autocomplete_vocab.field_name[i])
63
+ // don't navigate away from the field on tab when selecting an item
64
+ .bind( "keydown", function( event ) {
65
+ if ( event.keyCode === $.ui.keyCode.TAB &&
66
+ $( this ).data( "autocomplete" ).menu.active ) {
67
+ event.preventDefault();
68
+ }
69
+ })
70
+ .autocomplete( get_autocomplete_opts(autocomplete_vocab.url_var[i]) );
71
+
72
+ }
73
+
74
+
75
+ function setup_autocomplete(obj, cloneElem) {
76
+ // should we attach an auto complete based on the input
77
+ if (obj.id == 'additional_based_near_submit') {
78
+ cloneElem.find('input[type=text]').autocomplete(cities_autocomplete_opts);
79
+ }
80
+ else if ( (index = $.inArray(obj.id, autocomplete_vocab.add_btn_id)) != -1 ) {
81
+ cloneElem.find('input[type=text]').autocomplete(get_autocomplete_opts(autocomplete_vocab.url_var[index]));
82
+ }
83
+ }
84
+
85
+ $('form').multiForm({afterAdd: setup_autocomplete});
86
+ });