1 // General-purpose error-handling function.
2 // TODO make sure this gets used throughout, where appropriate.
3 function display_error( jqXHR, el ) {
5 if( jqXHR.responseText == "" ) {
6 errmsg = "perhaps the server went down?"
10 errobj = jQuery.parseJSON( jqXHR.responseText );
11 errmsg = errobj.error;
12 } catch ( parse_err ) {
13 errmsg = "something went wrong on the server."
16 var msghtml = $('<span>').attr('class', 'error').text( "An error occurred: " + errmsg );
17 $(el).empty().append( msghtml ).show();
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>' );
26 $('#upload_button').button('disable');
27 $('#new_file_name_container').html( '(Use \'pick file\' to select a tradition file to upload.)' );
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
37 function post_xhr2( url, data, cb, type ) {
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';
49 // Gin up an AJAX settings object
50 $.ajaxSetup({ url: url, type: 'POST' });
51 xhr.open( 'POST', url, true );
53 xhr.onload = function( e ) {
54 // Get the response and parse it
55 // Call the callback with the response, whatever it was
57 if( xhrs.status > 199 && xhrs.status < 300 ) { // Success
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;
70 // Trigger the ajaxError...
71 _trigger_ajaxerror( e );
74 xhr.onerror = _trigger_ajaxerror;
75 xhr.onabort = _trigger_ajaxerror;
79 function _trigger_ajaxerror( e ) {
81 var thrown = xhr.statusText || 'Request error';
82 jQuery.event.trigger( 'ajaxError', [ xhr, $.ajaxSettings, thrown ]);
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 );
95 data.append( 'file', newfile );
96 var upload_url = _get_url([ 'newtradition' ]);
97 post_xhr2( upload_url, data, function( ret ) {
99 $('#upload-collation-dialog').dialog('close');
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 ) );
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';
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');
125 reader.readAsBinaryString( newfile );
128 // Utility function to neatly construct an application URL
129 function _get_url( els ) {
130 return basepath + els.join('/');
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();
141 $('#upload-collation-dialog').dialog({
151 $('#upload_status').empty();
152 $('#upload_button').button("disable");
158 id: 'pick_file_button',
160 $('#new_file').click();
164 $('#upload-collation-dialog').dialog('close');
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();
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") );