Commit | Line | Data |
95071bdb |
1 | // General-purpose error-handling function. |
2 | // TODO make sure this gets used throughout, where appropriate. |
3 | function display_error( jqXHR, el ) { |
4 | var errmsg; |
5 | if( jqXHR.responseText == "" ) { |
6 | errmsg = "perhaps the server went down?" |
7 | } else { |
8 | var errobj; |
9 | try { |
10 | errobj = jQuery.parseJSON( jqXHR.responseText ); |
11 | errmsg = errobj.error; |
12 | } catch ( parse_err ) { |
13 | errmsg = "something went wrong on the server." |
14 | } |
15 | } |
16 | var msghtml = $('<span>').attr('class', 'error').text( "An error occurred: " + errmsg ); |
17 | $(el).empty().append( msghtml ).show(); |
18 | } |
19 | |
20 | // Event to enable the upload button when a file has been selected |
21 | function file_selected( e ) { |
22 | if( e.files.length == 1 ) { |
23 | $('#upload_button').button('enable'); |
24 | $('#new_file_name_container').html( '<span id="new_file_name">' + e.files[0].name + '</span>' ); |
25 | } else { |
26 | $('#upload_button').button('disable'); |
27 | $('#new_file_name_container').html( '(Use \'pick file\' to select a tradition file to upload.)' ); |
28 | } |
29 | } |
30 | |
31 | // Implement our own AJAX method that uses the features of XMLHttpRequest2 |
32 | // but try to let it have a similar interface to jquery.post |
33 | // The data var needs to be a FormData() object. |
34 | // The callback will be given a single argument, which is the response data |
35 | // of the given type. |
36 | |
37 | function post_xhr2( url, data, cb, type ) { |
38 | if( !type ) { |
39 | type = 'json'; |
40 | } |
41 | var xhr = new XMLHttpRequest(); |
42 | // Set the expected response type |
43 | if( type === 'data' ) { |
44 | xhr.responseType = 'blob'; |
45 | } else if( type === 'xml' ) { |
46 | xhr.responseType = 'document'; |
47 | } |
48 | // Post the form |
49 | // Gin up an AJAX settings object |
50 | $.ajaxSetup({ url: url, type: 'POST' }); |
51 | xhr.open( 'POST', url, true ); |
52 | // Handle the results |
53 | xhr.onload = function( e ) { |
54 | // Get the response and parse it |
55 | // Call the callback with the response, whatever it was |
56 | var xhrs = e.target; |
57 | if( xhrs.status > 199 && xhrs.status < 300 ) { // Success |
58 | var resp; |
59 | if( type === 'json' ) { |
60 | resp = $.parseJSON( xhrs.responseText ); |
61 | } else if ( type === 'xml' ) { |
62 | resp = xhrs.responseXML; |
63 | } else if ( type === 'text' ) { |
64 | resp = xhrs.responseText; |
65 | } else { |
66 | resp = xhrs.response; |
67 | } |
68 | cb( resp ); |
69 | } else { |
70 | // Trigger the ajaxError... |
71 | _trigger_ajaxerror( e ); |
72 | } |
73 | }; |
74 | xhr.onerror = _trigger_ajaxerror; |
75 | xhr.onabort = _trigger_ajaxerror; |
76 | xhr.send( data ); |
77 | } |
78 | |
79 | function _trigger_ajaxerror( e ) { |
80 | var xhr = e.target; |
81 | var thrown = xhr.statusText || 'Request error'; |
82 | jQuery.event.trigger( 'ajaxError', [ xhr, $.ajaxSettings, thrown ]); |
83 | } |
84 | |
85 | function upload_new () { |
86 | // Serialize the upload form, get the file and attach it to the request, |
87 | // POST the lot and handle the response. |
88 | var newfile = $('#new_file').get(0).files[0]; |
89 | var reader = new FileReader(); |
90 | reader.onload = function( evt ) { |
91 | var data = new FormData(); |
92 | $.each( $('#new_tradition').serializeArray(), function( i, o ) { |
93 | data.append( o.name, o.value ); |
94 | }); |
95 | data.append( 'file', newfile ); |
96 | var upload_url = _get_url([ 'newtradition' ]); |
97 | post_xhr2( upload_url, data, function( ret ) { |
98 | if( ret.id ) { |
99 | $('#upload-collation-dialog').dialog('close'); |
100 | refreshDirectory(); |
101 | loadTradition( ret.id, ret.name, 1 ); |
102 | } else if( ret.error ) { |
103 | $('#upload_status').empty().append( |
104 | $('<span>').attr('class', 'error').append( ret.error ) ); |
105 | } |
106 | }, 'json' ); |
107 | }; |
108 | reader.onerror = function( evt ) { |
109 | var err_resp = 'File read error'; |
110 | if( e.name == 'NotFoundError' ) { |
111 | err_resp = 'File not found'; |
112 | } else if ( e.name == 'NotReadableError' ) { |
113 | err_resp == 'File unreadable - is it yours?'; |
114 | } else if ( e.name == 'EncodingError' ) { |
115 | err_resp == 'File cannot be encoded - is it too long?'; |
116 | } else if ( e.name == 'SecurityError' ) { |
117 | err_resp == 'File read security error'; |
118 | } |
119 | // Fake a jqXHR object that we can pass to our generic error handler. |
120 | var jqxhr = { responseText: '{error:"' + err_resp + '"}' }; |
121 | display_error( jqxhr, $('#upload_status') ); |
122 | $('#upload_button').button('disable'); |
123 | } |
124 | |
125 | reader.readAsBinaryString( newfile ); |
126 | } |
127 | |
128 | // Utility function to neatly construct an application URL |
129 | function _get_url( els ) { |
130 | return basepath + els.join('/'); |
131 | } |
132 | |
133 | // TODO Attach unified ajaxError handler to document |
134 | $(document).ready( function() { |
135 | // See if we have the browser functionality we need |
136 | // TODO Also think of a test for SVG readiness |
137 | if( !!window.FileReader && !!window.File ) { |
138 | $('#compatibility_check').empty(); |
139 | } |
140 | |
141 | $('#upload-collation-dialog').dialog({ |
142 | autoOpen: false, |
143 | height: 360, |
144 | width: 480, |
145 | modal: true, |
146 | buttons: { |
147 | upload: { |
148 | text: 'Upload', |
149 | id: 'upload_button', |
150 | click: function() { |
151 | $('#upload_status').empty(); |
152 | $('#upload_button').button("disable"); |
153 | upload_new(); |
154 | } |
155 | }, |
156 | pick_file: { |
157 | text: 'Pick File', |
158 | id: 'pick_file_button', |
159 | click: function() { |
160 | $('#new_file').click(); |
161 | } |
162 | }, |
163 | Cancel: function() { |
164 | $('#upload-collation-dialog').dialog('close'); |
165 | } |
166 | }, |
167 | open: function() { |
168 | // Set the upload button to its correct state based on |
169 | // whether a file is loaded |
170 | file_selected( $('#new_file').get(0) ); |
171 | $('#upload_status').empty(); |
172 | } |
173 | }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) { |
174 | // Reset button state |
175 | file_selected( $('#new_file').get(0) ); |
176 | // Display error message if applicable |
177 | if( ajaxSettings.url.indexOf( 'newtradition' ) > -1 |
178 | && ajaxSettings.type == 'POST' ) { |
179 | display_error( jqXHR, $("#upload_status") ); |
180 | } |
181 | });; |
182 | |
183 | }); |