materio_search_api_ajax.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. // @codekit-prepend "gui.js"
  2. // @koala-prepend "gui_ck_fw/gui.js"
  3. (function($) {
  4. MaterioSearchApiAjax = function(){
  5. var _isloadingresults = false;
  6. var _$content = $('#content');
  7. // TODO: define $content by module settings
  8. /**
  9. * init()
  10. */
  11. function init(){
  12. //trace('init MaterioSearchApiAjax');
  13. initSearchAjax();
  14. initViewMode();
  15. };
  16. /**
  17. * searchAjax
  18. */
  19. function initSearchAjax(){
  20. trace('initSearchAjax');
  21. // fulltext search form
  22. $('#materio-search-api-search-form').bind('submit', function(event) {
  23. // trace('search submited', event);
  24. // var $this = $(this);
  25. setTimeout(function(){
  26. loadResults(getSearchKeys());
  27. },10);
  28. return false;
  29. });
  30. // filtered search form
  31. $('#materio-search-api-advanced-search-form').bind('submit', function(event) {
  32. event.preventDefault();
  33. // trace('advanced search submited', event);
  34. // var $this = $(this);
  35. setTimeout(function(){
  36. loadResults(getSearchFilters(), 'advanced');
  37. },10);
  38. return false;
  39. });
  40. // /!\ AUTOCOMPLETE SELECT EVENT need a patch http://drupal.org/node/365241#comment-5374686
  41. $("#edit-searchfield")
  42. .bind('autocompleteSelect', function(event) {
  43. // $(this).parents('.form').trigger('submit');
  44. setTimeout(function(){
  45. loadResults(getSearchKeys(), "taxonomy");
  46. },10);
  47. })
  48. .bind('focus', function(event){
  49. $(this).select();
  50. });
  51. $(document)
  52. .bind('theme-ready', onThemeReady)
  53. .bind('init-scroller-pager', onInitScrollerPager)
  54. .bind('load-scroller-pager', onLoadScrollerPager)
  55. .bind('view-mode-changed', onViewModeChanged)
  56. .bind('history-state-change', onHistoryStateChange);
  57. };
  58. function onThemeReady(event){
  59. // trace('MaterioSearchApiAjax :: onThemeReady');
  60. if( isActuality() || isExplore() ){
  61. $.event.trigger({
  62. type : 'resultschanged',
  63. container : isActuality() ? '#content .actuality-items' : '#content .search-results'
  64. });
  65. }
  66. };
  67. function getSearchKeys(){
  68. return $('#materio-search-api-search-form').find('input[name*="searchfield"]').val();
  69. };
  70. function getSearchFilters(){
  71. var keys = [];
  72. $('#materio-search-api-advanced-search-form')
  73. .find('.filter-line').each(function(i, line) {
  74. // get the select form items from last to first
  75. // remove the first select object as it's not keywords for search
  76. var $selects = $($('.form-item.form-type-select select', line).get().reverse()).slice(0,-1);
  77. // get the keys from select form items
  78. $selects.each(function(j, select) {
  79. if($(select).val() !== ""){
  80. keys.push('"' + $("option:selected",select).text() + '"');
  81. return false;
  82. }
  83. });
  84. });
  85. trace("getSearchFilters :: keys", keys);
  86. return keys.join("+");
  87. };
  88. function loadResults(keys, searchmode){
  89. trace('loadResults keys', keys);
  90. if(keys !== undefined && keys !== '' && keys.length >= 2){
  91. keys = keys.replace('/', ' ');
  92. // define mode (between full text or only term selected on autocompletion)
  93. searchmode = searchmode || "fulltext";
  94. // record the "node type filter" form item
  95. var types = {}, stringTypes = [];
  96. $('#edit-bundles-filter', '#materio-search-api-search-form').find('input[type*="checkbox"]').each(function(i){
  97. $this = $(this);
  98. if ( $this.attr('checked') )
  99. stringTypes.push($this.val());
  100. types[$this.val()] = $this.attr('checked');
  101. });
  102. //trace('types', types);
  103. if(!_isloadingresults){
  104. $.event.trigger('loading-content');
  105. _isloadingresults = true;
  106. $('#materio-search-api-search-form').addClass('loading');
  107. // trace('window.location.href',window.location.href);
  108. // TODO: record ajax path in a variable from materio_search_api_ajax_init
  109. $.getJSON(Drupal.settings.basePath+Drupal.settings.pathPrefix+'materio_search_api_ajax/search/',
  110. {'types':types,'current_path':document.location.href, 'keys':keys, 'searchmode':searchmode},
  111. function(json){
  112. //trace('json', json);
  113. // google analytics
  114. $.event.trigger({
  115. type : "record-stat",
  116. categorie : 'Search',
  117. action : keys,
  118. label : 'filters : '+ stringTypes.join(' ,'),
  119. value : json.count
  120. });
  121. if(json.redirect){
  122. window.location = json.redirect;
  123. }else{
  124. $.event.trigger('loaded-content');
  125. _isloadingresults = false;
  126. $('#materio-search-api-search-form').removeClass('loading');
  127. changeContent(json);
  128. }
  129. });
  130. }
  131. }
  132. };
  133. function loadActuality(){
  134. if(!_isloadingresults){
  135. $.event.trigger('loading-content');
  136. _isloadingresults = true;
  137. $('#materio-search-api-search-form').addClass('loading');
  138. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materio_search_api_ajax/actuality';
  139. $.getJSON(url,
  140. function(json){
  141. //trace('json', json);
  142. $.event.trigger('loaded-content');
  143. _isloadingresults = false;
  144. $('#materio-search-api-search-form').removeClass('loading');
  145. changeContent(json);
  146. });
  147. }
  148. };
  149. function changeContent(json){
  150. //trace('MaterioSearchApiAjax changeContent | json', json);
  151. if(json.returned){
  152. $.event.trigger('loaded-content');
  153. $('.inner-content',_$content).html(json.returned).find('ul.pager').hide();
  154. triggerContentChanged();
  155. }else{
  156. //trace('no results');
  157. }
  158. $.event.trigger({
  159. type : 'new-history-page',
  160. path : Drupal.settings.basePath + Drupal.settings.pathPrefix + json.path,
  161. title : json.title,
  162. content : json.returned
  163. });
  164. for (language in Drupal.settings.materio_search_api_ajax.languages) {
  165. var l = Drupal.settings.materio_search_api_ajax.languages[language];
  166. $('#block-locale-language li.'+language+' a').attr('href', Drupal.settings.basePath + l.prefix+'/' + json.search_path + '/' + json.keys)
  167. };
  168. };
  169. function triggerContentChanged(){
  170. //trace('MaterioSearchApiAjax :: triggerContentChanged');
  171. $.event.trigger({
  172. type : 'resultschanged',
  173. container : '#content .search-results, #content .actuality-items'
  174. });
  175. };
  176. function onInitScrollerPager(event){
  177. // trace("onInitScrollerPager");
  178. if(isActuality() || isExplore())
  179. event.pager.hide();
  180. };
  181. function onLoadScrollerPager(event){
  182. // trace("onLoadScrollerPager");
  183. if(!_isloadingresults){
  184. if (isExplore())
  185. loadNextResultsPage(event.href);
  186. if(isActuality())
  187. loadNextActualityPage(event.href);
  188. }
  189. };
  190. function loadNextResultsPage(href){
  191. trace('loadNextResultsPage');
  192. var keys = href.match(/explore\/([^\/|\?]+)/);
  193. var page = href.match(/\?page=([0-9]+)/);
  194. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materio_search_api_ajax/search/'+page[1];
  195. loadNextPage(url, keys[1], $('.materiobase-results', _$content), '.search-results');
  196. };
  197. function loadNextActualityPage(href){
  198. // trace('loadNextActualityPage');
  199. var page = href.match(/\?page=([0-9]+)/);
  200. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materio_search_api_ajax/actuality/'+page[1];
  201. loadNextPage(url, '', $('.materiobase-actuality', _$content), '.actuality-items');
  202. };
  203. function loadNextPage(url, keys, $container, target){
  204. // trace('MaterioSearchApiAjax :: loadNextPage()');
  205. _isloadingresults = true;
  206. $container.addClass('loading');
  207. $.getJSON(url, {'keys':keys}, function(json){
  208. //trace('json', json);
  209. $container.removeClass('loading');
  210. addNextpage(json, target);
  211. // addNextpageItemByItem($(json.return), target);
  212. });
  213. };
  214. function addNextpage(json, container_class){
  215. // trace('json',json);
  216. if(json){
  217. var $newcontent = $(json.returned),
  218. $newitems = $(container_class, $newcontent).children('article'), //.addClass('just-added'),
  219. $newpager = $('ul.pager', $newcontent);
  220. $(container_class, _$content).append($newitems);
  221. $('ul.pager', _$content).replaceWith($newpager.hide());
  222. // TODO: animation, this should be on theme side
  223. $(container_class, _$content).children('.just-added').each(function(i){
  224. var $this = $(this);
  225. setTimeout(function(){
  226. $this.removeClass('just-added');
  227. }, 150*i);
  228. });
  229. $.event.trigger({
  230. type : 'resultscompleted',
  231. container : $(container_class, _$content)
  232. });
  233. }
  234. _isloadingresults = false;
  235. };
  236. // TEST not used
  237. function addNextpageItemByItem($newcontent, container_class){
  238. //trace('MaterioSearchApiAjax :: addNextpageItemByItem()');
  239. $('ul.pager', _$content).remove();
  240. $(container_class, _$content).append($(container_class, $newcontent).children('article').eq(0));
  241. if($(container_class, $newcontent).children('article').length){
  242. setTimeout(function(){
  243. addNextpageItemByItem($newcontent, container_class);
  244. }, 200);
  245. }else{
  246. _isloadingresults = false;
  247. $('ul.pager', _$content).replaceWith($('ul.pager', $newcontent).hide());
  248. $.event.trigger({
  249. type : 'resultscompleted',
  250. container : $(container_class, _$content)
  251. });
  252. }
  253. };
  254. /**
  255. * viewmode
  256. */
  257. function initViewMode(){
  258. $('.viewmode-link').click(function(event){
  259. event.preventDefault();
  260. if(!$(this).is('.active')){
  261. $(this).trigger({type:'vm-clicked'});
  262. changeViewMode($(this).attr('rel'), $(this));
  263. }else{
  264. $(this).trigger({type:'vm-clicked-active'});
  265. }
  266. return false;
  267. });
  268. };
  269. function changeViewMode(vm, $btn){
  270. if(!_isloadingresults){
  271. _isloadingresults = true;
  272. $.getJSON(Drupal.settings.basePath+'materio_search_api_ajax/viewmode/change/'+vm, function(json){
  273. //trace('viewmode json', json);
  274. _isloadingresults = false;
  275. if (json.statut == "saved"){
  276. // google analytics
  277. $.event.trigger({
  278. type : "record-stat",
  279. categorie : 'Viewmode',
  280. action : vm,
  281. label : isActuality() ? 'Actualities' : 'Search results'
  282. });
  283. $.event.trigger('view-mode-changed');
  284. $('.viewmode-link, .viewmode-link i').removeClass('active');
  285. $btn.addClass('active').find('i').addClass('active');
  286. }
  287. });
  288. }
  289. };
  290. function onViewModeChanged(event){
  291. if (isExplore())
  292. loadResults(getSearchKeys());
  293. if(isActuality())
  294. loadActuality();
  295. };
  296. /**
  297. * history
  298. */
  299. function onHistoryStateChange(event){
  300. if(isExplore() || isActuality())
  301. triggerContentChanged();
  302. // TODO: pushstate trogger state change, so we have a retriggerring here on loading new results … how to avoid this
  303. };
  304. /**
  305. * helpers
  306. */
  307. function isExplore(){
  308. return $('.search-results', '#content').length;
  309. };
  310. function isActuality(){
  311. return $('.actuality-items', '#content').length;
  312. };
  313. init();
  314. };
  315. $(document).ready(function() {
  316. var materiosearchapiajax = new MaterioSearchApiAjax();
  317. });
  318. })(jQuery);