Spaces:
Sleeping
Sleeping
Funcion para elejir palabras para usar en formulario de configuracion de sesion
Browse files
tecnicas/static/img/list.svg
ADDED
|
|
tecnicas/static/img/lupa.svg
ADDED
|
|
tecnicas/static/js/panel-words.js
CHANGED
|
@@ -1,4 +1,178 @@
|
|
| 1 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
const tagsWords = document.querySelectorAll(".word");
|
| 3 |
let numberWords = 3;
|
| 4 |
const allWords = [];
|
|
@@ -66,3 +240,4 @@ function creadSelect(index) {
|
|
| 66 |
|
| 67 |
return label;
|
| 68 |
}
|
|
|
|
|
|
| 1 |
+
const imgList = document.querySelector(".ct-img-list");
|
| 2 |
+
|
| 3 |
+
const listWordsSelect = [];
|
| 4 |
+
const wordsSelectContainer = document.querySelector(".ct-palabras-usadas");
|
| 5 |
+
|
| 6 |
+
const errorp = document.getElementsByClassName("ct-error-words")[0];
|
| 7 |
+
const foundWordsContainer = document.getElementsByClassName(
|
| 8 |
+
"ct-palabras-encontradas"
|
| 9 |
+
)[0];
|
| 10 |
+
|
| 11 |
+
const formSearch = document.getElementsByClassName("ct-serach-words")[0];
|
| 12 |
+
formSearch.addEventListener("submit", getWordsByName);
|
| 13 |
+
|
| 14 |
+
async function getWordsByName(e) {
|
| 15 |
+
e.preventDefault();
|
| 16 |
+
errorp.classList.add("hidden");
|
| 17 |
+
foundWordsContainer.innerHTML = "";
|
| 18 |
+
|
| 19 |
+
let words = [];
|
| 20 |
+
|
| 21 |
+
const dataForm = new FormData(this);
|
| 22 |
+
const params = new URLSearchParams({
|
| 23 |
+
palabra: dataForm.get("search").trim(),
|
| 24 |
+
});
|
| 25 |
+
|
| 26 |
+
const url = `api/palabras?${params}`;
|
| 27 |
+
|
| 28 |
+
try {
|
| 29 |
+
const respone = await fetch(url, {
|
| 30 |
+
method: "GET",
|
| 31 |
+
headers: {
|
| 32 |
+
"X-CSRFToken": dataForm.get("csrfmiddlewaretoken"),
|
| 33 |
+
},
|
| 34 |
+
});
|
| 35 |
+
|
| 36 |
+
const jsonResponse = await respone.json();
|
| 37 |
+
|
| 38 |
+
if (jsonResponse.error) {
|
| 39 |
+
errorp.textContent = `Error: ${jsonResponse.error}`;
|
| 40 |
+
errorp.classList.remove("hidden");
|
| 41 |
+
return;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
words = jsonResponse["data"];
|
| 45 |
+
} catch (error) {
|
| 46 |
+
console.log("Error:", error);
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
showWordsFound(words);
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
function createWordElement({ word, add = true, callback = null }) {
|
| 53 |
+
const li = document.createElement("li");
|
| 54 |
+
li.classList.add(
|
| 55 |
+
add ? "bg-gray-600" : "bg-gray-400",
|
| 56 |
+
add ? "text-white" : "text-black",
|
| 57 |
+
"rounded",
|
| 58 |
+
"font-bold",
|
| 59 |
+
"text-lg",
|
| 60 |
+
"px-4",
|
| 61 |
+
"py-3",
|
| 62 |
+
"flex",
|
| 63 |
+
"flex-wrap",
|
| 64 |
+
"flex-row",
|
| 65 |
+
"flex-1",
|
| 66 |
+
"min-w-fit",
|
| 67 |
+
"justify-center",
|
| 68 |
+
"items-center",
|
| 69 |
+
"gap-3"
|
| 70 |
+
);
|
| 71 |
+
|
| 72 |
+
const pName = document.createElement("p");
|
| 73 |
+
pName.textContent = word.nombre_palabra;
|
| 74 |
+
pName.id = word.id;
|
| 75 |
+
|
| 76 |
+
let callButton;
|
| 77 |
+
|
| 78 |
+
if (callback) {
|
| 79 |
+
callButton = () => callback(word);
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
li.appendChild(pName);
|
| 83 |
+
li.appendChild(createButton(add, callButton));
|
| 84 |
+
|
| 85 |
+
return li;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
function createButton(add = true, callback = null) {
|
| 89 |
+
const button = document.createElement("button");
|
| 90 |
+
button.textContent = add ? "➕" : "➖";
|
| 91 |
+
button.classList.add(
|
| 92 |
+
"px-4",
|
| 93 |
+
"border-b-2",
|
| 94 |
+
"active:border-b-0",
|
| 95 |
+
"active:border-t-2",
|
| 96 |
+
"transition-all",
|
| 97 |
+
"rounded-xl",
|
| 98 |
+
"font-black",
|
| 99 |
+
"w-fit",
|
| 100 |
+
"capitalize"
|
| 101 |
+
);
|
| 102 |
+
|
| 103 |
+
button.classList.add(
|
| 104 |
+
add ? "active:border-green-500" : "active:border-red-500",
|
| 105 |
+
add ? "border-green-800" : "border-red-800",
|
| 106 |
+
add ? "bg-green-500" : "bg-red-500"
|
| 107 |
+
);
|
| 108 |
+
|
| 109 |
+
if (callback) {
|
| 110 |
+
button.addEventListener("click", callback);
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
return button;
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
function swtichGridSearch(change = true) {
|
| 117 |
+
change
|
| 118 |
+
? foundWordsContainer.classList.add("grid")
|
| 119 |
+
: foundWordsContainer.classList.remove("grid");
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
function showWordsFound(words) {
|
| 123 |
+
foundWordsContainer.innerHTML = "";
|
| 124 |
+
swtichGridSearch();
|
| 125 |
+
|
| 126 |
+
words.forEach((word) => {
|
| 127 |
+
const elemtnLi = createWordElement({ word: word, callback: addWordToUse });
|
| 128 |
+
foundWordsContainer.appendChild(elemtnLi);
|
| 129 |
+
});
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
function addWordToUse(word) {
|
| 133 |
+
if (listWordsSelect.find((w) => w.id === word.id)) {
|
| 134 |
+
const noti = document.querySelector(".ct-notification-red");
|
| 135 |
+
noti.textContent = `La palabra "${word.nombre_palabra}" ya fue seleccionada`;
|
| 136 |
+
noti.classList.remove("hidden");
|
| 137 |
+
|
| 138 |
+
setTimeout(() => {
|
| 139 |
+
noti.classList.add("hidden");
|
| 140 |
+
}, 1800);
|
| 141 |
+
|
| 142 |
+
return;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
listWordsSelect.push(word);
|
| 146 |
+
updatelistWordsSelect();
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
function spanNotificationRed(params) {}
|
| 150 |
+
|
| 151 |
+
function removeWordToUse(word) {
|
| 152 |
+
const index = listWordsSelect.findIndex((w) => w.id === word.id);
|
| 153 |
+
if (index > -1) {
|
| 154 |
+
listWordsSelect.splice(index, 1);
|
| 155 |
+
updatelistWordsSelect();
|
| 156 |
+
}
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
function updatelistWordsSelect() {
|
| 160 |
+
wordsSelectContainer.innerHTML = "";
|
| 161 |
+
listWordsSelect.forEach((word) => {
|
| 162 |
+
const elemtnLi = createWordElement({
|
| 163 |
+
word: word,
|
| 164 |
+
add: false,
|
| 165 |
+
callback: removeWordToUse,
|
| 166 |
+
});
|
| 167 |
+
wordsSelectContainer.appendChild(elemtnLi);
|
| 168 |
+
});
|
| 169 |
+
|
| 170 |
+
if (listWordsSelect.length === 0) {
|
| 171 |
+
wordsSelectContainer.appendChild(imgList);
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
/*const selectWordsContainer = document.querySelector(".ct-words-select");
|
| 176 |
const tagsWords = document.querySelectorAll(".word");
|
| 177 |
let numberWords = 3;
|
| 178 |
const allWords = [];
|
|
|
|
| 240 |
|
| 241 |
return label;
|
| 242 |
}
|
| 243 |
+
*/
|
tecnicas/templates/tecnicas/create_sesion/configuracion-panel-words.html
CHANGED
|
@@ -23,35 +23,42 @@
|
|
| 23 |
</p>
|
| 24 |
{% endif %}
|
| 25 |
|
| 26 |
-
<article class="flex flex-col md:flex-row gap-5 justify-between
|
| 27 |
-
<section class="flex-
|
| 28 |
-
<
|
| 29 |
-
</section>
|
| 30 |
-
<section class="flex-2/3 w-full">
|
| 31 |
-
<form action="" method="get" class="h-full w-full">
|
| 32 |
{% csrf_token %}
|
| 33 |
-
<
|
| 34 |
-
<
|
| 35 |
-
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
</form>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
</section>
|
| 39 |
</article>
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
<article class="p-4 flex flex-col items-center gap-2 rounded">
|
| 45 |
-
<h2 class="text-2xl mb-2 text-center font-bold">Estilo Atributos<br>Seleccion de palabras</h2>
|
| 46 |
-
<div class="ct-words-select flex flex-row flex-wrap justify-center items-center gap-5 text-lg">
|
| 47 |
-
</div>
|
| 48 |
-
<hr>
|
| 49 |
-
<button type="button"
|
| 50 |
-
class="ct-gen-or text-lg tracking-wider font-medium p-2 px-4 border-b-2 active:border-b-0 active:border-t-2 active:border-blue-500 border-blue-800 transition-all rounded-xl bg-blue-500 text-white w-fit capitalize">
|
| 51 |
-
Agregar otra palabra
|
| 52 |
-
</button>
|
| 53 |
-
</article>
|
| 54 |
-
</form>
|
| 55 |
</article>
|
| 56 |
</section>
|
| 57 |
</article>
|
|
|
|
| 23 |
</p>
|
| 24 |
{% endif %}
|
| 25 |
|
| 26 |
+
<article class="flex flex-col md:flex-row gap-5 justify-between">
|
| 27 |
+
<section class="flex-3/5 flex flex-col gap-4">
|
| 28 |
+
<form action="" method="get" class="ct-serach-words">
|
|
|
|
|
|
|
|
|
|
| 29 |
{% csrf_token %}
|
| 30 |
+
<section class="flex flex-row gap-2">
|
| 31 |
+
<label for="search" class="w-full">
|
| 32 |
+
<input type="text" name="search" id="search" placeholder="Buscar palabra"
|
| 33 |
+
class="p-2 px-4 bg-gray-200 rounded-lg w-full text-lg font-medium">
|
| 34 |
+
</label>
|
| 35 |
+
<button type="submit"
|
| 36 |
+
class="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 capitalize">
|
| 37 |
+
Buscar
|
| 38 |
+
</button>
|
| 39 |
+
</section>
|
| 40 |
</form>
|
| 41 |
+
<p
|
| 42 |
+
class="ct-error-words hidden capitalize text-white bg-red-600 text-center text-2xl p-1.5 rounded">
|
| 43 |
+
error</p>
|
| 44 |
+
<ul class="ct-palabras-encontradas gap-2 grid-cols-2 max-h-96 overflow-y-auto">
|
| 45 |
+
<object type="image/svg" class="flex justify-center items-center h-full">
|
| 46 |
+
<img src="{% static 'img/lupa.svg' %}" alt="lupa de busqueda" class="h-full">
|
| 47 |
+
</object>
|
| 48 |
+
</ul>
|
| 49 |
+
</section>
|
| 50 |
+
<section class="flex-1/3 bg-gray-600 text-white p-4 rounded-lg text-center min-h-96">
|
| 51 |
+
<p class="text-xl font-bold pb-3">Lista de palabras</p>
|
| 52 |
+
<hr class="mb-3 text-white">
|
| 53 |
+
<ul class="ct-palabras-usadas flex flex-col gap-3">
|
| 54 |
+
<img src="{% static 'img/list.svg' %}" alt="lista de palabras" class="ct-img-list">
|
| 55 |
+
</ul>
|
| 56 |
</section>
|
| 57 |
</article>
|
| 58 |
|
| 59 |
+
<article
|
| 60 |
+
class="ct-notification-red absolute max-md:fixed bottom-0 mb-4 left-1/2 -translate-x-1/2 bg-red-600 text-white p-2 px-4 rounded-lg text-center font-medium hidden">
|
| 61 |
+
</article>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
</article>
|
| 63 |
</section>
|
| 64 |
</article>
|
tecnicas/test/test_words.py
CHANGED
|
@@ -7,9 +7,9 @@ class TestsApiWords(TestCase):
|
|
| 7 |
def setUp(self):
|
| 8 |
Palabra.objects.create(nombre_palabra="salado")
|
| 9 |
|
| 10 |
-
def
|
| 11 |
word_name = "dulce"
|
| 12 |
-
expected_error = "
|
| 13 |
|
| 14 |
response = self.client.get(
|
| 15 |
reverse("cata_system:api_palabras")+f"?palabra={word_name}"
|
|
@@ -21,7 +21,7 @@ class TestsApiWords(TestCase):
|
|
| 21 |
self.assertIn("error", res_json)
|
| 22 |
self.assertEqual(res_json["error"], expected_error)
|
| 23 |
|
| 24 |
-
def
|
| 25 |
expected_error = "parametros no encontrados"
|
| 26 |
|
| 27 |
response = self.client.get(reverse("cata_system:api_palabras"))
|
|
@@ -32,11 +32,11 @@ class TestsApiWords(TestCase):
|
|
| 32 |
self.assertIn("error", res_json)
|
| 33 |
self.assertEqual(res_json["error"], expected_error)
|
| 34 |
|
| 35 |
-
def
|
| 36 |
-
word_name = "
|
| 37 |
-
expected_message = "
|
| 38 |
|
| 39 |
-
expected_data = Palabra.objects.
|
| 40 |
|
| 41 |
response = self.client.get(
|
| 42 |
reverse("cata_system:api_palabras")+f"?palabra={word_name}"
|
|
@@ -50,8 +50,7 @@ class TestsApiWords(TestCase):
|
|
| 50 |
self.assertEqual(res_json["message"], expected_message)
|
| 51 |
|
| 52 |
data = res_json["data"]
|
| 53 |
-
self.assertEqual(data
|
| 54 |
-
self.assertEqual(data["name"], expected_data["nombre_palabra"])
|
| 55 |
|
| 56 |
def test_post_word_success(self):
|
| 57 |
word_name = "dulce"
|
|
|
|
| 7 |
def setUp(self):
|
| 8 |
Palabra.objects.create(nombre_palabra="salado")
|
| 9 |
|
| 10 |
+
def test_get_words_fail(self):
|
| 11 |
word_name = "dulce"
|
| 12 |
+
expected_error = "no existen palabras"
|
| 13 |
|
| 14 |
response = self.client.get(
|
| 15 |
reverse("cata_system:api_palabras")+f"?palabra={word_name}"
|
|
|
|
| 21 |
self.assertIn("error", res_json)
|
| 22 |
self.assertEqual(res_json["error"], expected_error)
|
| 23 |
|
| 24 |
+
def test_get_words_no_parameter(self):
|
| 25 |
expected_error = "parametros no encontrados"
|
| 26 |
|
| 27 |
response = self.client.get(reverse("cata_system:api_palabras"))
|
|
|
|
| 32 |
self.assertIn("error", res_json)
|
| 33 |
self.assertEqual(res_json["error"], expected_error)
|
| 34 |
|
| 35 |
+
def test_get_words_success(self):
|
| 36 |
+
word_name = "sal"
|
| 37 |
+
expected_message = "datos localizados"
|
| 38 |
|
| 39 |
+
expected_data = Palabra.objects.filter(nombre_palabra__contains=word_name)
|
| 40 |
|
| 41 |
response = self.client.get(
|
| 42 |
reverse("cata_system:api_palabras")+f"?palabra={word_name}"
|
|
|
|
| 50 |
self.assertEqual(res_json["message"], expected_message)
|
| 51 |
|
| 52 |
data = res_json["data"]
|
| 53 |
+
self.assertEqual(len(data), len(expected_data))
|
|
|
|
| 54 |
|
| 55 |
def test_post_word_success(self):
|
| 56 |
word_name = "dulce"
|
tecnicas/views/api_words.py
CHANGED
|
@@ -8,18 +8,19 @@ def words(req: HttpRequest):
|
|
| 8 |
if req.method == "GET":
|
| 9 |
try:
|
| 10 |
word_name = req.GET["palabra"]
|
| 11 |
-
|
|
|
|
| 12 |
except KeyError:
|
| 13 |
return general_error("parametros no encontrados")
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
response = {
|
| 18 |
-
"message": "
|
| 19 |
-
"data":
|
| 20 |
-
"id": fund_word.id,
|
| 21 |
-
"name": fund_word.nombre_palabra,
|
| 22 |
-
}
|
| 23 |
}
|
| 24 |
|
| 25 |
return JsonResponse(response)
|
|
|
|
| 8 |
if req.method == "GET":
|
| 9 |
try:
|
| 10 |
word_name = req.GET["palabra"]
|
| 11 |
+
fund_words = Palabra.objects.filter(
|
| 12 |
+
nombre_palabra__contains=word_name)
|
| 13 |
except KeyError:
|
| 14 |
return general_error("parametros no encontrados")
|
| 15 |
+
|
| 16 |
+
if not fund_words:
|
| 17 |
+
return general_error("no existen palabras")
|
| 18 |
+
|
| 19 |
+
response_words = [word.to_dict() for word in fund_words]
|
| 20 |
|
| 21 |
response = {
|
| 22 |
+
"message": "datos localizados",
|
| 23 |
+
"data": response_words
|
|
|
|
|
|
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
return JsonResponse(response)
|