chartManD commited on
Commit
ef1685a
·
1 Parent(s): 4b0ed3c

Validacion y captura de etiquetas en form_tags

Browse files
tecnicas/forms/__init__.py CHANGED
@@ -1,2 +1,3 @@
1
  from .sesion_basic import SesionBasicForm
2
- from .sesion_tags import SesionTagsForm
 
 
1
  from .sesion_basic import SesionBasicForm
2
+ from .sesion_tags import SesionTagsForm
3
+ from .etiqueta import EtiquetaForm
tecnicas/forms/etiqueta.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ from django import forms
2
+
3
+ class EtiquetaForm(forms.Form):
4
+ nueva_etiqueta = forms.CharField(max_length=255, required=True, widget=forms.TextInput(attrs={
5
+ "class": "bg-gray-300 border-b text-center text-black",
6
+ "placeholder": "No repetir etiqueta"
7
+ }))
tecnicas/forms/sesion_tags.py CHANGED
@@ -5,10 +5,23 @@ from django.urls import reverse
5
  from ..models import Etiqueta
6
 
7
  class SesionTagsForm(forms.Form):
8
- def __init__(self, *args, segmentos=None, **kwargs):
9
  super().__init__(*args, **kwargs)
10
 
11
- for i in range(segmentos):
12
- self.fields[f'segmento_{i}'] = forms.ModelChoiceField(queryset=Etiqueta.objects.all(), required=True,label=f"segmento {i+1}", empty_label="Selecione opcion", widget=forms.Select(attrs={
13
- "class":"ct-select-op p-1 rounded bg-gray-200 [*]:capitalize"
14
- }))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  from ..models import Etiqueta
6
 
7
  class SesionTagsForm(forms.Form):
8
+ def __init__(self, *args, longitud=None, tipo_escala:str=None, **kwargs):
9
  super().__init__(*args, **kwargs)
10
 
11
+ if tipo_escala == "estructurada":
12
+ for i in range(longitud):
13
+ self.fields[f'segmento_{i}'] = forms.ModelChoiceField(queryset=Etiqueta.objects.all(), required=True,label=f"segmento {i+1}", empty_label="Selecione opcion", widget=forms.Select(attrs={
14
+ "class":"ct-select-op p-1 rounded bg-gray-200 [*]:capitalize"
15
+ }))
16
+ else:
17
+ self.fields['punto_inicial'] = forms.ModelChoiceField(queryset=Etiqueta.objects.all(), required=True, label="Punto inicial", empty_label="Selecione opcion", widget=forms.Select(attrs={
18
+ "class":"ct-select-op p-1 rounded bg-gray-200 [*]:capitalize"
19
+ }))
20
+
21
+ self.fields['punto_medio'] = forms.ModelChoiceField(queryset=Etiqueta.objects.all(), required=True, label="Punto medio", empty_label="Selecione opcion", widget=forms.Select(attrs={
22
+ "class":"ct-select-op p-1 rounded bg-gray-200 [*]:capitalize"
23
+ }))
24
+
25
+ self.fields['punto_final'] = forms.ModelChoiceField(queryset=Etiqueta.objects.all(), required=True, label="Punto final", empty_label="Selecione opcion", widget=forms.Select(attrs={
26
+ "class":"ct-select-op p-1 rounded bg-gray-200 [*]:capitalize"
27
+ }))
tecnicas/templates/tecnicas/configuracion-panel-tags.html CHANGED
@@ -11,52 +11,70 @@
11
  - Presentar un orden basico segun el numero de catadores y los productos, esta se le muestra el presentador
12
  -->
13
 
14
- <!-- <div class="flex flex-row justify-center items-center gap-5 text-lg">
15
- <p class="font-medium p-1 px-3 bg-gray-200">Segmento 1</p>
16
- <label for="etiquta_1">
17
- <select name="etiquta_1" class="p-1 rounded bg-gray-200 [*]:capitalize" id="etiquta_1" required>
18
- <option value="1">no se percibe</option>
19
- <option value="2">poca percepcion</option>
20
- <option value="3">se percibe</option>
21
- <option value="4">percepcion intensa</option>
22
- <option value="5">percepcion muy intensa</option>
23
- </select>
24
- </label>
25
- <button type="button" class="p-1 rounded-lg bg-gray-200 active:bg-gray-400">➕</button>
26
- </div> -->
27
-
28
  {% block content %}
