materio_flag.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. // @codekit-prepend "gui.js"
  2. (function($) {
  3. MaterioFlag = function(){
  4. var _isLoadingList = false ;
  5. /**
  6. * init()
  7. */
  8. function init(){
  9. //trace('MaterioFlag :: init MaterioFlag');
  10. buildBlocks();
  11. $(document)
  12. .bind('flagGlobalAfterLinkUpdate', onFlaging)
  13. .bind('resultscompleted resultschanged', onResultsUpdated)
  14. .bind('init-scroller-pager', onInitScrollerPager)
  15. .bind('load-scroller-pager', onLoadScrollerPager)
  16. .bind('view-mode-changed', onViewModeChanged)
  17. .bind('history-state-change', onHistoryStateChange);
  18. ajaxifyLinks();
  19. // trigger updated event for direct html loading
  20. if(isList()){
  21. setTimeout(function(){
  22. triggerContentChanged();
  23. }, 10);
  24. }
  25. };
  26. function onFlaging(event){
  27. //trace('MaterioFlag :: onFlaging', event);
  28. refreshBlocks();
  29. };
  30. function onResultsUpdated(event){
  31. //trace('MaterioFlag :: onResultsUpdated', event);
  32. ajaxifyLinks(event.container);
  33. };
  34. function buildBlocks(activename){
  35. //trace('MaterioFlag :: buildBlocks', activename);
  36. if($('#block-materio-flag-materio-flag-mybookmarks').length){
  37. var type = 'bookmarks';
  38. var block = '#block-materio-flag-materio-flag-mybookmarks';
  39. }else if($('#block-materio-flag-materio-flag-mylists').length){
  40. var type = 'lists';
  41. var block = '#block-materio-flag-materio-flag-mylists';
  42. }
  43. switch(type){
  44. case 'bookmarks':
  45. var name = type;
  46. $('h2 .listname', block).attr('name', name).bind('click', onClickShowPreview);
  47. $('<i class="icon-remove"></i>').appendTo($('h2', block)).attr('name', name).bind('click', onClickClosePreview);
  48. // $('<span class="preview"><i class="icon-eye-open"></i></span>').appendTo($('h2', block)).bind('click', onClickShowPreview);
  49. // if(!readCookie('materiobookmarkspreviewopened')){
  50. // showPreview('bookmarks', block);
  51. // }else{
  52. // }
  53. break;
  54. case 'lists':
  55. // nav block
  56. $('a.open-list:not(.ajax-processed)', '#block-materio-flag-materio-flag-mylists-nav').each(function(index){
  57. $this = $(this)
  58. .bind('click', onClickOpenLink)
  59. .addClass('ajax-processed');
  60. var name = $this.attr('class').match(/flag_lists_[^_]+_[0-9]+/);
  61. // trace('MaterioFlag :: name', name);
  62. $('<span class="preview"><i class="icon-eye-open"></i></span>').attr('name', name).insertAfter($this).bind('click', onClickShowPreview);
  63. });
  64. // preview block
  65. $('section.flag-list:not(.ajax-processed)', '#block-materio-flag-materio-flag-mylists').each(function(index){
  66. var name = $(this).attr('class').match(/flag_lists_[^_]+_[0-9]+/);
  67. $('<i class="icon-remove"></i>').appendTo($('h2.listname', this)).attr('name', name).bind('click', onClickClosePreview);
  68. $('a.open-list', this).bind('click', onClickOpenLink);
  69. }).addClass('ajax-processed');
  70. break;
  71. }
  72. // trigger refresh block event for enabling lazyload images
  73. setTimeout(function(){
  74. $.event.trigger({
  75. type : 'my'+type+'-block-builded',
  76. block : block,
  77. name : name
  78. });
  79. },10);
  80. // trace('MaterioFlag :: activename', activename);
  81. if(activename == undefined)
  82. activename = readCookie('materiomyflaglistsopened');
  83. // trace('MaterioFlag :: activename', activename);
  84. if(activename)
  85. showPreview(activename, block);
  86. };
  87. function refreshBlocks(name){
  88. //trace('MaterioFlag :: refreshBlocks | name', name);
  89. if($('#block-materio-flag-materio-flag-mybookmarks').length){
  90. var type = 'bookmarks';
  91. }else if($('#block-materio-flag-materio-flag-mylists').length){
  92. var type = 'lists';
  93. }
  94. if(type != undefined){
  95. var id = '#block-materio-flag-materio-flag-my'+type;
  96. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materioflag/refresh/block/'+type;
  97. $.getJSON(url, function(json){
  98. //trace('MaterioFlag :: block refreshed '+type, json);
  99. $(id).replaceWith(json.block);
  100. $('#block-materio-flag-materio-flag-mylists-nav').replaceWith(json.block_nav);
  101. buildBlocks(name);
  102. $.event.trigger({
  103. type : 'my'+type+'-block-updated',
  104. listname : name
  105. });
  106. });
  107. }
  108. ajaxifyLinks();
  109. };
  110. function ajaxifyLinks(container){
  111. //trace('MaterioFlag :: ajaxifyLinks', container);
  112. container = ((container != null) ? container : 'body');
  113. // trace('MaterioFlag :: typeof Drupal.flagLink', typeof Drupal.flagLink);
  114. if (typeof Drupal.flagLink != 'undefined')
  115. Drupal.flagLink(container);
  116. if(isList()){
  117. var fid = $('.materio-flags-list', '#content').attr('fid');
  118. $('li.unflag-action.fid-'+fid+' a:not(.ajax-processed), li.flag-bookmarks a.unflag-action:not(.ajax-processed)')
  119. .bind('click', onUnflagList)
  120. .addClass('ajax-processed');
  121. }
  122. $('a.flag-lists-create:not(.ajax-processed)', container)
  123. .bind('click', onClickCreatLink)
  124. .addClass('ajax-processed');
  125. $('a.edit-list:not(.ajax-processed)', container)
  126. .bind('click', onCLickEditList)
  127. .addClass('ajax-processed');
  128. };
  129. /**
  130. * show hide preview
  131. */
  132. function onClickShowPreview(event){
  133. //trace('MaterioFlag :: onClickShowPreview', event);
  134. showPreview($(this).attr('name'), $(this).parent('.block').attr('id'));
  135. };
  136. function showPreview(name, block){
  137. //trace('MaterioFlag :: showPreview', name);
  138. $('section.'+name, block).addClass('active')
  139. .siblings('section').removeClass('active');
  140. createCookie('materiomyflaglistsopened', name, 1);
  141. $.event.trigger('init-layout');
  142. };
  143. function onClickClosePreview(event){
  144. //trace('MaterioFlag :: onClickClosePreview', event);
  145. eraseCookie('materiomyflaglistsopened');
  146. if($(this).attr('name') == 'bookmarks'){
  147. $(this).parents('.block').find('section.bookmarks').removeClass('active');
  148. }else{
  149. $(this).parents('section.flag-list').removeClass('active');
  150. }
  151. $.event.trigger('init-layout');
  152. };
  153. /**
  154. * onClickOpenLink
  155. */
  156. function onClickOpenLink(event){
  157. event.preventDefault();
  158. var $link = $(event.currentTarget);
  159. var fid = $link.attr('href').match(/lists\/([0-9]+)$/);
  160. // trace('MaterioFlag :: type', type);
  161. loadList(fid[1]);
  162. return false;
  163. };
  164. function loadList(fid){
  165. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materioflag/ajax/list/'+fid;
  166. $.event.trigger('loading-content');
  167. $.getJSON(url, {'current_path':document.location.href},function(json){
  168. //trace('MaterioFlag :: json', json);
  169. if(json.redirect){
  170. window.location = json.redirect;
  171. }else{
  172. changeContent(json);
  173. }
  174. });
  175. };
  176. function changeContent(json){
  177. if(json.return){
  178. $('.inner-content','#content').html(json.return);
  179. $.event.trigger('loaded-content');
  180. // no need of ajaxifylinks because it's triggered with resultschanged
  181. // ajaxifyLinks('#content');
  182. var path = Drupal.settings.basePath + Drupal.settings.pathPrefix + json.path;
  183. $.event.trigger({
  184. type : 'new-history-page',
  185. path : path,
  186. title : json.title,
  187. content : json.return
  188. });
  189. // TODO: change language links for folders
  190. // for (language in Drupal.settings.materio_search_api_ajax.languages) {
  191. // var l = Drupal.settings.materio_search_api_ajax.languages[language];
  192. // $('#block-locale-language li.'+language+' a').attr('href', Drupal.settings.basePath + l.prefix+'/' + json.search_path + '/' + json.keys)
  193. // };
  194. triggerContentChanged();
  195. }else{
  196. //trace('MaterioFlag :: no results');
  197. }
  198. };
  199. function triggerContentChanged(){
  200. $.event.trigger({
  201. type: 'resultschanged',
  202. container : '#content .flaglist-items'
  203. });
  204. };
  205. /**
  206. * onClickCreatLink(event)
  207. */
  208. function onClickCreatLink(event){
  209. event.preventDefault();
  210. var $link = $(event.currentTarget);
  211. var type = $link.attr('href').match(/[^\/]*$/);
  212. // trace('MaterioFlag :: type', type);
  213. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materioflag/createlist/form/'+type[0];
  214. $.getJSON(url, function(json){
  215. //trace('MaterioFlag :: creat list : json', json);
  216. showCreateListForm(json, $link);
  217. });
  218. return false;
  219. };
  220. function showCreateListForm(json, $link){
  221. // google analytics
  222. $.event.trigger({
  223. type:"record-stat",
  224. categorie:"flagLists",
  225. action: 'show create form'
  226. });
  227. var $modal = $('<div id="modal" class="modal"/>').appendTo('body');
  228. $modal
  229. .css({
  230. position:'absolute',
  231. top:'40%', left:'50%',
  232. marginLeft:'-150px', width:'300px',
  233. zIndex:"99999"
  234. })
  235. .append(json.return)
  236. .find('input[type="submit"]', '#materio-flag-create-list-form').bind('click', function(event) {
  237. event.preventDefault();
  238. switch($(this).attr('name')){
  239. case 'cancel':
  240. //trace('MaterioFlag :: cancel',event);
  241. $(this).parents('#modal').remove();
  242. // google analytics
  243. $.event.trigger({
  244. type:"record-stat",
  245. categorie:"flagLists",
  246. action: 'cancel create form'
  247. });
  248. break;
  249. case 'create':
  250. //trace('MaterioFlag :: create',event);
  251. var title = $(this).parents('form').find('input[name*="flag-lists-name"]').val();
  252. var type = $(this).parents('form').find('input[name*="type"]').val();
  253. // google analytics
  254. $.event.trigger({
  255. type : "record-stat",
  256. categorie : "flagLists",
  257. action : "submit create form",
  258. label : 'title : '+title
  259. });
  260. createList($modal, type, title, $link);
  261. break;
  262. }
  263. return false;
  264. })
  265. .parents('form').find('input[type="text"]').focus();
  266. // TODO: esc keypressed close the form
  267. };
  268. function createList($modal, type, title, $link){
  269. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'flag-lists/add/'+type+'/js';
  270. $.getJSON(url, {name:title}, function(data) {
  271. if (data.error) {
  272. //trace(data.error);
  273. }
  274. else {
  275. // select.append('<option value="'+data.flag.fid+'">'+data.flag.title+'</option>');
  276. // $('input.name', $(this)).val('');
  277. // dialog.dialog('close');
  278. //trace('MaterioFlag :: created list : data', data);
  279. if($link.attr('nid') && $link.attr('token')){
  280. flagEntityWithList(data.flag.name, $link.attr('nid'), $link.attr('token'));
  281. }else{
  282. refreshBlocks(data.flag.name);
  283. refreshNodeLinks();
  284. }
  285. $modal.remove();
  286. }
  287. });
  288. };
  289. function flagEntityWithList(name, nid, token){
  290. // var ret;
  291. // Send POST request
  292. $.ajax({
  293. type: 'POST',
  294. url: Drupal.settings.basePath+Drupal.settings.pathPrefix+'flag-lists/flag/'+name+'/'+nid,
  295. data: { js: true, token: token },
  296. dataType: 'json',
  297. success: function (data2) {
  298. //trace('MaterioFlag :: node taged with newly created list : data2', data2)
  299. if (data2.status) {
  300. // google analytics
  301. $.event.trigger({
  302. type : "record-stat",
  303. categorie : 'FlagLists',
  304. action : 'node flaged',
  305. label : 'nid : '+nid+' | flag : '+name
  306. });
  307. refreshBlocks(name);
  308. refreshNodeLinks();
  309. }else {
  310. // Failure.
  311. alert(data2.errorMessage);
  312. }
  313. },
  314. error: function (xmlhttp) {
  315. alert('An HTTP error '+ xmlhttp.status +' occurred.\n'+ element.href);
  316. }
  317. });
  318. };
  319. function refreshNodeLinks(){
  320. var nids = new Array();
  321. $('.flag-lists-entity-links').parents('.node').each(function(index) {
  322. nids.push($(this).attr('class').match(/node-([0-9]+)/)[1]);
  323. });
  324. // trace('MaterioFlag :: nids', nids);
  325. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materioflag/nodelinks';
  326. $.getJSON(url, {nids:nids.join(";")}, function(data) {
  327. // trace('MaterioFlag :: data', data);
  328. for(nid in data.links){
  329. // trace('MaterioFlag :: nid', nid);
  330. // trace('MaterioFlag :: data.links[nid]', data.links[nid]);
  331. $('.node-'+nid+' .flag-lists-entity-links').replaceWith(data.links[nid]);
  332. // trace('MaterioFlag :: typeof Drupal.flagLink', typeof Drupal.flagLink);
  333. // if (typeof Drupal.flagLink != 'undefined')
  334. // Drupal.flagLink($('.node-'+nid+' .flag-lists-entity-links'));
  335. ajaxifyLinks('.node-'+nid+' .flag-lists-entity-links');
  336. }
  337. });
  338. $.event.trigger({
  339. type : 'materioflag-nodelinks-updated',
  340. nids : nids
  341. });
  342. };
  343. /**
  344. * onCLickEditList(event)
  345. */
  346. function onCLickEditList(event){
  347. // TODO: empécher le double formulaire
  348. event.preventDefault();
  349. var $link = $(event.currentTarget);
  350. var lid = $link.attr('href').match(/[^\/]*$/);
  351. var type = 'materiau'; // this is cheap
  352. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materioflag/editlistform/'+type+'/'+lid[0];
  353. $.getJSON(url, function(json){
  354. //trace('MaterioFlag :: editlist : json', json);
  355. showEditListForm(json, $link);
  356. });
  357. return false;
  358. };
  359. function showEditListForm(json, $link){
  360. // google analytics
  361. $.event.trigger({
  362. type:"record-stat",
  363. categorie:"flagLists",
  364. action: 'show edit form'
  365. });
  366. var $modal = $('<div id="modal" class="modal"/>').appendTo('body');
  367. $modal
  368. .css({
  369. position:'absolute',
  370. top:'40%', left:'50%',
  371. marginLeft:'-150px', width:'300px',
  372. zIndex:"99999"
  373. })
  374. .append(json.return)
  375. .find('input[type="submit"]', '#materio-flag-edit-list-form').bind('click', function(event) {
  376. event.preventDefault();
  377. var $form = $(this).parents('form');
  378. var title = $form.find('input[name*="flag-lists-title"]').val();
  379. var fid = $form.find('input[name*="fid"]').val();
  380. var name = $form.find('input[name*="name"]').val();
  381. switch($(this).attr('name')){
  382. case 'cancel':
  383. //trace('MaterioFlag :: cancel',event);
  384. $(this).parents('#modal').remove();
  385. // google analytics
  386. var action = 'cancel edit form';
  387. break;
  388. case 'save':
  389. //trace('MaterioFlag :: create',event);
  390. // google analytics
  391. var action = "submit edit form";
  392. editList($modal, fid, name, title);
  393. break;
  394. case 'delete':
  395. //trace('MaterioFlag :: delete',event);
  396. if(confirm('Do you realy want to delete the folder '+title+'?')){
  397. var action = "submit delete form";
  398. deleteList($modal, fid);
  399. }else{
  400. var action = "cancel delete form";
  401. }
  402. break;
  403. }
  404. // google analytics
  405. $.event.trigger({
  406. type:"record-stat",
  407. categorie:"flagLists",
  408. action: action
  409. });
  410. return false;
  411. })
  412. .parents('form').find('input[type="text"]').focus();
  413. // TODO: esc keypressed close the form
  414. };
  415. function editList($modal, fid, name, title){
  416. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materioflag/editlist/'+fid+'/'+name+'/'+title;
  417. $.getJSON(url, function(data) {
  418. if (data.error) {
  419. // trace(data.error);
  420. if(data.message)
  421. alert(data.message);
  422. }
  423. else {
  424. //trace('MaterioFlag :: saved list : data', data);
  425. $.event.trigger({
  426. type : 'list-edited',
  427. name : data.listname,
  428. title : data.title,
  429. });
  430. refreshBlocks();
  431. refreshNodeLinks();
  432. $modal.remove();
  433. }
  434. });
  435. };
  436. function deleteList($modal, fid){
  437. // prompt('are you sure ?');
  438. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materioflag/deletelist/'+fid;
  439. $.getJSON(url, function(data) {
  440. if (data.error) {
  441. // trace(data.error);
  442. if(data.message)
  443. alert(data.message);
  444. }
  445. else {
  446. //trace('MaterioFlag :: deleted list : data', data);
  447. refreshBlocks();
  448. refreshNodeLinks();
  449. // TODO: if the deleted list was the current displayed list ??
  450. $modal.remove();
  451. }
  452. });
  453. };
  454. /**
  455. * onUnflagList()
  456. */
  457. function onUnflagList(event){
  458. //trace('onUnflagList', event);
  459. $(this).parents('article.node').addClass('removed');
  460. };
  461. /**
  462. *
  463. */
  464. function onInitScrollerPager(event){
  465. // trace('MaterioFlag :: MaterioFlag :: onInitScrollerPager');
  466. if (isList()){
  467. // trace('MaterioFlag :: event.pager', event);
  468. event.pager.hide();
  469. }
  470. };
  471. function onLoadScrollerPager(event){
  472. if (isList())
  473. loadNextListPage(event.href);
  474. };
  475. function loadNextListPage(href){
  476. // trace('MaterioFlag :: loadNextListPage', href);
  477. if(!_isLoadingList){
  478. var fid = href.match(/lists\/([^\/|\?]+)/);
  479. var page = href.match(/\?page=([0-9]+)/);
  480. var url = Drupal.settings.basePath+Drupal.settings.pathPrefix+'materioflag/ajax/list/'+fid[1]+'/'+page[1];
  481. // trace('MaterioFlag :: url', url);
  482. loadNextPage(url, $('.materio-flags-list', '#content'), '.flaglist-items');
  483. }
  484. };
  485. function loadNextPage(url, $container, target){
  486. //trace('MaterioFlag :: loadNextPage');
  487. _isLoadingList = true;
  488. $container.addClass('loading');
  489. $.getJSON(url, function(json){
  490. //trace('json', json);
  491. _isLoadingList = false;
  492. $container.removeClass('loading');
  493. addNextpage(json, target);
  494. });
  495. };
  496. function addNextpage(json, container_class){
  497. var $newcontent = $(json.return),
  498. $newitems = $(container_class, $newcontent).children('article').addClass('just-added'),
  499. $newpager = $('ul.pager', $newcontent);
  500. $(container_class, '#content').append($newitems);
  501. $('ul.pager', '#content').replaceWith($newpager.hide());
  502. // TODO: animation, this should be on theme side
  503. $(container_class, '#content').children('.just-added').each(function(i){
  504. // $(this).delay(5000*i).removeClass('just-added');
  505. var $this = $(this);
  506. setTimeout(function(){
  507. $this.removeClass('just-added');
  508. }, 150*i);
  509. });
  510. $.event.trigger({
  511. type : 'resultscompleted',
  512. container : $(container_class, '#content')
  513. });
  514. };
  515. function onViewModeChanged(event){
  516. if (isList())
  517. loadList(getFid());
  518. };
  519. /**
  520. * history
  521. */
  522. function onHistoryStateChange(event){
  523. if(isList())
  524. triggerContentChanged();
  525. };
  526. /**
  527. * Helpers
  528. */
  529. function getFid(){
  530. return $('.materio-flags-list', '#content').attr('fid');;
  531. };
  532. function isList(){
  533. return $('.materio-flags-list', '#content').length;
  534. };
  535. /**
  536. * cookies
  537. */
  538. function createCookie(name,value,days) {
  539. if (days) {
  540. var date = new Date();
  541. date.setTime(date.getTime()+(days*24*60*60*1000));
  542. var expires = "; expires="+date.toGMTString();
  543. }
  544. else var expires = "";
  545. document.cookie = name+"="+value+expires+"; path=/";
  546. }
  547. function readCookie(name) {
  548. var nameEQ = name + "=";
  549. var ca = document.cookie.split(';');
  550. for(var i=0;i < ca.length;i++) {
  551. var c = ca[i];
  552. while (c.charAt(0)==' ') c = c.substring(1,c.length);
  553. if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  554. }
  555. return null;
  556. }
  557. function eraseCookie(name) {
  558. createCookie(name,"",-1);
  559. }
  560. init();
  561. };
  562. var materioflag = new MaterioFlag();
  563. })(jQuery);