muzich.js 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158
  1. /*
  2. * Scripts de Muzi.ch
  3. * Rédigé et propriété de Sevajol Bastien (http://www.bux.fr) sauf si mention
  4. * contraire sur la fonction.
  5. *
  6. */
  7. // Messages flashs
  8. var myMessages = ['info','warning','error','success']; // define the messages types
  9. function hideAllMessages()
  10. {
  11. var messagesHeights = new Array(); // this array will store height for each
  12. for (i=0; i<myMessages.length; i++)
  13. {
  14. messagesHeights[i] = $('.' + myMessages[i]).outerHeight();
  15. $('.' + myMessages[i]).css('top', -messagesHeights[i]); //move element outside viewport
  16. }
  17. }
  18. $(document).ready(function(){
  19. // Initially, hide them all
  20. hideAllMessages();
  21. $('.message').animate({top:"0"}, 500);
  22. // When message is clicked, hide it
  23. $('.message a.message-close').click(function(){
  24. $(this).parent('.message').animate({top: -$(this).outerHeight()-50}, 700);
  25. return false;
  26. });
  27. });
  28. function findKeyWithValue(arrayt, value)
  29. {
  30. for(i in arrayt)
  31. {
  32. if (arrayt[i] == value)
  33. {
  34. return i;
  35. }
  36. }
  37. return "";
  38. }
  39. function json_to_array(json_string)
  40. {
  41. if (json_string.length)
  42. {
  43. return eval("(" + json_string + ")");
  44. }
  45. return new Array();
  46. }
  47. function strpos (haystack, needle, offset) {
  48. // Finds position of first occurrence of a string within another
  49. //
  50. // version: 1109.2015
  51. // discuss at: http://phpjs.org/functions/strpos // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  52. // + improved by: Onno Marsman
  53. // + bugfixed by: Daniel Esteban
  54. // + improved by: Brett Zamir (http://brett-zamir.me)
  55. // * example 1: strpos('Kevin van Zonneveld', 'e', 5); // * returns 1: 14
  56. var i = (haystack + '').indexOf(needle, (offset || 0));
  57. return i === -1 ? false : i;
  58. }
  59. /**
  60. * Converts the given data structure to a JSON string.
  61. * Argument: arr - The data structure that must be converted to JSON
  62. * Example: var json_string = array2json(['e', {pluribus: 'unum'}]);
  63. * var json = array2json({"success":"Sweet","failure":false,"empty_array":[],"numbers":[1,2,3],"info":{"name":"Binny","site":"http:\/\/www.openjs.com\/"}});
  64. * http://www.openjs.com/scripts/data/json_encode.php
  65. */
  66. function array2json(arr) {
  67. var parts = [];
  68. var is_list = (Object.prototype.toString.apply(arr) === '[object Array]');
  69. for(var key in arr) {
  70. var value = arr[key];
  71. if(typeof value == "object") { //Custom handling for arrays
  72. if(is_list) parts.push(array2json(value)); /* :RECURSION: */
  73. else parts[key] = array2json(value); /* :RECURSION: */
  74. } else {
  75. var str = "";
  76. if(!is_list) str = '"' + key + '":';
  77. //Custom handling for multiple data types
  78. if(typeof value == "number") str += value; //Numbers
  79. else if(value === false) str += 'false'; //The booleans
  80. else if(value === true) str += 'true';
  81. else str += '"' + value + '"'; //All other things
  82. // :TODO: Is there any more datatype we should be in the lookout for? (Functions?)
  83. parts.push(str);
  84. }
  85. }
  86. var json = parts.join(",");
  87. if(is_list) return '[' + json + ']';//Return numerical JSON
  88. return '{' + json + '}';//Return associative JSON
  89. }
  90. function isInteger(s) {
  91. return (s.toString().search(/^-?[0-9]+$/) == 0);
  92. }
  93. function inArray(array, p_val) {
  94. var l = array.length;
  95. for(var i = 0; i < l; i++) {
  96. if(array[i] == p_val) {
  97. return true;
  98. }
  99. }
  100. return false;
  101. }
  102. if(typeof(String.prototype.trim) === "undefined")
  103. {
  104. String.prototype.trim = function()
  105. {
  106. return String(this).replace(/^\s+|\s+$/g, '');
  107. };
  108. }
  109. function str_replace (search, replace, subject, count) {
  110. // Replaces all occurrences of search in haystack with replace
  111. //
  112. // version: 1109.2015
  113. // discuss at: http://phpjs.org/functions/str_replace // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  114. // + improved by: Gabriel Paderni
  115. // + improved by: Philip Peterson
  116. // + improved by: Simon Willison (http://simonwillison.net)
  117. // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) // + bugfixed by: Anton Ongson
  118. // + input by: Onno Marsman
  119. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  120. // + tweaked by: Onno Marsman
  121. // + input by: Brett Zamir (http://brett-zamir.me) // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  122. // + input by: Oleg Eremeev
  123. // + improved by: Brett Zamir (http://brett-zamir.me)
  124. // + bugfixed by: Oleg Eremeev
  125. // % note 1: The count parameter must be passed as a string in order // % note 1: to find a global variable in which the result will be given
  126. // * example 1: str_replace(' ', '.', 'Kevin van Zonneveld');
  127. // * returns 1: 'Kevin.van.Zonneveld'
  128. // * example 2: str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars');
  129. // * returns 2: 'hemmo, mars' var i = 0,
  130. j = 0,
  131. temp = '',
  132. repl = '',
  133. sl = 0, fl = 0,
  134. f = [].concat(search),
  135. r = [].concat(replace),
  136. s = subject,
  137. ra = Object.prototype.toString.call(r) === '[object Array]', sa = Object.prototype.toString.call(s) === '[object Array]';
  138. s = [].concat(s);
  139. if (count) {
  140. this.window[count] = 0;
  141. }
  142. for (i = 0, sl = s.length; i < sl; i++) {
  143. if (s[i] === '') {
  144. continue;
  145. }for (j = 0, fl = f.length; j < fl; j++) {
  146. temp = s[i] + '';
  147. repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
  148. s[i] = (temp).split(f[j]).join(repl);
  149. if (count && s[i] !== temp) {this.window[count] += (temp.length - s[i].length) / f[j].length;
  150. }
  151. }
  152. }
  153. return sa ? s : s[0];
  154. }
  155. function explode (delimiter, string, limit) {
  156. // Splits a string on string separator and return array of components. If limit is positive only limit number of components is returned. If limit is negative all components except the last abs(limit) are returned.
  157. //
  158. // version: 1109.2015
  159. // discuss at: http://phpjs.org/functions/explode // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  160. // + improved by: kenneth
  161. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  162. // + improved by: d3x
  163. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // * example 1: explode(' ', 'Kevin van Zonneveld');
  164. // * returns 1: {0: 'Kevin', 1: 'van', 2: 'Zonneveld'}
  165. // * example 2: explode('=', 'a=bc=d', 2);
  166. // * returns 2: ['a', 'bc=d']
  167. var emptyArray = {0: ''
  168. };
  169. // third argument is not required
  170. if (arguments.length < 2 || typeof arguments[0] == 'undefined' || typeof arguments[1] == 'undefined') {return null;
  171. }
  172. if (delimiter === '' || delimiter === false || delimiter === null) {
  173. return false;}
  174. if (typeof delimiter == 'function' || typeof delimiter == 'object' || typeof string == 'function' || typeof string == 'object') {
  175. return emptyArray;
  176. }
  177. if (delimiter === true) {
  178. delimiter = '1';
  179. }
  180. if (!limit) {
  181. return string.toString().split(delimiter.toString());
  182. }
  183. // support for limit argument
  184. var splitted = string.toString().split(delimiter.toString());var partA = splitted.splice(0, limit - 1);
  185. var partB = splitted.join(delimiter.toString());
  186. partA.push(partB);
  187. return partA;
  188. }
  189. // fonction de nettoyage des tags
  190. function remove_tags(form_name)
  191. {
  192. tagsAddeds[form_name] = new Array();
  193. $('form[name="'+form_name+'"] ul.tagbox li.tag').remove();
  194. $('form[name="'+form_name+'"] input.tagBox_tags_ids').val('');
  195. $('div#tags_prompt_'+form_name+' ul.tagbox li.input input[type="text"]')
  196. .val(string_tag_prompt_input_help)
  197. ;
  198. }
  199. $(document).ready(function(){
  200. // Controle du focus sur la page
  201. function onBlur() {
  202. document.body.className = 'blurred';
  203. }
  204. function onFocus(){
  205. document.body.className = 'focused';
  206. }
  207. if (/*@cc_on!@*/false) { // check for Internet Explorer
  208. document.onfocusin = onFocus;
  209. document.onfocusout = onBlur;
  210. } else {
  211. window.onfocus = onFocus;
  212. window.onblur = onBlur;
  213. }
  214. // Bouton de personalisation du filtre
  215. // Aucun tags
  216. $('.tags_prompt input.clear, a.filter_clear_url').live("click", function(){
  217. $('img.elements_more_loader').show();
  218. $('ul.elements').html('');
  219. form = $(this).parent('div').parent('form');
  220. remove_tags(form.attr('name'));
  221. form.submit();
  222. });
  223. // tags préférés
  224. $('.tags_prompt input.mytags').live("click", function(){
  225. $('img.elements_more_loader').show();
  226. $('ul.elements').html('');
  227. form = $(this).parent('div').parent('form');
  228. $.getJSON(url_get_favorites_tags, function(response) {
  229. if (response.status == 'mustbeconnected')
  230. {
  231. $(location).attr('href', url_index);
  232. }
  233. remove_tags(form.attr('name'));
  234. // if (tags.length)
  235. // {
  236. inputTag = $("div#tags_prompt_"+form.attr('name')+" input.form-default-value-processed");
  237. for (i in response.tags)
  238. {
  239. $('input#tags_selected_tag_'+form.attr('name')).val(i);
  240. inputTag.val(response.tags[i]);
  241. // Et on execute l'évènement selectTag de l'input
  242. inputTag.trigger("selectTag");
  243. }
  244. form.submit();
  245. //}
  246. });
  247. });
  248. // Tag cliqué dans la liste d'éléments
  249. $('ul.element_tags li a.element_tag').live('click', function(){
  250. // Si il y a une liste de tags (comme sur la page favoris, profil)
  251. if ($('ul#favorite_tags').length)
  252. {
  253. id = str_replace('#', '', $(this).attr('href'));
  254. link = $('ul#favorite_tags li a[href="#'+id+'"]');
  255. list_tag_clicked(link, true);
  256. }
  257. if ($('form[name="search"]').length)
  258. {
  259. $('img.elements_more_loader').show();
  260. $('ul.elements').html('');
  261. form = $('form[name="search"]');
  262. id = str_replace('#', '', $(this).attr('href'));
  263. remove_tags('search');
  264. inputTag = $("div#tags_prompt_search input.form-default-value-processed");
  265. $('input#tags_selected_tag_search').val(id);
  266. inputTag.val($(this).html());
  267. inputTag.trigger("selectTag");
  268. form.submit();
  269. }
  270. });
  271. // Affichage un/des embed
  272. // 1328283150_media-playback-start.png
  273. // 1328283201_emblem-symbolic-link.png
  274. $('a.element_embed_open_link').live("click", function(){
  275. li = $(this).parent('td').parent('tr').parent().parent().parent('li.element');
  276. li.find('a.element_embed_close_link').show();
  277. li.find('a.element_embed_open_link_text').hide();
  278. li.find('div.element_embed').show();
  279. return false;
  280. });
  281. $('a.element_name_embed_open_link').live("click", function(){
  282. li = $(this).parent('span').parent('td').parent('tr').parent().parent().parent('li.element');
  283. li.find('a.element_embed_close_link').show();
  284. li.find('a.element_embed_open_link_text').hide();
  285. li.find('div.element_embed').show();
  286. return false;
  287. });
  288. // Fermeture du embed si demandé
  289. $('a.element_embed_close_link').live("click", function(){
  290. li = $(this).parent('td').parent('tr').parent().parent().parent('li.element');
  291. li.find('div.element_embed').hide();
  292. li.find('a.element_embed_open_link_text').show();
  293. $(this).hide();
  294. return false;
  295. });
  296. // Affichage du "play" ou du "open" (image png)
  297. $('li.element a.a_thumbnail, li.element img.open, li.element img.play').live({
  298. mouseenter:
  299. function()
  300. {
  301. td = $(this).parent('td');
  302. a = td.find('a.a_thumbnail');
  303. if (a.hasClass('embed'))
  304. {
  305. td.find('img.play').show();
  306. }
  307. else
  308. {
  309. td.find('img.open').show();
  310. }
  311. },
  312. mouseleave:
  313. function()
  314. {
  315. td = $(this).parent('td');
  316. a = td.find('a.a_thumbnail');
  317. if (a.hasClass('embed'))
  318. {
  319. td.find('img.play').hide();
  320. }
  321. else
  322. {
  323. td.find('img.open').hide();
  324. }
  325. }
  326. }
  327. );
  328. // Mise en favoris
  329. $('a.favorite_link').live("click", function(){
  330. link = $(this);
  331. // Pour ne pas attendre la fin du chargement ajax:
  332. img = link.find('img');
  333. if (!link.hasClass('loading'))
  334. {
  335. if (img.attr('src') == '/bundles/muzichcore/img/favorite_bw.png')
  336. {
  337. img.attr('src', '/bundles/muzichcore/img/favorite.png');
  338. }
  339. else
  340. {
  341. img.attr('src', '/bundles/muzichcore/img/favorite_bw.png');
  342. }
  343. }
  344. link.addClass('loading');
  345. $.getJSON($(this).attr('href'), function(response) {
  346. if (response.status == 'mustbeconnected')
  347. {
  348. $(location).attr('href', url_index);
  349. }
  350. img = link.find('img');
  351. link.attr('href', response.link_new_url);
  352. img.attr('src', response.img_new_src);
  353. img.attr('title', response.img_new_title);
  354. link.removeClass('loading');
  355. });
  356. return false;
  357. });
  358. // Affichage du bouton Modifier et Supprimer
  359. $('ul.elements li.element').live({
  360. mouseenter:
  361. function()
  362. {
  363. $(this).find('a.element_edit_link').show();
  364. $(this).find('a.element_remove_link').show();
  365. },
  366. mouseleave:
  367. function()
  368. {
  369. if (!$(this).find('a.element_edit_link').hasClass('mustBeDisplayed'))
  370. {
  371. $(this).find('a.element_edit_link').hide();
  372. }
  373. if (!$(this).find('a.element_remove_link').hasClass('mustBeDisplayed'))
  374. {
  375. $(this).find('a.element_remove_link').hide();
  376. }
  377. }
  378. }
  379. );
  380. // Plus d'éléments
  381. last_id = null;
  382. $('a.elements_more').click(function(){
  383. link = $(this);
  384. last_element = $('ul.elements li.element:last-child');
  385. id_last = str_replace('element_', '', last_element.attr('id'));
  386. invertcolor = 0;
  387. if (last_element.hasClass('even'))
  388. {
  389. invertcolor = 1;
  390. }
  391. $('img.elements_more_loader').show();
  392. $.getJSON(link.attr('href')+'/'+id_last+'/'+invertcolor, function(response) {
  393. if (response.status == 'mustbeconnected')
  394. {
  395. $(location).attr('href', url_index);
  396. }
  397. if (response.count)
  398. {
  399. $('ul.elements').append(response.html);
  400. $('img.elements_more_loader').hide();
  401. }
  402. if (response.end || response.count < 1)
  403. {
  404. $('img.elements_more_loader').hide();
  405. $('ul.elements').after('<div class="no_elements"><p class="no-elements">'+
  406. response.message+'</p></div>');
  407. link.hide();
  408. }
  409. });
  410. return false;
  411. });
  412. tag_box_input_value = $('ul.tagbox input[type="text"]').val();
  413. // Filtre et affichage éléments ajax
  414. $('form[name="search"] input[type="submit"]').click(function(){
  415. $('ul.elements').html('');
  416. $('div.no_elements').hide();
  417. $('img.elements_more_loader').show();
  418. });
  419. $('form[name="search"]').ajaxForm(function(response) {
  420. if (response.status == 'mustbeconnected')
  421. {
  422. $(location).attr('href', url_index);
  423. }
  424. $('ul.elements').html(response.html);
  425. if (response.count)
  426. {
  427. $('img.elements_more_loader').hide();
  428. $('span.elements_more').show();
  429. $('a.elements_more').show();
  430. }
  431. if (response.count < 1)
  432. {
  433. $('img.elements_more_loader').hide();
  434. $('ul.elements').after('<div class="no_elements"><p class="no-elements">'+
  435. response.message+'</p></div>');
  436. $('a.elements_more').hide()
  437. ;
  438. }
  439. $('ul.tagbox input[type="text"]').val($('ul.tagbox input[type="text"]').val());
  440. });
  441. // Suppression d'un element
  442. $('a.element_remove_link').jConfirmAction({
  443. question : "Vraiment supprimer ?",
  444. yesAnswer : "Oui",
  445. cancelAnswer : "Non",
  446. onYes: function(link){
  447. li = link.parent('td').parent('tr').parent().parent().parent('li.element');
  448. li.find('img.element_loader').show();
  449. $.getJSON(link.attr('href'), function(response){
  450. if (response.status == 'mustbeconnected')
  451. {
  452. $(location).attr('href', url_index);
  453. }
  454. if (response.status == 'success')
  455. {
  456. li.remove();
  457. }
  458. else
  459. {
  460. li.find('img.element_loader').hide();
  461. }
  462. });
  463. return false;
  464. },
  465. onOpen: function(link){
  466. li = link.parent('td').parent('tr').parent().parent().parent('li.element');
  467. li.find('a.element_edit_link').addClass('mustBeDisplayed');
  468. li.find('a.element_remove_link').addClass('mustBeDisplayed');
  469. },
  470. onClose: function(link){
  471. li = link.parent('td').parent('tr').parent().parent().parent('li.element');
  472. li.find('a.element_edit_link').removeClass('mustBeDisplayed');
  473. li.find('a.element_remove_link').removeClass('mustBeDisplayed');
  474. li.find('a.element_edit_link').hide();
  475. li.find('a.element_remove_link').hide();
  476. }
  477. });
  478. elements_edited = new Array();
  479. // Ouverture du formulaire de modification
  480. $('a.element_edit_link').live('click', function(){
  481. link = $(this);
  482. li = link.parent('td').parent('tr').parent().parent().parent('li.element');
  483. // On garde en mémoire l'élément édité en cas d'annulation
  484. elements_edited[li.attr('id')] = li.html();
  485. div_loader = li.find('div.loader');
  486. li.html(div_loader);
  487. li.find('img.element_loader').show();
  488. $.getJSON($(this).attr('href'), function(response) {
  489. if (response.status == 'mustbeconnected')
  490. {
  491. $(location).attr('href', url_index);
  492. }
  493. // On prépare le tagBox
  494. li.html(response.html);
  495. // Pour le click sur l'input de saisie de tag
  496. li.find('ul.tagbox li.input input[type="text"]').formDefaults();
  497. var options = new Array();
  498. options.form_name = response.form_name;
  499. options.tag_init = response.tags;
  500. ajax_query_timestamp = null;
  501. $("#tags_prompt_list_"+response.form_name).tagBox(options);
  502. // On rend ce formulaire ajaxFormable
  503. $('form[name="'+response.form_name+'"] input[type="submit"]').live('click', function(){
  504. li.prepend(div_loader);
  505. li.find('img.element_loader').show();
  506. });
  507. $('form[name="'+response.form_name+'"]').ajaxForm(function(response){
  508. if (response.status == 'mustbeconnected')
  509. {
  510. $(location).attr('href', url_index);
  511. }
  512. if (response.status == 'success')
  513. {
  514. li.html(response.html);
  515. delete(elements_edited[li.attr('id')]);
  516. }
  517. else if (response.status == 'error')
  518. {
  519. li.find('img.element_loader').hide();
  520. li.find('ul.error_list').remove();
  521. ul_errors = $('<ul>').addClass('error_list');
  522. for (i in response.errors)
  523. {
  524. ul_errors.append($('<li>').append(response.errors[i]));
  525. }
  526. li.prepend(ul_errors);
  527. }
  528. });
  529. });
  530. return false;
  531. });
  532. // Annulation d'un formulaire de modification d'élément
  533. $('form.edit_element input.cancel_edit').live('click', function(){
  534. var li = $(this).parent('form').parent('li');
  535. li.html(elements_edited[li.attr('id')]);
  536. delete(elements_edited[li.attr('id')]);
  537. });
  538. ////////////////// TAG PROMPT ///////////////
  539. ajax_query_timestamp = null;
  540. tag_text_help = $('input.tag_text_help').val();
  541. // Les deux clicks ci-dessous permettent de faire disparaitre
  542. // la div de tags lorsque l'on clique ailleurs
  543. $('html').click(function() {
  544. if ($("div.search_tag_list").is(':visible'))
  545. {
  546. $("div.search_tag_list").hide();
  547. }
  548. });
  549. $("div.search_tag_list, div.search_tag_list a.more").live('click', function(event){
  550. event.stopPropagation();
  551. $("div.search_tag_list").show();
  552. });
  553. function autocomplete_tag(input, form_name)
  554. {
  555. // Il doit y avoir au moin un caractère
  556. if ((input.val().length > 0) && (input.val() != string_tag_prompt_input_help))
  557. {
  558. // on met en variable l'input
  559. inputTag = input;
  560. // On récupére la div de tags
  561. divtags = $("#search_tag_"+form_name);
  562. // Si la fenêtre de tags est caché
  563. if (!divtags.is(':visible'))
  564. {
  565. // On la replace
  566. position = input.position();
  567. divtags.css('left', Math.round(position.left) + 5);
  568. divtags.css('top', Math.round(position.top) + 28);
  569. // Et on l'affiche
  570. divtags.show();
  571. }
  572. // On affiche le loader
  573. $('#tag_loader_'+form_name).show();
  574. // On cache la liste de tags
  575. search_tag_list = divtags.find('ul.search_tag_list');
  576. // On supprime les anciens li
  577. search_tag_list.find('li').remove();
  578. search_tag_list.hide();
  579. // Et on affiche une info
  580. span_info = divtags.find('span.info');
  581. span_info.show();
  582. // TODO: multilingue !
  583. span_info.text("Recherche des tags correspondants à \""+input.val()+"\" ...");
  584. // C'est en fonction du nb de resultats qu'il sera affiché
  585. divtags.find('a.more').hide();
  586. // On récupère le timestamp pour reconnaitre la dernière requête effectué
  587. ajax_query_timestamp = new Date().getTime();
  588. // Récupération des tags correspondants
  589. $.getJSON(url_search_tag+'/'+input.val()+'/'+ajax_query_timestamp, function(data) {
  590. if (data.status == 'mustbeconnected')
  591. {
  592. $(location).attr('href', url_index);
  593. }
  594. // Ce contrôle permet de ne pas continuer si une requete
  595. // ajax a été faite depuis.
  596. if (data.timestamp == ajax_query_timestamp)
  597. {
  598. status = data.status;
  599. tags = data.data;
  600. // Si on spécifie une erreur
  601. if (status == 'error')
  602. {
  603. // On l'affiche a l'utilisateur
  604. span_info.text(data.error);
  605. }
  606. // Si c'est un succés
  607. else if (status == 'success')
  608. {
  609. if (tags.length > 0)
  610. {
  611. more = false;
  612. // Pour chaque tags retournés
  613. for (i in tags)
  614. {
  615. var tag_name = tags[i]['name'];
  616. var tag_id = tags[i]['id'];
  617. var t_string = tag_name
  618. // On construit un li
  619. r_string = $.trim(input.val());
  620. var re = new RegExp(r_string, "i");
  621. t_string = t_string.replace(re,"<strong>" + r_string + "</strong>");
  622. li_tag =
  623. $('<li>').append(
  624. $('<a>').attr('href','#'+tag_id+'#'+tag_name)
  625. // qui réagit quand on clique dessus
  626. .click(function(e){
  627. // On récupère le nom du tag
  628. name = $(this).attr('href').substr(1,$(this).attr('href').length);
  629. name = name.substr(strpos(name, '#')+1, name.length);
  630. id = $(this).attr('href').substr(1,$(this).attr('href').length);
  631. id = str_replace(name, '', id);
  632. id = str_replace('#', '', id);
  633. $('input#tags_selected_tag_'+form_name).val(id);
  634. inputTag.val(name);
  635. // Et on execute l'évènement selectTag de l'input
  636. inputTag.trigger("selectTag");
  637. // On cache la liste puisque le choix vient d'être fait
  638. divtags.hide();
  639. inputTag.val(tag_text_help);
  640. return false;
  641. })
  642. .append(t_string)
  643. );
  644. // Si on depasse les 30 tags
  645. if (i > 30)
  646. {
  647. more = true;
  648. // On le cache
  649. li_tag.hide();
  650. }
  651. // On ajout ce li a la liste
  652. search_tag_list.append(li_tag);
  653. }
  654. if (more)
  655. {
  656. divtags.find('a.more').show();
  657. }
  658. span_info.show();
  659. span_info.text(data.message);
  660. // Et on affiche la liste
  661. search_tag_list.show();
  662. }
  663. else
  664. {
  665. span_info.show();
  666. span_info.text(data.message);
  667. search_tag_list.show();
  668. // Dans ce cas ou aucun tag n'a été trouvé, la proposition
  669. // d'ajout s'affichecf en dessous
  670. //span_info.text("Aucun tag de trouvé pour \""+inputTag.val()+"\"");
  671. }
  672. // Si le tag ne semble pas connu en base
  673. if (!data.same_found)
  674. {
  675. // Cette variable nous permettra de stocker le lien nouveau tag
  676. link_add_tag = null;
  677. li_tag =
  678. $('<li>').addClass('new').append(
  679. $('<a>').attr('href','#new#'+$.trim(input.val()))
  680. // qui réagit quand on clique dessus
  681. .click(function(e){
  682. // Effet fade-in du fond opaque
  683. $('body').append($('<div>').attr('id', 'fade'));
  684. //Apparition du fond - .css({'filter' : 'alpha(opacity=80)'}) pour corriger les bogues de IE
  685. $('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn();
  686. // On met le lien cliqué dans la variabke prévu
  687. link_add_tag = $(this);
  688. // En premier lieux on fait apparaître la fenêtre de confirmation
  689. popup = $('<div>')
  690. .attr('id', 'add_tag')
  691. .addClass('popin_block')
  692. .css('width', '400px')
  693. //.append($('<h2>').append(string_tag_add_title))
  694. .append($('<div>').addClass('tag')
  695. .append($('<ul>')
  696. .append($('<li>').addClass('button')
  697. .append($(this).text()))))
  698. .append($('<p>').append(string_tag_add_text))
  699. .append($('<p>').append(string_tag_add_argument))
  700. .append($('<textarea>').attr('name', 'argument'))
  701. .append($('<div>').addClass('inputs')
  702. .append($('<input>')
  703. .attr('type', 'button')
  704. .attr('value', string_tag_add_inputs_cancel)
  705. .addClass('button')
  706. .click(function(){
  707. $('#fade').fadeOut(1000, function(){$('#fade').remove();});
  708. $('#add_tag').remove();
  709. return false;
  710. })
  711. )
  712. .append($('<input>')
  713. .attr('type', 'button')
  714. .attr('value', string_tag_add_inputs_submit)
  715. .addClass('button')
  716. .click(function(){
  717. var arguments = $('#add_tag textarea').val();
  718. $('#fade').fadeOut(400, function(){$('#fade').remove();});
  719. $('#add_tag').remove();
  720. // On récupère le nom du tag
  721. name = link_add_tag.attr('href').substr(1,link_add_tag.attr('href').length);
  722. name = name.substr(strpos(name, '#')+1, name.length);
  723. link_add_tag.parent('li').parent('ul').parent('div').find('img.tag_loader').show();
  724. // La on fait l'ajout en base en tant que nouveau tag
  725. $.getJSON(url_add_tag+'/'+name+'/'+arguments, function(response){
  726. if (response.status == 'mustbeconnected')
  727. {
  728. $(location).attr('href', url_index);
  729. }
  730. tag_id = response.tag_id;
  731. tag_name = response.tag_name;
  732. $('input#tags_selected_tag_'+form_name).val(tag_id);
  733. inputTag.val(tag_name);
  734. // Et on execute l'évènement selectTag de l'input
  735. inputTag.trigger("selectTag");
  736. // On cache la liste puisque le choix vient d'être fait
  737. divtags.hide();
  738. inputTag.val(tag_text_help);
  739. link_add_tag.parent('li').parent('ul').parent('div').find('img.tag_loader').hide();
  740. });
  741. return false;
  742. })
  743. )
  744. )
  745. ;
  746. // Il faut ajouter le popup au dom avant de le positionner en css
  747. // Sinon la valeur height n'est pas encore calculable
  748. $('body').prepend(popup);
  749. //Récupération du margin, qui permettra de centrer la fenêtre - on ajuste de 80px en conformité avec le CSS
  750. var popMargTop = (popup.height() + 50) / 2;
  751. var popMargLeft = (popup.width() + 50) / 2;
  752. //On affecte le margin
  753. $(popup).css({
  754. 'margin-top' : -popMargTop,
  755. 'margin-left' : -popMargLeft
  756. });
  757. return false;
  758. })
  759. .append($.trim(input.val()))
  760. );
  761. search_tag_list.append(li_tag);
  762. }
  763. }
  764. // On cache le loader
  765. $('#tag_loader_'+form_name).hide();
  766. }
  767. });
  768. }
  769. }
  770. last_keypress = 0;
  771. function check_timelaps_and_search(input, form_name, time_id, timed, info)
  772. {
  773. if (!timed)
  774. {
  775. // C'est une nouvelle touche (pas redirigé) on lui donne un id
  776. // et on met a jour l'id de la dernière pressé
  777. last_keypress = new Date().getTime();
  778. var this_time_id = last_keypress;
  779. }
  780. else
  781. {
  782. // Si elle a été redirigé, on met son id dans cette variable
  783. var this_time_id = time_id;
  784. }
  785. // C'est une touche redirigé dans le temps qui a été suivit d'une autre touche
  786. if (time_id != last_keypress && timed)
  787. {
  788. // elle disparait
  789. }
  790. else
  791. {
  792. //
  793. if ((new Date().getTime() - last_keypress) < 600 || timed == false)
  794. {
  795. // Si elle vient d'être tapé (timed == false) elle doit attendre (au cas ou une autre touche soit tapé)
  796. // Si c'est une redirigé qui n'a pas été remplacé par une nouvelle lettre
  797. // elle doit attendre au cas ou soit pressé.
  798. setTimeout(function(){check_timelaps_and_search(input, form_name, this_time_id, true, info)}, 700);
  799. }
  800. else
  801. {
  802. // il n'y a plus a attendre, on envoie la demande de tag.
  803. autocomplete_tag(input, form_name);
  804. }
  805. }
  806. }
  807. // Autocompletion de tags
  808. $("div.tags_prompt ul.tagbox li.input input").live('keypress', function(e){
  809. var form_name = $(this).parent('li').parent('ul.tagbox')
  810. .parent('div.tags_prompt').parent('form').attr('name')
  811. ;
  812. var code = (e.keyCode ? e.keyCode : e.which);
  813. if ((e.which !== 0 && e.charCode !== 0) || (code == 8 || code == 46))
  814. {
  815. check_timelaps_and_search($(this), form_name, new Date().getTime(), false, $(this).val());
  816. }
  817. });
  818. // Un click sur ce lien affiche tout les tags cachés de la liste
  819. $('div.search_tag_list a.more').live('click', function(){
  820. jQuery.each( $(this).parent('div').find('ul.search_tag_list li') , function(){
  821. $(this).show();
  822. });
  823. $(this).hide();
  824. return false;
  825. });
  826. $('ul.tagbox li.input input[type="text"]').val(tag_text_help);
  827. $('ul.tagbox li.input input[type="text"]').formDefaults();
  828. ////////////////// FIN TAG PROMPT ///////////////
  829. // Suppression d'un element
  830. $('a.group_remove_link').jConfirmAction({
  831. question : "Supprimer ce groupe ?",
  832. yesAnswer : "Oui",
  833. cancelAnswer : "Non",
  834. onYes: function(link){
  835. window.location = link.attr('href');
  836. return false;
  837. },
  838. onOpen: function(){},
  839. onClose: function(){}
  840. });
  841. // Selection Réseau global / Mon réseau
  842. $('div.select_network a').live('click', function(){
  843. divSelect = $(this).parent('div');
  844. if ($(this).hasClass('all_network'))
  845. {
  846. divSelect.find('a.all_network').addClass('active');
  847. divSelect.find('a.my_network').removeClass('active');
  848. divSelect.find('select').val('network_public');
  849. }
  850. else
  851. {
  852. divSelect.find('a.my_network').addClass('active');
  853. divSelect.find('a.all_network').removeClass('active');
  854. divSelect.find('select').val('network_personal');
  855. }
  856. });
  857. // Ajout d'un element
  858. $('form[name="add"] input[type="submit"]').live('click', function(){
  859. $('form[name="add"]').find('img.tag_loader').show();
  860. });
  861. $('form[name="add"]').ajaxForm(function(response) {
  862. if (response.status == 'mustbeconnected')
  863. {
  864. $(location).attr('href', url_index);
  865. }
  866. $('form[name="add"] img.tag_loader').hide();
  867. if (response.status == 'success')
  868. {
  869. $('form[name="add"]').find('ul.error_list').remove();
  870. $('ul.elements').prepend(response.html);
  871. $('form[name="add"] input[type="text"]').val('');
  872. $('div#element_add_box').slideUp();
  873. $('a#element_add_link').show();
  874. if ($('form[name="search"]').length)
  875. {
  876. $('form[name="search"]').slideDown();
  877. }
  878. remove_tags('add');
  879. }
  880. else if (response.status == 'error')
  881. {
  882. $('form[name="add"]').find('ul.error_list').remove();
  883. ul_errors = $('<ul>').addClass('error_list');
  884. for (i in response.errors)
  885. {
  886. ul_errors.append($('<li>').append(response.errors[i]));
  887. }
  888. $('form[name="add"]').prepend(ul_errors);
  889. }
  890. return false;
  891. });
  892. // Check périodique
  893. // TODO.
  894. /////////////////////
  895. // Filtre par tags (show, favorite)
  896. function refresh_elements_with_tags_selected(link)
  897. {
  898. // Puis on fait notre rekékéte ajax.
  899. $('ul.elements').html('');
  900. $('div.no_elements').hide();
  901. $('img.elements_more_loader').show();
  902. $.getJSON($('input#get_elements_url').val()+'/'+array2json(tags_ids), function(response){
  903. if (response.status == 'mustbeconnected')
  904. {
  905. $(location).attr('href', url_index);
  906. }
  907. $('ul.elements').html(response.html);
  908. if (response.count)
  909. {
  910. $('img.elements_more_loader').hide();
  911. $('span.elements_more').show();
  912. $('a.elements_more').show();
  913. }
  914. });
  915. return false;
  916. }
  917. function list_tag_clicked(link, erease)
  918. {
  919. if (erease)
  920. {
  921. $('ul#favorite_tags a.tag').removeClass('active');
  922. }
  923. // Ensuite on l'active ou le désactive
  924. if (link.hasClass('active'))
  925. {
  926. link.removeClass('active');
  927. }
  928. else
  929. {
  930. link.addClass('active');
  931. }
  932. // On construit notre liste de tags
  933. tags_ids = new Array();
  934. $('ul#favorite_tags a.tag.active').each(function(index){
  935. id = str_replace('#', '', link.attr('href'));
  936. tags_ids[id] = id;
  937. });
  938. // On adapte le lien afficher plus de résultats
  939. a_more = $('a.elements_more');
  940. a_more.attr('href', $('input#more_elements_url').val()+'/'+array2json(tags_ids));
  941. return check_timelaps_and_find_with_tags(link, new Date().getTime(), false);
  942. }
  943. $('ul#favorite_tags a.tag').click(function(){
  944. list_tag_clicked();
  945. });
  946. last_keypress = 0;
  947. function check_timelaps_and_find_with_tags(link, time_id, timed)
  948. {
  949. if (!timed)
  950. {
  951. // C'est une nouvelle touche (pas redirigé) on lui donne un id
  952. // et on met a jour l'id de la dernière pressé
  953. last_keypress = new Date().getTime();
  954. var this_time_id = last_keypress;
  955. }
  956. else
  957. {
  958. // Si elle a été redirigé, on met son id dans cette variable
  959. var this_time_id = time_id;
  960. }
  961. // C'est une touche redirigé dans le temps qui a été suivit d'une autre touche
  962. if (time_id != last_keypress && timed)
  963. {
  964. // elle disparait
  965. }
  966. else
  967. {
  968. //
  969. if ((new Date().getTime() - last_keypress) < 800 || timed == false)
  970. {
  971. // Si elle vient d'être tapé (timed == false) elle doit attendre (au cas ou une autre touche soit tapé)
  972. // Si c'est une redirigé qui n'a pas été remplacé par une nouvelle lettre
  973. // elle doit attendre au cas ou soit pressé.
  974. setTimeout(function(){check_timelaps_and_find_with_tags(link, this_time_id, true)}, 900);
  975. }
  976. else
  977. {
  978. // il n'y a plus a attendre, on envoie la demande de tag.
  979. return refresh_elements_with_tags_selected(link);
  980. }
  981. }
  982. return null;
  983. }
  984. });