29
  <article class="w-full flex flex-col justify-center items-center bg-gray-600 my-10">
30
- <article class="flex flex-col gap-4 bg-gray-400 md:p-10 p-5 rounded-2xl lg:w-4xl w-full">
31
- <h1 class="text-center font-bold text-4xl">Panel de configuración</h1>
32
- <hr>
33
- <form method="post" action="" class="[&>article]:not-last:mb-4 [&>article]:not-first:pt-4 [&>article]:px-6">
34
- {% csrf_token %}
35
- <article class="bg-gray-500 p-4 flex flex-col gap-2">
36
- {% for field in form_tags %}
37
- <div class="flex flex-row justify-center items-center gap-5 text-lg">
38
- <label for="{{ field.id_for_label }}" class="font-medium p-1 px-3 bg-gray-200 capitalize">
39
- {{ field.label }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  </label>
41
- {{ field }}
42
- <button type="button" class="p-1 rounded-lg bg-gray-200 active:bg-gray-400">➕</button>
43
- </div>
44
- {% endfor %}
45
- </article>
46
- <article class="bg-gray-800/70 justify-center items-center">
47
- <button class="p-2 bg-gray-400 w-fit" type="submit">Mandar</button>
48
- </article>
49
- <article class="absolute bg-gray-800/70 p-5 w-full h-full justify-center items-center hidden">
50
- <section class="p-2 bg-gray-400 w-fit">
51
- <form action="">
52
- {% csrf_token %}
53
- <label for="nueva_etiqueta">Nueva etiqueta:<input id="nueva_etiqueta" type="text"
54
- required></label>
55
- </form>
56
- </section>
57
- </article>
58
- </form>
59
- </article>
60
  </article>
61
  {% endblock %}
62
 
@@ -66,6 +84,74 @@
66
  const options = itemsSelects.item(0).getElementsByTagName("option")
67
  const values = []
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  for (let i = 0; i < options.length; i++) {
70
  if (options.item(i).value) {
71
  values.push(options.item(i).value)
@@ -74,8 +160,9 @@
74
 
75
  values.sort()
76
 
77
- for (let i = 0; i < itemsSelects.length; i++) {
78
  itemsSelects.item(i).value = values[i]
79
  }
80
  </script>
 
81
  {% endblock %}
 
11
  - Presentar un orden basico segun el numero de catadores y los productos, esta se le muestra el presentador
12
  -->
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  {% block content %}
15
  <article class="w-full flex flex-col justify-center items-center bg-gray-600 my-10">
16
+ <section class="w-fit h-fit relative">
17
+ <article class="flex flex-col gap-4 bg-gray-400 md:p-10 p-5 rounded-2xl lg:w-4xl w-full">
18
+ <h1 class="text-center font-bold text-4xl">Panel de configuración</h1>
19
+ <hr>
20
+ {% if error %}
21
+ <p class="bg-red-400 font-bold text-lg tracking-wide text-white capitalize text-center py-2">
22
+ {{ error }}
23
+ </p>
24
+ {% endif %}
25
+ <form method="post" action="" class="flex flex-col gap-5">
26
+ {% csrf_token %}
27
+ <article class="p-4 flex flex-col gap-2 rounded">
28
+ <h2 class="text-2xl mb-2 font-bold">Seleccion de etiquetas</h2>
29
+ {% for field in form_tags %}
30
+ <div class="flex flex-row justify-center items-center gap-5 text-lg">
31
+ <label for="{{ field.id_for_label }}" class="font-medium p-1 px-3 bg-gray-200 capitalize rounded">
32
+ {{ field.label }}
33
+ </label>
34
+ {{ field }}
35
+ </div>
36
+ {% endfor %}
37
+ </article>
38
+ <hr>
39
+ <article class="flex gap-3 flex-wrap p-2 justify-center rounded">
40
+ <p class="bg-gray-300 p-2 text-center rounded font-bold text-md">
41
+ Agregar otra etiqueta
42
+ </p>
43
+ <button type="button" onclick="showHiddeExtraTags()"
44
+ class="p-1 px-10 uppercase text-lg tracking-wider font-medium border-b-2 active:border-b-0 active:border-t-2 active:border-yellow-500 border-yellow-800 transition-all rounded-xl bg-yellow-500 w-fit">
45
+
46
+ </button>
47
+ </article>
48
+ <hr>
49
+ <article class="flex justify-center items-center py-3 rounded">
50
+ <button type="submit"
51
+ class="uppercase text-lg tracking-wider font-medium p-2 px-4 border-b-2 active:border-b-0 active:border-t-2 active:border-yellow-500 border-yellow-800 transition-all rounded-xl bg-yellow-500 text-white w-fit">Continuar</button>
52
+ </article>
53
+ </form>
54
+ </article>
55
+ <article
56
+ class="ct-new-tags absolute top-0 w-full h-full bg-gray-600/70 p-5 flex justify-center items-center rounded-2xl hidden">
57
+ <section class="p-5 bg-gray-400 w-fit rounded">
58
+ <form method="post" action="" class="ct-form-new-tag p-3">
59
+ {% csrf_token %}
60
+ <label for="{{ form_new_tag.nueva_etiqueta.id_for_label }}"
61
+ class="font-medium text-md text-white flex gap-3">
62
+ <p class="bg-gray-600 px-4">Nueva etiqueta:</p>
63
+ {{ form_new_tag.nueva_etiqueta }}
64
  </label>
65
+ <p
66
+ class="ct-error-tag mt-4 font-bold bg-red-500 text-white text-md capitalize text-center rounded hidden">
67
+ error</p>
68
+ <article class="flex justify-center gap-8 mt-4 text-white font-medium tracking-wide">
69
+ <button class="rounded px-3 py-1 bg-green-700 active:bg-green-600"
70
+ type="submit">Agregar</button>
71
+ <button class="rounded px-3 py-1 bg-red-500 active:bg-red-400" type="button"
72
+ onclick="showHiddeExtraTags()">Cancelar</button>
73
+ </article>
74
+ </form>
75
+ </section>
76
+ </article>
77
+ </section>
 
 
 
 
 
 
78
  </article>
79
  {% endblock %}
80
 
 
84
  const options = itemsSelects.item(0).getElementsByTagName("option")
85
  const values = []
86
 
87
+ const extraPanel = document.getElementsByClassName("ct-new-tags")[0]
88
+ function showHiddeExtraTags () {
89
+ if (extraPanel.classList.contains("hidden")) {
90
+ extraPanel.classList.remove("hidden")
91
+ } else {
92
+ extraPanel.classList.add("hidden")
93
+ }
94
+ }
95
+
96
+ const formNewTag = document.getElementsByClassName("ct-form-new-tag")[0]
97
+ if (formNewTag) {
98
+ formNewTag.addEventListener("submit", postNewTag)
99
+ }
100
+
101
+ async function postNewTag (e) {
102
+ e.preventDefault()
103
+
104
+ const dataForm = new FormData(this)
105
+ const url = "/cata/nueva-etiqueta"
106
+
107
+ try {
108
+ const respone = await fetch(url, {
109
+ method: "POST",
110
+ headers: {
111
+ 'X-CSRFToken': dataForm.get('csrfmiddlewaretoken'),
112
+ },
113
+ body: dataForm
114
+ })
115
+
116
+ const jsonResponse = await respone.json()
117
+
118
+ if (jsonResponse.error) {
119
+ const errorp = document.getElementsByClassName("ct-error-tag")[0]
120
+ errorp.textContent = `error: ${jsonResponse.error}`
121
+ errorp.classList.remove("hidden")
122
+ return
123
+ }
124
+
125
+ const inputTag = document.getElementsByName("nueva_etiqueta")[0]
126
+ inputTag.value = ""
127
+ showHiddeExtraTags()
128
+
129
+ const newTag = jsonResponse["new_tag"]
130
+ addNewOptionToSelect(newTag)
131
+ } catch (error) {
132
+ console.log("Error:", error)
133
+
134
+ }
135
+ }
136
+
137
+ function createOptionSelect (value = 0, text = "define texto") {
138
+ const option = document.createElement("option")
139
+ option.value = value
140
+ option.textContent = text
141
+ return option
142
+ }
143
+
144
+ function addNewOptionToSelect(newValues) {
145
+ for (let i = 0; i < itemsSelects.length; i++) {
146
+ const newOption = createOptionSelect(newValues.id, newValues.valor)
147
+ itemsSelects.item(i).appendChild(newOption)
148
+ }
149
+ }
150
+ </script>
151
+
152
+ {%if escala == "estructurada"%}
153
+ <script>
154
+ // Asignacion rapida de valores a los select
155
  for (let i = 0; i < options.length; i++) {
156
  if (options.item(i).value) {
157
  values.push(options.item(i).value)
 
160
 
161
  values.sort()
162
 
163
+ for (let i = 0; i < values.length; i++) {
164
  itemsSelects.item(i).value = values[i]
165
  }
166
  </script>
167
+ {% endif %}
168
  {% endblock %}
tecnicas/urls.py CHANGED
@@ -13,4 +13,5 @@ urlpatterns = [
13
  path("seleccion-tecnica", views.selecionTecnica, name="seleccion_tecnica"),
14
  path("panel-configuracion-basic", views.configuracionPanelBasic, name="panel_configuracion_basic"),
15
  path("panel-configuracion-tags", views.configuracionPanelTags, name="panel_configuracion_tags"),
 
16
  ]
 
13
  path("seleccion-tecnica", views.selecionTecnica, name="seleccion_tecnica"),
14
  path("panel-configuracion-basic", views.configuracionPanelBasic, name="panel_configuracion_basic"),
15
  path("panel-configuracion-tags", views.configuracionPanelTags, name="panel_configuracion_tags"),
16
+ path("nueva-etiqueta", views.newTag, name="nueva_etiqueta"),
17
  ]
tecnicas/views/__init__.py CHANGED
@@ -5,4 +5,5 @@ from .management_catadores import managementCatadores
5
  from .panel_sessions import sesionesPanel
6
  from .seleccion_tecnica import selecionTecnica
7
  from .configuration_panel_basic import configuracionPanelBasic
8
- from .configuration_panel_tags import configuracionPanelTags
 
 
5
  from .panel_sessions import sesionesPanel
6
  from .seleccion_tecnica import selecionTecnica
7
  from .configuration_panel_basic import configuracionPanelBasic
8
+ from .configuration_panel_tags import configuracionPanelTags
9
+ from .api_tag import newTag
tecnicas/views/api_tag.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from django.http import HttpRequest, JsonResponse
2
+ from django.db import IntegrityError
3
+ from ..models import Etiqueta
4
+ from ..forms import EtiquetaForm
5
+ import json
6
+
7
+ def newTag(req:HttpRequest):
8
+ if req.method == "GET":
9
+ return error()
10
+ elif req.method == "POST":
11
+ print("Entre al api post tag")
12
+ try:
13
+ form = EtiquetaForm(req.POST)
14
+ if form.is_valid():
15
+ value_etiqueta = form.cleaned_data["nueva_etiqueta"]
16
+ value_etiqueta = value_etiqueta.strip()
17
+ value_etiqueta = value_etiqueta.lower()
18
+ else:
19
+ return error()
20
+ except KeyError:
21
+ return error()
22
+
23
+ # return JsonResponse({"message": "etiqueta registrada", "new_tag": { "valor": value_etiqueta, "id":6 }})
24
+
25
+ try:
26
+ new_etiqueta = Etiqueta.objects.create(valor_etiqueta=value_etiqueta)
27
+ except IntegrityError:
28
+ return error("etiqueta repetida")
29
+
30
+ return JsonResponse({
31
+ "message": "etiqueta registrada",
32
+ "new_tag": {
33
+ "id": new_etiqueta.id,
34
+ "valor": new_etiqueta.valor_etiqueta
35
+ }
36
+ })
37
+
38
+ def error(message="informacion incorrecta"):
39
+ respuesta = { "error" : message }
40
+ return JsonResponse(respuesta)
tecnicas/views/configuration_panel_basic.py CHANGED
@@ -6,19 +6,22 @@ from ..models import TipoTecnica
6
 
7
  def configuracionPanelBasic(req: HttpRequest):
8
  if req.method == "POST":
9
- form = SesionBasicForm(req.POST)
 
 
 
 
10
 
11
- if form.is_valid():
12
- values = {}
13
-
14
- for name, value in form.cleaned_data.items():
15
- if not name == "tipo_escala":
16
- values[name] = value
17
- else:
18
- values[name] = value.id
19
-
20
- req.session['datos_formulario'] = values
21
- return redirect(reverse("cata_system:panel_configuracion_tags"))
22
 
23
  return render(req, "tecnicas/configuracion-panel-basic.html", { "form_sesion": form, "error": "Ha ocurrido un error al continuar al siguiente paso." })
24
  elif req.method == "GET":
 
6
 
7
  def configuracionPanelBasic(req: HttpRequest):
8
  if req.method == "POST":
9
+ try:
10
+ form = SesionBasicForm(req.POST)
11
+
12
+ if form.is_valid():
13
+ values = {}
14
 
15
+ for name, value in form.cleaned_data.items():
16
+ if not name == "tipo_escala":
17
+ values[name] = value
18
+ else:
19
+ values[name] = value.id
20
+
21
+ req.session['form_basic'] = values
22
+ return redirect(reverse("cata_system:panel_configuracion_tags"))
23
+ except KeyError:
24
+ return redirect(reverse("cata_system:seleccion_tecnica") + "?error=error en datos de configuracion")
 
25
 
26
  return render(req, "tecnicas/configuracion-panel-basic.html", { "form_sesion": form, "error": "Ha ocurrido un error al continuar al siguiente paso." })
27
  elif req.method == "GET":
tecnicas/views/configuration_panel_tags.py CHANGED
@@ -1,13 +1,43 @@
1
  from django.http import HttpRequest
2
  from django.shortcuts import redirect, render
3
  from django.urls import reverse
4
- from ..forms import SesionTagsForm
 
5
 
6
  def configuracionPanelTags(req: HttpRequest):
7
- # basic_data = req.session.get("basic_form", None)
8
 
9
- # if basic_data is None:
10
- # return redirect(reverse('cata_system:panel_configuracion_basic'))
 
 
 
 
11
 
12
- etiquetas = SesionTagsForm(segmentos=5)
13
- return render(req, "tecnicas/configuracion-panel-tags.html", {"form_tags":etiquetas})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from django.http import HttpRequest
2
  from django.shortcuts import redirect, render
3
  from django.urls import reverse
4
+ from ..forms import SesionTagsForm, EtiquetaForm
5
+ from ..models import TipoEscala
6
 
7
  def configuracionPanelTags(req: HttpRequest):
8
+ basic_data = req.session.get("form_basic", {})
9
 
10
+ if not basic_data:
11
+ return redirect(reverse('cata_system:panel_configuracion_basic'))
12
+
13
+ tipo_escala = TipoEscala.objects.get(pk=basic_data["tipo_escala"])
14
+ tamano_escala = basic_data["tamano_escala"]
15
+ form_new_etiqueta = EtiquetaForm()
16
 
17
+ if req.method == "GET":
18
+ form_etiqutas = SesionTagsForm(longitud=tamano_escala, tipo_escala=tipo_escala.nombre_escala)
19
+
20
+ context_tags = {
21
+ "form_tags":form_etiqutas,
22
+ "form_new_tag": form_new_etiqueta
23
+ }
24
+
25
+ return render(req, "tecnicas/configuracion-panel-tags.html", context_tags)
26
+ elif req.method == "POST":
27
+ values = {}
28
+ form = SesionTagsForm(req.POST, longitud=tamano_escala, tipo_escala=tipo_escala.nombre_escala)
29
+
30
+ context_tags = {
31
+ "form_tags":form,
32
+ "form_new_tag": form_new_etiqueta
33
+ }
34
+
35
+ if form.is_valid():
36
+ for name, value in form.cleaned_data.items():
37
+ values[name] = value.id
38
+
39
+ req.session["form_tags"] = values
40
+ return render(req, "tecnicas/configuracion-panel-tags.html", context_tags)
41
+ else:
42
+ context_tags["error"] = "ha ocurrido un error"
43
+ return render(req, "tecnicas/configuracion-panel-tags.html", context_tags)