blacklight 3.4.2 → 3.5.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 (95) hide show
  1. data/Gemfile +4 -0
  2. data/VERSION +1 -1
  3. data/app/assets/javascripts/blacklight/blacklight.js +15 -474
  4. data/app/assets/javascripts/blacklight/bookmark_toggle.js +21 -0
  5. data/app/assets/javascripts/blacklight/checkbox_submit.js +126 -0
  6. data/app/assets/javascripts/blacklight/core.js +2 -0
  7. data/app/assets/javascripts/blacklight/facet_expand_contract.js +40 -0
  8. data/app/assets/javascripts/blacklight/folder_toggle.js +24 -0
  9. data/app/assets/javascripts/blacklight/lightbox_dialog.js +15 -0
  10. data/app/assets/javascripts/blacklight/more_facets.js +15 -0
  11. data/app/assets/javascripts/blacklight/search_context.js +26 -0
  12. data/app/assets/javascripts/blacklight/select_submit.js +18 -0
  13. data/app/assets/javascripts/blacklight/zebra_stripe.js +13 -0
  14. data/app/assets/javascripts/jquery.uiExt.ajaxyDialog.js +180 -0
  15. data/app/controllers/bookmarks_controller.rb +9 -9
  16. data/app/controllers/feedback_controller.rb +3 -3
  17. data/app/controllers/folder_controller.rb +3 -3
  18. data/app/controllers/saved_searches_controller.rb +7 -7
  19. data/app/controllers/search_history_controller.rb +2 -2
  20. data/app/helpers/blacklight/blacklight_helper_behavior.rb +6 -10
  21. data/app/helpers/blacklight/catalog_helper_behavior.rb +8 -11
  22. data/app/helpers/blacklight/facets_helper_behavior.rb +2 -2
  23. data/app/helpers/blacklight/search_history_constraints_helper_behavior.rb +2 -2
  24. data/app/models/bookmark.rb +5 -0
  25. data/app/models/record_mailer.rb +5 -11
  26. data/app/views/_user_util_links.html.erb +6 -6
  27. data/app/views/bookmarks/index.html.erb +8 -8
  28. data/app/views/catalog/_bookmark_control.html.erb +2 -2
  29. data/app/views/catalog/_bookmark_form.html.erb +3 -3
  30. data/app/views/catalog/_citation.html.erb +3 -3
  31. data/app/views/catalog/_constraints.html.erb +1 -1
  32. data/app/views/catalog/_constraints_element.html.erb +2 -2
  33. data/app/views/catalog/_did_you_mean.html.erb +2 -7
  34. data/app/views/catalog/_document.html.erb +1 -1
  35. data/app/views/catalog/_email_form.html.erb +4 -4
  36. data/app/views/catalog/_facet_limit.html.erb +1 -1
  37. data/app/views/catalog/_facet_pagination.html.erb +7 -7
  38. data/app/views/catalog/_facets.html.erb +1 -1
  39. data/app/views/catalog/_folder_control.html.erb +1 -1
  40. data/app/views/catalog/_home_text.html.erb +1 -1
  41. data/app/views/catalog/_marc_view.html.erb +2 -2
  42. data/app/views/catalog/_refworks_form.html.erb +2 -2
  43. data/app/views/catalog/_results_pagination.html.erb +1 -1
  44. data/app/views/catalog/_search_form.html.erb +5 -5
  45. data/app/views/catalog/_show_tools.html.erb +6 -6
  46. data/app/views/catalog/_sms_form.html.erb +5 -5
  47. data/app/views/catalog/_sort_and_per_page.html.erb +6 -9
  48. data/app/views/catalog/index.atom.builder +3 -3
  49. data/app/views/catalog/index.html.erb +2 -2
  50. data/app/views/catalog/index.rss.builder +3 -3
  51. data/app/views/catalog/show.html.erb +2 -2
  52. data/app/views/feedback/complete.html.erb +2 -2
  53. data/app/views/feedback/show.html.erb +5 -5
  54. data/app/views/folder/_tools.html.erb +4 -4
  55. data/app/views/folder/index.html.erb +1 -1
  56. data/app/views/layouts/blacklight.html.erb +1 -1
  57. data/app/views/record_mailer/email_record.text.erb +2 -2
  58. data/app/views/record_mailer/sms_record.text.erb +1 -1
  59. data/app/views/saved_searches/index.html.erb +6 -6
  60. data/app/views/search_history/index.html.erb +6 -6
  61. data/config/locales/blacklight.en.yml +227 -0
  62. data/lib/blacklight.rb +0 -2
  63. data/lib/blacklight/catalog.rb +11 -13
  64. data/lib/blacklight/configurable.rb +0 -3
  65. data/lib/blacklight/configuration.rb +0 -42
  66. data/lib/blacklight/configuration/fields.rb +2 -0
  67. data/lib/blacklight/routes.rb +14 -2
  68. data/lib/blacklight/search_fields.rb +1 -1
  69. data/lib/blacklight/solr/document/email.rb +6 -6
  70. data/lib/blacklight/solr/document/sms.rb +4 -4
  71. data/lib/blacklight/solr_helper.rb +1 -3
  72. data/lib/generators/blacklight/blacklight_generator.rb +3 -0
  73. data/lib/railties/blacklight_cucumber.rake +12 -3
  74. data/lib/railties/blacklight_rspec.rake +9 -2
  75. data/test_support/alternate_controller.rb +4 -0
  76. data/test_support/bin/test.sh +13 -1
  77. data/test_support/features/bookmarks.feature +1 -1
  78. data/test_support/features/librarian_view.feature +2 -1
  79. data/test_support/features/record_view.feature +1 -0
  80. data/test_support/features/search.feature +1 -0
  81. data/test_support/features/step_definitions/general_steps.rb +4 -0
  82. data/test_support/features/support/env.rb +12 -1
  83. data/test_support/features/support/paths.rb +2 -1
  84. data/test_support/spec/helpers/blacklight_helper_spec.rb +8 -2
  85. data/test_support/spec/helpers/search_history_constraints_helper_spec.rb +6 -18
  86. data/test_support/spec/lib/search_fields_spec.rb +18 -25
  87. data/test_support/spec/models/record_mailer_spec.rb +5 -4
  88. data/test_support/spec/requests/alternate_controller_spec.rb +15 -0
  89. data/test_support/spec/spec_helper.rb +12 -0
  90. data/test_support/spec/views/catalog/_index_default.erb_spec.rb +6 -17
  91. data/test_support/spec/views/catalog/_show_default.erb_spec.rb +7 -17
  92. metadata +19 -8
  93. data/config/locales/kaminari.yml +0 -10
  94. data/lib/blacklight/global_configurable.rb +0 -46
  95. data/test_support/spec/lib/global_configurable_spec.rb +0 -98
