diff --git a/module/VuFind/src/VuFind/Controller/AjaxController.php b/module/VuFind/src/VuFind/Controller/AjaxController.php index 72ef9fbe439c3b2a68b94cfa056a68c44737696a..edcfa676c881eaec837ae0a378c3bf8e51a3c862 100644 --- a/module/VuFind/src/VuFind/Controller/AjaxController.php +++ b/module/VuFind/src/VuFind/Controller/AjaxController.php @@ -88,12 +88,13 @@ class AjaxController extends AbstractBase ? ': ' . $e->getMessage() : ''; return $this->output( $this->translate('An error has occurred') . $debugMsg, - self::STATUS_ERROR + self::STATUS_ERROR, + 500 ); } } else { return $this->output( - $this->translate('Invalid Method'), self::STATUS_ERROR + $this->translate('Invalid Method'), self::STATUS_ERROR, 400 ); } } @@ -478,7 +479,8 @@ class AjaxController extends AbstractBase if (!$user) { return $this->output( $this->translate('You must be logged in first'), - self::STATUS_NEED_AUTH + self::STATUS_NEED_AUTH, + 401 ); } @@ -490,7 +492,8 @@ class AjaxController extends AbstractBase if (!is_array($ids) || !is_array($sources)) { return $this->output( $this->translate('Argument must be array.'), - self::STATUS_ERROR + self::STATUS_ERROR, + 400 ); } $result = []; @@ -611,7 +614,8 @@ class AjaxController extends AbstractBase } catch (AuthException $e) { return $this->output( $this->translate($e->getMessage()), - self::STATUS_ERROR + self::STATUS_ERROR, + 401 ); } @@ -629,7 +633,8 @@ class AjaxController extends AbstractBase if ($user === false) { return $this->output( $this->translate('You must be logged in first'), - self::STATUS_NEED_AUTH + self::STATUS_NEED_AUTH, + 401 ); } // empty tag @@ -650,7 +655,8 @@ class AjaxController extends AbstractBase } catch (\Exception $e) { return $this->output( ('development' == APPLICATION_ENV) ? $e->getMessage() : 'Failed', - self::STATUS_ERROR + self::STATUS_ERROR, + 500 ); } @@ -886,71 +892,56 @@ class AjaxController extends AbstractBase $id = $this->params()->fromQuery('id'); $data = $this->params()->fromQuery('data'); $requestType = $this->params()->fromQuery('requestType'); - if (!empty($id) && !empty($data)) { - // check if user is logged in - $user = $this->getUser(); - if (!$user) { - return $this->output( - [ - 'status' => false, - 'msg' => $this->translate('You must be logged in first') - ], - self::STATUS_NEED_AUTH - ); - } - - try { - $catalog = $this->getILS(); - $patron = $this->getILSAuthenticator()->storedCatalogLogin(); - if ($patron) { - switch ($requestType) { - case 'ILLRequest': - $results = $catalog->checkILLRequestIsValid( - $id, $data, $patron - ); - - $msg = $results - ? $this->translate( - 'ill_request_place_text' - ) - : $this->translate( - 'ill_request_error_blocked' - ); - break; - case 'StorageRetrievalRequest': - $results = $catalog->checkStorageRetrievalRequestIsValid( - $id, $data, $patron - ); - - $msg = $results - ? $this->translate( - 'storage_retrieval_request_place_text' - ) - : $this->translate( - 'storage_retrieval_request_error_blocked' - ); - break; - default: - $results = $catalog->checkRequestIsValid( - $id, $data, $patron - ); + if (empty($id) || empty($data)) { + return $this->output( + $this->translate('bulk_error_missing'), + self::STATUS_ERROR, + 400 + ); + } + // check if user is logged in + $user = $this->getUser(); + if (!$user) { + return $this->output( + $this->translate('You must be logged in first'), + self::STATUS_NEED_AUTH, + 401 + ); + } - $msg = $results - ? $this->translate('request_place_text') - : $this->translate('hold_error_blocked'); - break; - } - return $this->output( - ['status' => $results, 'msg' => $msg], self::STATUS_OK + try { + $catalog = $this->getILS(); + $patron = $this->getILSAuthenticator()->storedCatalogLogin(); + if ($patron) { + switch ($requestType) { + case 'ILLRequest': + $results = $catalog->checkILLRequestIsValid($id, $data, $patron); + $msg = $results + ? 'ill_request_place_text' : 'ill_request_error_blocked'; + break; + case 'StorageRetrievalRequest': + $results = $catalog->checkStorageRetrievalRequestIsValid( + $id, $data, $patron ); + $msg = $results ? 'storage_retrieval_request_place_text' + : 'storage_retrieval_request_error_blocked'; + break; + default: + $results = $catalog->checkRequestIsValid($id, $data, $patron); + $msg = $results ? 'request_place_text' : 'hold_error_blocked'; + break; } - } catch (\Exception $e) { - // Do nothing -- just fail through to the error message below. + return $this->output( + ['status' => $results, 'msg' => $this->translate($msg)], + self::STATUS_OK + ); } + } catch (\Exception $e) { + // Do nothing -- just fail through to the error message below. } return $this->output( - $this->translate('An error has occurred'), self::STATUS_ERROR + $this->translate('An error has occurred'), self::STATUS_ERROR, 500 ); } @@ -965,7 +956,8 @@ class AjaxController extends AbstractBase if ($user === false) { return $this->output( $this->translate('You must be logged in first'), - self::STATUS_NEED_AUTH + self::STATUS_NEED_AUTH, + 401 ); } @@ -973,7 +965,9 @@ class AjaxController extends AbstractBase $comment = $this->params()->fromPost('comment'); if (empty($id) || empty($comment)) { return $this->output( - $this->translate('An error has occurred'), self::STATUS_ERROR + $this->translate('bulk_error_missing'), + self::STATUS_ERROR, + 400 ); } @@ -997,15 +991,25 @@ class AjaxController extends AbstractBase if ($user === false) { return $this->output( $this->translate('You must be logged in first'), - self::STATUS_NEED_AUTH + self::STATUS_NEED_AUTH, + 401 ); } $id = $this->params()->fromQuery('id'); + if (empty($id)) { + return $this->output( + $this->translate('bulk_error_missing'), + self::STATUS_ERROR, + 400 + ); + } $table = $this->getTable('Comments'); - if (empty($id) || !$table->deleteIfOwnedByUser($id, $user)) { + if (!$table->deleteIfOwnedByUser($id, $user)) { return $this->output( - $this->translate('An error has occurred'), self::STATUS_ERROR + $this->translate('edit_list_fail'), + self::STATUS_ERROR, + 403 ); } @@ -1076,7 +1080,8 @@ class AjaxController extends AbstractBase if (!$pluginManager->has($resolverType)) { return $this->output( $this->translate("Could not load driver for $resolverType"), - self::STATUS_ERROR + self::STATUS_ERROR, + 500 ); } $resolver = new \VuFind\Resolver\Connection( @@ -1151,46 +1156,45 @@ class AjaxController extends AbstractBase $this->writeSession(); // avoid session write timing bug $id = $this->params()->fromQuery('id'); $pickupLib = $this->params()->fromQuery('pickupLib'); - if (!empty($id) && !empty($pickupLib)) { - // check if user is logged in - $user = $this->getUser(); - if (!$user) { - return $this->output( - [ - 'status' => false, - 'msg' => $this->translate('You must be logged in first') - ], - self::STATUS_NEED_AUTH - ); - } + if (empty($id) || empty($pickupLib)) { + return $this->output( + $this->translate('bulk_error_missing'), + self::STATUS_ERROR, + 400 + ); + } + // check if user is logged in + $user = $this->getUser(); + if (!$user) { + return $this->output( + $this->translate('You must be logged in first'), + self::STATUS_NEED_AUTH, + 401 + ); + } - try { - $catalog = $this->getILS(); - $patron = $this->getILSAuthenticator()->storedCatalogLogin(); - if ($patron) { - $results = $catalog->getILLPickupLocations( - $id, $pickupLib, $patron - ); - foreach ($results as &$result) { - if (isset($result['name'])) { - $result['name'] = $this->translate( - 'location_' . $result['name'], - [], - $result['name'] - ); - } + try { + $catalog = $this->getILS(); + $patron = $this->getILSAuthenticator()->storedCatalogLogin(); + if ($patron) { + $results = $catalog->getILLPickupLocations($id, $pickupLib, $patron); + foreach ($results as &$result) { + if (isset($result['name'])) { + $result['name'] = $this->translate( + 'location_' . $result['name'], + [], + $result['name'] + ); } - return $this->output( - ['locations' => $results], self::STATUS_OK - ); } - } catch (\Exception $e) { - // Do nothing -- just fail through to the error message below. + return $this->output(['locations' => $results], self::STATUS_OK); } + } catch (\Exception $e) { + // Do nothing -- just fail through to the error message below. } return $this->output( - $this->translate('An error has occurred'), self::STATUS_ERROR + $this->translate('An error has occurred'), self::STATUS_ERROR, 500 ); } @@ -1204,50 +1208,49 @@ class AjaxController extends AbstractBase $this->writeSession(); // avoid session write timing bug $id = $this->params()->fromQuery('id'); $requestGroupId = $this->params()->fromQuery('requestGroupId'); - if (!empty($id) && !empty($requestGroupId)) { - // check if user is logged in - $user = $this->getUser(); - if (!$user) { - return $this->output( - [ - 'status' => false, - 'msg' => $this->translate('You must be logged in first') - ], - self::STATUS_NEED_AUTH - ); - } + if (empty($id) || empty($requestGroupId)) { + return $this->output( + $this->translate('bulk_error_missing'), + self::STATUS_ERROR, + 400 + ); + } + // check if user is logged in + $user = $this->getUser(); + if (!$user) { + return $this->output( + $this->translate('You must be logged in first'), + self::STATUS_NEED_AUTH, + 401 + ); + } - try { - $catalog = $this->getILS(); - $patron = $this->getILSAuthenticator()->storedCatalogLogin(); - if ($patron) { - $details = [ - 'id' => $id, - 'requestGroupId' => $requestGroupId - ]; - $results = $catalog->getPickupLocations( - $patron, $details - ); - foreach ($results as &$result) { - if (isset($result['locationDisplay'])) { - $result['locationDisplay'] = $this->translate( - 'location_' . $result['locationDisplay'], - [], - $result['locationDisplay'] - ); - } + try { + $catalog = $this->getILS(); + $patron = $this->getILSAuthenticator()->storedCatalogLogin(); + if ($patron) { + $details = [ + 'id' => $id, + 'requestGroupId' => $requestGroupId + ]; + $results = $catalog->getPickupLocations($patron, $details); + foreach ($results as &$result) { + if (isset($result['locationDisplay'])) { + $result['locationDisplay'] = $this->translate( + 'location_' . $result['locationDisplay'], + [], + $result['locationDisplay'] + ); } - return $this->output( - ['locations' => $results], self::STATUS_OK - ); } - } catch (\Exception $e) { - // Do nothing -- just fail through to the error message below. + return $this->output(['locations' => $results], self::STATUS_OK); } + } catch (\Exception $e) { + // Do nothing -- just fail through to the error message below. } return $this->output( - $this->translate('An error has occurred'), self::STATUS_ERROR + $this->translate('An error has occurred'), self::STATUS_ERROR, 500 ); } diff --git a/themes/bootstrap3/js/check_item_statuses.js b/themes/bootstrap3/js/check_item_statuses.js index 45ba11f6f39716cfad2f775356da060c86abad20..0aeec0d860ad510de4fcb9fed2fdeee818c723a5 100644 --- a/themes/bootstrap3/js/check_item_statuses.js +++ b/themes/bootstrap3/js/check_item_statuses.js @@ -13,75 +13,76 @@ function checkItemStatuses() { dataType: 'json', method: 'POST', url: VuFind.getPath() + '/AJAX/JSON?method=getItemStatuses', - data: {id:id}, - success: function(response) { - if(response.status == 'OK') { - $.each(response.data, function(i, result) { - var item = $($('.ajaxItem')[result.record_number]); + data: {id:id} + }) + .done(function(response) { + $.each(response.data, function(i, result) { + var item = $($('.ajaxItem')[result.record_number]); - item.find('.status').empty().append(result.availability_message); - if (typeof(result.full_status) != 'undefined' - && result.full_status.length > 0 - && item.find('.callnumAndLocation').length > 0 + item.find('.status').empty().append(result.availability_message); + if (typeof(result.full_status) != 'undefined' + && result.full_status.length > 0 + && item.find('.callnumAndLocation').length > 0 + ) { + // Full status mode is on -- display the HTML and hide extraneous junk: + item.find('.callnumAndLocation').empty().append(result.full_status); + item.find('.callnumber').addClass('hidden'); + item.find('.location').addClass('hidden'); + item.find('.hideIfDetailed').addClass('hidden'); + item.find('.status').addClass('hidden'); + } else if (typeof(result.missing_data) != 'undefined' + && result.missing_data + ) { + // No data is available -- hide the entire status area: + item.find('.callnumAndLocation').addClass('hidden'); + item.find('.status').addClass('hidden'); + } else if (result.locationList) { + // We have multiple locations -- build appropriate HTML and hide unwanted labels: + item.find('.callnumber').addClass('hidden'); + item.find('.hideIfDetailed').addClass('hidden'); + item.find('.location').addClass('hidden'); + var locationListHTML = ""; + for (var x=0; x<result.locationList.length; x++) { + locationListHTML += '<div class="groupLocation">'; + if (result.locationList[x].availability) { + locationListHTML += '<i class="fa fa-ok text-success"></i> <span class="text-success">' + + result.locationList[x].location + '</span> '; + } else if (typeof(result.locationList[x].status_unknown) !== 'undefined' + && result.locationList[x].status_unknown ) { - // Full status mode is on -- display the HTML and hide extraneous junk: - item.find('.callnumAndLocation').empty().append(result.full_status); - item.find('.callnumber').addClass('hidden'); - item.find('.location').addClass('hidden'); - item.find('.hideIfDetailed').addClass('hidden'); - item.find('.status').addClass('hidden'); - } else if (typeof(result.missing_data) != 'undefined' - && result.missing_data - ) { - // No data is available -- hide the entire status area: - item.find('.callnumAndLocation').addClass('hidden'); - item.find('.status').addClass('hidden'); - } else if (result.locationList) { - // We have multiple locations -- build appropriate HTML and hide unwanted labels: - item.find('.callnumber').addClass('hidden'); - item.find('.hideIfDetailed').addClass('hidden'); - item.find('.location').addClass('hidden'); - var locationListHTML = ""; - for (var x=0; x<result.locationList.length; x++) { - locationListHTML += '<div class="groupLocation">'; - if (result.locationList[x].availability) { - locationListHTML += '<i class="fa fa-ok text-success"></i> <span class="text-success">' - + result.locationList[x].location + '</span> '; - } else if (typeof(result.locationList[x].status_unknown) !== 'undefined' - && result.locationList[x].status_unknown - ) { - if (result.locationList[x].location) { - locationListHTML += '<i class="fa fa-status-unknown text-warning"></i> <span class="text-warning">' - + result.locationList[x].location + '</span> '; - } - } else { - locationListHTML += '<i class="fa fa-remove text-error"></i> <span class="text-error"">' - + result.locationList[x].location + '</span> '; - } - locationListHTML += '</div>'; - locationListHTML += '<div class="groupCallnumber">'; - locationListHTML += (result.locationList[x].callnumbers) - ? result.locationList[x].callnumbers : ''; - locationListHTML += '</div>'; + if (result.locationList[x].location) { + locationListHTML += '<i class="fa fa-status-unknown text-warning"></i> <span class="text-warning">' + + result.locationList[x].location + '</span> '; } - item.find('.locationDetails').removeClass('hidden'); - item.find('.locationDetails').empty().append(locationListHTML); } else { - // Default case -- load call number and location into appropriate containers: - item.find('.callnumber').empty().append(result.callnumber+'<br/>'); - item.find('.location').empty().append( - result.reserve == 'true' - ? result.reserve_message - : result.location - ); + locationListHTML += '<i class="fa fa-remove text-danger"></i> <span class="text-danger"">' + + result.locationList[x].location + '</span> '; } - }); + locationListHTML += '</div>'; + locationListHTML += '<div class="groupCallnumber">'; + locationListHTML += (result.locationList[x].callnumbers) + ? result.locationList[x].callnumbers : ''; + locationListHTML += '</div>'; + } + item.find('.locationDetails').removeClass('hidden'); + item.find('.locationDetails').empty().append(locationListHTML); } else { - // display the error message on each of the ajax status place holder - $(".ajax-availability").empty().append(response.data); + // Default case -- load call number and location into appropriate containers: + item.find('.callnumber').empty().append(result.callnumber+'<br/>'); + item.find('.location').empty().append( + result.reserve == 'true' + ? result.reserve_message + : result.location + ); } - $(".ajax-availability").removeClass('ajax-availability'); - } + }); + + $(".ajax-availability").removeClass('ajax-availability'); + }) + .fail(function(response, textStatus) { + if (textStatus == "abort") { return; } + // display the error message on each of the ajax status place holder + $(".ajax-availability").empty().append(response.responseJSON.data).addClass('text-danger'); }); } diff --git a/themes/bootstrap3/js/check_save_statuses.js b/themes/bootstrap3/js/check_save_statuses.js index a7259a62c8421ebffe9eb49d7892146732d46312..032c7eda006a563e225f76ef173146fd08ddd11c 100644 --- a/themes/bootstrap3/js/check_save_statuses.js +++ b/themes/bootstrap3/js/check_save_statuses.js @@ -18,23 +18,21 @@ function checkSaveStatuses() { dataType: 'json', method: 'POST', url: VuFind.getPath() + '/AJAX/JSON?method=getSaveStatuses', - data: {id:ids, 'source':srcs}, - success: function(response) { - if(response.status == 'OK') { - for (var rn in response.data) { - var list = $('#result'+rn).find('.savedLists') - if (list.length == 0) { - list = $('.savedLists'); - } - var html = list.find('strong')[0].outerHTML+'<ul>'; - for (var i=0; i<response.data[rn].length; i++) { - html += '<li><a href="' + VuFind.getPath() + '/MyResearch/MyList/' + response.data[rn][i].list_id + '">' - + response.data[rn][i].list_title + '</a></li>'; - } - html += '</ul>'; - list.html(html).removeClass('hidden'); - } + data: {id:ids, 'source':srcs} + }) + .done(function(response) { + for (var rn in response.data) { + var list = $('#result'+rn).find('.savedLists') + if (list.length == 0) { + list = $('.savedLists'); } + var html = list.find('strong')[0].outerHTML+'<ul>'; + for (var i=0; i<response.data[rn].length; i++) { + html += '<li><a href="' + VuFind.getPath() + '/MyResearch/MyList/' + response.data[rn][i].list_id + '">' + + response.data[rn][i].list_title + '</a></li>'; + } + html += '</ul>'; + list.html(html).removeClass('hidden'); } }); } diff --git a/themes/bootstrap3/js/common.js b/themes/bootstrap3/js/common.js index 9528b20897e4bb544ae99dea97cdddfd4ab52694..de3aa0505695d1a05a593d76756c19b8f1a9f3f5 100644 --- a/themes/bootstrap3/js/common.js +++ b/themes/bootstrap3/js/common.js @@ -1,5 +1,8 @@ /*global btoa, console, hexEncode, isPhoneNumberValid, Lightbox, rc4Encrypt, unescape, VuFind */ +// IE 9< console polyfill +window.console = window.console || {log: function () {}}; + function VuFindNamespace(p, s, dsb) { var defaultSearchBackend = dsb; var path = p; @@ -196,57 +199,49 @@ function newAccountHandler(html) { function ajaxLogin(form) { Lightbox.ajax({ url: VuFind.getPath() + '/AJAX/JSON?method=getSalt', - dataType: 'json', - success: function(response) { - if (response.status == 'OK') { - var salt = response.data; - - // extract form values - var params = {}; - for (var i = 0; i < form.length; i++) { - // special handling for password - if (form.elements[i].name == 'password') { - // base-64 encode the password (to allow support for Unicode) - // and then encrypt the password with the salt - var password = rc4Encrypt( - salt, btoa(unescape(encodeURIComponent(form.elements[i].value))) - ); - // hex encode the encrypted password - params[form.elements[i].name] = hexEncode(password); - } else { - params[form.elements[i].name] = form.elements[i].value; - } - } + dataType: 'json' + }) + .done(function(response) { + var salt = response.data; - // login via ajax - Lightbox.ajax({ - type: 'POST', - url: VuFind.getPath() + '/AJAX/JSON?method=login', - dataType: 'json', - data: params, - success: function(response) { - if (response.status == 'OK') { - Lightbox.addCloseAction(refreshPageForLogin); - // and we update the modal - var params = deparam(Lightbox.lastURL); - if (params['subaction'] == 'UserLogin') { - Lightbox.close(); - } else { - Lightbox.getByUrl( - Lightbox.lastURL, - Lightbox.lastPOST, - Lightbox.changeContent - ); - } - } else { - Lightbox.displayError(response.data); - } - } - }); + // extract form values + var params = {}; + for (var i = 0; i < form.length; i++) { + // special handling for password + if (form.elements[i].name == 'password') { + // base-64 encode the password (to allow support for Unicode) + // and then encrypt the password with the salt + var password = rc4Encrypt( + salt, btoa(unescape(encodeURIComponent(form.elements[i].value))) + ); + // hex encode the encrypted password + params[form.elements[i].name] = hexEncode(password); } else { - Lightbox.displayError(response.data); + params[form.elements[i].name] = form.elements[i].value; } } + + // login via ajax + Lightbox.ajax({ + type: 'POST', + url: VuFind.getPath() + '/AJAX/JSON?method=login', + dataType: 'json', + data: params + }) + .done(function(response) { + Lightbox.addCloseAction(refreshPageForLogin); + // and we update the modal + var params = deparam(Lightbox.lastURL); + if (params['subaction'] == 'UserLogin') { + Lightbox.close(); + } else { + Lightbox.getByUrl( + Lightbox.lastURL, + Lightbox.lastPOST, + Lightbox.changeContent + ); + } + }); }); } @@ -325,7 +320,7 @@ function setupAutocomplete() { }, dataType:'json', success: function(json) { - if (json.status == 'OK' && json.data.length > 0) { + if (json.data.length > 0) { var datums = []; for (var i=0;i<json.data.length;i++) { datums.push(json.data[i]); diff --git a/themes/bootstrap3/js/hierarchyTree.js b/themes/bootstrap3/js/hierarchyTree.js index 20b906b56c95dc7040214d6bb28f35aa770d368f..a4f24c9de44058c5eeb5aacac0a940cb1abf12cf 100644 --- a/themes/bootstrap3/js/hierarchyTree.js +++ b/themes/bootstrap3/js/hierarchyTree.js @@ -27,18 +27,16 @@ function html_entity_decode(string, quote_style) { function getRecord(recordID) { $.ajax({ url: VuFind.getPath() + '/Hierarchy/GetRecord?' + $.param({id: recordID}), - dataType: 'html', - success: function(response) { - if (response) { - $('#hierarchyRecord').html(html_entity_decode(response)); - // Remove the old path highlighting - $('#hierarchyTree a').removeClass("jstree-highlight"); - // Add Current path highlighting - var jsTreeNode = $(":input[value='"+recordID+"']").parent(); - jsTreeNode.children("a").addClass("jstree-highlight"); - jsTreeNode.parents("li").children("a").addClass("jstree-highlight"); - } - } + dataType: 'html' + }) + .done(function(response) { + $('#hierarchyRecord').html(html_entity_decode(response)); + // Remove the old path highlighting + $('#hierarchyTree a').removeClass("jstree-highlight"); + // Add Current path highlighting + var jsTreeNode = $(":input[value='"+recordID+"']").parent(); + jsTreeNode.children("a").addClass("jstree-highlight"); + jsTreeNode.parents("li").children("a").addClass("jstree-highlight"); }); } @@ -78,27 +76,27 @@ function doTreeSearch() { 'lookfor': keyword, 'hierarchyID': hierarchyID, 'type': $("#treeSearchType").val() - }) + "&format=true", - 'success': function(data) { - if(data.results.length > 0) { - $('#hierarchyTree').find('.jstree-search').removeClass('jstree-search'); - var tree = $('#hierarchyTree').jstree(true); - tree.close_all(); - for(var i=data.results.length;i--;) { - var id = htmlEncodeId(data.results[i]); - tree._open_to(id); - } - for(i=data.results.length;i--;) { - var tid = htmlEncodeId(data.results[i]); - $('#hierarchyTree').find('#'+tid).addClass('jstree-search'); - } - changeNoResultLabel(false); - changeLimitReachedLabel(data.limitReached); - } else { - changeNoResultLabel(true); + }) + "&format=true" + }) + .done(function(data) { + if(data.results.length > 0) { + $('#hierarchyTree').find('.jstree-search').removeClass('jstree-search'); + var tree = $('#hierarchyTree').jstree(true); + tree.close_all(); + for(var i=data.results.length;i--;) { + var id = htmlEncodeId(data.results[i]); + tree._open_to(id); } - $('#treeSearchLoadingImg').addClass('hidden'); + for(i=data.results.length;i--;) { + var tid = htmlEncodeId(data.results[i]); + $('#hierarchyTree').find('#'+tid).addClass('jstree-search'); + } + changeNoResultLabel(false); + changeLimitReachedLabel(data.limitReached); + } else { + changeNoResultLabel(true); } + $('#treeSearchLoadingImg').addClass('hidden'); }); } } @@ -127,17 +125,18 @@ function buildJSONNodes(xml) { } function buildTreeWithXml(cb) { - $.ajax({'url': VuFind.getPath() + '/Hierarchy/GetTree', + $.ajax({ + 'url': VuFind.getPath() + '/Hierarchy/GetTree', 'data': { 'hierarchyID': hierarchyID, 'id': recordID, 'context': hierarchyContext, 'mode': 'Tree' - }, - 'success': function(xml) { - var nodes = buildJSONNodes($(xml).find('root')); - cb.call(this, nodes); } + }) + .done(function(xml) { + var nodes = buildJSONNodes($(xml).find('root')); + cb.call(this, nodes); }); } diff --git a/themes/bootstrap3/js/hold.js b/themes/bootstrap3/js/hold.js index 4895a5ab3447543c44999d7cd34d1adfc5056a0e..a34780b1ba58309e7f4afe229bcca6c69294080c 100644 --- a/themes/bootstrap3/js/hold.js +++ b/themes/bootstrap3/js/hold.js @@ -17,25 +17,24 @@ function setUpHoldRequestForm(recordId) { data: params, dataType: 'json', cache: false, - url: VuFind.getPath() + '/AJAX/JSON', - success: function(response) { - if (response.status == 'OK') { - var defaultValue = $('#pickUpLocation').data('default'); - $.each(response.data.locations, function() { - var option = $('<option></option>').attr('value', this.locationID).text(this.locationDisplay); - if (this.locationID == defaultValue || (defaultValue == '' && this.isDefault && $emptyOption.length == 0)) { - option.attr('selected', 'selected'); - } - $('#pickUpLocation').append(option); - }); + url: VuFind.getPath() + '/AJAX/JSON' + }) + .done(function(response) { + var defaultValue = $('#pickUpLocation').data('default'); + $.each(response.data.locations, function() { + var option = $('<option></option>').attr('value', this.locationID).text(this.locationDisplay); + if (this.locationID == defaultValue || (defaultValue == '' && this.isDefault && $emptyOption.length == 0)) { + option.attr('selected', 'selected'); } - $('#pickUpLocationLabel i').removeClass("fa fa-spinner icon-spin"); - $('#pickUpLocation').removeAttr('disabled'); - }, - fail: function() { - $('#pickUpLocationLabel i').removeClass("fa fa-spinner icon-spin"); - $('#pickUpLocation').removeAttr('disabled'); - } + $('#pickUpLocation').append(option); + }); + + $('#pickUpLocationLabel i').removeClass("fa fa-spinner icon-spin"); + $('#pickUpLocation').removeAttr('disabled'); + }) + .fail(function(response) { + $('#pickUpLocationLabel i').removeClass("fa fa-spinner icon-spin"); + $('#pickUpLocation').removeAttr('disabled'); }); }); $('#requestGroupId').change(); diff --git a/themes/bootstrap3/js/ill.js b/themes/bootstrap3/js/ill.js index e9033271d002878188f8cec5774cb8800d0e467d..cdef12d3c19d6a396b1d9843e11c2650bbd9f4de 100644 --- a/themes/bootstrap3/js/ill.js +++ b/themes/bootstrap3/js/ill.js @@ -11,22 +11,20 @@ function setUpILLRequestForm(recordId) { $.ajax({ dataType: 'json', cache: false, - url: url, - success: function(response) { - if (response.status == 'OK') { - $.each(response.data.locations, function() { - var option = $("<option></option>").attr("value", this.id).text(this.name); - if (this.isDefault) { - option.attr("selected", "selected"); - } - $("#ILLRequestForm #pickupLibraryLocation").append(option); - }); + url: url + }) + .done(function(response) { + $.each(response.data.locations, function() { + var option = $("<option></option>").attr("value", this.id).text(this.name); + if (this.isDefault) { + option.attr("selected", "selected"); } - $("#ILLRequestForm #pickupLibraryLocationLabel i").removeClass("fa fa-spinner icon-spin"); - }, - fail: function() { - $("#ILLRequestForm #pickupLibraryLocationLabel i").removeClass("fa fa-spinner icon-spin"); - } + $("#ILLRequestForm #pickupLibraryLocation").append(option); + }); + $("#ILLRequestForm #pickupLibraryLocationLabel i").removeClass("fa fa-spinner icon-spin"); + }) + .fail(function(response) { + $("#ILLRequestForm #pickupLibraryLocationLabel i").removeClass("fa fa-spinner icon-spin"); }); }); $("#ILLRequestForm #pickupLibrary").change(); diff --git a/themes/bootstrap3/js/lightbox.js b/themes/bootstrap3/js/lightbox.js index 531dc25b2edb29bc9685cbb747ba030423050119..5ac629f9c6ed3749c0db388763623ebc19583891 100644 --- a/themes/bootstrap3/js/lightbox.js +++ b/themes/bootstrap3/js/lightbox.js @@ -75,11 +75,25 @@ var Lightbox = { * We store all the ajax calls in case we need to cancel. * This function cancels the previous call and creates a new one. */ - ajax: function(obj) { + ajax: function(obj) { if(this.XHR) { this.XHR.abort(); } - this.XHR = $.ajax(obj); + this.XHR = $.ajax(obj) + this.XHR.then().fail(function(response, textStatus) { + if (textStatus == "abort") { return; } + if (response.responseJSON) { + Lightbox.displayError(response.responseJSON.data); + } else { + var json = JSON.parse(response.responseText); + if (json.data) { + Lightbox.displayError(json.data); + } else { + Lightbox.displayError(response.responseText); + } + } + }); + return this.XHR; }, /**********************************/ /* ====== LIGHTBOX ACTIONS ====== */ @@ -227,24 +241,12 @@ var Lightbox = { this.ajax({ type:'POST', url:url, - data:post, - success:function(html) { // Success! - callback(html); - }, - error:function(d,e) { - if (d.status == 200) { - try { - var data = JSON.parse(d.responseText); - Lightbox.changeContent('<p class="alert alert-danger">'+data.data+'</p>'); - } catch(error) { - Lightbox.changeContent('<p class="alert alert-danger">'+d.responseText+'</p>'); - } - } else if(d.status > 0) { - Lightbox.changeContent('<p class="alert alert-danger">'+d.statusText+' ('+d.status+')</p>'); - } - console.log(e,d); // Error reporting - console.log(url,post); - } + data:post + }) + .done(callback) + .fail(function(response, textStatus) { + console.log(response, textStatus); // Error reporting + console.log(url, post); }); // Store current "page" context for empty targets if(this.openingURL === false) { @@ -474,22 +476,19 @@ $(document).ready(function() { }); Lightbox.addFormHandler('exportForm', function(evt) { - $.ajax({ + Lightbox.ajax({ url: VuFind.getPath() + '/AJAX/JSON?' + $.param({method:'exportFavorites'}), type:'POST', dataType:'json', - data:Lightbox.getFormData($(evt.target)), - success:function(data) { - if(data.data.export_type == 'download' || data.data.needs_redirect) { - document.location.href = data.data.result_url; - Lightbox.close(); - return false; - } else { - Lightbox.changeContent(data.data.result_additional); - } - }, - error:function(d,e) { - //console.log(d,e); // Error reporting + data:Lightbox.getFormData($(evt.target)) + }) + .done(function(data) { + if(data.data.export_type == 'download' || data.data.needs_redirect) { + document.location.href = data.data.result_url; + Lightbox.close(); + return false; + } else { + Lightbox.changeContent(data.data.result_additional); } }); return false; diff --git a/themes/bootstrap3/js/openurl.js b/themes/bootstrap3/js/openurl.js index 7d9f4432e2c6fb9415700db59675baecca2f9d86..3594d138048f2cf20c8e807549b1594ae58fa32b 100644 --- a/themes/bootstrap3/js/openurl.js +++ b/themes/bootstrap3/js/openurl.js @@ -5,16 +5,15 @@ function loadResolverLinks($target, openUrl) { var url = VuFind.getPath() + '/AJAX/JSON?' + $.param({method:'getResolverLinks',openurl:openUrl}); $.ajax({ dataType: 'json', - url: url, - success: function(response) { - if (response.status == 'OK') { - $target.removeClass('ajax_availability') - .empty().append(response.data); - } else { - $target.removeClass('ajax_availability').addClass('error') - .empty().append(response.data); - } - } + url: url + }) + .done(function(response) { + $target.removeClass('ajax_availability').empty().append(response.data); + }) + .fail(function(response, textStatus) { + if (textStatus == "abort") { return; } + $target.removeClass('ajax_availability').addClass('text-danger') + .empty().append(response.responseJSON.data); }); } diff --git a/themes/bootstrap3/js/pubdate_vis.js b/themes/bootstrap3/js/pubdate_vis.js index 2d0915b062b6e038715d343d09b5588bce60addd..ef7721426c11e3a4e7b6fe90e4ce0c2c0694e172 100644 --- a/themes/bootstrap3/js/pubdate_vis.js +++ b/themes/bootstrap3/js/pubdate_vis.js @@ -54,81 +54,79 @@ function loadVis(facetFields, searchParams, baseURL, zooming) { // AJAX call var url = baseURL + '/AJAX/json?method=getVisData&facetFields=' + encodeURIComponent(facetFields) + '&' + searchParams; $.getJSON(url, function (data) { - if (data.status == 'OK') { - $.each(data['data'], function(key, val) { - //check if there is data to display, if there isn't hide the box - if (val['data'] == undefined || val['data'].length == 0) { - return; - } - $("#datevis" + key + "xWrapper").removeClass('hidden'); + $.each(data['data'], function(key, val) { + //check if there is data to display, if there isn't hide the box + if (val['data'] == undefined || val['data'].length == 0) { + return; + } + $("#datevis" + key + "xWrapper").removeClass('hidden'); - // plot graph - var placeholder = $("#datevis" + key + "x"); + // plot graph + var placeholder = $("#datevis" + key + "x"); - //set up the hasFilter variable - var hasFilter = true; + //set up the hasFilter variable + var hasFilter = true; - //set the has filter - if (val['min'] == 0 && val['max']== 0) { - hasFilter = false; - } + //set the has filter + if (val['min'] == 0 && val['max']== 0) { + hasFilter = false; + } - //check if the min and max value have been set otherwise set them to the ends of the graph - if (val['min'] == 0) { - val['min'] = val['data'][0][0] - 5; + //check if the min and max value have been set otherwise set them to the ends of the graph + if (val['min'] == 0) { + val['min'] = val['data'][0][0] - 5; + } + if (val['max']== 0) { + val['max'] = parseInt(val['data'][val['data'].length - 1][0], 10) + 5; + } + + if (zooming) { + //check the first and last elements of the data array against min and max value (+padding) + //if the element exists leave it, otherwise create a new marker with a minus one value + if (val['data'][val['data'].length - 1][0] != parseInt(val['max'], 10) + 5) { + val['data'].push([parseInt(val['max'], 10) + 5, -1]); } - if (val['max']== 0) { - val['max'] = parseInt(val['data'][val['data'].length - 1][0], 10) + 5; + if (val['data'][0][0] != val['min'] - 5) { + val['data'].push([val['min'] - 5, -1]); } - - if (zooming) { - //check the first and last elements of the data array against min and max value (+padding) - //if the element exists leave it, otherwise create a new marker with a minus one value - if (val['data'][val['data'].length - 1][0] != parseInt(val['max'], 10) + 5) { - val['data'].push([parseInt(val['max'], 10) + 5, -1]); - } - if (val['data'][0][0] != val['min'] - 5) { - val['data'].push([val['min'] - 5, -1]); + //check for values outside the selected range and remove them by setting them to null + for (var i=0; i<val['data'].length; i++) { + if (val['data'][i][0] < val['min'] -5 || val['data'][i][0] > parseInt(val['max'], 10) + 5) { + //remove this + val['data'].splice(i,1); + i--; } - //check for values outside the selected range and remove them by setting them to null - for (var i=0; i<val['data'].length; i++) { - if (val['data'][i][0] < val['min'] -5 || val['data'][i][0] > parseInt(val['max'], 10) + 5) { - //remove this - val['data'].splice(i,1); - i--; - } - } - - } else { - //no zooming means that we need to specifically set the margins - //do the last one first to avoid getting the new last element - val['data'].push([parseInt(val['data'][val['data'].length - 1][0], 10) + 5, -1]); - //now get the first element - val['data'].push([val['data'][0][0] - 5, -1]); } + } else { + //no zooming means that we need to specifically set the margins + //do the last one first to avoid getting the new last element + val['data'].push([parseInt(val['data'][val['data'].length - 1][0], 10) + 5, -1]); + //now get the first element + val['data'].push([val['data'][0][0] - 5, -1]); + } - var plot = $.plot(placeholder, [val], options); - if (hasFilter) { - // mark pre-selected area - plot.setSelection({ x1: val['min'] , x2: val['max']}); - } - // selection handler - placeholder.bind("plotselected", function (event, ranges) { - var from = Math.floor(ranges.xaxis.from); - var to = Math.ceil(ranges.xaxis.to); - location.href = val['removalURL'] + '&daterange[]=' + key + '&' + key + 'to=' + PadDigits(to,4) + '&' + key + 'from=' + PadDigits(from,4); - }); - if (hasFilter) { - var newdiv = document.createElement('span'); - var text = document.getElementById("clearButtonText").innerHTML; - newdiv.setAttribute('id', 'clearButton' + key); - newdiv.innerHTML = '<a href="' + htmlEncode(val['removalURL']) + '">' + text + '</a>'; - newdiv.className += "dateVisClear"; - placeholder.before(newdiv); - } + var plot = $.plot(placeholder, [val], options); + if (hasFilter) { + // mark pre-selected area + plot.setSelection({ x1: val['min'] , x2: val['max']}); + } + // selection handler + placeholder.bind("plotselected", function (event, ranges) { + var from = Math.floor(ranges.xaxis.from); + var to = Math.ceil(ranges.xaxis.to); + location.href = val['removalURL'] + '&daterange[]=' + key + '&' + key + 'to=' + PadDigits(to,4) + '&' + key + 'from=' + PadDigits(from,4); }); - } + + if (hasFilter) { + var newdiv = document.createElement('span'); + var text = document.getElementById("clearButtonText").innerHTML; + newdiv.setAttribute('id', 'clearButton' + key); + newdiv.innerHTML = '<a href="' + htmlEncode(val['removalURL']) + '">' + text + '</a>'; + newdiv.className += "dateVisClear"; + placeholder.before(newdiv); + } + }); }); } \ No newline at end of file diff --git a/themes/bootstrap3/js/record.js b/themes/bootstrap3/js/record.js index deed2b2c01cd2c5987467a34fa9b5569bf32ccf9..c3ea5fc2e5638efeb9dce06c66d91135c488bdd9 100644 --- a/themes/bootstrap3/js/record.js +++ b/themes/bootstrap3/js/record.js @@ -12,19 +12,19 @@ function checkRequestIsValid(element, requestType, blockedClass) { $.ajax({ dataType: 'json', cache: false, - url: url, - success: function(response) { - if (response.data.status) { - $(element).removeClass('disabled') - .attr('title', response.data.msg) - .html('<i class="fa fa-flag"></i> '+response.data.msg); - } else { - $(element).remove(); - } - }, - error: function(response) { + url: url + }) + .done(function(response) { + if (response.data.status) { + $(element).removeClass('disabled') + .attr('title', response.data.msg) + .html('<i class="fa fa-flag"></i> '+response.data.msg); + } else { $(element).remove(); } + }) + .fail(function(response) { + $(element).remove(); }); } @@ -44,12 +44,10 @@ function deleteRecordComment(element, recordId, recordSource, commentId) { var url = VuFind.getPath() + '/AJAX/JSON?' + $.param({method:'deleteRecordComment',id:commentId}); $.ajax({ dataType: 'json', - url: url, - success: function(response) { - if (response.status == 'OK') { - $($(element).closest('.comment')[0]).remove(); - } - } + url: url + }) + .done(function(response) { + $($(element).closest('.comment')[0]).remove(); }); } @@ -57,21 +55,19 @@ function refreshCommentList($target, recordId, recordSource) { var url = VuFind.getPath() + '/AJAX/JSON?' + $.param({method:'getRecordCommentsAsHTML',id:recordId,'source':recordSource}); $.ajax({ dataType: 'json', - url: url, - success: function(response) { - // Update HTML - if (response.status == 'OK') { - var $commentList = $target.find('.comment-list'); - $commentList.empty(); - $commentList.append(response.data); - $commentList.find('.delete').unbind('click').click(function() { - var commentId = $(this).attr('id').substr('recordComment'.length); - deleteRecordComment(this, recordId, recordSource, commentId); - return false; - }); - $target.find('.comment-form input[type="submit"]').button('reset'); - } - } + url: url + }) + .done(function(response) { + // Update HTML + var $commentList = $target.find('.comment-list'); + $commentList.empty(); + $commentList.append(response.data); + $commentList.find('.delete').unbind('click').click(function() { + var commentId = $(this).attr('id').substr('recordComment'.length); + deleteRecordComment(this, recordId, recordSource, commentId); + return false; + }); + $target.find('.comment-form input[type="submit"]').button('reset'); }); } @@ -91,17 +87,17 @@ function registerAjaxCommentRecord() { type: 'POST', url: url, data: data, - dataType: 'json', - success: function(response) { - if (response.status == 'OK') { - var $tab = $(form).closest('.tab-pane'); - refreshCommentList($tab, id, recordSource); - $(form).find('textarea[name="comment"]').val(''); - $(form).find('input[type="submit"]').button('loading'); - } else { - Lightbox.displayError(response.data); - } - } + dataType: 'json' + }) + .done(function(response) { + var $tab = $(form).closest('.tab-pane'); + refreshCommentList($tab, id, recordSource); + $(form).find('textarea[name="comment"]').val(''); + $(form).find('input[type="submit"]').button('loading'); + }) + .fail(function(response, textStatus) { + if (textStatus == "abort") { return; } + Lightbox.displayError(response.responseJSON.data); }); return false; }); @@ -156,15 +152,15 @@ function ajaxLoadTab($newTab, tabid, setHash) { url: path + urlroot + '/AjaxTab', type: 'POST', data: {tab: tabid}, - success: function(data) { - $newTab.html(data); - registerTabEvents(); - if(typeof syn_get_widget === "function") { - syn_get_widget(); - } - if (typeof setHash == 'undefined' || setHash) { - window.location.hash = tabid; - } + }) + .done(function(data) { + $newTab.html(data); + registerTabEvents(); + if(typeof syn_get_widget === "function") { + syn_get_widget(); + } + if (typeof setHash == 'undefined' || setHash) { + window.location.hash = tabid; } }); return false; @@ -179,20 +175,18 @@ function refreshTagList(target, loggedin) { var recordSource = $(target).find('.hiddenSource').val(); var $tagList = $(target).find('.tagList'); if ($tagList.length > 0) { - $tagList.empty(); var url = VuFind.getPath() + '/AJAX/JSON?' + $.param({method:'getRecordTags',id:recordId,'source':recordSource}); $.ajax({ - dataType: 'json', - url: url, - complete: function(response) { - if(response.status == 200) { - $tagList.replaceWith(response.responseText); - if(loggedin) { - $tagList.addClass('loggedin'); - } else { - $tagList.removeClass('loggedin'); - } - } + dataType: 'html', + url: url + }) + .done(function(response) { + $tagList.empty(); + $tagList.replaceWith(response); + if(loggedin) { + $tagList.addClass('loggedin'); + } else { + $tagList.removeClass('loggedin'); } }); } @@ -216,10 +210,10 @@ function ajaxTagUpdate(link, tag, remove) { id:recordId, source:recordSource, remove:remove - }, - complete: function() { - refreshTagList($target, false); } + }) + .always(function() { + refreshTagList($target, false); }); } @@ -330,7 +324,7 @@ function recordDocReady() { }); // Tag lightbox Lightbox.addFormCallback('tagRecord', function(html) { - refreshTagList(true); + refreshTagList(document, true); Lightbox.confirm(VuFind.translate('add_tag_success')); }); } \ No newline at end of file diff --git a/themes/bootstrap3/js/vudl/record.js b/themes/bootstrap3/js/vudl/record.js index 3e40714ad6fdfad419a737e8b47682564b89e72c..9e62e5ab5cbeaa6eddbc5d37e1ad6c54f7a6001f 100644 --- a/themes/bootstrap3/js/vudl/record.js +++ b/themes/bootstrap3/js/vudl/record.js @@ -17,21 +17,20 @@ function ajaxGetView(pageObject) { type: 'POST', url : '../VuDL/ajax?method=viewLoad', data: pageObject, - success: function(e) { - $('#view').html(e.data); - currentType = pageObject['filetype']; - var tab = $('#'+currentTab, e.data); - if(tab.length > 0) { - tab.click(); - } else { - currentTab = $('.nav-tabs li a:eq(0)')[0].id; - } - }, - error: function(d,e){ - console.log(d.responseText); - console.log(e); - }, dataType: 'json' + }) + .done(function(e) { + $('#view').html(e.data); + currentType = pageObject['filetype']; + var tab = $('#'+currentTab, e.data); + if(tab.length > 0) { + tab.click(); + } else { + currentTab = $('.nav-tabs li a:eq(0)')[0].id; + } + }) + .fail(function(response, textStatus) { + console.log(response, textStatus); }); } else { updateFunction(pageObject, currentTab); @@ -43,19 +42,18 @@ function updateTechInfo(record) { $.ajax({dataType:'json', type:'post', url:path+'/VuDL/ajax?method=getTechInfo', - data:record, - success:function(d) { - $('#techinfo').html(d.data.div); - var downloadSrc = 'MASTER'; - if(typeof d.data.type !== "undefined") { - $('#download-button .details').html(d.data.type+' ~ '+d.data.size); - } - $('#file-download').attr('action', VuFind.getPath()+'/files/'+record.id+'/'+downloadSrc+'?download=true'); - }, - error:function(d,e) { - console.log(d.responseText); - console.log(e); + data:record + }) + .done(function(d) { + $('#techinfo').html(d.data.div); + var downloadSrc = 'MASTER'; + if(typeof d.data.type !== "undefined") { + $('#download-button .details').html(d.data.type+' ~ '+d.data.size); } + $('#file-download').attr('action', VuFind.getPath()+'/files/'+record.id+'/'+downloadSrc+'?download=true'); + }) + .fail(function(response, textStatus) { + console.log(response, textStatus); }); } // ====== GET MORE THUMBNAILS ====== // @@ -85,32 +83,31 @@ function ajaxLoadPages(min, max) { //console.log('ajax', min, max, counts); $.ajax({ url:path+'/VuDL/ajax?method=pageAjax&record='+documentID+'&start='+min+'&end='+max, - dataType:'json', - success : function(response) { - loadWait = false; - // For each page - for(var i=0;i<response.data.length;i++) { - var page = response.data.outline[response.data.start]; - if(page == undefined) continue; - var img = $('<img src="'+page.thumbnail+'"/>'); - $('.page-link#item'+response.data.start) - .attr('onClick','ajaxGetView('+JSON.stringify(page).replace(/"/g, "'")+', this)') - .attr('title',page.id) - .attr('alt',page.label) - .attr('id', 'item'+response.data.start) - .html('<br/>'+page.label) - .prepend(img) - .addClass('active') - .removeClass('loading') - .removeClass('unloaded'); - response.data.start++; - } - findVisible(); - }, - error : function(d,e){ - console.log(d.responseText); - console.log(e); + dataType:'json' + }) + .done(function(response) { + loadWait = false; + // For each page + for(var i=0;i<response.data.length;i++) { + var page = response.data.outline[response.data.start]; + if(page == undefined) continue; + var img = $('<img src="'+page.thumbnail+'"/>'); + $('.page-link#item'+response.data.start) + .attr('onClick','ajaxGetView('+JSON.stringify(page).replace(/"/g, "'")+', this)') + .attr('title',page.id) + .attr('alt',page.label) + .attr('id', 'item'+response.data.start) + .html('<br/>'+page.label) + .prepend(img) + .addClass('active') + .removeClass('loading') + .removeClass('unloaded'); + response.data.start++; } + findVisible(); + } + .fail(function(response, textStatus) { + console.log(response, textStatus); }); } // Pages