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>