sufia 0.1.0 → 1.0.0

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 (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
+ });