templates/base.html.twig line 1

Open in your IDE?
  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="UTF-8">
  5.         <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6.         <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no">
  7.         <title>{% block title %}Welcome!{% endblock %}</title>
  8.         <link rel="apple-touch-icon" sizes="180x180" href="/assets/images/favicon/apple-touch-icon.png">
  9.         <link rel="icon" type="image/png" sizes="32x32" href="/assets/images/favicon/favicon-32x32.png">
  10.         <link rel="icon" type="image/png" sizes="16x16" href="/assets/images/favicon/favicon-16x16.png">
  11.         <link rel="manifest" href="/assets/images/favicon/site.webmanifest">
  12.         <!-- BEGIN GLOBAL MANDATORY STYLES -->
  13.         <link href="https://fonts.googleapis.com/css?family=Nunito:400,600,700" rel="stylesheet">
  14.         <link href="{{ asset('assets/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css" />
  15.         <link href="{{ asset('assets/css/plugins.css') }}" rel="stylesheet" type="text/css" />
  16.         <link href="{{ asset('assets/plugins/notification/toastr/toastr.min.css') }}" rel="stylesheet" type="text/css" />
  17.         <link rel="stylesheet" type="text/css" href="{{ asset('assets/plugins/select2/select2.min.css') }}">
  18.         <link rel="stylesheet" type="text/css" href="{{ asset('assets/plugins/flatpickr/flatpickr.css') }}">
  19.         <link rel="stylesheet" type="text/css" href="{{ asset('assets/plugins/flatpickr/custom-flatpickr.css') }}">
  20.         <link rel="stylesheet" type="text/css" href="{{ asset('assets/plugins/fancybox/fancybox.css') }}"/>
  21.         <!-- END GLOBAL MANDATORY STYLES -->
  22.         <!-- BEGIN PAGE LEVEL PLUGINS/CUSTOM STYLES -->
  23.         <link rel="stylesheet" href="{{ asset('assets/css/custom.css') }}">
  24.         {% block stylesheets %}{% endblock %}
  25.         <link rel="stylesheet" media="print" href="{{ asset('assets/css/print.css') }}" />
  26.         <!-- END PAGE LEVEL PLUGINS/CUSTOM STYLES -->
  27.         {% if app.user %}
  28.         <style>
  29.         :root {
  30.             --primary: {{ app.user.company.color }}!important;
  31.             --primary_15l: {{ app.user.company.color }}33!important;/* 0.15 opacity */
  32.             --secondary: {{ app.user.company.color2 }}!important;
  33.         }
  34.         </style>
  35.         {% endif %}
  36.         {% if global_vars.metaPixelId %}
  37.         <!-- Meta Pixel Code -->
  38.         <script>
  39.         !function(f,b,e,v,n,t,s)
  40.         {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
  41.         n.callMethod.apply(n,arguments):n.queue.push(arguments)};
  42.         if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
  43.         n.queue=[];t=b.createElement(e);t.async=!0;
  44.         t.src=v;s=b.getElementsByTagName(e)[0];
  45.         s.parentNode.insertBefore(t,s)}(window, document,'script',
  46.         'https://connect.facebook.net/en_US/fbevents.js');
  47.         fbq('init', '{{ global_vars.metaPixelId }}');
  48.         fbq('track', 'PageView');
  49.         </script>
  50.         <noscript><img height="1" width="1" style="display:none"
  51.             src="https://www.facebook.com/tr?id={{ global_vars.metaPixelId }}&ev=PageView&noscript=1"/></noscript>
  52.         <!-- End Meta Pixel Code -->
  53.         {% endif %}
  54.     </head>
  55.     <body class="alt-menu sidebar-noneoverflow {% block bodyClass %}{% endblock %}">
  56.     {% if app.user %}
  57.     {{ include('navbar.html.twig') }}
  58.     <!--  BEGIN MAIN CONTAINER  -->
  59.     <div class="main-container sidebar-closed sbar-open" id="container">
  60.         <div class="overlay"></div>
  61.         <div class="cs-overlay"></div>
  62.         <div class="search-overlay"></div>
  63.         {{ include('sidebar.html.twig') }}
  64.         
  65.         <!--  BEGIN CONTENT AREA  -->
  66.         <div id="content" class="main-content">
  67.             <div class="layout-px-spacing">
  68.                 <div class="page-header">
  69.                     <div class="page-title">
  70.                         <h3>{% block pageHeader %}{% endblock %}</h3>
  71.                     </div>
  72.                 </div>
  73.                 <!-- CONTENT AREA -->
  74.                 
  75.                 {% block pageContent %}{% endblock %}
  76.                 <!-- CONTENT AREA -->
  77.             </div>
  78.         </div>
  79.         <!--  END CONTENT AREA  -->
  80.     </div>
  81.     <!-- END MAIN CONTAINER -->
  82.     {{ include('footer.html.twig')}}
  83.     {% endif %}
  84.     {% block login %}{% endblock %}
  85.     <!-- BEGIN GLOBAL MANDATORY SCRIPTS -->
  86.     <script src="{{ asset('assets/js/libs/jquery-3.1.1.min.js') }}"></script>
  87.     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js"></script>
  88.     <script src="{{ asset('assets/bootstrap/js/popper.min.js') }}"></script>
  89.     <script src="{{ asset('assets/bootstrap/js/bootstrap.min.js') }}"></script>
  90.     <script src="{{ asset('assets/plugins/perfect-scrollbar/perfect-scrollbar.min.js') }}"></script>
  91.     <script src="{{ asset('assets/plugins/notification/toastr/toastr.min.js') }}"></script>
  92.     <script src="{{ asset('assets/plugins/select2/select2.min.js') }}"></script>
  93.     <script src="{{ asset('assets/plugins/flatpickr/flatpickr.js') }}"></script>
  94.     <script src="{{ asset('assets/plugins/flatpickr/fr.js') }}"></script>
  95.     <script src="{{ asset('assets/js/jquery.collection.js') }}"></script>
  96.     <script src="{{ asset('assets/plugins/fancybox/fancybox.umd.js') }}"></script>
  97.     <script src="{{ asset('assets/js/jquery.tagsinput.js') }}"></script>
  98.     <script src="{{ asset('assets/js/app.js') }}"></script>
  99.     <script>
  100.     flatpickr.localize(flatpickr.l10ns.fr);
  101.     toastr.options = {
  102.         "closeButton": true,
  103.         "debug": false,
  104.         "newestOnTop": true,
  105.         "progressBar": true,
  106.         "positionClass": "toast-bottom-left",
  107.         "preventDuplicates": false,
  108.         "onclick": null,
  109.         "showDuration": "300",
  110.         "hideDuration": "1000",
  111.         "timeOut": "10000",
  112.         "extendedTimeOut": "1000",
  113.         "showEasing": "swing",
  114.         "hideEasing": "linear",
  115.         "showMethod": "fadeIn",
  116.         "hideMethod": "fadeOut"
  117.     }
  118.     jQuery(document).ready(function() {
  119.         App.init();
  120.         if ($.fn.DataTable) {
  121.             $('.table-data').DataTable({
  122.                 "select": "true",
  123.                 "aaSorting": [],
  124.                 "oLanguage": {
  125.                     select: {
  126.                         rows: {
  127.                             _: "%d lignes sélectionnées",
  128.                             1: "1 ligne sélectionnée"
  129.                         }
  130.                     },
  131.                     "oPaginate": { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
  132.                     "sInfo": "Page _PAGE_ de _PAGES_",
  133.                     "sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
  134.                     "sSearchPlaceholder": "Recherche...",
  135.                     "sLengthMenu": "Résultats :  _MENU_",
  136.                     "sInfo":          "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
  137.                     "sInfoEmpty":     "Affichage de 0 à 0 sur 0 entrées",
  138.                     "sInfoFiltered":  "(filtrées depuis un total de _MAX_ entrées)",
  139.                 },
  140.                 "stripeClasses": [],
  141.             });
  142.             const selectTable = $('.table-data-select').DataTable({
  143.                 "columnDefs": [
  144.                     // These are the column name variables that will be sent to the server
  145.                     { 
  146.                         "name": "id",'targets': 0,
  147.                         'checkboxes': {
  148.                         'selectRow': true,
  149.                         'selectAll': false
  150.                         }  
  151.                     }
  152.                 
  153.                 ],
  154.                 'select': {
  155.                     'style': 'multi'
  156.                 },
  157.                 "oLanguage": {
  158.                     select: {
  159.                         rows: {
  160.                             _: "%d lignes sélectionnées",
  161.                             1: "1 ligne sélectionnée"
  162.                         }
  163.                     },
  164.                     "oPaginate": { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
  165.                     "sInfo": "Page _PAGE_ de _PAGES_",
  166.                     "sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
  167.                     "sSearchPlaceholder": "Recherche...",
  168.                     "sLengthMenu": "Résultats :  _MENU_",
  169.                     "sInfo":          "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
  170.                     "sInfoEmpty":     "Affichage de 0 à 0 sur 0 entrées",
  171.                     "sInfoFiltered":  "(filtrées depuis un total de _MAX_ entrées)",
  172.                 },
  173.             });
  174.             
  175.             // Event listener to the filtering select to redraw on change
  176.             $('#content').on('change','.data-filter',function ()  { 
  177.                     selectTable.draw();
  178.             } );
  179.             $('.table-data-select thead input[name="select_all"]').on('click', function (e) {
  180.             var checked = $('#selectall').prop('checked');
  181.                 // get all filtered rows
  182.                 var allRowsCount = selectTable.rows().count()
  183.                 var filteredRowsCount = selectTable.rows({ search: 'applied' }).count();
  184.                 var visibleRowsCount = selectTable.rows({ page: 'current' }).count();
  185.                 //console.log(allRowsCount, filteredRowsCount, visibleRowsCount)
  186.                 var rows = (allRowsCount == filteredRowsCount) ? { page: 'current' } : { search: 'applied' };
  187.                 if (this.checked) {
  188.                     selectTable.rows(rows).select();
  189.                 } else {
  190.                     //selectTable.rows(rows).deselect();
  191.                     selectTable.rows({ selected: true }).deselect();
  192.                 }
  193.             });
  194.             selectTable.on('length.dt', function () {
  195.                 selectTable.rows({ selected: true }).deselect();
  196.                 $('.table-data-select thead input[name="select_all"]').prop('checked', false);
  197.             });
  198.             $('body').on('click', 'a#table-data-select-export', function(e){
  199.                 //alert();
  200.                 var rows_selected = selectTable.column(0).checkboxes.selected();
  201.                 //console.log(rows_selected);
  202.                 if (typeof rows_selected !== 'undefined' && rows_selected.length > 1  && rows_selected.length < 51) {
  203.                     var url = $(this).attr("href");
  204.                     // Iterate over all selected checkboxes
  205.                     $.each(rows_selected, function(index, row){
  206.                         rowId = row.replace(/[^0-9]/g,'');
  207.                         if (url.indexOf('?') === -1) {
  208.                             url = url + '?a[]=' + rowId;  
  209.                         }else {
  210.                             url = url + '&a[]=' + rowId;
  211.                         }
  212.                     });
  213.                     window.open(url, "_blank");
  214.                 } else if (rows_selected.length > 50) {
  215.                     toastr["error"]('Merci de ne pas selectionner plus que 50 documents ... ');
  216.                 } else {
  217.                     toastr["warning"]('Merci de selectionner au moins deux éléments ...');
  218.                 }
  219.                 return false;
  220.                 
  221.             }); 
  222.         }
  223.         $('.emails-tags').tagsInput({
  224.             'unique': true,
  225.             'validationPattern': new RegExp('(.+)@(.+){2,}\.(.+){2,}'),
  226.             'delimiter': [' ']
  227.         });
  228.         
  229.         flatpickr($('.flatpickr'), {
  230.             enableTime: true,
  231.             dateFormat: "Y-m-d H:i",
  232.             disableMobile: "true",
  233.             "locale": {
  234.                 "firstDayOfWeek": 7 // start week on Sunday
  235.             },
  236.             minDate: new Date(),
  237.             allowInput: true,
  238.             onOpen: function(selectedDates, dateStr, instance) {
  239.             $(instance.altInput).prop('readonly', true);
  240.             },
  241.             onClose: function(selectedDates, dateStr, instance) {
  242.                 $(instance.altInput).prop('readonly', false);
  243.                 $(instance.altInput).blur();
  244.             },
  245.             onChange: function(selectedDates, dateStr, instance) {
  246.                 validateInput(dateStr, $('.flatpickr')[0]);
  247.             }
  248.         });
  249.         // Add an additional event listener to the date input field
  250.         $('.flatpickr').on('change', function() {
  251.             validateInput(this.value, $(this)[0]);
  252.         });
  253.         flatpickr($('.flatpickr_date'), {
  254.             enableTime: false,
  255.             dateFormat: "Y-m-d",
  256.             disableMobile: "true",
  257.             "locale": {
  258.                 "firstDayOfWeek": 7 // start week on Sunday
  259.             },
  260.             defaultDate: new Date(),
  261.             allowInput: true,
  262.             onOpen: function(selectedDates, dateStr, instance) {
  263.             $(instance.altInput).prop('readonly', true);
  264.             },
  265.             onClose: function(selectedDates, dateStr, instance) {
  266.                 $(instance.altInput).prop('readonly', false);
  267.                 $(instance.altInput).blur();
  268.             },
  269.             onChange: function(selectedDates, dateStr, instance) {
  270.                 validateInput(dateStr, $('.flatpickr_date')[0]);
  271.             }
  272.         });
  273.         // Add an additional event listener to the date input field
  274.         $('.flatpickr_date').on('change', function() {
  275.             validateInput(this.value, $(this)[0]);
  276.         });
  277.         flatpickr($('.flatpickr_date_nodefault'), {
  278.             enableTime: false,
  279.             dateFormat: "Y-m-d",
  280.             disableMobile: "true",
  281.             "locale": {
  282.                 "firstDayOfWeek": 7 // start week on Sunday
  283.             },
  284.             allowInput: true,
  285.             onOpen: function(selectedDates, dateStr, instance) {
  286.             $(instance.altInput).prop('readonly', true);
  287.             },
  288.             onClose: function(selectedDates, dateStr, instance) {
  289.                 $(instance.altInput).prop('readonly', false);
  290.                 $(instance.altInput).blur();
  291.             },
  292.             onChange: function(selectedDates, dateStr, instance) {
  293.                 validateInput(dateStr, $('.flatpickr_date_nodefault')[0]);
  294.             }
  295.         });
  296.         // Add an additional event listener to the date input field
  297.         $('.flatpickr_date_nodefault').on('change', function() {
  298.             validateInput(this.value, $(this)[0]);
  299.         });
  300.         function validateInput(dateValue, input) {
  301.             var date = new Date(dateValue);
  302.             console.log(date, input);
  303.             if (!isNaN(date.getTime())) {
  304.                 // If the date is valid, clear the error message
  305.                 input.setCustomValidity(''); 
  306.             } else {
  307.                 // If the date is not valid, set a custom error message on the field
  308.                 input.setCustomValidity('Merci de choisir une date valide !');
  309.             }
  310.         }
  311.         flatpickr($('.flatpickr_time'), {
  312.             enableTime: true,
  313.             noCalendar: true,
  314.             dateFormat: "H:i",
  315.             //defaultDate: new Date(),
  316.             disableMobile: "true",
  317.         });
  318.         $('.collections').collection({
  319.             allow_down: false,
  320.             allow_up: false,
  321.             add: '<a href="#" class="btn btn-primary mb-2 mr-2 rounded-circle"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>',
  322.             remove: '<a href="#" class="btn btn-primary mb-2 mr-2 rounded-circle"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><circle cx="12" cy="12" r="10"></circle><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>'
  323.             });
  324.         $('.select2_collections').collection({
  325.             after_add: function(collection, element) { initializeSelect2(element.find('.select2')) },
  326.             allow_down: false,
  327.             allow_up: false,
  328.             add: '<a href="#" class="btn btn-primary mb-2 mr-2 rounded-circle"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>',
  329.             remove: '<a href="#" class="btn btn-primary mb-2 mr-2 rounded-circle"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><circle cx="12" cy="12" r="10"></circle><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>'
  330.             });
  331.         function initializeSelect2(selectElementObj) {
  332.             selectElementObj.select2({
  333.             });
  334.             return true;
  335.         }
  336.         
  337.         {% for message in app.flashes('notice') %}
  338.             toastr["warning"]("{{ message }}");
  339.         {% endfor %}
  340.         {% for message in app.flashes('success') %}
  341.             toastr["success"]("{{ message }}");
  342.         {% endfor %}
  343.         {% for message in app.flashes('error') %}
  344.             toastr["error"]("{{ message }}");
  345.         {% endfor %}
  346.         {% for message in app.flashes('critical') %}
  347.             toastr.options.closeButton = true;
  348.             toastr.options.tapToDismiss = false;
  349.             toastr.options.timeOut = 0;
  350.             toastr.options.extendedTimeOut = 0;
  351.             toastr.options.showDuration = 0;
  352.             toastr.options.hideDuration = 0;
  353.             toastr.options.escapeHtml = false;
  354.             toastr.options.preventDuplicates = true;
  355.             toastr["error"]("{{ message|raw }}");
  356.         {% endfor %}
  357.         {% for message in app.flashes('error_action') %}
  358.             //toastr.options = {onclick: function () {document.location.href='{{app.request.get("action")}}'; }}
  359.             toastr.options.onclick = function () {document.location.href='{{app.request.get("action")}}'; }
  360.             toastr["error"]("{{ message }}<br /><button type="button" class="btn clear">Éditer</button>");
  361.             });
  362.         {% endfor %}
  363.         /*
  364.         ================================================
  365.         |   navbar inbox / send photo / input file     |
  366.         ================================================
  367.         */
  368.         $.ajax({
  369.             type: "GET",
  370.             url: "{{ path('message_unread_index') }}",
  371.         })
  372.         .done(function(data){ 
  373.             if (data.length > 0) {
  374.                 var elem = "";
  375.                 for (i = 0; i < data.length; i++) {
  376.                     elem += "<a href='{{ path('message_index') }}' class='dropdown-item'><div><div class='media notification-new'><div class='usr-profile-img mr-3'><div class='user-profile'><div>"+data[i]["initials"]+"</div>";
  377.                     elem += "</div></div><div class='media-body'><p class='meta-user-name mr-3'>"+data[i]["sender"]+"</p><p class='message-text'>"+data[i]["subject"]+"</p><p class='meta-time align-self-center mb-0'>"+data[i]["time"]+"</p></div></div></div></a>";    
  378.                 }
  379.                 $('#message-dropdown').html(elem);
  380.                 $('li.message-dropdown span.badge').html(data.length)
  381.             }    else {
  382.                 $('#message-dropdown').html("<p class='m-3 text-center'>Aucun nouveau message!<br><a class='btn btn-primary mt-3' href='/message'>Boîte de Réception</a></p>");
  383.             }
  384.         });
  385.         $('#send-photos').off('click').on('click', function(event) {
  386.             $( "#sendPictureModal form[name='message']" ).submit();
  387.             event.preventDefault();
  388.         });
  389.         $("input[type=file]").each(function (index, inputFile) {
  390.             if($(inputFile).data("filename"))
  391.             {
  392.                 var label = $("label[for='" + $(inputFile).attr('id') + "']")[0];
  393.                 label.innerHTML = $(inputFile).data("filename");
  394.             }
  395.         });
  396.         $(document).on('change', "input[type='file']", function(){
  397.             //get the file name
  398.             var fileName = $(this).val().replace('C:\\fakepath\\', " ");
  399.             //replace the "Choose a file" label
  400.             $(this).next('.custom-file-label').html(fileName);
  401.         });
  402.          /*
  403.         ================================================
  404.         |               submit button loader            |
  405.         ================================================
  406.         */
  407.          $("button[data-spinning-button]").click(function(e) {
  408.             var $this = $(this);
  409.             let $form  = $this.parents("form");
  410.             $this
  411.                 .addClass("button-loading")
  412.                 .attr("disabled", "");
  413.             //return true;
  414.             if ($form.length) {
  415.                 //form.valid() will be applicable If you are using jQuery validate https://jqueryvalidation.org/
  416.                 //asp.net mvc used it by default with jQuery Unobtrusive Validation
  417.                 //you need to check the form before it goes into the if statement
  418.                 if ($form[0].checkValidity()) {
  419.                     $form.submit();
  420.                 } else {
  421.                     $this
  422.                         .removeClass("button-loading")
  423.                         .removeAttr("disabled", "");
  424.                 }
  425.             }
  426.         });
  427.         $("a[data-spinning-link]").click(function(e) {
  428.             var $this = $(this);
  429.             $this
  430.                 .addClass("button-loading")
  431.                 .attr("disabled", "");
  432.             return true;
  433.         });
  434.         /*
  435.         ================================================
  436.         |                  Fancybox                  |
  437.         ================================================
  438.         */
  439.             Fancybox.defaults.l10n = {
  440.                 CLOSE: "Fermer",
  441.                 NEXT: "Suivant",
  442.                 PREV: "Précédent",
  443.                 MODAL: "Vous pouvez fermer ce contenu modal avec la touche ESC",
  444.                 ERROR: "Quelque chose s'est mal passé, veuillez réessayer plus tard",
  445.                 IMAGE_ERROR: "Image non trouvée",
  446.                 ELEMENT_NOT_FOUND: "Élément HTML introuvable",
  447.                 AJAX_NOT_FOUND: "Erreur lors du chargement d'AJAX : introuvable",
  448.                 AJAX_FORBIDDEN: "Erreur lors du chargement d'AJAX : Interdit",
  449.                 IFRAME_ERROR: "Erreur de chargement de la page",
  450.                 TOGGLE_ZOOM: "Zoomer et dézoomer",
  451.                 ROTATE_LEFT: "Faire tourner à gauche",
  452.                 ROTATE_RIGHT: "Faire tourner à droite",
  453.                 TOGGLE_FULLSCREEN: "Basculer en plein écran",
  454.             };
  455.             Fancybox.Plugins.Toolbar.defaults.items.rotateRight = {
  456.                 type: "button",
  457.                 class: "fancybox__button--rotateRight",
  458.                 label: "ROTATE_RIGHT",
  459.                 html:
  460.                     '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>',
  461.                 click: function (event) {
  462.                     event.preventDefault();
  463.                     console.log(event.target.className);
  464.                     var orientation = event.target.classList.contains("fancybox__button--rotateRight") ? "cw" : "acw";
  465.                     var fancybox = this.fancybox;
  466.                     rotatingFunction (fancybox, orientation);
  467.                 },
  468.             };
  469.             Fancybox.Plugins.Toolbar.defaults.items.rotateLeft = {
  470.                 type: "button",
  471.                 class: "fancybox__button--rotateLeft",
  472.                 label: "ROTATE_LEFT",
  473.                 html:
  474.                     '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg>',
  475.                 click: function (event) {
  476.                     event.preventDefault();
  477.                     console.log(event.target.className);
  478.                     var orientation = event.target.classList.contains("fancybox__button--rotateRight") ? "cw" : "acw";
  479.                     var fancybox = this.fancybox;
  480.                     rotatingFunction (fancybox, orientation);
  481.                 },
  482.             };
  483.             Fancybox.bind("[data-fancybox]" , {
  484.                 Toolbar: {
  485.                     display: [
  486.                         "counter",
  487.                         "rotateRight",
  488.                         "rotateLeft",
  489.                         "zoom",
  490.                         "slideshow",
  491.                         "fullscreen",
  492.                         "close",
  493.                     ],
  494.                     fullScreen: {
  495.                         autoStart: true
  496.                     }
  497.                 },
  498.                 on: {
  499.                     load: (fancybox, slide) => {
  500.                         console.log(`#${slide.type} slide is loaded!`);
  501.                         //console.log(
  502.                         //    `This slide is selected: ${fancybox.getSlide().index === slide.index}`
  503.                         //);
  504.                         for (const $el of document.querySelectorAll(".fancybox__button--rotateLeft, .fancybox__button--rotateRight")) {
  505.                                 if (slide.type === "image") {
  506.                                     $el.removeAttribute("disabled");
  507.                                 } else {
  508.                                     $el.setAttribute("disabled", "");
  509.                                 }
  510.                         }
  511.                     },
  512.                 },
  513.             });
  514.             function rotatingFunction (fancybox, orientation) {
  515.                 $.ajax({
  516.                     type: 'POST',
  517.                     url: "{{ path('images_rotate') }}",
  518.                     data: { "file": fancybox.getSlide().src, 'orientation': orientation },
  519.                     beforeSend: function( xhr ) {
  520.                         var slide = fancybox.getSlide();
  521.                         fancybox.showLoading(slide);
  522.                     }
  523.                 }).done(function( data ) {
  524.                     //var slide = fancybox.getSlide();
  525.                     //fancybox.hideLoading(slide);
  526.                     
  527.                     //console.log(src);
  528.                     
  529.                     //Image rortated
  530.                     if (data["message"] == "ok") { 
  531.                         /*var thisImg = slide.$el.querySelector("img");
  532.                         var src = $(thisImg).attr("src");
  533.                         degrees = orientation == "cw" ? 90 : -90;
  534.                         $("img[src='"+src+"']").css({
  535.                             'transform': 'rotate(' + degrees + 'deg)',
  536.                             '-ms-transform': 'rotate(' + degrees + 'deg)',
  537.                             '-moz-transform': 'rotate(' + degrees + 'deg)',
  538.                             '-webkit-transform': 'rotate(' + degrees + 'deg)',
  539.                             '-o-transform': 'rotate(' + degrees + 'deg)'
  540.                          });*/
  541.                         
  542.                         var slide = fancybox.getSlide();
  543.                         var actualUrl = slide.src;
  544.                         var newUrl = slide.src + "?" + new Date().getTime();
  545.                         var thisImg = slide.$el.querySelector("img");
  546.                         
  547.                         //creating an xmlHTTP in order to show a loader while of the new rotated img is loaded
  548.                         var xmlHTTP = new XMLHttpRequest();
  549.                         xmlHTTP.open('GET', newUrl, true);
  550.                         //xmlHTTP.withCredentials = true;
  551.                         xmlHTTP.responseType = 'arraybuffer';
  552.                         xmlHTTP.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0");
  553.                         xmlHTTP.setRequestHeader("Expires", "Tue, 01 Jan 1980 1:00:00 GMT");
  554.                         xmlHTTP.setRequestHeader("Pragma", "no-cache"); 
  555.                         xmlHTTP.onload = function(e) {
  556.                             var blob = new Blob([this.response]);
  557.                             thisImg.src = window.URL.createObjectURL(blob);
  558.                             slide.src = newUrl;
  559.                             fancybox.hideLoading(slide);
  560.                         };
  561.                         xmlHTTP.onloadstart = function() {
  562.                             //fancybox.showLoading(slide);
  563.                             //updating the intial triggers
  564.                             var x =document.querySelectorAll("a.fancybox[href='"+actualUrl+"'], a.fancybox img[src='"+actualUrl+"']")
  565.                             var i;
  566.                             for (i = 0; i < x.length; i++) {
  567.                                 if (x[i].hasAttribute("src")) {      
  568.                                     x[i].src = newUrl;
  569.                                 } else {
  570.                                     x[i].href = newUrl;
  571.                                 }
  572.                                 
  573.                             }
  574.                         };
  575.                         //fancybox.showLoading(slide);
  576.                         xmlHTTP.send();   
  577.                         
  578.                     } else {
  579.                         toastr["error"]("Une erreur s'est produite. Veuillez réessayer ultérieurement...");
  580.                     }
  581.                 });
  582.             }
  583.         
  584.     } );
  585.     </script>
  586.     <script src="{{ asset('assets/js/custom.js') }}"></script>
  587.     <script src="{{ asset('assets/js/image-crop.js') }}"></script>
  588.     <!-- END GLOBAL MANDATORY SCRIPTS -->
  589.     <!-- BEGIN PAGE LEVEL PLUGINS/CUSTOM SCRIPTS -->
  590.     {% block javascripts %}{% endblock %}
  591.     <!-- BEGIN PAGE LEVEL PLUGINS/CUSTOM SCRIPTS -->
  592.     </body>
  593. </html>