materio_search_api_ajax.js 11 KB

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