Norberto Montalvo García commited on
Commit
110ecad
·
unverified ·
2 Parent(s): 6dccd53 a7c6a83

Merge pull request #27 from CascoArcilla/HU5

Browse files
tecnicas/static/js/download-table-csv.js ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener("DOMContentLoaded", function () {
2
+ const btn = document.getElementById("download-csv-btn");
3
+ if (!btn) return;
4
+
5
+ btn.addEventListener("click", function () {
6
+ // Try set the table in the page
7
+ let table = document.getElementById("convencional-table");
8
+ if (!table) {
9
+ const section = btn.closest("section");
10
+ if (section) table = section.querySelector("table");
11
+ }
12
+ if (!table) {
13
+ console.warn("No se encontró la tabla para descargar.");
14
+ return;
15
+ }
16
+
17
+ // helper to trim and normalize cell text
18
+ const cellText = (cell) => {
19
+ if (!cell) return "";
20
+ return String(cell.textContent || "").trim();
21
+ };
22
+
23
+ // Collect headers
24
+ const headers = [];
25
+ const ths = table.querySelectorAll("thead th");
26
+ ths.forEach((th) => headers.push(cellText(th)));
27
+
28
+ // Collect rows
29
+ const rows = [];
30
+ const trs = table.querySelectorAll("tbody tr");
31
+ trs.forEach((tr) => {
32
+ const cols = [];
33
+ const tds = tr.querySelectorAll("td");
34
+ tds.forEach((td) => cols.push(cellText(td)));
35
+ rows.push(cols);
36
+ });
37
+
38
+ // Convert to CSV string (escape quotes, wrap in quotes if needed)
39
+ const escapeValue = (val) => {
40
+ if (val == null) return "";
41
+ normalVal = val.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
42
+ const needsQuotes = /[",\n,]/.test(normalVal);
43
+ let v = String(normalVal).replace(/"/g, '""');
44
+ if (needsQuotes) v = `"${v}"`;
45
+ return v;
46
+ };
47
+
48
+ const lines = [];
49
+ if (headers.length) lines.push(headers.map(escapeValue).join(","));
50
+ rows.forEach((r) => lines.push(r.map(escapeValue).join(",")));
51
+
52
+ const csvContent = lines.join("\n");
53
+
54
+ // File name: data_{nombre_sesion or codigo_sesion}
55
+ const rawName = (btn.dataset.sessionName || "").trim();
56
+ const code = (btn.dataset.sessionCode || "").trim() || "session";
57
+ const namePart = rawName
58
+ ? rawName.replace(/[^a-zA-Z0-9-_áéíóúÁÉÍÓÚ ]/g, "").replace(/\s+/g, "_")
59
+ : code;
60
+ const fileName = `data_${namePart}.csv`;
61
+
62
+ // Create blob and force download
63
+ const blob = new Blob([csvContent], { type: "text/csv;charset=UTF-8;" });
64
+ if (navigator.msSaveBlob) {
65
+ navigator.msSaveBlob(blob, fileName);
66
+ } else {
67
+ const link = document.createElement("a");
68
+ const url = URL.createObjectURL(blob);
69
+ link.setAttribute("href", url);
70
+ link.setAttribute("download", fileName);
71
+ link.style.visibility = "hidden";
72
+ document.body.appendChild(link);
73
+ link.click();
74
+ document.body.removeChild(link);
75
+ URL.revokeObjectURL(url);
76
+ }
77
+ });
78
+ });
tecnicas/templates/tecnicas/components/table-convencional.html CHANGED
@@ -1,6 +1,7 @@
 
1
  <section>
2
  <div class="overflow-x-auto rounded-lg border border-surface-general">
3
- <table class="min-w-max w-full text-sm text-center border-collapse">
4
  <thead class="bg-surface-sweet text-black font-semibold">
5
  <tr>
6
  <th class="py-2 px-3 border border-surface-general">Repetición</th>
@@ -41,8 +42,11 @@
41
  </div>
42
 
43
  <div class="flex justify-end mt-3">
44
- <button class="cts-btn-general cts-btn-primary btn-push">
 
 
45
  Descargar CSV
46
  </button>
47
  </div>
48
- </section>
 
 
1
+ {% load static %}
2
  <section>
3
  <div class="overflow-x-auto rounded-lg border border-surface-general">
4
+ <table id="convencional-table" class="min-w-max w-full text-sm text-center border-collapse">
5
  <thead class="bg-surface-sweet text-black font-semibold">
6
  <tr>
7
  <th class="py-2 px-3 border border-surface-general">Repetición</th>
 
42
  </div>
43
 
44
  <div class="flex justify-end mt-3">
45
+ <button id="download-csv-btn" class="cts-btn-general cts-btn-primary btn-push"
46
+ data-session-name="{% if sesion and sesion.nombre_sesion %}{{ sesion.nombre_sesion }}{% else %}{% endif %}"
47
+ data-session-code="{% if sesion and sesion.codigo_sesion %}{{ sesion.codigo_sesion }}{% else %}{% endif %}">
48
  Descargar CSV
49
  </button>
50
  </div>
51
+ </section>
52
+ <script src="{% static 'js/download-table-csv.js' %}"></script>
tecnicas/templates/tecnicas/manage_sesions/detalles-sesion.html CHANGED
@@ -260,7 +260,7 @@
260
  Máximo valor por dato: <span class="font-bold">{{ scale.size }}</span>
261
  </p>
262
  </section>
263
- {% include "../components/table-convencional.html" with calificaciones=calificaciones palabras=palabras %}
264
  </article>
265
  {% else %}
266
  {% include "../components/error-message.html" with message='Sin calificaciones que mostrar aún' %}
 
260
  Máximo valor por dato: <span class="font-bold">{{ scale.size }}</span>
261
  </p>
262
  </section>
263
+ {% include "../components/table-convencional.html" with calificaciones=calificaciones palabras=palabras sesion=sesion %}
264
  </article>
265
  {% else %}
266
  {% include "../components/error-message.html" with message='Sin calificaciones que mostrar aún' %}