templates/DemandeAchatVue/demandeAchat.html.twig line 1

Open in your IDE?
  1. {% extends 'layoutachat.html.twig' %}
  2. {% block stylesheets2 %}
  3. <link rel="stylesheet" href="{{ asset('css/bootstrap-datepicker.min.css') }}" type="text/css" />
  4. <style type="text/css">
  5. .custom-shadow {
  6. box-shadow: 0 8px 20px rgba(0,0,0,0.15);
  7. border-radius: 10px;
  8. transition: all 0.3s ease;
  9. }
  10. .custom-shadow:hover {
  11. box-shadow: 0 12px 30px rgba(0,0,0,0.25);
  12. transform: translateY(-3px);
  13. }
  14. select {
  15. font-size: 13px;
  16. font-weight: 600;
  17. letter-spacing: 0.3px;
  18. }
  19. .police {
  20. font-size: 13px;
  21. font-weight: 600;
  22. letter-spacing: 0.3px;
  23. }
  24. .modal-dialog {
  25. max-width: 570px; /* ajuste ici */
  26. height: 600px; /* ajuste ici */
  27. }
  28. .modal .form-control {
  29. height: calc(1.5em + .4rem + 2px);
  30. padding: .2rem .4rem;
  31. font-size: 0.85rem;
  32. }
  33. .modal-right {
  34. margin: 0;
  35. margin-left: auto; /* pousse le modal à droite */
  36. margin-right: 10px; /* petit espace du bord */
  37. }
  38. .taille {color:#006666;}
  39. .vert {color:green;}
  40. .rouge {color:red;}
  41. #listecom{
  42. width:550px;
  43. height:400px;
  44. overflow:auto;
  45. }
  46. .cre{
  47. margin-left:0px;
  48. padding-left:0px;
  49. padding-right:0px;
  50. }
  51. .limit{
  52. border:solid 1px #CCCCCC;
  53. height:100px;
  54. margin-right:10px;
  55. background-color:#FFFFFFF;
  56. box-shadow: 1px 1px 1px #656565;
  57. }
  58. .taille2{
  59. font-size: 10px;
  60. }
  61. #parente {
  62. width:1200px;
  63. }
  64. #match3, #match, #match2 {
  65. max-width:400px;
  66. height:100px;
  67. overflow:auto;
  68. }
  69. #li{
  70. color: #FF0000;
  71. }
  72. #bol{
  73. color: #000099;
  74. }
  75. /* ── MODAL GLOBAL ── */
  76. #infos .modal-content {
  77. border: none !important;
  78. border-radius: 16px !important;
  79. box-shadow: 0 25px 60px rgba(0,0,0,.2) !important;
  80. overflow: hidden;
  81. font-family: 'Nunito', sans-serif;
  82. }
  83. /* ── HEADER ── */
  84. #infos .modal-header {
  85. background: linear-gradient(135deg, #0f2942 0%, #1d6fa4 100%) !important;
  86. border-bottom: none !important;
  87. padding: 1.1rem 1.4rem !important;
  88. display: flex !important;
  89. align-items: center !important;
  90. justify-content: space-between !important;
  91. }
  92. .modal-header-left {
  93. display: flex; align-items: center; gap: .75rem;
  94. }
  95. .modal-header-icon {
  96. width: 40px; height: 40px;
  97. background: rgba(255,255,255,.2); border-radius: 10px;
  98. display: flex; align-items: center; justify-content: center;
  99. font-size: 1rem; color: #fff; flex-shrink: 0;
  100. }
  101. #infos .modal-title {
  102. font-size: .95rem !important; font-weight: 800 !important;
  103. color: #fff !important; margin: 0 !important;
  104. }
  105. .modal-subtitle {
  106. font-size: .72rem; color: rgba(255,255,255,.65); margin: 0;
  107. }
  108. .close-btn {
  109. width: 32px; height: 32px; border-radius: 8px;
  110. background: rgba(255,255,255,.15); border: none; color: #fff;
  111. display: flex; align-items: center; justify-content: center;
  112. font-size: .9rem; cursor: pointer; transition: background .15s; flex-shrink: 0;
  113. }
  114. .close-btn:hover { background: rgba(255,255,255,.3); }
  115. /* ── BODY ── */
  116. #infos .modal-body {
  117. padding: 0 !important;
  118. background: #f8fafc;
  119. }
  120. /* ── FORM SECTIONS ── */
  121. .form-section {
  122. background: #fff;
  123. border-radius: 12px;
  124. margin: 1rem 1.25rem;
  125. padding: 1.1rem 1.25rem;
  126. box-shadow: 0 1px 6px rgba(0,0,0,.06);
  127. border: 1px solid #e2e8f0;
  128. }
  129. .form-section-title {
  130. font-size: .75rem; font-weight: 800; text-transform: uppercase;
  131. letter-spacing: .09em; color: #1d6fa4;
  132. display: flex; align-items: center; gap: .4rem;
  133. margin-bottom: 1rem; padding-bottom: .6rem;
  134. border-bottom: 1px solid #e2e8f0;
  135. }
  136. /* ── LABELS & INPUTS ── */
  137. .field-label {
  138. font-size: .79rem; font-weight: 700; color: #374151;
  139. margin-bottom: .3rem; display: block;
  140. }
  141. .required-star { color: #dc2626; font-weight: 800; }
  142. .optional-tag {
  143. font-size: .68rem; font-weight: 600; color: #94a3b8;
  144. background: #f1f5f9; padding: .1rem .4rem; border-radius: 4px; margin-left: .3rem;
  145. }
  146. .da-form .da-input,
  147. .da-form .form-control {
  148. border-radius: 8px !important;
  149. border: 1.5px solid #e2e8f0 !important;
  150. font-family: 'Nunito', sans-serif !important;
  151. font-size: .84rem !important;
  152. color: #1e293b !important;
  153. background: #fff !important;
  154. transition: border-color .2s, box-shadow .2s;
  155. height: calc(1.5em + .75rem + 4px);
  156. }
  157. .da-form .da-input:focus,
  158. .da-form .form-control:focus {
  159. border-color: #1d6fa4 !important;
  160. box-shadow: 0 0 0 3px rgba(29,111,164,.15) !important;
  161. outline: none !important;
  162. }
  163. .da-form textarea.da-input { height: auto !important; }
  164. .da-form select.da-input { cursor: pointer; }
  165. /* Input avec icône */
  166. .input-icon-wrap { position: relative; }
  167. .input-icon {
  168. position: absolute; left: .75rem; top: 50%;
  169. transform: translateY(-50%); color: #94a3b8; font-size: .8rem; z-index: 1;
  170. }
  171. .da-form .with-icon { padding-left: 2.1rem !important; }
  172. /* ── BOUTONS ACTION ── */
  173. .action-buttons {
  174. display: flex; flex-direction: column; gap: .4rem; align-items: stretch;
  175. }
  176. .btn-da {
  177. display: flex; align-items: center; justify-content: center; gap: .35rem;
  178. padding: .5rem .85rem; border-radius: 8px; font-size: .78rem;
  179. font-weight: 700; font-family: 'Nunito', sans-serif;
  180. border: none; cursor: pointer; transition: all .15s; white-space: nowrap;
  181. }
  182. .btn-da-primary {
  183. background: linear-gradient(135deg, #0f2942, #1d6fa4);
  184. color: #fff;
  185. }
  186. .btn-da-primary:hover { filter: brightness(1.1); transform: translateY(-1px); }
  187. .btn-da-secondary {
  188. background: #f1f5f9; color: #64748b;
  189. border: 1.5px solid #e2e8f0 !important;
  190. }
  191. .btn-da-secondary:hover { background: #e2e8f0; color: #334155; }
  192. /* ── RESPONSIVE ── */
  193. @media (max-width: 767px) {
  194. .form-section { margin: .75rem; padding: .85rem; }
  195. #infos .modal-dialog { margin: .5rem; }
  196. .action-buttons { flex-direction: row; }
  197. }
  198. </style>
  199. {% endblock %}
  200. {% block section %}
  201. <div class="container-fluid mt-2">
  202. <div class="card shadow-sm p-2 mb-3">
  203. <div class="d-flex flex-wrap align-items-center justify-content-between">
  204. <div>
  205. <img src="{{ asset('img/demachat.jpg') }}" width="35">
  206. <strong>DEMANDE D'ACHAT</strong>
  207. </div>
  208. <div class="btn-group flex-wrap">
  209. <button data-toggle="modal" href="#infos" class="btn btn-info btn-sm">
  210. ➕ Nouveau
  211. </button>
  212. &nbsp;&nbsp;
  213. {% if is_granted('ROLE_LOGIS') or is_granted('ROLE_DAPPM') %}
  214. <button data-toggle="modal" href="#inf33" class="btn btn-secondary btn-sm">
  215. 📄 DA PPM
  216. </button>
  217. {% endif %}
  218. &nbsp;&nbsp;
  219. <button data-toggle="modal" href="#pss" class="btn btn-secondary btn-sm">
  220. 📁 DA fichier
  221. </button>
  222. &nbsp;&nbsp;
  223. <a href="{{ path('reception_achat') }}" class="btn btn-secondary btn-sm">
  224. 📥 Réception
  225. </a>
  226. &nbsp;&nbsp;
  227. </div>
  228. </div>
  229. </div>
  230. </div>
  231. <div class="container-fluid">
  232. <div class="card p-3 shadow-sm mb-3">
  233. <!-- FILTRES -->
  234. <div class="row mt-2">
  235. <div class="col-md-4 mb-2">
  236. {{ form_widget(form6.user)}}
  237. <img id="loduse" src="{{ asset('img/loders.gif')}}" width="20">
  238. {{ form_widget(form6.listnum4)}}
  239. </div>
  240. <div class="col-md-4 mb-2">
  241. {{ form_widget(form8.usebaille)}}
  242. <img id="lodbail" src="{{ asset('img/loders.gif')}}" width="20">
  243. {{ form_widget(form8.listnum6)}}
  244. </div>
  245. <div class="col-md-2 mb-2">
  246. {{ form_widget(form110.listnum55) }}
  247. </div>
  248. </div>
  249. </div>
  250. </div>
  251. <div class="container-fluid">
  252. <div class="row text-center">
  253. <div class="col-6 col-md-2 mb-2">
  254. <div class="card p-3 custom-shadow text-center">
  255. <div class=" police" >Mes DAs</div>
  256. <span class=" taille" > <h3>{{ nbmesda }}</h3></span>
  257. <form id="monlistnum9" action="{{ path('mstopes_gestion_demande_achat') }}" method="post">
  258. <div class="mt-2">
  259. {{ form_widget(form9.listnum9) }}
  260. </div>
  261. </form>
  262. </div>
  263. </div>
  264. <div class="col-6 col-md-2 mb-2">
  265. <div class="card p-3 custom-shadow">
  266. <div class=" police">DA à mon niveau</div>
  267. <h3>{{ nbdanivo }}</h3>
  268. <form id="monlistnum2" action="{{ path('mstopes_gestion_demande_achat') }}" method="post">
  269. <div class="mt-2">
  270. {{ form_widget(form4.listnum2) }}
  271. </div>
  272. </form>
  273. </div>
  274. </div>
  275. <div class="col-6 col-md-2 mb-2">
  276. <div class="card p-3 custom-shadow">
  277. <div class=" police">DAs que j'ai Validé</div>
  278. <span class="vert" > <h3>{{ nbdavalid }}</h3> </span >
  279. <form id="monlistnum3" action="{{ path('mstopes_gestion_demande_achat') }}" method="post">
  280. <div class="mt-2">
  281. {{ form_widget(form5.listnum3) }}
  282. </div>
  283. </form>
  284. </div>
  285. </div>
  286. <div class="col-6 col-md-2 mb-2">
  287. <div class="card p-3 custom-shadow">
  288. <div class=" police">DAs que j'ai Rejeté</div>
  289. <span class="rouge" > <h3>{{ nbdarejet }}</h3> </span>
  290. <form id="monlistnum7" action="{{ path('mstopes_gestion_demande_achat') }}" method="post">
  291. <div class="mt-2">
  292. {{ form_widget(form7.listnum7) }}
  293. </div>
  294. </form>
  295. </div>
  296. </div>
  297. {% if is_granted('ROLE_VU_ALL') %}
  298. <div class="col-6 col-md-2 mb-2">
  299. <div class="card p-3 custom-shadow">
  300. <div class=" police">Toute DAs </div>
  301. <span > <h3>{{ nballda }}</h3> </span>
  302. <div class="mt-2">
  303. {{ form_widget(form2.listnum)}}
  304. </div>
  305. </div>
  306. </div>
  307. <div class="col-6 col-md-2 mb-2">
  308. <div class="card p-3 custom-shadow">
  309. <div class=" police">- </div>
  310. <span > <h3>-</h3> </span>
  311. <div class="mt-2">
  312. -
  313. </div>
  314. </div>
  315. </div>
  316. {% endif %}
  317. </div>
  318. </div>
  319. <!-- TABLE / CONTENU -->
  320. <div class=" mt-1" align="center">
  321. <img src="{{ asset('img/load.gif')}}" id="load" />
  322. <div id="liste">
  323. </div>
  324. </div>
  325. {# ── MODAL : Créer une DA ── #}
  326. <div class="modal fade" id="infos" tabindex="-1" role="dialog" aria-labelledby="infosLabel" aria-hidden="true">
  327. <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable" role="document">
  328. <div class="modal-content">
  329. {# ── HEADER ── #}
  330. <div class="modal-header">
  331. <div class="modal-header-left">
  332. <div class="modal-header-icon">
  333. <i class="fas fa-file-alt"></i>
  334. </div>
  335. <div>
  336. <h5 class="modal-title" id="infosLabel">Créer une Demande d'Achat</h5>
  337. <p class="modal-subtitle">Remplissez les champs obligatoires <span class="required-star">*</span></p>
  338. </div>
  339. </div>
  340. <button type="button" class="close-btn" data-dismiss="modal" aria-label="Close">
  341. <i class="fas fa-times"></i>
  342. </button>
  343. </div>
  344. {# ── BODY ── #}
  345. <div class="modal-body">
  346. {{ form_start(form, {
  347. 'action': path('mstopes_gestion_demande_achat'),
  348. 'attr': {'id': 'monForms', 'class': 'da-form'}
  349. }) }}
  350. {# ── Section : Informations générales ── #}
  351. <div class="form-section">
  352. <div class="form-section-title">
  353. <i class="fas fa-info-circle"></i> Informations générales
  354. </div>
  355. <div class="form-row">
  356. <div class="form-group col-md-6">
  357. <label class="field-label">
  358. Région <span class="required-star">*</span>
  359. </label>
  360. {{ form_widget(form.region1, {'attr': {'class': 'form-control da-input'}}) }}
  361. </div>
  362. <div class="form-group col-md-6">
  363. <label class="field-label">Objet</label>
  364. {{ form_widget(form.obje, {'attr': {'class': 'form-control da-input'}}) }}
  365. </div>
  366. <div class="form-group col-md-6">
  367. <label class="field-label">
  368. Centre de Coût <span class="required-star">*</span>
  369. </label>
  370. {{ form_widget(form.centreCou, {'attr': {'class': 'form-control da-input'}}) }}
  371. </div>
  372. <div class="form-group col-md-6">
  373. <label class="field-label">
  374. Nom du Projet <span class="required-star">*</span>
  375. </label>
  376. {{ form_widget(form.baille, {'attr': {'class': 'form-control da-input'}}) }}
  377. </div>
  378. </div>
  379. </div>
  380. {# ── Section : Détails de la commande ── #}
  381. <div class="form-section">
  382. <div class="form-section-title">
  383. <i class="fas fa-shopping-cart"></i> Détails de la commande
  384. </div>
  385. <div class="form-row">
  386. <div class="form-group col-md-6">
  387. <label class="field-label">Délais de livraison souhaité</label>
  388. {{ form_widget(form.delais, {'attr': {'class': 'form-control da-input', 'autocomplete': 'off' }}) }}
  389. </div>
  390. <div class="form-group col-md-6">
  391. <label class="field-label">
  392. Quantité demandée <span class="required-star">*</span>
  393. </label>
  394. {{ form_widget(form.quantDemand, {'attr': {'class': 'form-control da-input', 'min': '1'}}) }}
  395. </div>
  396. <div class="form-group col-md-6">
  397. <label class="field-label">
  398. Prix Unitaire <span class="required-star">*</span>
  399. </label>
  400. <div class="input-icon-wrap">
  401. <i class="fas fa-coins input-icon"></i>
  402. {{ form_widget(form.prixUnit, {'attr': {'class': 'form-control da-input with-icon'}}) }}
  403. </div>
  404. </div>
  405. <div class="form-group col-md-6">
  406. <label class="field-label">Description <span class="optional-tag">Optionnel</span></label>
  407. {{ form_widget(form.descript, {'attr': {'class': 'form-control da-input', 'rows': '2'}}) }}
  408. </div>
  409. </div>
  410. </div>
  411. {# ── Section : Désignation ── #}
  412. <div class="form-section">
  413. <div class="form-section-title">
  414. <i class="fas fa-tag"></i> Désignation de l'article
  415. </div>
  416. <div class="form-row align-items-end">
  417. <div class="form-group col-md-9 mb-0">
  418. <label class="field-label">
  419. Désignation <span class="required-star">*</span>
  420. </label>
  421. <div style="position:relative;">
  422. <i class="fas fa-search" style="position:absolute;left:.75rem;top:50%;transform:translateY(-50%);color:#94a3b8;font-size:.8rem;z-index:1;"></i>
  423. {{ form_widget(form.designrech, {
  424. 'attr': {
  425. 'class': 'form-control da-input',
  426. 'style': 'padding-left:2.1rem;',
  427. 'autocomplete': 'off',
  428. 'placeholder': 'Rechercher une désignation…'
  429. }
  430. }) }}
  431. </div>
  432. <div id="match" class="mt-1"></div>
  433. </div>
  434. <div class="form-group col-md-3 mb-0">
  435. <div class="action-buttons">
  436. <img id="loders" src="{{ asset('img/loders.gif')}}" width="32"
  437. style="display:none; margin-bottom:.4rem;">
  438. <button type="submit" id="but" class="btn-da btn-da-primary">
  439. <i class="fas fa-plus-circle"></i> Ajouter
  440. </button>
  441. <button type="button" id="but2" class="btn-da btn-da-secondary">
  442. <i class="fas fa-plus"></i> Ajouter
  443. </button>
  444. </div>
  445. </div>
  446. </div>
  447. </div>
  448. {{ form_end(form, {'render_rest': false}) }}
  449. </div>{# end modal-body #}
  450. </div>
  451. </div>
  452. </div>
  453. <div class="modal fade" id="inf33" tabindex="-1" role="dialog" aria-labelledby="inf33Label" aria-hidden="true">
  454. <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable" modal-right" role="document">
  455. <div class="modal-content">
  456. <!-- HEADER -->
  457. <div class="modal-header">
  458. <h5 class="modal-title" id="inf33Label">Ajouter un item</h5>
  459. <button type="button" class="close" data-dismiss="modal">
  460. <span>&times;</span>
  461. </button>
  462. </div>
  463. <!-- BODY -->
  464. <div class="modal-body">
  465. {{ form_start(form33, {
  466. 'action': path('mstopes_gestion_demande_achat'),
  467. 'attr': {'id': 'monFormul33', 'class': 'monForm'}
  468. }) }}
  469. <div class="container-fluid">
  470. <div class="form-row">
  471. <div class="form-group col-md-6">
  472. <label>Objet</label>
  473. {{ form_widget(form33.obje2, {'attr': {'class': 'form-control'}}) }}
  474. </div>
  475. <div class="form-group col-md-6">
  476. <label>Nom de Projet</label>
  477. {{ form_widget(form33.baille2, {'attr': {'class': 'form-control'}}) }}
  478. </div>
  479. <div class="form-group col-md-6">
  480. <label>Quantité Demandée</label>
  481. {{ form_widget(form33.quantd2, {'attr': {'class': 'form-control'}}) }}
  482. </div>
  483. <div class="form-group col-md-6">
  484. <label>Prix Unitaire</label>
  485. {{ form_widget(form33.prixUni2, {'attr': {'class': 'form-control'}}) }}
  486. </div>
  487. <div class="form-group col-md-6">
  488. <label>Designation</label>
  489. {{ form_widget(form33.design2, {
  490. 'attr': {
  491. 'class': 'form-control ui-autocomplete-input',
  492. 'autocomplete': 'off'
  493. }
  494. }) }}
  495. <div id="match3" class="mt-1"></div>
  496. </div>
  497. <div class="form-group col-md-6">
  498. <label>Description</label>
  499. {{ form_widget(form33.descrip2, {'attr': {'class': 'form-control'}}) }}
  500. </div>
  501. </div>
  502. </div>
  503. <!-- FOOTER -->
  504. <div class="d-flex justify-content-between align-items-center mt-3">
  505. <img id="loa" src="{{ asset('img/loders.gif')}}" width="50">
  506. <div>
  507. <button type="submit" id="button" class="btn btn-primary">
  508. Ajouter Item
  509. </button>
  510. <button type="button" id="button2" class="btn btn-secondary">
  511. Ajouter Item
  512. </button>
  513. </div>
  514. {{ form_end(form, {'render_rest': false}) }}
  515. </div>
  516. </div>
  517. </div>
  518. </div>
  519. </div>
  520. <div class="modal fade" id="pss" tabindex="-1" role="dialog" aria-labelledby="pssLabel" aria-hidden="true">
  521. <div class="modal-dialog modal-dialog-centered" role="document">
  522. <div class="modal-content">
  523. <!-- HEADER -->
  524. <div class="modal-header">
  525. <h5 class="modal-title" id="pssLabel">Importer un fichier</h5>
  526. <!-- Bouton télécharger -->
  527. <a href="{{ path('download_file_DA', {'id_ap': admin.images.id}) }}"
  528. class="btn btn-info btn-sm ml-3">
  529. Télécharger modèle
  530. </a>
  531. <button type="button" class="close ml-auto" data-dismiss="modal">
  532. <span>&times;</span>
  533. </button>
  534. </div>
  535. <!-- BODY -->
  536. <div class="modal-body">
  537. {{ form_start(form01, {
  538. 'action': path('mstopes_gestion_demande_achat'),
  539. 'attr': {'id': 'monForms', 'class': 'monForm'}
  540. }) }}
  541. <div class="form-group">
  542. {{ form_widget(form01.fiche, {'attr': {'class': 'form-control-file'}}) }}
  543. </div>
  544. <!-- FOOTER -->
  545. <div class="d-flex justify-content-center">
  546. <button type="submit" class="btn btn-primary">
  547. OK
  548. </button>
  549. </div>
  550. {{ form_end(form, {'render_rest': false}) }}
  551. </div>
  552. </div>
  553. </div>
  554. </div>
  555. <div class="modal fade" id="inf" tabindex="-1" role="dialog" aria-labelledby="infLabel" aria-hidden="true">
  556. <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable" role="document">
  557. <div class="modal-content">
  558. <!-- HEADER -->
  559. <div class="modal-header">
  560. <h5 class="modal-title" id="infLabel">Modifier / Ajouter</h5>
  561. <button type="button" class="close" data-dismiss="modal">
  562. <span>&times;</span>
  563. </button>
  564. </div>
  565. <!-- BODY -->
  566. <div class="modal-body">
  567. {{ form_start(form3, {
  568. 'action': path('mstopes_gestion_demande_achat'),
  569. 'attr': {'id': 'monFormul', 'class': 'monForm'}
  570. }) }}
  571. <div class="container-fluid">
  572. <div class="form-row">
  573. <div class="form-group col-md-6">
  574. <label>Nom de Projet</label>
  575. {{ form_widget(form3.bailleu, {'attr': {'class': 'form-control'}}) }}
  576. </div>
  577. <div class="form-group col-md-6">
  578. <label>Centre Cout</label>
  579. {{ form_widget(form3.centreCo, {'attr': {'class': 'form-control'}}) }}
  580. </div>
  581. <div class="form-group col-md-6">
  582. <label>Quantité Demandée</label>
  583. {{ form_widget(form3.quantd, {'attr': {'class': 'form-control'}}) }}
  584. </div>
  585. <div class="form-group col-md-6">
  586. <label>Prix Unitaire</label>
  587. {{ form_widget(form3.prixUni, {'attr': {'class': 'form-control'}}) }}
  588. </div>
  589. <div class="form-group col-md-6">
  590. <label>Description</label>
  591. {{ form_widget(form3.descrip, {'attr': {'class': 'form-control'}}) }}
  592. </div>
  593. <div class="form-group col-md-10">
  594. <label>Designation</label>
  595. {{ form_widget(form3.design, {
  596. 'attr': {
  597. 'class': 'form-control ui-autocomplete-input',
  598. 'autocomplete': 'off'
  599. }
  600. }) }}
  601. <div id="match2" class="mt-1"></div>
  602. </div>
  603. <div class="form-group col-md-2">
  604. <img id="lodes" src="{{ asset('img/loders.gif')}}" width="50">
  605. <button type="submit" id="buton" class="btn btn-primary"> Valider </button>
  606. </div>
  607. </div>
  608. </div>
  609. <!-- FOOTER -->
  610. <div class="d-flex justify-content-between align-items-center mt-3">
  611. </div>
  612. {{ form_end(form, {'render_rest': false}) }}
  613. </div>
  614. </div>
  615. </div>
  616. </div>
  617. {% endblock %}
  618. {% block js %}
  619. <script type="text/javascript" src="{{ asset('js/bootstrap-datepicker.min.js')}}"></script>
  620. <script type="text/javascript" src="{{ asset('js/da-offline.js') }}"></script>
  621. <script>
  622. DAOffline.init({
  623. routes: {
  624. ajouterTemp : '{{ path("api_da_ajouter_temp") }}',
  625. ajoutDesign : '{{ path("api_da_ajout_design_temp") }}',
  626. daEnvoyer : '{{ path("api_da_envoyer") }}',
  627. importExcel : '{{ path("api_da_import_excel") }}',
  628. }
  629. });
  630. </script>
  631. <script>
  632. /**
  633. * Mise en cache des données de référence pour le mode offline
  634. * (catalogue, centres de coût, bailleurs)
  635. * Exécuté une fois à chaque visite online, stocke dans IndexedDB
  636. */
  637. (async function cacheReferences() {
  638. if (!navigator.onLine) return;
  639. if (!('indexedDB' in window)) return;
  640. // Ne rafraîchir que toutes les 12h maximum
  641. const lastCache = localStorage.getItem('da_references_cached_at');
  642. if (lastCache) {
  643. const diff = Date.now() - parseInt(lastCache);
  644. if (diff < 12 * 60 * 60 * 1000) return; // moins de 12h → skip
  645. }
  646. try {
  647. const resp = await fetch('{{ path("api_da_references") }}', {
  648. credentials: 'include'
  649. });
  650. if (!resp.ok) return;
  651. const data = await resp.json();
  652. if (!data.success) return;
  653. // Ouvrir IndexedDB (même base que da-shell.html)
  654. const db = await new Promise((resolve, reject) => {
  655. const r = indexedDB.open('erp_da_offline', 2);
  656. r.onsuccess = e => resolve(e.target.result);
  657. r.onerror = () => reject();
  658. r.onupgradeneeded = e => {
  659. const d = e.target.result;
  660. // Stores avec keyPath 'localId' (cohérent avec da-offline.js)
  661. ['pending_temp', 'pending_envoi', 'pending_excel', 'brouillons_locaux'].forEach(name => {
  662. if (!d.objectStoreNames.contains(name))
  663. d.createObjectStore(name, { keyPath: 'localId', autoIncrement: true });
  664. });
  665. // Stores avec keyPath 'id' (pour les caches de référence)
  666. ['catalogue_cache', 'centrecout_cache', 'bailleur_cache'].forEach(name => {
  667. if (!d.objectStoreNames.contains(name))
  668. d.createObjectStore(name, { keyPath: 'id' });
  669. });
  670. };
  671. });
  672. // Fonction helper pour vider et repeupler un store
  673. async function replaceStore(storeName, items, keyField = 'id') {
  674. return new Promise((resolve, reject) => {
  675. const tx = db.transaction(storeName, 'readwrite');
  676. const store = tx.objectStore(storeName);
  677. store.clear();
  678. items.forEach(item => store.put(item));
  679. tx.oncomplete = resolve;
  680. tx.onerror = reject;
  681. });
  682. }
  683. // Normaliser les clés (Doctrine retourne parfois des indices numériques)
  684. const catalogue = data.catalogue.map(c => ({
  685. id : c.id,
  686. designation : c.designation,
  687. prix : 0, // ← 0 par défaut, sera saisi manuellement
  688. }));
  689. const centres = data.centres.map(c => ({
  690. id : c.id,
  691. libele: c.libele,
  692. }));
  693. const bailleurs = data.bailleurs.map(b => ({
  694. id : b.id,
  695. libele: b.libele,
  696. }));
  697. await Promise.all([
  698. replaceStore('catalogue_cache', catalogue),
  699. replaceStore('centrecout_cache', centres),
  700. replaceStore('bailleur_cache', bailleurs),
  701. ]);
  702. localStorage.setItem('da_references_cached_at', Date.now().toString());
  703. console.log('[DA Offline] Références mises en cache :',
  704. catalogue.length, 'articles,',
  705. centres.length, 'centres,',
  706. bailleurs.length, 'bailleurs'
  707. );
  708. } catch (e) {
  709. console.warn('[DA Offline] Impossible de mettre les références en cache:', e);
  710. }
  711. })();
  712. </script>
  713. <script>
  714. $(document).ready(function() {
  715. $('#but').click(function(e)
  716. { e.preventDefault();
  717. var region = $('#form_region1').val();
  718. // Vérifie si le champ est vide
  719. if (!region.trim()) {
  720. $('#form_region1').focus();
  721. return false;
  722. }
  723. var centreCou = $('#form_centreCou').val();
  724. // Vérifie si le champ est vide
  725. if (!centreCou.trim()) {
  726. $('#form_centreCou').focus();
  727. return false;
  728. }
  729. var baille = $('#form_baille').val();
  730. if (!baille.trim()) {
  731. $('#form_baille').focus();
  732. return false;
  733. }
  734. $("#but").prop("disabled",true);
  735. $("#loders").show();
  736. $.ajax({
  737. type : 'POST',
  738. url : '{{ path('ajouter_achat_temp')}}',
  739. data : 'centreCout=' + $("#form_centreCou").val()+
  740. '&bailleur=' + $("#form_baille").val()+
  741. '&quantDemand=' + $("#form_quantDemand").val()+
  742. '&prixUnit=' + $("#form_prixUnit").val()+
  743. '&obje=' + $("#form_obje").val()+
  744. '&delais=' + $("#form_delais").val()+
  745. '&descrip=' + $("#form_descript").val()+
  746. '&region=' + $("#form_region1").val()+
  747. '&iddesignrech=' + $("#form_designrech").val(),
  748. success: function(data)
  749. {
  750. alert('ajout effectué avec succes');
  751. $("#loders").hide();
  752. $("#but").hide();
  753. $("#but2").show();
  754. $("#obj").hide();
  755. $("#del").hide();
  756. $("#reg").hide();
  757. $("#form_quantDeman").val("");
  758. $("#form_prixUnit").val("");
  759. $("#form_designrech").val("");
  760. $("#form_descript").val("");
  761. $('#liste').html(data);
  762. }
  763. });
  764. });
  765. });
  766. </script>
  767. <script>
  768. $("#load").hide();
  769. $("#but2").hide();
  770. $("#loders").hide();
  771. $("#lodes").hide();
  772. $("#button2").hide();
  773. $("#loa").hide();
  774. $("#loduse").hide();
  775. $("#lodbail").hide();
  776. </script>
  777. <script>
  778. $("#load2").hide();
  779. </script>
  780. <script>
  781. $("#form_date1_day").hide();
  782. $("#form_date2_day").hide();
  783. </script>
  784. <script>
  785. $(document).ready(function() {
  786. $('#form_listnum').change(function()
  787. {
  788. $("#load").show();
  789. $.ajax({
  790. type : 'POST',
  791. url : '{{ path('ajax_liste_demachat')}}',
  792. data : 'listnum=' + $('#form_listnum').val(),
  793. })
  794. .done(function(response)
  795. {
  796. $("#load").hide();
  797. $('#liste').html(response);
  798. })
  799. .fail(function(jqXHR, textStatus, errorThrown)
  800. {
  801. $("#load").hide();
  802. alert('Error : ' + errorThrown);
  803. });
  804. return false;
  805. });
  806. });
  807. </script>
  808. <script>
  809. $('#monFormul').submit(function(e)
  810. { e.preventDefault();
  811. $("#buton").prop("disabled",true);
  812. $("#lodes").show();
  813. $.ajax({
  814. type : 'POST',
  815. url : '{{ path('ajax_ajout_design_achat')}}',
  816. data : 'quantDemand=' + $("#form_quantd").val()+
  817. '&prixUni=' + $("#form_prixUni").val()+
  818. '&listnum=' + $("#form_listnum").val()+
  819. '&listnum2=' + $('#form_listnum2').val()+
  820. '&listnum1=' + $('#form_listnum1').val()+
  821. '&listnum5=' + $('#form_listnum5').val()+
  822. '&listnum4=' + $('#form_listnum4').val()+
  823. '&listnum3=' + $('#form_listnum3').val()+
  824. '&listnum7=' + $('#form_listnum7').val()+
  825. '&listnum9=' + $('#form_listnum9').val()+
  826. '&centreCout=' + $("#form_centreCo").val()+
  827. '&bailleur=' + $("#form_bailleu").val()+
  828. '&descrip=' + $("#form_descrip").val()+
  829. '&designation=' + $("#form_design").val(),
  830. success: function(data)
  831. {
  832. $("#lodes").hide();
  833. $("#buton").prop("disabled",false);
  834. $('#liste').html(data);
  835. $("#form_design").val("");
  836. $("#form_quantd").val("");
  837. $("#form_prixUni").val("");
  838. }
  839. });
  840. });
  841. </script>
  842. <script>
  843. $('#monlistnum2').change(function()
  844. {
  845. $("#load").show();
  846. $.ajax({
  847. type : 'POST',
  848. url : '{{ path('ajax_liste_demachat')}}',
  849. data : 'listnum=' + $('#form_listnum2').val(),
  850. })
  851. .done(function(response)
  852. {
  853. $("#load").hide();
  854. $('#liste').html(response);
  855. })
  856. .fail(function(jqXHR, textStatus, errorThrown)
  857. {
  858. $("#load").hide();
  859. alert('Error : ' + errorThrown);
  860. });
  861. return false;
  862. });
  863. </script>
  864. <script>
  865. $('#monlistnum3').change(function()
  866. {
  867. $("#load").show();
  868. $.ajax({
  869. type : 'POST',
  870. url : '{{ path('ajax_liste_demachat')}}',
  871. data : 'listnum=' + $('#form_listnum3').val(),
  872. })
  873. .done(function(response)
  874. {
  875. $("#load").hide();
  876. $('#liste').html(response);
  877. })
  878. .fail(function(jqXHR, textStatus, errorThrown)
  879. {
  880. $("#load").hide();
  881. alert('Error : ' + errorThrown);
  882. });
  883. return false;
  884. });
  885. </script>
  886. <script>
  887. $("#form_user").change(function() {
  888. $("#loduse").show();
  889. $.ajax({
  890. type: 'POST',
  891. url: '{{ path('ajax_listnum4') }}',
  892. data: 'id=' + $(this).val(),
  893. success: function(response)
  894. {
  895. $("#loduse").hide();
  896. $('#form_listnum4').find("option").remove();
  897. $.each(response, function(i, item) {
  898. $('#form_listnum4').append(new Option(item, i));
  899. });
  900. }
  901. });
  902. });
  903. </script>
  904. <script>
  905. $('#form_listnum4').change(function()
  906. {
  907. $("#load").show();
  908. $.ajax({
  909. type : 'POST',
  910. url : '{{ path('ajax_liste_demachat')}}',
  911. data : 'listnum=' + $(this).val(),
  912. })
  913. .done(function(response)
  914. {
  915. $("#load").hide();
  916. $('#liste').html(response);
  917. })
  918. .fail(function(jqXHR, textStatus, errorThrown)
  919. {
  920. $("#load").hide();
  921. alert('Error : ' + errorThrown);
  922. });
  923. return false;
  924. });
  925. </script>
  926. <script>
  927. $("#form_usebaille").change(function() {
  928. $("#lodbail").show();
  929. $.ajax({
  930. type: 'POST',
  931. url: '{{ path('ajax_listnum6') }}',
  932. data: 'id=' + $(this).val(),
  933. success: function(response)
  934. {
  935. $("#lodbail").hide();
  936. $('#form_listnum6').find("option").remove();
  937. $.each(response, function(i, item) {
  938. $('#form_listnum6').append(new Option(item, i));
  939. });
  940. }
  941. });
  942. });
  943. </script>
  944. <script>
  945. $('#form_listnum6 , #form_listnum55').change(function()
  946. {
  947. $("#load").show();
  948. $.ajax({
  949. type : 'POST',
  950. url : '{{ path('ajax_liste_demachat')}}',
  951. data : 'listnum=' + $(this).val(),
  952. })
  953. .done(function(response)
  954. {
  955. $("#load").hide();
  956. $('#liste').html(response);
  957. })
  958. .fail(function(jqXHR, textStatus, errorThrown)
  959. {
  960. $("#load").hide();
  961. alert('Error : ' + errorThrown);
  962. });
  963. return false;
  964. });
  965. </script>
  966. <script>
  967. var loader = "{{ asset('img/loder.gif') }}";
  968. $(document).ready(function(){
  969. $("#form_designrech").on('keyup', function() {
  970. var input = $(this).val();
  971. if (input.length >= 1) {
  972. // ── OFFLINE : chercher dans IndexedDB ────────────────────
  973. if (!navigator.onLine) {
  974. DAOffline.searchCatalogue(input, function(html) {
  975. $('#match').html(html);
  976. $('#matchList li').on('click', function() {
  977. $('#form_designrech').val($(this).text());
  978. $('#match').text('');
  979. });
  980. });
  981. return;
  982. }
  983. // ── ONLINE : comportement AJAX existant ──────────────────
  984. var data = {input: input};
  985. $.ajax({
  986. type : "POST",
  987. url : '{{ path('ajax_autocomplete_design')}}',
  988. data : data,
  989. dataType: 'json',
  990. timeout : 3000,
  991. success : function(response){
  992. $('#match').html(response.countryList);
  993. $('#matchList li').on('click', function() {
  994. $('#form_designrech').val($(this).text());
  995. $('#match').text('');
  996. });
  997. },
  998. error: function() {
  999. $('#match').text('Probleme de connexion internet!');
  1000. }
  1001. });
  1002. } else {
  1003. $('#match').text('');
  1004. }
  1005. });
  1006. });
  1007. </script>
  1008. <script>
  1009. var loader = "{{ asset('img/loder.gif') }}";
  1010. $(document).ready(function(){
  1011. $("#form_design").on('keyup', function() {
  1012. var input = $(this).val();
  1013. if ( input.length >= 1 ) {
  1014. //$('#match2').html('<img src="' + window.loader + '" />');
  1015. var data = {input: input};
  1016. $.ajax({
  1017. type: "POST",
  1018. url:'{{ path('ajax_autocomplete_design')}}',
  1019. data: data,
  1020. dataType: 'json',
  1021. timeout: 3000,
  1022. success: function(response){
  1023. $('#match2').html(response.countryList);
  1024. $('#matchList li').on('click', function() {
  1025. $('#form_design').val($(this).text());
  1026. $('#match2').text('');
  1027. });
  1028. },
  1029. error: function() {
  1030. $('#match2').text('Problem de connexion internet!');
  1031. }
  1032. });
  1033. } else {
  1034. $('#match2').text('');
  1035. }
  1036. });
  1037. });
  1038. </script>
  1039. <script>
  1040. $('#form_delais').datepicker({
  1041. language: 'fr',
  1042. format: 'dd/mm/yyyy',
  1043. startDate: new Date(), // Empêche la sélection de dates antérieures à aujourd'hui
  1044. autoclose: true, // Ferme automatiquement le calendrier après sélection
  1045. todayHighlight: true // Met en surbrillance la date du jour
  1046. });
  1047. </script>
  1048. <script>
  1049. $(document).ready(function() {
  1050. $('#but2').click(function(e)
  1051. { e.preventDefault();
  1052. var baille = $('#form_baille').val();
  1053. if (!baille.trim()) {
  1054. $('#form_baille').focus();
  1055. return false;
  1056. }
  1057. var quant = $('#form_quantDemand').val();
  1058. if (!quant.trim()) {
  1059. $('#form_quantDemand').focus();
  1060. return false;
  1061. }
  1062. var prix = $('#form_prixUnit').val();
  1063. if (!prix.trim()) {
  1064. $('#form_prixUnit').focus();
  1065. return false;
  1066. }
  1067. $("#but2").prop("disabled",true);
  1068. $("#loders").show();
  1069. $.ajax({
  1070. type : 'POST',
  1071. url : '{{ path('ajout_design_da_temp')}}',
  1072. data : 'quantDemand=' + $("#form_quantDemand").val()+
  1073. '&bailleur=' + $("#form_baille").val()+
  1074. '&prixUnit=' + $("#form_prixUnit").val()+
  1075. '&descrip=' + $("#form_descript").val()+
  1076. '&centreCout=' + $("#form_centreCou").val()+
  1077. '&iddesignrech=' + $("#form_designrech").val(),
  1078. success: function(data)
  1079. {
  1080. alert('ajout effectué avec succes');
  1081. $("#loders").hide();
  1082. $("#form_quantDemand").val("");
  1083. $("#form_prixUnit").val("");
  1084. $("#form_designrech").val("");
  1085. $("#form_descript").val("");
  1086. $("#but2").prop("disabled",false);
  1087. $('#liste').html(data);
  1088. }
  1089. });
  1090. });
  1091. });
  1092. </script>
  1093. <script>
  1094. $('#monlistnum7').change(function()
  1095. {
  1096. $("#load").show();
  1097. $.ajax({
  1098. type : 'POST',
  1099. url : '{{ path('ajax_liste_demachat')}}',
  1100. data : 'listnum=' + $('#form_listnum7').val(),
  1101. })
  1102. .done(function(response)
  1103. {
  1104. $("#load").hide();
  1105. $('#liste').html(response);
  1106. })
  1107. .fail(function(jqXHR, textStatus, errorThrown)
  1108. {
  1109. $("#load").hide();
  1110. alert('Error : ' + errorThrown);
  1111. });
  1112. return false;
  1113. });
  1114. </script>
  1115. <script>
  1116. $('#monlistnum9').change(function()
  1117. {
  1118. $("#load").show();
  1119. $.ajax({
  1120. type : 'POST',
  1121. url : '{{ path('ajax_liste_demachat')}}',
  1122. data : 'listnum=' + $('#form_listnum9').val(),
  1123. })
  1124. .done(function(response)
  1125. {
  1126. $("#load").hide();
  1127. $('#liste').html(response);
  1128. })
  1129. .fail(function(jqXHR, textStatus, errorThrown)
  1130. {
  1131. $("#load").hide();
  1132. alert('Error : ' + errorThrown);
  1133. });
  1134. return false;
  1135. });
  1136. </script>
  1137. <script>
  1138. $('#monlistnum1').change(function()
  1139. {
  1140. $("#load").show();
  1141. $.ajax({
  1142. type : 'POST',
  1143. url : '{{ path('ajax_liste_demachat')}}',
  1144. data : 'listnum=' + $('#form_listnum1').val(),
  1145. })
  1146. .done(function(response)
  1147. {
  1148. $("#load").hide();
  1149. $('#liste').html(response);
  1150. })
  1151. .fail(function(jqXHR, textStatus, errorThrown)
  1152. {
  1153. $("#load").hide();
  1154. alert('Error : ' + errorThrown);
  1155. });
  1156. return false;
  1157. });
  1158. </script>
  1159. <script>
  1160. $('#monlistnum5').change(function()
  1161. {
  1162. $("#load").show();
  1163. $.ajax({
  1164. type : 'POST',
  1165. url : '{{ path('ajax_liste_demachat')}}',
  1166. data : 'listnum=' + $('#form_listnum5').val(),
  1167. })
  1168. .done(function(response)
  1169. {
  1170. $("#load").hide();
  1171. $('#liste').html(response);
  1172. })
  1173. .fail(function(jqXHR, textStatus, errorThrown)
  1174. {
  1175. $("#load").hide();
  1176. alert('Error : ' + errorThrown);
  1177. });
  1178. return false;
  1179. });
  1180. </script>
  1181. <script>
  1182. $("#form_usebaille").change(function() {
  1183. $.ajax({
  1184. type: 'POST',
  1185. url: '{{ path('ajax_listnum6') }}',
  1186. data: 'id=' + $(this).val(),
  1187. success: function(response)
  1188. {
  1189. $('#form_listnum6').find("option").remove();
  1190. $.each(response, function(i, item) {
  1191. $('#form_listnum6').append(new Option(item, i));
  1192. });
  1193. }
  1194. });
  1195. });
  1196. </script>
  1197. <script>
  1198. $('#form_listnum6').change(function()
  1199. {
  1200. $("#load").show();
  1201. $.ajax({
  1202. type : 'POST',
  1203. url : '{{ path('ajax_liste_demachat')}}',
  1204. data : 'listnum=' + $(this).val(),
  1205. })
  1206. .done(function(response)
  1207. {
  1208. $("#load").hide();
  1209. $('#liste').html(response);
  1210. })
  1211. .fail(function(jqXHR, textStatus, errorThrown)
  1212. {
  1213. $("#load").hide();
  1214. alert('Error : ' + errorThrown);
  1215. });
  1216. return false;
  1217. });
  1218. </script>
  1219. <script>
  1220. $(document).ready(function() {
  1221. $('#button2').click(function(e)
  1222. { e.preventDefault();
  1223. $("#button2").prop("disabled",true);
  1224. $("#loa").show();
  1225. function sendForm() {
  1226. $.ajax({
  1227. type : 'POST',
  1228. url : '{{ path('ajax_ajout_da_temp')}}',
  1229. data : 'quantDemand=' + $("#form_quantd2").val()+
  1230. '&prixUnit=' + $("#form_prixUni2").val()+
  1231. '&obje=' + $("#form_obje2").val()+
  1232. '&descrip=' + $("#form_descrip2").val()+
  1233. '&baille2=' + $("#form_baille2").val()+
  1234. '&iddesignrech=' + $("#form_design2").val(),
  1235. success: function(data)
  1236. {
  1237. alert('ajout effectué avec succes');
  1238. $("#loa").hide();
  1239. $("#button2").prop("disabled",false);
  1240. $("#form_quantDeman2").val("");
  1241. $("#form_prixUnit2").val("");
  1242. $("#form_design2").val("");
  1243. $("#form_descript2").val("");
  1244. $('#liste').html(data);
  1245. },
  1246. error: function(xhr, status, error) {
  1247. if (!navigator.onLine) {
  1248. // Si la connexion internet est perdue
  1249. alert('Connexion perdue. Tentative de réenvoi dans 5 secondes...');
  1250. setTimeout(retrySending, 5000); // Réessaye dans 5 secondes
  1251. }
  1252. }
  1253. });
  1254. }
  1255. // Fonction pour retenter l'envoi
  1256. function retrySending() {
  1257. if (navigator.onLine) {
  1258. sendForm(); // Si la connexion est rétablie, renvoie le formulaire
  1259. } else {
  1260. setTimeout(retrySending, 5000); // Réessayer jusqu'à ce que la connexion revienne
  1261. }
  1262. }
  1263. // Premier essai d'envoi
  1264. sendForm();
  1265. });
  1266. });
  1267. </script>
  1268. <script>
  1269. $(document).ready(function() {
  1270. $('#button').click(function(e) {
  1271. e.preventDefault();
  1272. $("#button").prop("disabled", true); // Désactiver le bouton
  1273. $("#loa").show(); // Afficher le loader
  1274. function sendForm() {
  1275. $.ajax({
  1276. type : 'POST',
  1277. url : '{{ path('ajax_da_temp')}}',
  1278. data : 'quantDemand=' + $("#form_quantd2").val()+
  1279. '&prixUnit=' + $("#form_prixUni2").val()+
  1280. '&obje=' + $("#form_obje2").val()+
  1281. '&descrip=' + $("#form_descrip2").val()+
  1282. '&baille2=' + $("#form_baille2").val()+
  1283. '&iddesignrech=' + $("#form_design2").val(),
  1284. success: function(data) {
  1285. alert('ajout effectué avec succès');
  1286. $("#loa").hide(); // Cacher le loader
  1287. $("#button").hide();
  1288. $("#button2").show();
  1289. $("#obje2").hide();
  1290. $("#form_quantd2").val("");
  1291. $("#form_prixUni2").val("");
  1292. $("#form_design2").val("");
  1293. $("#form_descrip2").val("");
  1294. $('#liste').html(data);
  1295. },
  1296. error: function(xhr, status, error) {
  1297. if (!navigator.onLine) {
  1298. // Si la connexion internet est perdue
  1299. alert('Connexion perdue. Tentative de réenvoi dans 5 secondes...');
  1300. setTimeout(retrySending, 5000); // Réessaye dans 5 secondes
  1301. }
  1302. }
  1303. });
  1304. }
  1305. // Fonction pour retenter l'envoi
  1306. function retrySending() {
  1307. if (navigator.onLine) {
  1308. sendForm(); // Si la connexion est rétablie, renvoie le formulaire
  1309. } else {
  1310. setTimeout(retrySending, 5000); // Réessayer jusqu'à ce que la connexion revienne
  1311. }
  1312. }
  1313. // Premier essai d'envoi
  1314. sendForm();
  1315. });
  1316. });
  1317. </script>
  1318. <script>
  1319. var loader = "{{ asset('img/loders.gif') }}";
  1320. $(document).ready(function(){
  1321. $("#form_design2").on('keyup', function() {
  1322. var input = $(this).val();
  1323. if ( input.length >= 1 ) {
  1324. //$('#match3').html('<img src="' + window.loader + '" />');
  1325. var data = {input: input};
  1326. $.ajax({
  1327. type: "POST",
  1328. url:'{{ path('ajax_autocomplete_design')}}',
  1329. data: data,
  1330. dataType: 'json',
  1331. timeout: 3000,
  1332. success: function(response){
  1333. $('#match3').html(response.countryList);
  1334. $('#matchList li').on('click', function() {
  1335. $('#form_design2').val($(this).text());
  1336. $('#match3').text('');
  1337. });
  1338. },
  1339. error: function() {
  1340. $('#match3').text('Problem de connexion internet!');
  1341. }
  1342. });
  1343. } else {
  1344. $('#match3').text('');
  1345. }
  1346. });
  1347. });
  1348. </script>
  1349. <script>
  1350. $('#monlistnum55').change(function()
  1351. {
  1352. $("#load").show();
  1353. $.ajax({
  1354. type : 'POST',
  1355. url : '{{ path('ajax_liste_demachat')}}',
  1356. data : 'listnum=' + $('#form_listnum55').val(),
  1357. })
  1358. .done(function(response)
  1359. {
  1360. $("#load").hide();
  1361. $('#liste').html(response);
  1362. })
  1363. .fail(function(jqXHR, textStatus, errorThrown)
  1364. {
  1365. $("#load").hide();
  1366. alert('Error : ' + errorThrown);
  1367. });
  1368. return false;
  1369. });
  1370. </script>
  1371. {% endblock %}