Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Juan Montilla
/
TBW2223_equipo12
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
dd539db1
authored
May 05, 2023
by
Juan Montilla
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Ajax para ingredientes
parent
5a5fba1c
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
293 additions
and
178 deletions
app/Config/Routes.php
app/Controllers/InsertRecipeController.php
app/Models/IngredientModel.php
app/Views/pages/home.php
app/Views/pages/insertRecipe.php
app/Views/pages/recipe_view.php
public/css/insert.css
public/js/insert.js
app/Config/Routes.php
View file @
dd539db1
...
...
@@ -33,14 +33,16 @@ use App\Controllers\User;
$routes
->
match
([
'get'
],
'/'
,
[
User
::
class
,
'login'
]);
$routes
->
match
([
'get'
,
'post'
],
'/login'
,
[
User
::
class
,
'login'
]);
$routes
->
match
([
'
get'
,
'post'
],
'/insertRecipe'
,
[
InsertRecipeController
::
class
,
'insertAjax
'
]);
$routes
->
match
([
'
post'
],
'/insert_recipe'
,
[
InsertRecipeController
::
class
,
'insertRecipe
'
]);
$routes
->
match
([
'get'
,
'post'
],
'/loginAjax'
,
[
User
::
class
,
'loginAjax'
]);
$routes
->
match
([
'get'
,
'post'
],
'/registerAjax'
,
[
User
::
class
,
'registerAjax'
]);
$routes
->
match
([
'post'
],
'/insert_recipe'
,
[
InsertRecipeController
::
class
,
'insert_recipe'
]);
$routes
->
match
([
'get'
],
'/home'
,
[
User
::
class
,
'user_ok'
]);
$routes
->
get
(
'/insert_recipe'
,
'InsertRecipeController::index'
);
$routes
->
match
([
'get'
,
'post'
],
'/search_ingredient'
,
'InsertRecipeController::search_ingredient'
);
$routes
->
get
(
'insertRecipe'
,
'InsertRecipeController::insertRecipe'
);
$routes
->
get
(
'login'
,
'Pages::viewLogin'
);
$routes
->
get
(
'users'
,
'User::list'
);
$routes
->
get
(
'home'
,
'Pages::prueba'
);
...
...
app/Controllers/InsertRecipeController.php
View file @
dd539db1
...
...
@@ -6,14 +6,28 @@ use CodeIgniter\Controller;
class
InsertRecipeController
extends
Controller
{
public
function
in
sertRecipe
()
public
function
in
dex
()
{
return
view
(
'templates/header'
)
.
view
(
'pages/insertRecipe'
)
.
view
(
'templates/footer'
);
}
public
function
search_ingredient
()
{
// Obtener la consulta de búsqueda desde el formulario
$query
=
$this
->
request
->
getVar
(
'query'
);
// Cargar el modelo de ingredientes (si no lo has hecho)
$ingredientModel
=
new
\App\Models\IngredientModel
();
// Buscar ingredientes en la base de datos que coincidan con la consulta
$ingredients
=
$ingredientModel
->
search_ingredient
(
$query
);
// Devolver los ingredientes coincidentes en formato JSON
return
$this
->
response
->
setJSON
(
$ingredients
);
}
}
app/Models/IngredientModel.php
View file @
dd539db1
...
...
@@ -19,7 +19,7 @@ class IngredientModel extends Model
protected
$skipValidation
=
false
;
public
function
save
Recipe
(
$id
,
$name
,
$icon
)
public
function
save
Ingredient
(
$id
,
$name
,
$icon
)
{
$data
=
[
'id'
=>
$id
,
...
...
@@ -29,5 +29,13 @@ class IngredientModel extends Model
return
$this
->
insert
(
$data
);
}
public
function
search_ingredient
(
$query
)
{
if
(
$query
)
{
return
$this
->
like
(
'name'
,
$query
)
->
findAll
();
}
return
[];
}
}
\ No newline at end of file
app/Views/pages/home.php
View file @
dd539db1
...
...
@@ -63,7 +63,7 @@
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/insert
R
ecipe"
>
<a
class=
"nav-link collapsed"
href=
"/insert
_r
ecipe"
>
<i
class=
"bi bi-person"
></i>
<span>
Perfil
</span>
</a>
...
...
app/Views/pages/insertRecipe.php
View file @
dd539db1
...
...
@@ -3,36 +3,45 @@
<section
class=
"section dashboard"
>
<h1>
Upload a Recipe
</h1>
<h1>
Subir una receta
</h1>
<form
action=
<?=
base_url
(
'/insert_recipe'
);
?>
method="post"
enctype=
"multipart/form-data"
class=
"my-form"
>
<!-- Seleccionar nombre receta-->
<div
class=
"form-group"
>
<label
for=
"recipe_name"
>
Recipe Name
:
</label>
<label
for=
"recipe_name"
>
Nombre de la receta
:
</label>
<input
type=
"text"
id=
"recipe_name"
name=
"recipe_name"
required
class=
"form-control"
>
</div>
<!-- Seleccionar descripción -->
<div
class=
"form-group"
>
<label
for=
"recipe_description"
>
Recipe Description
:
</label>
<label
for=
"recipe_description"
>
Descripción de la receta
:
</label>
<textarea
id=
"recipe_description"
name=
"recipe_description"
rows=
"4"
cols=
"50"
required
class=
"form-control"
></textarea>
</div>
<!-- Selccionar opción vegana -->
<div
class=
"form-group form-check"
>
<input
type=
"checkbox"
id=
"is_vegan"
name=
"is_vegan"
class=
"form-check-input"
>
<label
class=
"form-check-label"
for=
"is_vegan"
>
Vegan
</label>
<label
class=
"form-check-label"
for=
"is_vegan"
>
Vegan
a
</label>
</div>
<!-- Seleccionar origen -->
<div
class=
"form-group"
>
<label
for=
"origin"
>
Orig
i
n:
</label>
<label
for=
"origin"
>
Orig
e
n:
</label>
<select
id=
"origin"
name=
"origin"
class=
"form-control"
>
<option
value=
"american"
>
American
</option>
<option
value=
"chinese"
>
Chinese
</option>
<option
value=
"indian"
>
Indian
</option>
<option
value=
"italian"
>
Italian
</option>
<option
value=
"mexican"
>
Mexican
</option>
<option
value=
"Española"
>
Española
</option>
<option
value=
"Francesa"
>
Francesa
</option>
<option
value=
"Italiana"
>
Italiana
</option>
<option
value=
"Mexiana"
>
Mexicana
</option>
<option
value=
"Americana"
>
Americana
</option>
<option
value=
"China"
>
China
</option>
<option
value=
"India"
>
India
</option>
</select>
</div>
<!-- Seleccionar temporada -->
<div
class=
"form-group"
>
<label
for=
"season"
>
Season
:
</label>
<label
for=
"season"
>
Temporada
:
</label>
<select
id=
"season"
name=
"season"
class=
"form-control"
>
<option
value=
"invierno"
>
Invierno
</option>
<option
value=
"primavera"
>
Primavera
</option>
...
...
@@ -43,111 +52,70 @@
</div>
<!-- Seleccionar instrucciones -->
<div
class=
"form-group"
>
<label
for=
"instructions"
>
Instruc
tion
s:
</label>
<label
for=
"instructions"
>
Instruc
cione
s:
</label>
<textarea
id=
"instructions"
name=
"instructions"
rows=
"6"
cols=
"50"
required
class=
"form-control"
></textarea>
</div>
<div
class=
"form-group"
>
<label
for=
"ingredient_search"
>
Search Ingredients:
</label>
<div
class=
"input-group"
>
<input
type=
"search"
id=
"ingredient_search"
name=
"ingredient_search"
placeholder=
"Search ingredients..."
class=
"form-control"
>
<div
class=
"input-group-append"
>
<button
class=
"btn btn-primary"
type=
"button"
id=
"add_ingredient_btn"
>
Add
</button>
</div>
<!-- Seleccionar ingredientes -->
<label
>
Ingredientes:
</label>
<div
class=
"input-group my-form"
>
<input
type=
"search"
id=
"ingredient_search"
name=
"ingredient_search"
placeholder=
"Buscar ingredientes..."
class=
"form-control"
/>
</div>
<ul
id=
"ingredients_list"
class=
"ingredients-list list-unstyled"
></ul>
<div
class=
"form-group"
>
<label
for=
"selected_ingredients"
>
Ingredientes seleccionados:
</label>
<div
id=
"selected_ingredients"
class=
"selected-ingredients-container"
></div>
</div>
<!-- Modal para ingresar la cantidad del ingrediente -->
<div
class=
"modal fade"
id=
"quantityModal"
tabindex=
"-1"
role=
"dialog"
aria-labelledby=
"quantityModalLabel"
aria-hidden=
"true"
>
<div
class=
"modal-dialog"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
id=
"quantityModalLabel"
>
Ingresa la cantidad
</h5>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"Close"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
<div
class=
"form-group"
>
<label
for=
"selected_ingredients"
>
Selected Ingredients:
</label>
<div
id=
"selected_ingredients"
class=
"form-control"
></div>
<label
for=
"ingredient_quantity"
>
Cantidad
</label>
<input
type=
"text"
class=
"form-control"
id=
"ingredient_quantity"
name=
"ingredient_quantity"
placeholder=
"Ej: 2 tazas"
>
</div>
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
class=
"btn btn-secondary"
data-dismiss=
"modal"
>
Cancelar
</button>
<button
type=
"button"
class=
"btn btn-primary"
id=
"save_quantity"
>
Guardar
</button>
</div>
</div>
</div>
</div>
<!--Seleccionar foto -->
<div
class=
"form-group"
>
<label
for=
"recipe_photo"
>
Upload a Ph
oto:
</label>
<label
for=
"recipe_photo"
>
Subir una f
oto:
</label>
<input
type=
"file"
id=
"recipe_photo"
name=
"recipe_photo"
accept=
"image/*"
class=
"form-control-file"
>
</div>
<div
class=
"form-group"
>
<label
for=
"recipe_video"
>
Ingrese el enlace del video:
</label>
<input
type=
"text"
id=
"recipe_video"
name=
"recipe_video"
class=
"form-control"
>
<input
type=
"text"
id=
"recipe_video"
name=
"recipe_video"
class=
"form-control"
placeholder=
"ej: https://www.youtube.com/watch?v=cks8liHVdZg"
>
</div>
<input
type=
"submit"
value=
"
Upload Recipe
"
class=
"btn btn-primary"
>
<input
type=
"submit"
value=
"
Subir receta
"
class=
"btn btn-primary"
>
</form>
<script>
// Seleccionar elementos DOM
const
ingredientSearch
=
document
.
querySelector
(
'#ingredient_search'
);
const
addIngredientBtn
=
document
.
querySelector
(
'#add_ingredient_btn'
);
const
selectedIngredients
=
document
.
querySelector
(
'#selected_ingredients'
);
// Array para almacenar palabras clave seleccionadas
let
ingredients
=
[];
// Función para agregar una palabra clave
function
addIngredient
()
{
const
ingredient
=
ingredientSearch
.
value
.
trim
();
// Agregar la palabra clave al array y actualizar el campo de selección
if
(
ingredient
&&
!
ingredients
.
includes
(
ingredient
))
{
ingredients
.
push
(
ingredient
);
updateSelectedIngredients
();
ingredientSearch
.
value
=
''
;
}
}
// Función para eliminar una palabra clave
function
removeIngredient
(
ingredient
)
{
// Eliminar la palabra clave del array y actualizar el campo de selección
ingredients
=
ingredients
.
filter
(
function
(
value
)
{
return
value
!=
ingredient
;
});
updateSelectedIngredients
();
}
// Función para actualizar el campo de selección de palabras clave
function
updateSelectedIngredients
()
{
// Limpiar el campo de selección
selectedIngredients
.
innerHTML
=
''
;
// Agregar cada palabra clave seleccionada al campo de selección
ingredients
.
forEach
(
function
(
ingredient
)
{
const
ingredientElement
=
document
.
createElement
(
'div'
);
ingredientElement
.
classList
.
add
(
'selected-ingredient'
);
ingredientElement
.
textContent
=
ingredient
;
const
removeBtn
=
document
.
createElement
(
'button'
);
removeBtn
.
classList
.
add
(
'btn'
,
'btn-danger'
,
'btn-sm'
);
removeBtn
.
textContent
=
'x'
;
removeBtn
.
addEventListener
(
'click'
,
function
()
{
removeIngredient
(
ingredient
);
});
ingredientElement
.
appendChild
(
removeBtn
);
selectedIngredients
.
appendChild
(
ingredientElement
);
});
}
// Agregar evento para agregar ingredientes cuando se hace clic en el botón "Add"
addIngredientBtn
.
addEventListener
(
'click'
,
function
()
{
addIngredient
();
});
// Agregar evento para agregar ingredientes cuando se presiona Enter en el campo de búsqueda
ingredientSearch
.
addEventListener
(
'keydown'
,
function
(
event
)
{
// Verificar si la tecla presionada es "Enter"
if
(
event
.
key
===
'Enter'
)
{
event
.
preventDefault
();
// Prevenir el envío del formulario
addIngredient
();
}
});
</script>
<script
src=
"
<?=
base_url
(
"js/insert.js"
)
?>
"
></script>
</section>
...
...
app/Views/pages/recipe_view.php
View file @
dd539db1
...
...
@@ -76,7 +76,7 @@ function getYoutubeVideoId($url) {
}
</style>
<main
id=
"main"
class=
"main"
>
<main
id=
"main"
class=
"main
view
"
>
<section
class=
"section dashboard"
>
...
...
public/css/insert.css
View file @
dd539db1
...
...
@@ -19,7 +19,6 @@ body {
.my-form
input
[
type
=
"search"
],
.my-form
textarea
{
background-color
:
#f5f5f5
;
border
:
none
;
border-radius
:
5px
;
padding
:
10px
;
margin-bottom
:
10px
;
...
...
@@ -46,7 +45,6 @@ body {
.my-form
select
{
background-color
:
#f5f5f5
;
border
:
none
;
border-radius
:
5px
;
padding
:
10px
;
margin-bottom
:
10px
;
...
...
@@ -99,7 +97,7 @@ body {
}
}
/* Estilos para el botón "x" en el campo de selección de ingredientes */
.selected-ingredient
button
{
.selected-ingredient
button
{
background-color
:
#f8d7da
;
border
:
none
;
border-radius
:
50%
;
...
...
@@ -114,7 +112,72 @@ body {
width
:
1.5rem
;
}
.selected-ingredient
button
:hover
{
background-color
:
#721c24
;
color
:
#fff
;
}
/* Agregar estilos para la lista desplegable de ingredientes */
.ingredients-list
{
margin-top
:
5px
;
max-height
:
200px
;
overflow-y
:
auto
;
}
.ingredient-item
{
cursor
:
pointer
;
transition
:
background-color
0.2s
ease
;
}
.ingredient-item
:hover
{
background-color
:
#e2e2e2
;
}
.ingredient-icon
{
width
:
24px
;
height
:
24px
;
}
/* Estilos para el contenedor de ingredientes seleccionados */
.selected-ingredients-container
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
5px
;
padding
:
5px
;
border
:
1px
solid
#ced4da
;
border-radius
:
0.25rem
;
min-height
:
38px
;
align-items
:
center
;
}
.selected-ingredient
{
display
:
flex
;
align-items
:
center
;
background-color
:
#f5f5f5
;
border-radius
:
4px
;
padding
:
4px
8px
;
font-size
:
0.875rem
;
color
:
#333
;
margin
:
0
5px
5px
0
;
}
/* Estilos para el botón "x" en el campo de selección de ingredientes */
.selected-ingredient
button
{
background-color
:
#f8d7da
;
border-radius
:
50%
;
color
:
#721c24
;
cursor
:
pointer
;
font-size
:
0.8rem
;
height
:
1.5rem
;
line-height
:
0.8rem
;
margin-left
:
0.5rem
;
padding
:
0
;
transition
:
background-color
0.3s
ease
;
width
:
1.5rem
;
}
.selected-ingredient
button
:hover
{
background-color
:
#721c24
;
color
:
#fff
;
}
public/js/insert.js
View file @
dd539db1
// Seleccionar elementos DOM
const
ingredientSearch
=
document
.
querySelector
(
'#ingredient_search'
);
const
selectedIngredients
=
document
.
querySelector
(
'#selected_ingredients'
);
//jQuery time
var
current_fs
,
next_fs
,
previous_fs
;
//fieldsets
var
left
,
opacity
,
scale
;
//fieldset properties which we will animate
var
animating
;
//flag to prevent quick multi-click glitches
$
(
".next"
).
click
(
function
(){
if
(
animating
)
return
false
;
animating
=
true
;
current_fs
=
$
(
this
).
parent
();
next_fs
=
$
(
this
).
parent
().
next
();
//activate next step on progressbar using the index of next_fs
$
(
"#progressbar li"
).
eq
(
$
(
"fieldset"
).
index
(
next_fs
)).
addClass
(
"active"
);
//show the next fieldset
next_fs
.
show
();
//hide the current fieldset with style
current_fs
.
animate
({
opacity
:
0
},
{
step
:
function
(
now
,
mx
)
{
//as the opacity of current_fs reduces to 0 - stored in "now"
//1. scale current_fs down to 80%
scale
=
1
-
(
1
-
now
)
*
0.2
;
//2. bring next_fs from the right(50%)
left
=
(
now
*
50
)
+
"%"
;
//3. increase opacity of next_fs to 1 as it moves in
opacity
=
1
-
now
;
current_fs
.
css
({
'transform'
:
'scale('
+
scale
+
')'
,
'position'
:
'absolute'
});
next_fs
.
css
({
'left'
:
left
,
'opacity'
:
opacity
});
},
duration
:
800
,
complete
:
function
(){
current_fs
.
hide
();
animating
=
false
;
// Array para almacenar palabras clave seleccionadas
let
ingredients
=
[];
function
searchIngredients
(
query
)
{
fetch
(
'/search_ingredient'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'X-Requested-With'
:
'XMLHttpRequest'
// Añadir esta línea
},
//this comes from the custom easing plugin
easing
:
'easeInOutBack'
body
:
'query='
+
encodeURIComponent
(
query
)
})
.
then
((
response
)
=>
response
.
json
())
.
then
((
searchResults
)
=>
{
// Limpiar la lista de ingredientes coincidentes anterior
const
ingredientsList
=
document
.
querySelector
(
'#ingredients_list'
);
ingredientsList
.
innerHTML
=
''
;
// Agregar ingredientes coincidentes a la lista desplegable
searchResults
.
forEach
((
ingredient
)
=>
{
const
listItem
=
document
.
createElement
(
'li'
);
listItem
.
classList
.
add
(
'ingredient-item'
,
'd-flex'
,
'align-items-center'
,
'p-2'
,
'mb-1'
,
'bg-light'
,
'rounded'
);
const
iconElement
=
document
.
createElement
(
'img'
);
iconElement
.
setAttribute
(
'src'
,
'../imagenes/ingredientes/'
+
ingredient
.
icon
);
iconElement
.
setAttribute
(
'alt'
,
ingredient
.
name
+
' icon'
);
iconElement
.
classList
.
add
(
'ingredient-icon'
,
'mr-2'
);
listItem
.
appendChild
(
iconElement
);
const
nameElement
=
document
.
createElement
(
'span'
);
nameElement
.
textContent
=
ingredient
.
name
;
nameElement
.
classList
.
add
(
'ingredient-name'
,
'flex-grow-1'
);
listItem
.
appendChild
(
nameElement
);
listItem
.
setAttribute
(
'data-id'
,
ingredient
.
id
);
listItem
.
setAttribute
(
'title'
,
'Haz clic para seleccionar '
+
ingredient
.
name
);
// Añade información adicional al ingrediente
listItem
.
addEventListener
(
'click'
,
function
()
{
$
(
"#quantityModal"
).
modal
(
"show"
);
const
saveQuantityBtn
=
document
.
getElementById
(
"save_quantity"
);
saveQuantityBtn
.
onclick
=
function
()
{
const
quantity
=
document
.
getElementById
(
"ingredient_quantity"
).
value
;
if
(
quantity
)
{
addIngredient
(
ingredient
.
name
,
ingredient
.
id
,
quantity
);
$
(
"#quantityModal"
).
modal
(
"hide"
);
document
.
getElementById
(
"ingredient_quantity"
).
value
=
""
;
}
};
});
});
ingredientsList
.
appendChild
(
listItem
);
});
});
}
$
(
".previous"
).
click
(
function
(){
if
(
animating
)
return
false
;
animating
=
true
;
current_fs
=
$
(
this
).
parent
();
previous_fs
=
$
(
this
).
parent
().
prev
();
//de-activate current step on progressbar
$
(
"#progressbar li"
).
eq
(
$
(
"fieldset"
).
index
(
current_fs
)).
removeClass
(
"active"
);
//show the previous fieldset
previous_fs
.
show
();
//hide the current fieldset with style
current_fs
.
animate
({
opacity
:
0
},
{
step
:
function
(
now
,
mx
)
{
//as the opacity of current_fs reduces to 0 - stored in "now"
//1. scale previous_fs from 80% to 100%
scale
=
0.8
+
(
1
-
now
)
*
0.2
;
//2. take current_fs to the right(50%) - from 0%
left
=
((
1
-
now
)
*
50
)
+
"%"
;
//3. increase opacity of previous_fs to 1 as it moves in
opacity
=
1
-
now
;
current_fs
.
css
({
'left'
:
left
});
previous_fs
.
css
({
'transform'
:
'scale('
+
scale
+
')'
,
'opacity'
:
opacity
});
},
duration
:
800
,
complete
:
function
(){
current_fs
.
hide
();
animating
=
false
;
},
//this comes from the custom easing plugin
easing
:
'easeInOutBack'
// Función para agregar un ingrediente
function
addIngredient
(
ingredientName
,
ingredientId
)
{
// Agregar el ingrediente al array y actualizar el campo de selección
if
(
ingredientName
&&
!
ingredients
.
find
(
ing
=>
ing
.
name
===
ingredientName
))
{
ingredients
.
push
({
name
:
ingredientName
,
id
:
ingredientId
});
updateSelectedIngredients
();
ingredientSearch
.
value
=
''
;
}
}
// Función para eliminar una palabra clave
function
removeIngredient
(
ingredient
)
{
// Eliminar la palabra clave del array y actualizar el campo de selección
ingredients
=
ingredients
.
filter
(
function
(
value
)
{
return
value
!=
ingredient
;
});
updateSelectedIngredients
();
}
// Función para actualizar el campo de selección de palabras clave
function
updateSelectedIngredients
()
{
// Limpiar el campo de selección
selectedIngredients
.
innerHTML
=
''
;
// Agregar cada ingrediente seleccionado al campo de selección
ingredients
.
forEach
(
function
(
ingredient
)
{
const
ingredientElement
=
document
.
createElement
(
'div'
);
ingredientElement
.
classList
.
add
(
'selected-ingredient'
);
ingredientElement
.
setAttribute
(
'data-id'
,
ingredient
.
id
);
// Crear el elemento de imagen para el icono del ingrediente
const
iconElement
=
document
.
createElement
(
'img'
);
iconElement
.
classList
.
add
(
'ingredient-icon'
);
iconElement
.
src
=
'../imagenes/ingredientes/'
+
ingredient
.
icon
;
ingredientElement
.
appendChild
(
iconElement
);
const
ingredientNameAndQuantity
=
document
.
createTextNode
(
`
${
ingredient
.
name
}
(
${
ingredient
.
quantity
}
)`
);
ingredientElement
.
appendChild
(
ingredientNameAndQuantity
);
const
removeBtn
=
document
.
createElement
(
'button'
);
removeBtn
.
classList
.
add
(
'btn'
,
'btn-danger'
,
'btn-sm'
);
removeBtn
.
textContent
=
'x'
;
removeBtn
.
addEventListener
(
'click'
,
function
()
{
removeIngredient
(
ingredient
);
});
ingredientElement
.
appendChild
(
removeBtn
);
selectedIngredients
.
appendChild
(
ingredientElement
);
// Crear un campo oculto para almacenar el ID y la cantidad del ingrediente seleccionado
const
hiddenInputId
=
document
.
createElement
(
'input'
);
hiddenInputId
.
setAttribute
(
'type'
,
'hidden'
);
hiddenInputId
.
setAttribute
(
'name'
,
'selected_ingredient_ids[]'
);
hiddenInputId
.
setAttribute
(
'value'
,
ingredient
.
id
);
ingredientElement
.
appendChild
(
hiddenInputId
);
const
hiddenInputQuantity
=
document
.
createElement
(
'input'
);
hiddenInputQuantity
.
setAttribute
(
'type'
,
'hidden'
);
hiddenInputQuantity
.
setAttribute
(
'name'
,
'selected_ingredient_quantities[]'
);
hiddenInputQuantity
.
setAttribute
(
'value'
,
ingredient
.
quantity
);
ingredientElement
.
appendChild
(
hiddenInputQuantity
);
selectedIngredients
.
appendChild
(
ingredientElement
);
});
}
// Agregar evento para agregar ingredientes cuando se presiona Enter en el campo de búsqueda
ingredientSearch
.
addEventListener
(
'input'
,
function
(
event
)
{
// Llamar a la función searchIngredients para buscar y mostrar ingredientes coincidentes
searchIngredients
(
event
.
target
.
value
);
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment