diff --git a/app/assets/javascripts/application/search.js b/app/assets/javascripts/application/search.js index 16d286a245fd942327d0507d010d26360d28d0f2..28d8a1b4697e146322159efc7f8d8dfa020aebc5 100644 --- a/app/assets/javascripts/application/search.js +++ b/app/assets/javascripts/application/search.js @@ -1,198 +1,340 @@ +////// SEARCH var search = function() { - var state = history.state; - var intervalId = 0; - var params = {}; - //// initialize search parameters - resetParam(); - - function resetParam() { - params.query = ""; - params.page = 1; - params.order = ""; - params.subject = []; - params.type = []; - params.school_year = []; - params.year = ""; - } + //// SEARCH FETCH + // get results from params + var searchFetch = function(append) { + // append result - see more + if ((append === undefined) || (append === false)) { + append = false; - $(document).ready(function () { - checkUrl(); + // reset pagination + params.reset('page'); + } - watchers(); - }); + // change url with new parameters + searchState(params); - // get parameters from url when page is loaded - function checkUrl() { - var element, - values = state.url.slice(state.url.indexOf('?') + 1).split('&'), - length = values.length; - for(var i = 0; i < length; i++) { - element = values[i].split('='); - // validates parameters - if (params[element[0]] !== undefined) { - // if string type - if (params[element[0]] !== undefined){ - params[element[0]] = element[1]; + $.ajax({ + url:"/search/fetch", + type: 'get', + data: params.get(), + beforeSend: function() { + if (append) { + $('.search-more').remove(); } - // object else { - params[element[0]].push(element[1]); + $("#search-fetch").empty(); } + $('#search-fetch').append('<div class="search-loading" style="text-align:center;"><br><div class="pong-loader">Carregando...</div></div>'); } - } + }) + .done(function (data) { + if (append) { + $('.search-more, .search-loading').remove(); + } + else { + $("#search-fetch").empty(); + } - fetch(); - } + $("#search-fetch").append(data); - // watch elements for change in parameters - function watchers() { - watchSearchInput(); - watchOrder(); - watchFilters(); + searchWatchers().attachMoreResults(); + }); } - function watchSearchInput() { - $('.search-input form').on('submit', function (event) { - event.preventDefault(); - resetParam(); - params.query = $('input[name="query"]', this).val(); - fetch(); - }); - } + //// SEARCH WATCHERS + // get initial params from url and watch inputs for params + var searchWatchers = function() { + var intervalId = 0; + var has_init = false; - function watchOrder() { - $('select[name="order"]').on('change', function (event) { - params.order = $(this).val(); - fetch(); - }); - } + function init() { + // init when document is ready + $(document).ready(function () { + // check url and set inputs with params + checkUrl(); - function watchMoreResults() { - $('.search-more').on('click', function (event) { - event.preventDefault(); - params.page += 1; - fetch(true); - }); - } + watchSearchInput(); + watchOrder(); + watchFilters(); + }); + } + + // get parameters from url when page is loaded + function checkUrl() { + if (history.state.search_params !== undefined) { + params.reload(history.state.search_params); + } + else { + var element, + url = history.state.url, + values = url.slice(url.indexOf('?') + 1).split('&'), + length = values.length; + + for(var i = 0; i < length; i++) { + element = values[i].split('='); + params.add(element[0], element[1]); + } + + // replace history state with new parameters + searchState(params, true); + } + + searchFetch(); + } + + function watchSearchInput() { + $('.search-input form input[name="query"]').val(params.get('query')); + $('.search-input form').on('submit', function (event) { + event.preventDefault(); + params.reset(); + params.add('query', $('input[name="query"]', this).val()); + searchFetch(); + }); + } - function watchFilters() { - $('.search-link').on('change', function(e) { + function watchOrder() { + $('select[name="order"]').val(params.get('order')); + $('select[name="order"]').on('change', function (event) { + params.add('order', $(this).val()); + searchFetch(); + }); + } + + function watchFilters() { + watchFilterSubject(); + watchFilterType(); + watchFilterSchoolYear(); + } + + function filtersFetchInterval() { // cancel previous function call clearInterval(intervalId); - intervalId = setInterval(function () { checkFilters(); }, 1000 ); - }); - } + intervalId = setInterval(function () { + searchFetch(); + // cancel to not loop (interval) + clearInterval(intervalId); + }, 800 ); + } - function checkFilters() { - clearInterval(intervalId); + function watchFilterSubject() { + // add values from url + var subjects = params.get('subject'); + $('.filter-subject').each(function() { + // TODO: add logic / select2 + }); - checkFilterSubject(); - checkFilterType(); - checkFilterSchoolYear(); + // watch for changes + $('.filter-subject').on('change', function () { + var subject_filters = []; + $('.filter-subject').each(function() { + //add only non-null values + if($(this).val()) + subject_filters.push($(this).val()); + }); + //flatten the array + subject_filters = [].concat.apply([], subject_filters); - fetch(); - } + params.add('subject', subject_filters, true); - function checkFilterSubject() { - var subject_filters = []; - $('.filter-subject').each(function() { - //add only non-null values - if($(this).val()) - subject_filters.push($(this).val()); - }); - //flatten the array - subject_filters = [].concat.apply([], subject_filters); + filtersFetchInterval(); + }); + } - params.subject = subject_filters; - } + function watchFilterType() { + // add values from url + var types = params.get('type'); + $('input[name="filter-type"]').each(function() { + if (~types.indexOf($(this).val())) { + $(this).attr('checked', true); + } + }); - function checkFilterType() { - params.type = []; - $('input[name="filter-type"]:checked').each(function() { - params.type.push($(this).val()); - }); - } + // watch for changes + $('input[name="filter-type"]').on('change', function () { + params.reset('type'); + $('input[name="filter-type"]:checked').each(function() { + params.add('type', $(this).val()); + }); - function checkFilterSchoolYear() { - params.school_year = []; - $('input[name="filter-school-year"]:checked').each(function(){ - params.school_year.push($(this).val()); - }); - } + filtersFetchInterval(); + }); + } + + function watchFilterSchoolYear() { + // add values from url + var types = params.get('school-year'); + $('input[name="filter-school-year"]').each(function() { + if (~types.indexOf($(this).val())) { + $(this).attr('checked', true); + } + }); + // watch for changes + $('input[name="filter-school-year"]').on('change', function () { + params.reset('school_year'); + $('input[name="filter-school-year"]:checked').each(function(){ + params.add('school_year', $(this).val()); + }); - function createUrlFromParameters() { - var base = state.url.split('?', 1), - url = base + "?", - keys = Object.keys(params), - length = keys.length; + filtersFetchInterval(); + }); + } - // check every parameter - for (var i = 0; i < length; ++i) { - // only get non empty values - if (params[keys[i]].length > 0) { - // string concat in url - if (typeof params[keys[i]] === "string") { - url += "&" + keys[i] + "=" + params[keys[i]]; - } - // object can have more than one element to concat in url - else { - var object_length = params[keys[i]].length - for (var j = 0; j < object_length; ++j) { - url += "&" + keys[i] + "=" + params[keys[i]][j]; - } + return { + init: function() { + if (!has_init) { + init(); + has_init = true; } + }, + attachMoreResults: function() { + $('.search-more').on('click', function (event) { + event.preventDefault(); + params.add('page', params.get('page') + 1); + searchFetch(true); + }); } } - - return url; } - // get objects html to embed - function fetch(append) { - // append result - see more - if (append === undefined || append === false) { - append = false; + //// INIT + // initiate params + var params = searchParameters(); - // reset pagination - params.page = 1; - } + // init when document is ready + $(document).ready(function () { + // return previous state when back + $(window).on("popstate", function(e) { + var original = e.originalEvent.state; + history.replaceState(original, original.url, original.url); + searchFetch(); + }); - // change url with new parameters - var url = createUrlFromParameters(); - history.pushState(state, url, url); + // run watchers + searchWatchers().init(); + }); +}; +//// SEARCH STATE +// take care of History API +var searchState = function(params, replace) { + if (replace === undefined) { + replace = false; + } + var newState = history.state; + newState.url = params.url(); + newState.search_params = params.get(); - $.ajax({ - url:"/search/fetch", - type: 'get', - data: params, - beforeSend: function() { - if (append) { - $('.search-more').remove(); + if (replace) { + history.replaceState(newState, newState.url, newState.url); + } + else { + history.pushState(newState, newState.url, newState.url); + } +} + +//// SEARCH PARAMETERS +// take care of params (setters and getters) +var searchParameters = function() { + var default_params = { + query: "", + page: 1, + order: "", + subject: [], + type: [], + school_year: [], + year: "" + } + // clone default_params + var params = JSON.parse(JSON.stringify(default_params)); + + function validate_type(type) { + return params[type] !== undefined; + } + + return { + reload: function(params_new) { + params = params_new; + }, + add: function(type, value, replace) { + if (replace === undefined) { + replace = false; + } + if (validate_type(type)) { + // if string type or replace + if ((typeof params[type] === "string") || (typeof params[type] === "number") || replace) { + params[type] = value; } + // if object, append else { - $("#search-fetch").empty(); + params[type].push(value); } - $("#search-fetch").append('<div class="search-loading" style="text-align:center;"><br><div class="pong-loader">Carregando...</div></div>'); } - }) - .done(function (data) { - if (append) { - $('.search-more, .search-loading').remove(); + }, + remove: function(type, value) { + if (validate_type(type)) { + // if string type + if ((typeof params[type] === "string") || (typeof params[type] === "number")){ + // remove element + params[type] = ""; } + // if object else { - $("#search-fetch").empty(); + // remove only if element exists + // https://stackoverflow.com/questions/18347033/how-to-shorten-my-conditional-statements/18347047#answer-18347047 + var index = params[type].indexOf(value); + if (~index) { + params[type].splice(index,1); + } } + } + }, + get: function(type) { + if (type === undefined) { + return params; + } + return params[type]; + }, + url: function() { + var url = history.state.url.split('?', 1) + "?", + keys = Object.keys(params), + length = keys.length; - $("#search-fetch").append(data); - - watchMoreResults(); - }); - } + // check every parameter + for (var i = 0; i < length; ++i) { + // only get non empty values + if (params[keys[i]].length > 0) { + // string concat in url + if (typeof params[keys[i]] === "string") { + url += "&" + keys[i] + "=" + params[keys[i]]; + } + // object can have more than one element to concat in url + else { + var object_length = params[keys[i]].length + for (var j = 0; j < object_length; ++j) { + url += "&" + keys[i] + "=" + params[keys[i]][j]; + } + } + } + } + return url; + }, + reset: function(type) { + if (type === undefined) { + // reset params + params = JSON.parse(JSON.stringify(default_params)); + } + else { + // reset params.type + params[type] = JSON.parse(JSON.stringify(default_params[type])); + } + } + }; }; +//// DROPDOWN var runDropdown = function(element) { if ($(element).next().is(':hidden')) { $('> .caret', element).addClass('caret-up'); diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index f62a25ff87c726691ed61d1b65d1a6b86a470085..06c3c5104b2cc3332c3e191e06fbf11a889c7c4e 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -13,9 +13,6 @@ class SearchController < ApplicationController end @pagination_limit=10 - if (params[:page_limit]) - @pagination_limit=params[:page_limit].to_i - end unless params[:query].blank? params[:order] = "" if params[:order].blank? @@ -23,10 +20,6 @@ class SearchController < ApplicationController objectsFound = search params[:query], params[:order] @numFound = objectsFound.length - # if params[:order] - # @ordena = params[:order] - # end - # # case params[:order] # items = objectsFound.collect{ |x| Ranking::Item.new(x.name,x.views,0,x.likes,x) } #puts each object in an item # diff --git a/app/views/search/index.html.erb b/app/views/search/index.html.erb index 3db1026d6dc43a58522d486b0c4ff9b94b879e45..3d2b691c5536661c69716a4e88907d6dccaa3bfa 100644 --- a/app/views/search/index.html.erb +++ b/app/views/search/index.html.erb @@ -259,7 +259,7 @@ <%= page_entries_info @result unless @result.blank? %> <select class="order" name="order"> - <option value=<%= @ordena %>>Ordenar por</option> + <option value="">Ordenar por</option> <option value="author">Autores</option> <option value="publicationasc">Mais novos</option> <option value="publicationdesc">Mais velhos</option> @@ -270,7 +270,7 @@ <br/> </div> <br/> - <div id="search-fetch" class="container-fluid"></div> + <div id="search-fetch" class="container-fluid" data-no-turbolink></div> </div> </div>