plugins.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. // Avoid `console` errors in browsers that lack a console.
  2. (function() {
  3. var method;
  4. var noop = function () {};
  5. var methods = [
  6. 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
  7. 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
  8. 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
  9. 'timeline', 'timelineEnd', 'timeStamp', 'trace', 'warn'
  10. ];
  11. var length = methods.length;
  12. var console = (window.console = window.console || {});
  13. while (length--) {
  14. method = methods[length];
  15. // Only stub undefined methods.
  16. if (!console[method]) {
  17. console[method] = noop;
  18. }
  19. }
  20. }());
  21. //Affiche un message 'message' de type 'type' pendant 'timeout' secondes
  22. $.message = function (type,message,timeout){
  23. $.toast({ type: type, content: message, timeout: timeout });
  24. }
  25. //Permet les notifications types toast sans dépendance de librairie/css/html
  26. $.toast = function (options) {
  27. var defaults = {
  28. title: null,
  29. content: '',
  30. type: 'info',
  31. timeout: 3000
  32. };
  33. var o = $.extend(defaults, options);
  34. var css = "word-wrap:break-word;color:#ffffff;display:none;border-radius:1px;margin-bottom:10px;text-align:center;width:100%;box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);position:relative;";
  35. var types = {
  36. error: { css: "background:#dc2626;", icon: 'fas fa-exclamation-triangle' },
  37. warning: { css: "background:#ffc107;color:#212529;", icon: 'fas fa-exclamation-circle' },
  38. info: { css: "background:#2AA7EA;", icon: 'fas fa-info-circle' },
  39. success: { css: "background:#28a745;", icon: 'fas fa-check' },
  40. }
  41. css += types[o.type].css;
  42. o.icon = types[o.type].icon;
  43. if ($('.toastContainer').length == 0)
  44. $('body').append('<div class="toastContainer" style="z-index:1100;position:fixed;right:15px;top:65px;width:350px;"></div>');
  45. var popupContainer = $('.toastContainer');
  46. var popup = $('<div style="' + css + '" class="noPrint toast-'+o.type+'"><i class="toastRemove fas fa-times" style="position:absolute;top:5px;right:5px;display:none;cursor:pointer;" onclick="$(this).parent().remove();"; style="position:absolute;top:5px;right:5px;cursor:pointer;"></i><h1 class="toastTitle" style="margin:0;padding:10px;"></h1><i class="toastIcon" style="display:inline-block;vertical-align:top;width:30px;font-size:20px;margin:15px 0;"></i><p style="display: inline-block;margin-top: 10px;padding:0 10px 0 10px;width:300px;" class="toastContent"></p><div style="clear:both;"></div></div>');
  47. $(popupContainer).append(popup);
  48. if (o.title) $('.toastTitle', popup).html(o.title);
  49. $('.toastIcon', popup).attr('class', o.icon);
  50. if (!o.title) $('.toastTitle', popup).remove();
  51. $('.toastContent', popup).html(o.content);
  52. popup.fadeIn();
  53. if (o.timeout != 0) {
  54. setTimeout(function () { popup.fadeOut(); }, o.timeout);
  55. } else {
  56. popup.find('.toastRemove').show();
  57. }
  58. }
  59. $.page = function(element){
  60. var path = window.location.pathname.split('/') ;
  61. path = path[path.length-1];
  62. path = path.replace('.php','');
  63. return path;
  64. }
  65. $.getForm= function(element){
  66. return $(element).getForm();
  67. }
  68. $.setForm= function(element,data){
  69. var o = {};
  70. var obj = $(element);
  71. $('input,select,textarea',obj).each(function(i,element){
  72. if(element.id!=null && element.id!=""){
  73. if(data[element.id]!=null){
  74. if($(element).attr("type")=='checkbox' || $(element).attr("type")=='radio'){
  75. $(element).prop("checked",data[element.id]==1 || data[element.id]=='true' ?true:false);
  76. } else {
  77. $(element).val(data[element.id]);
  78. }
  79. }
  80. }
  81. });
  82. return o;
  83. }
  84. //Gestion des tableaux pour le formData
  85. $.form_data = function(formData, key,values){
  86. var hasFile = false;
  87. if(values instanceof File ) hasFile = true;
  88. if( typeof values == 'object' && !(values instanceof File) ){
  89. for(subkey in values)
  90. if($.form_data(formData,key + '[' + subkey + ']',values[subkey])) hasFile = true;
  91. }else{
  92. formData.append(key, values);
  93. }
  94. return hasFile;
  95. }
  96. $.action = function(data,success,error,progress) {
  97. var formData = new FormData();
  98. var defaultSuccess = data.defaultSuccess !== undefined ? data.defaultSuccess : true;
  99. // if(data.defaultSuccess !== undefined) delete data.defaultSuccess;
  100. //hasFile determine si un fichier uploadé se trouve dans le tableau des data
  101. // Si c'est le cas, il envois les données en multipart, sinon il les envoie en json classique.
  102. var hasFile = false;
  103. $.each(data, function(key, value){
  104. if($.form_data(formData,key, value) == true) hasFile = true;
  105. });
  106. var request = {
  107. url : 'action.php',
  108. method : 'POST',
  109. success: function(response){
  110. if(response && !response.error){
  111. if(success!=null)success(response);
  112. } else {
  113. var errorMessage = 'ERREUR : '+"\n"+response.error;
  114. if(response.trace) errorMessage += "\n<div style='font-size:10px;max-height:200px;overflow:auto;text-align:left;'>"+response.trace+"</div>";
  115. if(defaultSuccess) $.message('error',errorMessage,0);
  116. if(error!=null) error(response);
  117. }
  118. },
  119. error : function(response){
  120. if(response.status == 200 && $.localhost() ){
  121. $('body').append('<div class="debugFrame" style="box-shadow: 0px 0px 10px rgba(0,0,0,0.5);z-index: 10001;padding: 5px;position: fixed;left: 0;top: 0;width: 40%;min-height: 100%;border-right: 2px solid #ff3b00;background: rgba(210, 222, 255, 0.9);overflow-y: auto;height: 100%;"><h3>Action debug</h3> <i style="position:absolute; right:10px; top:10px;font-size:1.5em;" onclick="$(this).parent().remove()" class="fas fa-times pointer"></i>'+response.responseText+'</div>');
  122. } else {
  123. if(response.readyState == 0 && error==null) return;
  124. if(error!=null)
  125. error(response);
  126. else
  127. $.message('error','Erreur indefinie, merci de contacter un administrateur',0);
  128. }
  129. },
  130. xhr: function() {
  131. var xhr = new window.XMLHttpRequest();
  132. if(data.downloadResponse) xhr.responseType = 'blob';
  133. xhr.upload.addEventListener("progress", function(evt){
  134. if (evt.lengthComputable) {
  135. var percentComplete = (evt.loaded / evt.total) * 100;
  136. percentComplete = Math.round(percentComplete * 100) / 100;
  137. if(progress) progress(percentComplete,'upload');
  138. }
  139. }, false);
  140. xhr.addEventListener("progress", function(evt){
  141. if (evt.lengthComputable) {
  142. var percentComplete = evt.loaded / evt.total;
  143. if(progress) progress(percentComplete,'download');
  144. }
  145. }, false);
  146. xhr.addEventListener('readystatechange', function(e) {
  147. if(xhr.readyState == 4 && xhr.status == 200) {
  148. if(data.downloadResponse){
  149. var disposition = xhr.getResponseHeader('content-disposition');
  150. var matches = /"([^"]*)"/.exec(disposition);
  151. var filename = (matches != null && matches[1] ? matches[1] : 'file');
  152. var blob = new Blob([xhr.response], { type: xhr.response.type });
  153. var link = document.createElement('a');
  154. link.href = window.URL.createObjectURL(blob);
  155. link.download = filename;
  156. $('body').append(link);
  157. link.click();
  158. link.remove();
  159. window.URL.revokeObjectURL(link);
  160. }
  161. }
  162. });
  163. return xhr;
  164. }
  165. };
  166. if(!hasFile){
  167. request.data = data;
  168. }else{
  169. request.data = formData;
  170. request.processData = false;
  171. request.contentType = false;
  172. }
  173. $.ajax(request);
  174. }
  175. $.localhost = function(){
  176. return (document.location.hostname=='127.0.0.1' || document.location.hostname=='localhost');
  177. }
  178. $.hashData = function(name){
  179. var page = window.location.hash.substring(1);
  180. page += "&"+window.location.search.substring(1);
  181. data = {};
  182. if(page!='' && page!= null){
  183. options = page.split('&');
  184. var data = {};
  185. for(var key in options){
  186. infos = options[key].split('=');
  187. data[infos[0]] = infos[1];
  188. }
  189. }
  190. if(name == null) return data;
  191. if(typeof name === "object"){
  192. data = name;
  193. hashstring = '';
  194. for(var key in data)
  195. hashstring+= "&"+key+"="+data[key];
  196. hashstring = hashstring.substring(1);
  197. window.location.hash = hashstring;
  198. return;
  199. }
  200. return typeof data[name] == "undefined" ? '':data[name];
  201. }
  202. $.urlParam = function (name,value) {
  203. var parameters = window.location.href.match(/[\\?&]([^&#]*)=([^&#]*)/g);
  204. var data = {};
  205. for (var key in parameters) {
  206. var couple = parameters[key].substring(1, parameters[key].length).split('=');
  207. data[couple[0]] = couple[1];
  208. }
  209. if(name == null) return data;
  210. if (value == null)
  211. return data[name] ? data[name] : null;
  212. if (value != false) data[name] = value;
  213. var url = '?';
  214. for (var key in data) {
  215. if (value == false && key == name) continue;
  216. url += key + '=' + data[key]+'&';
  217. }
  218. window.history.pushState('', document.title, url.substring(0, url.length-1));
  219. }
  220. $.fn.extend({
  221. toJson : function(){
  222. return $.getForm(this);
  223. },
  224. getForm : function(){
  225. var o = {};
  226. var obj = $(this);
  227. for(var key in obj.data()){
  228. if(key!="action" && key != "id") continue;
  229. o[key] = obj.attr('data-'+key);
  230. }
  231. $('input,select,textarea',obj).each(function(i,element){
  232. if(element.id!=null && element.id!=""){
  233. if($(element).attr("type")=='checkbox' || $(element).attr("type")=='radio'){
  234. o[element.id] = ($(element).is(':checked')?1:0);
  235. }else{
  236. o[element.id] = $(element).val();
  237. }
  238. }
  239. });
  240. return o;
  241. },
  242. upload: function (options) {
  243. //var options = $.extend(defaults, options);
  244. return this.each(function () {
  245. var o = options;
  246. var droppedFiles = false;
  247. var div = $(this);
  248. var data = div.data();
  249. data.html =!div.attr('data-label') ? '': div.attr('data-label');
  250. data.label = data.html;
  251. div.html('');
  252. var o = $.extend(o, data);
  253. if(o.readonly == false){
  254. var form = $('<form class="box" method="post" action="' + o.action + '" enctype="multipart/form-data"><input type="file" name="'+(o.fileName?o.fileName:div.attr('id'))+'[]" multiple /></form>');
  255. div.append(form);
  256. var input = form.find('input[type="file"]');
  257. var zone = $('<div>' + o.label + '</div>');
  258. div.append(zone);
  259. //test if dnd is enabled n browser
  260. var div = document.createElement('div');
  261. var dragAndDropEnabled = (('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) && 'FormData' in window && 'FileReader' in window;
  262. //set elements styles
  263. input.attr('style', "width: 0.1px;height: 0.1px;opacity: 0;overflow: hidden; position: absolute;z-index: -1");
  264. zone.css('cursor', "pointer");
  265. //set events
  266. zone
  267. .on('click', function (e) {
  268. form.find('input[type="file"]').trigger('click');
  269. e.preventDefault();
  270. e.stopPropagation();
  271. })
  272. .on('drag dragstart dragend dragover dragenter dragleave drop', function (e) {
  273. e.preventDefault();
  274. e.stopPropagation();
  275. })
  276. .on('dragover dragenter', function () {
  277. if (o.hover) form.addClass(o.hover);
  278. })
  279. .on('dragleave dragend drop', function () {
  280. if (o.hover) form.removeClass(o.hover);
  281. })
  282. .on('drop', function (e) {
  283. droppedFiles = e.originalEvent.dataTransfer.files;
  284. form.trigger('submit');
  285. });
  286. input.on('change', function (e) {
  287. form.trigger('submit');
  288. });
  289. form.on('submit', function (e) {
  290. if (o.start) o.start();
  291. if (dragAndDropEnabled) {
  292. e.preventDefault();
  293. var ajaxData = new FormData();
  294. if (droppedFiles) {
  295. $.each(droppedFiles, function (i, file) {
  296. var ext = file.name.split('.');
  297. ext = ext.pop();
  298. if(o.allowed && $.inArray(ext.toLowerCase(),o.allowed.split(','))===-1){
  299. $.message('error','Extension fichier '+ext+' non permise (autorisé:'+o.allowed+')',0);
  300. return;
  301. }
  302. if(o.size && file.size > o.size){
  303. $.message('error','Taille fichier '+file.size+' octets trop grande (autorisé:'+o.size+' octets)',0);
  304. return;
  305. }
  306. ajaxData.append(input.attr('name'), file);
  307. });
  308. }else{
  309. ajaxData = new FormData(form.get(0));
  310. for(var key in $('input',form).get(0).files){
  311. var file = $('input',form).get(0).files[key];
  312. if(file.name==null || typeof file !='object') continue;
  313. var ext = file.name.split('.');
  314. ext = ext.pop();
  315. if(o.allowed && $.inArray(ext.toLowerCase(),o.allowed.split(','))===-1){
  316. $.message('error','Extension fichier '+ext+' non permise (autorisé:'+o.allowed+')',0);
  317. $('input',form).val();
  318. return;
  319. }
  320. if(o.size && file.size > o.size){
  321. $.message('error','Taille fichier '+file.size+' octets trop grande (autorisé:'+o.size+' octets)',0);
  322. $('input',form).val();
  323. return;
  324. }
  325. }
  326. }
  327. if (o.addData){
  328. var addionalData = o.addData();
  329. for(var k in addionalData){
  330. ajaxData.append(k, addionalData[k]);
  331. }
  332. }
  333. droppedFiles = null;
  334. $.ajax({
  335. url: form.attr('action'),
  336. type: form.attr('method'),
  337. data: ajaxData,
  338. dataType: 'json',
  339. cache: false,
  340. contentType: false,
  341. processData: false,
  342. complete: function (data) {
  343. if (o.complete) o.complete(data.responseJSON);
  344. },
  345. success: function (data) {
  346. if (o.success) o.success(data);
  347. },
  348. error: function (data) {
  349. if (o.error) o.error(data);
  350. }
  351. });
  352. } else {
  353. var iframeName = 'uploadiframe' + new Date().getTime();
  354. iframe = $('<iframe name="' + iframeName + '" style="display: none;"></iframe>');
  355. $('body').append(iframe);
  356. form.attr('target', iframeName);
  357. iframe.one('load', function () {
  358. var data = JSON.parse(iframe.contents().find('body').text());
  359. if (!data.success) alert(data.error);
  360. form.removeAttr('target');
  361. iframe.remove();
  362. if (o.complete) o.complete();
  363. });
  364. }
  365. });
  366. }
  367. });
  368. },
  369. clear: function (){
  370. return this.each(function() {
  371. var obj = $(this);
  372. obj.find('input,select,textarea').val('');
  373. });
  374. },
  375. addLine: function (rows){
  376. return this.each(function() {
  377. var obj = $(this);
  378. var model = null;
  379. var container = null;
  380. if(obj.prop("tagName") == 'UL'){
  381. container = obj;
  382. model = container.find('li:first-child');
  383. container.find('li:visible').remove();
  384. }else if(obj.prop("tagName") == 'TABLE'){
  385. container = obj.find('tbody');
  386. model = container.find('tr:first-child');
  387. container.find('tr:visible').remove();
  388. }else{
  389. container = obj;
  390. childName = container.children().get(0).nodeName;
  391. model = container.find(childName+':first-child');
  392. container.find(childName+':visible:not(.nofill)').remove();
  393. }
  394. var tpl = model.get(0).outerHTML;
  395. //fix jquery backslahes break
  396. tpl = tpl.replace(/{{##/g,'{{/').replace(/{{\/(.*)}}=""/g,'{{/$1}}');
  397. //fix images url not found on template
  398. tpl = tpl.replace(/(<img\s[^>]*\s)(data-src)/g,'$1src');
  399. for(var key in rows){
  400. var line = $(Mustache.render(tpl,rows[key]));
  401. container.append(line);
  402. line.show();
  403. }
  404. });
  405. },
  406. fill: function (option,callback,progress){
  407. return this.each(function() {
  408. var obj = $(this);
  409. var model = null;
  410. var container = null;
  411. option = $.extend({showItems:true},option);
  412. var preloader = null;
  413. if(option.preloader){
  414. var preloader = $(option.preloader);
  415. preloader.css('position','absolute');
  416. preloader.css('left',(obj.offset().left+obj.width()/2)+'px');
  417. preloader.css('top',(obj.offset().top+30)+'px');
  418. $('body').append(preloader);
  419. }
  420. if(obj.prop("tagName") == 'UL'){
  421. container = obj;
  422. model = container.find('li:first-child');
  423. container.children('li:not(.hidden)').remove();
  424. } else if(obj.prop("tagName") == 'TABLE'){
  425. container = obj.find('tbody');
  426. model = container.find('tr:first-child');
  427. container.children('tr:visible').remove();
  428. } else if(obj.prop("tagName") == "SELECT"){
  429. container = obj;
  430. model = container.find('option[value*="{{"]');
  431. if(model.length==0) model = $('<option class="hidden" value="{{value}}">{{label}}</option>');
  432. container.find('option:not([value*="{{"])').remove();
  433. } else{
  434. container = obj;
  435. childName = container.children().get(0).nodeName;
  436. model = container.find(childName+':first-child');
  437. container.find(childName+':visible:not(.nofill)').remove();
  438. }
  439. var tpl = model.get(0).outerHTML;
  440. //fix jquery backslashes break
  441. tpl = tpl.replace(/{{##/g,'{{/').replace(/{{\/(.*)}}=""/g,'{{/$1}}');
  442. //fix images url not found on template
  443. tpl = tpl.replace(/(<img\s[^>]*\s?)(data-src)/g,'$1src');
  444. var pagination = obj.nextAll('.pagination').length ? obj.nextAll('.pagination') : obj.parent().nextAll('.pagination');
  445. if(pagination.length!=0) option.page = $('li.active',pagination).attr('data-value');
  446. tpl = tpl.replace(/(data-style)/g, 'style');
  447. $.action(option,function(r){
  448. for(var key in r.rows){
  449. var line = $(Mustache.render(tpl,r.rows[key]));
  450. container.append(line);
  451. if(option.showItems){
  452. line.removeClass('hidden').removeClass('hide').removeClass('noDisplay');
  453. }
  454. }
  455. if(r.pagination){
  456. var template = pagination.find('li:not(:visible)').get(0).outerHTML;
  457. $('li:not(.hidden)',pagination).remove();
  458. for(i=0;i<r.pagination.pages;i++){
  459. var li = $(Mustache.render(template,{value:i,label:i+1}));
  460. li.removeClass('hidden');
  461. pagination.append(li);
  462. }
  463. pagination.find('li:not(.hidden)').eq(r.pagination.current).addClass('active');
  464. if(r.pagination.pages>1)
  465. pagination.find('.page-item:not(.hidden):first .page-link').css('border-radius','0.25rem 0 0 0.25rem');
  466. else
  467. pagination.find('.page-item:not(.hidden):first .page-link').css('border-radius','0.25rem 0.25rem 0.25rem 0.25rem');
  468. }
  469. if(preloader) preloader.remove();
  470. if(callback!=null)callback(r);
  471. },null,function(percent,type){
  472. if(progress) progress(percent,type);
  473. });
  474. });
  475. },
  476. filters: function (option){
  477. var obj = $(this);
  478. var box = obj.next('.filter-box');
  479. var formData = {
  480. keyword : $('.filter-keyword',box).val()
  481. };
  482. formData.advanced = [], formData.multiple = [], formData.custom = {};
  483. $('.filterRow:visible',box).each(function(i,row){
  484. var row = $(row);
  485. if(row.find('.filter-column').val()=='') return;
  486. var filter = {
  487. join : row.find('.filter-join').val(),
  488. column : row.find('.filter-column').val(),
  489. type : row.find('.filter-column option:selected').attr('data-filter-type'),
  490. operator : {},
  491. value : {}
  492. }
  493. if ($('.filter-value-block',row).length > 1) {
  494. $('.filter-value-block',row).each(function(j,block){
  495. var block = $(block);
  496. filter.operator[j] = block.find('.filter-operator').val();
  497. filter.value[j] = block.find('.filter-value').last().val();
  498. });
  499. formData.multiple.push(filter);
  500. } else {
  501. filter.operator = row.find('.filter-operator').val();
  502. values = row.find('.filter-value');
  503. if(values.length > 1){
  504. filter.value = [];
  505. for(var j=0; j<values.length; ++j){
  506. filter.value.push(values.eq(j).val());
  507. }
  508. values.eq(j).attr('data-custom') == 'true' ? formData.custom[filter.column] = filter : formData.advanced.push(filter);
  509. } else {
  510. filter.value = values.val();
  511. values.last().attr('data-custom') == 'true' ? formData.custom[filter.column] = filter : formData.advanced.push(filter);
  512. }
  513. }
  514. });
  515. return formData;
  516. },
  517. enter: function (option){
  518. return this.each(function() {
  519. var obj = $(this);
  520. obj.keydown(function(event){
  521. if(event.keyCode == 13){
  522. option();
  523. return false;
  524. }
  525. });
  526. });
  527. },
  528. sortable_table: function (option){
  529. if(option=='get'){
  530. var obj = $(this);
  531. var response = {};
  532. obj.find('thead th[data-sortable]').each(function(i,th){
  533. var th = $(th);
  534. if(th.attr('data-sort') && th.attr('data-sort')!=""){
  535. response = {
  536. sort : th.attr('data-sort'),
  537. sortable : th.attr('data-sortable')
  538. };
  539. }
  540. });
  541. return response;
  542. }
  543. return this.each(function() {
  544. var obj = $(this);
  545. obj.find('thead th[data-sortable]').click(function(){
  546. var th = $(this);
  547. var data = th.data();
  548. if(!data.sort || data.sort==''){
  549. data.sort = 'asc'
  550. }else if(data.sort == 'asc'){
  551. data.sort ='desc'
  552. }else{
  553. data.sort = '';
  554. }
  555. obj.find('thead th').removeClass('sort-asc').removeClass('sort-desc').removeAttr('data-sort');
  556. if(data.sort!='') th.addClass('sort-'+data.sort);
  557. th.attr('data-sort',data.sort);
  558. if(option.onSort) option.onSort();
  559. });
  560. });
  561. },
  562. autocomplete: function(o){
  563. return this.each(function() {
  564. var obj = $(this);
  565. obj.attr('autocomplete','off');
  566. var option = obj.data();
  567. option = $.extend(option,o);
  568. obj.typeahead({
  569. items: 5,
  570. minLength: 2,
  571. fitToElement: false,
  572. autoSelect : false,
  573. selectOnBlur : false,
  574. displayText : function(item){
  575. return (o.skin) ? o.skin(item) : item.name || item;
  576. },
  577. source: function(keyword, response){
  578. $.action({
  579. action: option.action,
  580. keyword: obj.val(),
  581. data: o.data
  582. },function(r){
  583. if(r.rows != null)
  584. response(r.rows);
  585. });
  586. },
  587. highlighter: function(item){
  588. if(o.highlight) {
  589. return o.highlight(item)
  590. }
  591. else {
  592. var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
  593. return item.replace(new RegExp('('+query+')', 'ig'), function($1, match){
  594. return '<strong>'+match+'</strong>';
  595. });
  596. }
  597. },
  598. matcher: function(r){
  599. if(obj.val() == r.name)
  600. if(o.onClick)
  601. o.onClick(r,obj);
  602. return '<div>'+r.name+'</div>';
  603. },
  604. afterSelect: function(item) {
  605. obj.data('selected',true);
  606. if(o.onClick) o.onClick(item,obj);
  607. obj.trigger("change");
  608. }
  609. }).blur(function(){
  610. if(o.onBlur) o.onBlur(obj);
  611. });
  612. obj.data('typeahead').next = function (event) {
  613. var active = this.$menu.find('.active').removeClass('active');
  614. var next = active.next();
  615. if (!next.length) {
  616. next = $(this.$menu.find($(this.options.item || this.theme.item).prop('tagName'))[0]);
  617. }
  618. while (next.hasClass('divider') || next.hasClass('dropdown-header')) {
  619. next = next.next();
  620. }
  621. next.addClass('active');
  622. var newVal = this.updater(next.data('value'));
  623. this.$element.val(newVal.name || newVal);
  624. };
  625. obj.data('typeahead').prev = function (event) {
  626. var active = this.$menu.find('.active').removeClass('active');
  627. var prev = active.prev();
  628. if (!prev.length){
  629. prev = this.$menu.find($(this.options.item || this.theme.item).prop('tagName')).last();
  630. }
  631. while (prev.hasClass('divider') || prev.hasClass('dropdown-header')) {
  632. prev = prev.prev();
  633. }
  634. prev.addClass('active');
  635. var newVal = this.updater(prev.data('value'));
  636. if (this.changeInputOnMove) this.$element.val(newVal.name || newVal);
  637. };
  638. });
  639. },
  640. location: function (options){
  641. return this.each(function() {
  642. try{
  643. //var options = $.extend({},options);
  644. var obj = $(this);
  645. obj.attr('autocomplete','off');
  646. var data = $('#algolia').data();
  647. var placesAutocomplete = places({
  648. appId: data.api,
  649. apiKey: data.key,
  650. container: obj.get(0)
  651. });
  652. placesAutocomplete.on('change', function(e) {
  653. var m = /[0-9]*/m.exec(e.suggestion.name)
  654. var infos = {
  655. latitude: e.suggestion.latlng.lat,
  656. longitude : e.suggestion.lng,
  657. types : e.suggestion.type,
  658. number : '',
  659. street : e.suggestion.name,
  660. city : e.suggestion.city,
  661. country : e.suggestion.country,
  662. code : e.suggestion.postcode,
  663. picture : '',
  664. map : ''
  665. };
  666. if(m && m.length > 0 ) infos.number = m[0] ;
  667. infos.address = (infos.street && infos.street.length && infos.number && infos.number.length) ? infos.number+' '+infos.street : (infos.street ? infos.street : '');
  668. if(options.select) options.select(infos);
  669. });
  670. }catch(e){
  671. console.warn('Composant Location en erreur, désactivé :'+e);
  672. }
  673. });
  674. },
  675. date: function (){
  676. return this.each(function() {
  677. var obj = $(this);
  678. obj.on('paste', function(e){
  679. is_valid_date(e.originalEvent.clipboardData.getData('Text')) ? obj.val("") : e.preventDefault();
  680. });
  681. obj.datepicker({
  682. dateFormat: "dd/mm/yy",
  683. dayNames: ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"],
  684. dayNamesMin: ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"],
  685. dayNamesShort: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"],
  686. monthNames: ["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Aout","Septembre","Octobre","Novembre","Décembre"],
  687. monthNamesShort: ["Jan","Fév","Mars","Avr","Mai","Juin","Juil","Aout","Sept","Oct","Nov","Déc"],
  688. firstDay: 1,
  689. changeMonth: true,
  690. yearRange: "-100:+0",
  691. changeYear: true,
  692. onSelect: function(dateText, inst) {
  693. $(this).trigger("blur");
  694. }
  695. }).keypress(function(event){
  696. var length = $(this).val().length;
  697. if(length == 2 || length == 5) $(this).val($(this).val()+'/');
  698. }).blur(function(event){
  699. $(this).removeClass('border border-danger')
  700. if($(this).val()=='') return;
  701. var segments = $(this).val().split('/');
  702. if(segments.length!=3) return;
  703. if(segments[0] > 31 || segments[1] > 12) $(this).addClass('border border-danger');
  704. }).attr('maxlength','10');
  705. obj.attr("placeholder","jj/mm/aaaa");
  706. obj.attr('pattern',"[0-9/]{10}");
  707. obj.attr("title","Format jj/mm/aaaa");
  708. });
  709. },
  710. hour: function (){
  711. return this.each(function() {
  712. var obj = $(this);
  713. var step = obj.attr('data-step');
  714. obj.on('paste', function(e){
  715. is_valid_hour(e.originalEvent.clipboardData.getData('Text')) ? obj.val("") : e.preventDefault();
  716. });
  717. obj.timepicker({
  718. disableAlphaInput: true,
  719. timeFormat: 'H:i',
  720. scrollDefault: 'now',
  721. 'step': is_numeric(step) && step>0 ? obj.attr('data-step') : 1
  722. });
  723. obj.attr("placeholder","hh:mm");
  724. obj.attr('pattern',"[0-9:]{5}");
  725. obj.attr('title',"Format hh:mm");
  726. });
  727. },
  728. raiseNumber: function(from,to) {
  729. return this.each(function(){
  730. var obj = $(this);
  731. obj.text(from);
  732. var interval = 800 / (to - from);
  733. var interval = setInterval(function(){
  734. var number = parseFloat(obj.text());
  735. if(number>=to) {
  736. clearInterval(interval);
  737. return;
  738. }
  739. obj.text(number+1);
  740. },interval);
  741. });
  742. }
  743. });