materio_search_api_ajax.js 11 KB

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