@@ -0,0 +1,21 @@
1
+ //= require blacklight/core
2
+ //= require blacklight/checkbox_submit
3
+ (function($) {
4
+ //change form submit toggle to checkbox
5
+ Blacklight.do_bookmark_toggle_behavior = function() {
6
+ $(Blacklight.do_bookmark_toggle_behavior.selector).bl_checkbox_submit({
7
+ checked_label: "In Bookmarks",
8
+ unchecked_label: "Bookmark",
9
+ progress_label: "Saving...",
10
+ //css_class is added to elements added, plus used for id base
11
+ css_class: "toggle_bookmark"
12
+ });
13
+ };
14
+ Blacklight.do_bookmark_toggle_behavior.selector = "form.bookmark_toggle";
15
+
16
+ $(document).ready(function() {
17
+ Blacklight.do_bookmark_toggle_behavior();
18
+ });
19
+
20
+
21
+ })(jQuery);
@@ -0,0 +1,126 @@
1
+ /* A JQuery plugin (should this be implemented as a widget instead? not sure)
2
+ that will convert a "toggle" form, with single submit button to add/remove
3
+ something, like used for Bookmarks/Folder, into an AJAXy checkbox instead.
4
+
5
+ Apply to a form. Does require certain assumption about the form:
6
+ 1) The same form 'action' href must be used for both ADD and REMOVE
7
+ actions, with the different being the hidden input name="_method"
8
+ being set to "put" or "delete" -- that's the Rails method to pretend
9
+ to be doing a certain HTTP verb. So same URL, PUT to add, DELETE
10
+ to remove. This plugin assumes that.
11
+
12
+ Plus, the form this is applied to should provide a data-doc-id
13
+ attribute (HTML5-style doc-*) that contains the id/primary key
14
+ of the object in question -- used by plugin for a unique value for
15
+ DOM id's.
16
+
17
+ Pass in options for your class name and labels:
18
+ $("form.something").bl_checkbox_submit({
19
+ checked_label: "Selected",
20
+ unchecked_label: "Select",
21
+ progress_label: "Saving...",
22
+ //css_class is added to elements added, plus used for id base
23
+ css_class: "toggle_my_kinda_form",
24
+ success: function(after_success_check_state) {
25
+ #optional callback
26
+ }
27
+ });
28
+ */
29
+ (function($) {
30
+ $.fn.bl_checkbox_submit = function(arg_opts) {
31
+
32
+ this.each(function() {
33
+ var options = $.extend({}, $.fn.bl_checkbox_submit.defaults, arg_opts);
34
+
35
+
36
+ var form = $(this);
37
+ form.children().hide();
38
+ //We're going to use the existing form to actually send our add/removes
39
+ //This works conveneintly because the exact same action href is used
40
+ //for both bookmarks/$doc_id. But let's take out the irrelevant parts
41
+ //of the form to avoid any future confusion.
42
+ form.find("input[type=submit]").remove();
43
+
44
+ //View needs to set data-doc-id so we know a unique value
45
+ //for making DOM id
46
+ var unique_id = form.attr("data-doc-id") || Math.random();
47
+ // if form is currently using method delete to change state,
48
+ // then checkbox is currently checked
49
+ var checked = (form.find("input[name=_method][value=delete]").size() != 0);
50
+
51
+ var checkbox = $('<input type="checkbox">')
52
+ .addClass( options.css_class )
53
+ .attr("id", options.css_class + "_" + unique_id);
54
+ var label = $('<label>')
55
+ .addClass( options.css_class )
56
+ .attr("for", options.css_class + '_' + unique_id)
57
+ .attr("title", form.attr("title") || "");
58
+
59
+
60
+ function update_state_for(state) {
61
+ checkbox.attr("checked", state);
62
+ label.toggleClass("checked", state);
63
+ if (state) {
64
+ //Set the Rails hidden field that fakes an HTTP verb
65
+ //properly for current state action.
66
+ form.find("input[name=_method]").val("delete");
67
+ label.text(options.checked_label);
68
+ } else {
69
+ form.find("input[name=_method]").val("put");
70
+ label.text(options.unchecked_label);
71
+ }
72
+ }
73
+
74
+ form.append(checkbox).append(" ").append(label);
75
+ update_state_for(checked);
76
+
77
+ checkbox.click(function() {
78
+ label.text(options.progress_label).attr("disabled", "disabled");
79
+ checkbox.attr("disabled", "disabled");
80
+
81
+ $.ajax({
82
+ url: form.attr("action"),
83
+ dataType: 'json',
84
+ type: form.attr("method").toUpperCase(),
85
+ data: form.serialize(),
86
+ error: function() {
87
+ alert("Error");
88
+ update_state_for(checked);
89
+ label.removeAttr("disabled");
90
+ checkbox.removeAttr("disabled");
91
+ },
92
+ success: function(data, status, xhr) {
93
+ //if app isn't running at all, xhr annoyingly
94
+ //reports success with status 0.
95
+ if (xhr.status != 0) {
96
+ checked = ! checked;
97
+ update_state_for(checked);
98
+ label.removeAttr("disabled");
99
+ checkbox.removeAttr("disabled");
100
+ options.success.call(form, checked);
101
+ } else {
102
+ alert("Error");
103
+ update_state_for(checked);
104
+ label.removeAttr("disabled");
105
+ checkbox.removeAttr("disabled");
106
+ }
107
+ }
108
+ });
109
+
110
+ return false;
111
+ }); //checkbox.click
112
+
113
+
114
+ }); //this.each
115
+ return this;
116
+ };
117
+
118
+ $.fn.bl_checkbox_submit.defaults = {
119
+ checked_label: "",
120
+ unchecked_label: "",
121
+ progress_label: "Saving...",
122
+ //css_class is added to elements added, plus used for id base
123
+ css_class: "bl_checkbox_submit",
124
+ success: function() {} //callback
125
+ };
126
+ })(jQuery);
@@ -0,0 +1,2 @@
1
+ //= require jquery.uiExt.ajaxyDialog.js
2
+ Blacklight = {};
@@ -0,0 +1,40 @@
1
+ //= require blacklight/core
2
+ (function($) {
3
+ Blacklight.do_facet_expand_contract_behavior = function() {
4
+ $( Blacklight.do_facet_expand_contract_behavior.selector ).each (
5
+ Blacklight.facet_expand_contract
6
+ );
7
+ }
8
+ Blacklight.do_facet_expand_contract_behavior.selector = '#facets h3';
9
+
10
+ /* Behavior that makes facet limit headings in sidebar expand/contract
11
+ their contents. This is kind of fragile code targeted specifically
12
+ at how we currently render facet HTML, which is why I put it in a function
13
+ on Blacklight instead of in a jquery plugin. Perhaps in the future this
14
+ could/should be expanded to a general purpose jquery plugin -- or
15
+ we should just use one of the existing ones for expand/contract? */
16
+ Blacklight.facet_expand_contract = function() {
17
+ $(this).next("ul, div").each(function(){
18
+ var f_content = $(this);
19
+ $(f_content).prev('h3').addClass('twiddle');
20
+ // find all f_content's that don't have any span descendants with a class of "selected"
21
+ if($('span.selected', f_content).length == 0){
22
+ // hide it
23
+ f_content.hide();
24
+ } else {
25
+ $(this).prev('h3').addClass('twiddle-open');
26
+ }
27
+
28
+ // attach the toggle behavior to the h3 tag
29
+ $('h3', f_content.parent()).click(function(){
30
+ // toggle the content
31
+ $(this).toggleClass('twiddle-open');
32
+ $(f_content).slideToggle();
33
+ });
34
+ });
35
+ };
36
+ $(document).ready(function() {
37
+ Blacklight.do_facet_expand_contract_behavior();
38
+ });
39
+ })(jQuery);
40
+
@@ -0,0 +1,24 @@
1
+ //= require blacklight/core
2
+ //= require blacklight/checkbox_submit
3
+ (function($) {
4
+ Blacklight.do_folder_toggle_behavior = function() {
5
+ $( Blacklight.do_folder_toggle_behavior.selector ).bl_checkbox_submit({
6
+ checked_label: "Selected",
7
+ unchecked_label: "Select",
8
+ css_class: "toggle_folder",
9
+ success: function(new_state) {
10
+
11
+ if (new_state) {
12
+ $("#folder_number").text(parseInt($("#folder_number").text()) + 1);
13
+ }
14
+ else {
15
+ $("#folder_number").text(parseInt($("#folder_number").text()) - 1);
16
+ }
17
+ }
18
+ });
19
+ };
20
+ Blacklight.do_folder_toggle_behavior.selector = "form.folder_toggle";
21
+ $(document).ready(function() {
22
+ Blacklight.do_folder_toggle_behavior();
23
+ });
24
+ })(jQuery);
@@ -0,0 +1,15 @@
1
+ //= require blacklight/core
2
+ (function($) {
3
+ Blacklight.do_lightbox_dialog = function() {
4
+ $("a.lightboxLink").ajaxyDialog({
5
+ chainAjaxySelector: false
6
+ });
7
+ //But make the librarian link wider than 300px default.
8
+ $('a.lightboxLink#librarianLink').ajaxyDialog("option", "width", 650);
9
+ //And the email one too needs to be wider to fit the textarea
10
+ $("a.lightboxLink#emailLink").ajaxyDialog("option", "width", 500);
11
+ };
12
+ $(document).ready(function() {
13
+ Blacklight.do_lightbox_dialog();
14
+ });
15
+ })(jQuery);
@@ -0,0 +1,15 @@
1
+ //= require blacklight/core
2
+ (function($) {
3
+ //add ajaxy dialogs to certain links, using the ajaxyDialog widget.
4
+ Blacklight.do_more_facets_behavior = function () {
5
+ $( Blacklight.do_more_facets_behavior.selector ).ajaxyDialog({
6
+ width: $(window).width() / 2,
7
+ chainAjaxySelector: "a.next_page, a.prev_page, a.sort_change"
8
+ });
9
+ };
10
+ Blacklight.do_more_facets_behavior.selector = "a.more_facets_link";
11
+
12
+ $(document).ready(function() {
13
+ Blacklight.do_more_facets_behavior();
14
+ });
15
+ })(jQuery);
@@ -0,0 +1,26 @@
1
+ //= require blacklight/core
2
+ (function($) {
3
+ Blacklight.do_search_context_behavior = function() {
4
+ $('a[data-counter]').click(function(event) {
5
+ var f = document.createElement('form'); f.style.display = 'none';
6
+ this.parentNode.appendChild(f);
7
+ f.method = 'POST';
8
+ f.action = $(this).attr('href');
9
+ if(event.metaKey || event.ctrlKey){f.target = '_blank';};
10
+ var d = document.createElement('input'); d.setAttribute('type', 'hidden');
11
+ d.setAttribute('name', 'counter'); d.setAttribute('value', $(this).data('counter')); f.appendChild(d);
12
+ var m = document.createElement('input'); m.setAttribute('type', 'hidden');
13
+ m.setAttribute('name', '_method'); m.setAttribute('value', 'put'); f.appendChild(m);
14
+ var m = document.createElement('input'); m.setAttribute('type', 'hidden');
15
+ m.setAttribute('name', $('meta[name="csrf-param"]').attr('content')); m.setAttribute('value', $('meta[name="csrf-token"]').attr('content')); f.appendChild(m);
16
+
17
+ f.submit();
18
+
19
+ return false;
20
+ });
21
+
22
+ };
23
+ $(document).ready(function() {
24
+ Blacklight.do_search_context_behavior();
25
+ });
26
+ })(jQuery);
@@ -0,0 +1,18 @@
1
+ //= require blacklight/core
2
+ (function($) {
3
+ // Used for sort-by and per-page controls, hide the submit button
4
+ // and make the select auto-submit
5
+ Blacklight.do_select_submit = function() {
6
+ $(Blacklight.do_select_submit.selector).each(function() {
7
+ var select = $(this);
8
+ select.closest("form").find("input[type=submit]").hide();
9
+ select.bind("change", function() {
10
+ this.form.submit();
11
+ });
12
+ });
13
+ };
14
+ Blacklight.do_select_submit.selector = "form.sort select, form.per_page select";
15
+ $(document).ready(function() {
16
+ Blacklight.do_select_submit();
17
+ });
18
+ })(jQuery);
@@ -0,0 +1,13 @@
1
+ //= require blacklight/core
2
+ (function($) {
3
+ // adds classes for zebra striping table rows
4
+ Blacklight.do_zebra_stripe = function() {
5
+ $(Blacklight.do_zebra_stripe.selector).addClass('zebra_stripe');
6
+ };
7
+ Blacklight.do_zebra_stripe.selector = "table.zebra tr:even, ul.zebra li:even";
8
+
9
+
10
+ $(document).ready(function() {
11
+ Blacklight.do_zebra_stripe();
12
+ });
13
+ })(jQuery);
@@ -0,0 +1,180 @@
1
+ /* A widget written by jrochkind to make a link or form result in
2
+ an in-window ajaxy dialog, instead of page load, using JQuery UI
3
+ Dialog widget.
4
+
5
+ This widget is actually hosted at: https://github.com/jrochkind/jquery.uiExt.ajaxyDialog
6
+
7
+ */
8
+
9
+ (function($) {
10
+ var widgetNamespace = "uiExt";
11
+ var widgetName = "ajaxyDialog";
12
+
13
+ $.widget(widgetNamespace + "." + widgetName, {
14
+ options: {
15
+ extractTitleSelector: "h1, h2, h3, h4, h5",
16
+ chainAjaxySelector: "a:not([target]), form:not([target])",
17
+ closeDialogSelector: "a.dialog-close"
18
+ },
19
+
20
+ _create: function() {
21
+ var self = this;
22
+ var element = self.element[0];
23
+ if (element.tagName.toUpperCase() == "A") {
24
+ $(element).bind("click."+self.widgetName, function(event, ui) {
25
+ self._handleClick();
26
+ return false;
27
+ });
28
+ }
29
+ else if (element.tagName.toUpperCase() == "FORM") {
30
+ $(element).bind("submit."+self.widgetName, function(event, ui) {
31
+ self._handleSubmit();
32
+ return false;
33
+ });
34
+ }
35
+ },
36
+
37
+ open: function() {
38
+ var self = this;
39
+ var element = self.element[0];
40
+
41
+ if ( element.tagName.toUpperCase() == "A") {
42
+ self._handleClick();
43
+ } else if (element.tagName.toUpperCase() == "FORM") {
44
+ self._handleSubmit();
45
+ }
46
+ },
47
+
48
+ close: function() {
49
+ this.dialogContainer().dialog("close");
50
+ },
51
+
52
+ _handleClick: function() {
53
+ var self = this;
54
+ var url = this.element.attr("href");
55
+ var requestDialog = self.dialogContainer();
56
+
57
+ $("body").css("cursor", "progress");
58
+
59
+ $.ajax({
60
+ url: url,
61
+ dataType: "html",
62
+ success: function(resp, status, xhr) {
63
+ if (xhr.status != 0) {
64
+ self._loadToDialog(resp);
65
+ } else {
66
+ //stupid jquery calling this 'success', it's
67
+ //network unavailable.
68
+ self._displayFailure(url, xhr, status);
69
+ }
70
+ },
71
+ error: function(xhr, msg) {
72
+ self._displayFailure(url, xhr, msg);
73
+ }
74
+ });
75
+ },
76
+
77
+ _handleSubmit: function() {
78
+ var self = this;
79
+ var form = self.element;
80
+ var actionUri = form.attr("action");
81
+ var serialized = form.serialize();
82
+
83
+ $("body").css("cursor", "progress");
84
+
85
+ $.ajax({
86
+ url: actionUri,
87
+ data: serialized,
88
+ type: form.attr("method").toUpperCase(),
89
+ dataType: "html",
90
+ success: function(resp, status, xhr) {
91
+ if (xhr.status != 0) {
92
+ self._loadToDialog(resp);
93
+ } else {
94
+ //stupid jquery calling this 'success', it's
95
+ //network unavailable.
96
+ self._displayFailure(url, xhr, status);
97
+ }
98
+ },
99
+ error: function(xhr, msg) {
100
+ self._displayFailure(actionUri, xhr, msg);
101
+ }
102
+ });
103
+ },
104
+
105
+ _loadToDialog: function(html_content) {
106
+ var self = this;
107
+ var dialog = self.dialogContainer();
108
+ //Cheesy way to restore it to it's default options, plus
109
+ //our own local options, since its' a reuseable dialog.
110
+ //for now we insist on modal:true.
111
+ dialog.dialog($.extend({},
112
+ $.ui.dialog.prototype.options,
113
+ self.options,
114
+ {autoOpen:false, modal:true}
115
+ ));
116
+
117
+ if (self._trigger('beforeDisplay', 0, html_content) !== false) {
118
+ dialog.html( html_content );
119
+
120
+ //extract and set title
121
+ var title;
122
+ self.options.extractTitleSelector &&
123
+ (title = dialog.find(self.options.extractTitleSelector).first().remove().text());
124
+ title = title ||
125
+ self.element.attr("title")
126
+ title && dialog.dialog("option", "title", title);
127
+
128
+ //Make any hyperlinks or forms ajaxified, by applying
129
+ //this very same plugin to em, and passing on our options.
130
+ if (self.options.chainAjaxySelector) {
131
+ dialog.find(self.options.chainAjaxySelector).ajaxyDialog(self.options);
132
+ }
133
+
134
+ //Make any links marked dialog-close do so
135
+ if ( self.options.closeDialogSelector ) {
136
+ dialog.find(self.options.closeDialogSelector).unbind("click." + widgetName);
137
+ dialog.find(self.options.closeDialogSelector).bind("click." + widgetName, function() {
138
+ dialog.dialog("close");
139
+ return false;
140
+ });
141
+ }
142
+
143
+ dialog.dialog("open");
144
+ }
145
+ $("body").css("cursor", "auto");
146
+ },
147
+
148
+ _displayFailure: function(uri, xhr, serverMsg) {
149
+ if ( this._trigger("error", 0, {uri:uri, xhr: xhr, serverMsg: serverMsg}) !== false) {
150
+ var dialog = this.dialogContainer();
151
+
152
+ dialog.html("<div class='ui-state-error' style='padding: 1em;'><p><span style='float: left; margin-right: 0.3em;' class='ui-icon ui-icon-alert'></span>Sorry, a software error has occured.</p><p>" + uri + ": " + xhr.status + " " + serverMsg+"</p></div>");
153
+ dialog.dialog("option", "title", "Sorry, an error has occured.");
154
+ dialog.dialog("option", "buttons", {"OK": function() { dialog.dialog("close"); }});
155
+ dialog.dialog("open");
156
+ }
157
+ $("body").css("cursor", "auto");
158
+ },
159
+
160
+ // The DOM element which has a ui dialog() called on it.
161
+ // Right now we insist upon modal dialogs, and re-use the same
162
+ // <div>.dialog() for all of them. It's lazily created here.
163
+ // If client calls dialog("destroy") on it, no problem, it'll
164
+ // be lazily created if it's needed again.
165
+ dialogContainer: function() {
166
+ var existing = $("#reusableModalDialog");
167
+ if ( existing.size() > 0) {
168
+ return existing.first();
169
+ }
170
+ else {
171
+ //single shared element for modal dialogs
172
+ var requestDialog = $('<div id="reusableModalDialog" style="display:none"></div>').appendTo('body').
173
+ dialog({autoOpen: false});
174
+ return requestDialog;
175
+ }
176
+ }
177
+
178
+ });
179
+ }(jQuery));
180
+