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
0a9b0608
authored
May 07, 2023
by
Juan Montilla
Committed by
Manuel Ruiz Toribio
May 09, 2023
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
ajax
parent
83dd03bb
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1008 additions
and
822 deletions
app/Config/Routes.php
app/Controllers/RecipesController.php
app/Models/RecipesModel.php
app/Views/pages/home.php
app/Views/pages/insertRecipe.php
app/Views/pages/recipe_view.php
app/Views/templates/header.php
public/css/style.css
public/imagenes/2729270.png
public/js/insert.js
public/js/main.js
app/Config/Routes.php
View file @
0a9b0608
...
...
@@ -38,6 +38,8 @@ $routes->match(['get', 'post'], '/registerAjax', [User::class, 'registerAjax']);
$routes
->
match
([
'get'
],
'/home'
,
[
User
::
class
,
'user_ok'
]);
$routes
->
get
(
'/recipe/(:num)'
,
'RecipesController::view_recipe/$1'
);
// Ruta para obtener una imagen de una receta dado un id
$routes
->
get
(
'recipe/image/(:num)'
,
'RecipesController::show_image/$1'
);
...
...
@@ -46,15 +48,19 @@ $routes->get('/insert_recipe', 'InsertRecipeController::index');
$routes
->
match
([
'get'
,
'post'
],
'/search_ingredient'
,
'InsertRecipeController::search_ingredient'
);
$routes
->
post
(
'/insert_recipe'
,
'InsertRecipeController::insert_recipe'
);
// Ruta para la búsqueda de recetas
$routes
->
match
([
'get'
,
'post'
],
'/search_recipe'
,
'RecipesController::search_recipe'
);
$routes
->
post
(
'filter_recipes'
,
'RecipesController::get_filtered_recipes'
);
$routes
->
get
(
'login'
,
'Pages::viewLogin'
);
$routes
->
get
(
'users'
,
'User::list'
);
$routes
->
get
(
'home'
,
'Pages::prueba'
);
$routes
->
get
(
'(:segment)'
,
'Home::index'
);
$routes
->
get
(
'/recipe/(:num)'
,
'RecipesController::view_recipe/$1'
);
...
...
app/Controllers/RecipesController.php
View file @
0a9b0608
...
...
@@ -25,7 +25,7 @@ class RecipesController extends Controller
];
return
view
(
'templates/header'
,
$data
)
.
view
(
'pages/recipe_view'
,
$data
)
.
view
(
'pages/recipe_view'
)
.
view
(
'templates/footer'
);
}
...
...
@@ -45,25 +45,26 @@ class RecipesController extends Controller
}
}
//public function search_recipe() {
// Obtener la consulta de búsqueda desde el formulario
// $query = $this->request->getVar('query');
// Cargar el modelo de ingredientes (si no lo has hecho)
//$recipesModel = new \App\Models\RecipesModel();
// Buscar ingredientes en la base de datos que coincidan con la consulta
// $recipes = $recipesModel->search_recipe($query);
// Devolver los ingredientes coincidentes en formato JSON
// return $this->response->setJSON($recipes);
// }
public
function
search_recipe
()
{
$query
=
$this
->
request
->
getVar
(
'query'
);
$recipesModel
=
new
\App\Models\RecipesModel
();
$recipes
=
$recipesModel
->
search
_r
ecipe
(
$query
);
$recipes
=
$recipesModel
->
search
R
ecipe
(
$query
);
return
$this
->
response
->
setJSON
(
$recipes
);
}
// En tu controlador de recetas
public
function
get_filtered_recipes
()
{
$recipesModel
=
new
\App\Models\RecipesModel
();
$vegan
=
$this
->
request
->
getPost
(
'is_vegan'
)
==
"true"
?
true
:
false
;
$country
=
$this
->
request
->
getPost
(
'origin'
);
$season
=
$this
->
request
->
getPost
(
'season'
);
$filtered_recipes
=
$recipesModel
->
get_filtered_recipes
(
$vegan
,
$country
,
$season
);
return
$this
->
response
->
setJSON
(
$filtered_recipes
);
}
}
\ No newline at end of file
app/Models/RecipesModel.php
View file @
0a9b0608
...
...
@@ -3,7 +3,7 @@ namespace App\Models;
use
CodeIgniter\Model
;
class
r
ecipesModel
extends
Model
class
R
ecipesModel
extends
Model
{
protected
$table
=
'recipes'
;
protected
$primaryKey
=
'id'
;
...
...
@@ -11,7 +11,7 @@ class recipesModel extends Model
protected
$returnType
=
'object'
;
# 'object' or 'array'
protected
$useSoftDeletes
=
false
;
# true if you expect to recover data
# Fields that can be set during save, insert, or update methods
protected
$allowedFields
=
[
'id'
,
'name'
,
'season'
,
'origin'
,
'photo'
,
'is_vegan'
,
'description'
,
'instructions'
,
'link'
];
protected
$allowedFields
=
[
'id'
,
'name'
,
'season'
,
'origin'
,
'photo'
,
'is_vegan'
,
'description'
,
'instructions'
,
'link'
];
protected
$useTimestamps
=
false
;
# no timestamps on inserts and updates
# Do not use validations rules (for the time being...)
protected
$validationRules
=
[];
...
...
@@ -35,7 +35,8 @@ class recipesModel extends Model
return
$this
->
insert
(
$data
);
}
public
function
get_recipe_ingredients
(
$recipe_id
)
{
public
function
get_recipe_ingredients
(
$recipe_id
)
{
$builder
=
$this
->
db
->
table
(
'recipes_ingredient'
);
$builder
->
select
(
'ingredient.name, ingredient.icon, recipes_ingredient.amount'
);
$builder
->
join
(
'ingredient'
,
'recipes_ingredient.id_ingredient = ingredient.id'
);
...
...
@@ -43,21 +44,40 @@ class recipesModel extends Model
$query
=
$builder
->
get
();
return
$query
->
getResult
();
}
/* public function search_recipe($query)
public
function
searchRecipe
(
$query
)
{
if
(
$query
)
{
// Seleccionar todas las columnas excepto 'photo'
$this
->
select
(
'id, name, season, origin, is_vegan, description, instructions, link'
);
return
$this
->
like
(
'name'
,
$query
)
->
findAll
();
}
return
[];
}
*/
}
public
function
search_recipe
(
$query
)
{
if
(
$query
)
{
return
$this
->
like
(
'name'
,
$query
)
->
findAll
();
public
function
get_filtered_recipes
(
$vegan
,
$country
,
$season
)
{
$builder
=
$this
->
db
->
table
(
'recipes'
);
if
(
$vegan
)
{
$builder
->
where
(
'is_vegan'
,
true
);
}
return
[];
if
(
!
empty
(
$country
))
{
$builder
->
where
(
'origin'
,
$country
);
}
if
(
!
empty
(
$season
))
{
$builder
->
where
(
'season'
,
$season
);
}
$query
=
$builder
->
get
();
return
$query
->
getResult
();
}
}
\ No newline at end of file
app/Views/pages/home.php
View file @
0a9b0608
<!-- ======= Sidebar ======= -->
<aside
id=
"sidebar"
class=
"sidebar"
>
<ul
class=
"sidebar-nav"
id=
"sidebar-nav"
>
<li
class=
"nav-item"
>
<a
class=
"nav-link "
href=
"index.html"
>
<i
class=
"bi bi-grid"
></i>
<span>
Recetas
</span>
</a>
</li>
<!-- End Dashboard Nav -->
<!-- Filtro 1-->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Filtro Vegano
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"vegan-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxOne"
value=
"Order one"
>
<label
for=
"checkboxOne"
>
Recetas Veganas
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<!-- Filtro 1-->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav2"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Filtro 2
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav2"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"indian-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxFour"
value=
"Order four"
>
<label
for=
"checkboxFour"
>
India
</label>
</li>
</ul>
<ul
class=
"french-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxFive"
value=
"Order five"
>
<label
for=
"checkboxFive"
>
Francia
</label>
</li>
</ul>
<ul
class=
"chinese-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxSix"
value=
"Order six"
>
<label
for=
"checkboxSix"
>
China
</label>
</li>
</ul>
<ul
class=
"mexican-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxSeven"
value=
"Order seven"
>
<label
for=
"checkboxSeven"
>
México
</label>
</li>
</ul>
<ul
class=
"spanish-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxEight"
value=
"Order eigth"
>
<label
for=
"checkboxEight"
>
España
</label>
</li>
</ul>
<ul
class=
"japanese-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxNine"
value=
"Order nine"
>
<label
for=
"checkboxNine"
>
Japón
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav3"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Estaciones
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav3"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"winter-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxTen"
value=
"Order ten"
>
<label
for=
"checkboxTen"
>
Invierno
</label>
</li>
</ul>
<ul
class=
"spring-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxEleven"
value=
"Order eleven"
>
<label
for=
"checkboxEleven"
>
Primavera
</label>
</li>
</ul>
<ul
class=
"summer-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxTwelve"
value=
"Order twelve"
>
<label
for=
"checkboxTwelve"
>
Verano
</label>
</li>
</ul>
<ul
class=
"autumn-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkbox13"
value=
"Order 13"
>
<label
for=
"checkbox13"
>
Otoño
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/insert_recipe"
>
<i
class=
"bi bi-file-earmark"
></i>
<span>
Subir receta
</span>
</a>
</li>
<!-- End Profile Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"https://www.instagram.com/salvaperfectti/"
>
<i
class=
"bi bi-envelope"
></i>
<span>
Contacto
</span>
</a>
</li>
<!-- End Contact Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/login"
>
<i
class=
"bi bi-box-arrow-in-right"
></i>
<span>
Registro/Login
</span>
</a>
</li>
<!-- End Login Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"http://www.homerswebpage.com/"
>
<i
class=
"bi bi-dash-circle"
></i>
<span>
Error 404
</span>
</a>
</li>
<!-- End Error 404 Page Nav -->
</ul>
</aside>
<!-- End Sidebar-->
<main
id=
"main"
class=
"main"
>
<div
class=
"pagetitle"
>
<h1>
Recetas
</h1>
<nav>
...
...
@@ -169,8 +12,8 @@
</nav>
</div>
<!-- End Page Title -->
<section
class=
"section dashboard"
>
<section
class=
"section dashboard"
id=
"recipeSection"
>
<div
id=
"recipeCards"
>
<?php
$recipesModel
=
new
\App\Models\RecipesModel
();
$recipes
=
$recipesModel
->
findAll
();
...
...
@@ -179,59 +22,157 @@
foreach
(
$recipes
as
$row
)
{
$ingredients
=
$recipesModel
->
get_recipe_ingredients
(
$row
->
id
);
?>
<!-- Inicio de la tarjeta de la receta -->
<div
class=
"recipe-card-wrapper"
>
<a
href=
"
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
"
class=
"recipe-card-link"
>
<div
class=
"card info-card sales-card"
>
<div
class=
"row"
>
<div
class=
"col-md-3 imagen-container"
>
<img
src=
"
<?php
echo
base_url
(
'recipe/image/'
.
$row
->
id
);
?>
"
alt=
""
class=
"img-fluid rounded-start"
>
</div>
<div
class=
"col-md-9"
>
<div
class=
"filter"
>
<a
class=
"icon"
href=
"#"
data-bs-toggle=
"dropdown"
><i
class=
"bi bi-three-dots"
></i></a>
<ul
class=
"dropdown-menu dropdown-menu-end dropdown-menu-arrow"
>
<li
class=
"dropdown-header text-start"
>
<h6>
Opciones
</h6>
</li>
<li><a
class=
"dropdown-item"
href=
"#"
>
Guardar
</a></li>
<li><a
class=
"dropdown-item"
href=
"#"
>
Compartir
</a></li>
</ul>
</div>
<div
class=
"card info-card sales-card"
onclick=
"window.location.href='
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
'"
>
<a
href=
"
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
"
>
</a>
<div
class=
"row flex-nowrap"
>
<div
class=
"col-lg-3 col-md-4 col-sm-12 imagen-container"
>
<img
src=
"
<?php
echo
base_url
(
'recipe/image/'
.
$row
->
id
);
?>
"
alt=
""
class=
"img-fluid rounded-start"
>
</div>
<div
class=
"col-lg-9 col-md-8 col-sm-12"
>
<div
class=
"filter"
>
<a
class=
"icon"
href=
"#"
data-bs-toggle=
"dropdown"
><i
class=
"bi bi-three-dots"
></i></a>
<ul
class=
"dropdown-menu dropdown-menu-end dropdown-menu-arrow"
>
<li
class=
"dropdown-header text-start"
>
<h6>
Opciones
</h6>
</li>
<li><a
class=
"dropdown-item"
href=
"#"
>
Guardar
</a></li>
<li><a
class=
"dropdown-item"
href=
"#"
>
Compartir
</a></li>
</ul>
</div>
<div
class=
"card-body"
>
<h5
class=
"card-title"
>
<?php
echo
$row
->
name
;
?>
<span>
|
<?php
echo
$row
->
origin
;
?>
</span>
</h5>
<!--ingredientes-->
<?php
foreach
(
$ingredients
as
$ingredient
)
{
?>
<div
class=
"chip"
title=
"Cantidad:
<?php
echo
$ingredient
->
amount
;
?>
"
>
<img
src=
"imagenes/ingredientes/
<?php
echo
$ingredient
->
icon
;
?>
"
>
<b
style=
"font-size: 14px"
>
<?php
echo
$ingredient
->
name
;
?>
</b>
</div>
<?php
}
?>
<!--fin ingredientes-->
<div
class=
"card-body"
>
<h5
class=
"card-title"
>
<?php
echo
$row
->
name
;
?>
<span>
|
<?php
echo
$row
->
origin
;
?>
</span>
</h5>
<!--ingredientes-->
<?php
foreach
(
$ingredients
as
$ingredient
)
{
?>
<div
class=
"chip"
title=
"Cantidad:
<?php
echo
$ingredient
->
amount
;
?>
"
>
<img
src=
"imagenes/ingredientes/
<?php
echo
$ingredient
->
icon
;
?>
"
>
<b
style=
"font-size: 14px"
>
<?php
echo
$ingredient
->
name
;
?>
</b>
</div>
</div>
<?php
}
?>
<!--fin ingredientes-->
</div>
</div>
</
a
>
</
div
>
</div>
<!-- Fin de la tarjeta de la receta -->
<?php
}
}
?>
</div>
</section>
</main>
<!-- End #main -->
</section>
<script>
function
updateRecipeList
()
{
// Obtén el estado de los checkboxes
var
vegan
=
document
.
getElementById
(
"checkboxOne"
).
checked
;
var
countries
=
[
'India'
,
'Francia'
,
'China'
,
'México'
,
'España'
,
'Japón'
];
var
country
=
''
;
</main>
<!-- End #main -->
\ No newline at end of file
var
checkboxes
=
document
.
querySelectorAll
(
'input[type=checkbox]'
);
for
(
var
i
=
0
;
i
<
checkboxes
.
length
;
i
++
)
{
if
(
checkboxes
[
i
].
checked
&&
countries
.
includes
(
checkboxes
[
i
].
nextElementSibling
.
innerText
))
{
country
=
checkboxes
[
i
].
nextElementSibling
.
innerText
;
break
;
}
}
var
seasons
=
[
'Invierno'
,
'Primavera'
,
'Verano'
,
'Otoño'
];
var
season
=
''
;
for
(
var
i
=
0
;
i
<
checkboxes
.
length
;
i
++
)
{
if
(
checkboxes
[
i
].
checked
&&
seasons
.
includes
(
checkboxes
[
i
].
nextElementSibling
.
innerText
))
{
season
=
checkboxes
[
i
].
nextElementSibling
.
innerText
;
break
;
}
}
// Enviar una solicitud AJAX a tu controlador de recetas
var
xhr
=
new
XMLHttpRequest
();
xhr
.
open
(
"POST"
,
"/filter_recipes"
,
true
);
xhr
.
setRequestHeader
(
"Content-Type"
,
"application/x-www-form-urlencoded"
);
xhr
.
onreadystatechange
=
function
()
{
if
(
this
.
readyState
===
4
&&
this
.
status
===
200
)
{
// Actualizar el contenido de la página con las recetas filtradas
var
recipes
=
JSON
.
parse
(
this
.
responseText
);
var
recipeList
=
document
.
getElementById
(
"recipeCards"
);
recipeList
.
innerHTML
=
''
;
// Limpiar la lista de recetas
for
(
var
i
=
0
;
i
<
recipes
.
length
;
i
++
)
{
var
recipeHTML
=
generateRecipeHTML
(
recipes
[
i
]);
recipeList
.
innerHTML
+=
recipeHTML
;
}
}
};
xhr
.
send
(
"is_vegan="
+
vegan
+
"&origin="
+
country
+
"&season="
+
season
);
}
function
generateRecipeHTML
(
recipe
)
{
var
recipeHTML
=
`
<div class="card info-card sales-card"
onclick="window.location.href='
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
'">
<a href="
<?php
echo
base_url
(
'recipe/'
.
$row
->
id
);
?>
">
</a>
<div class="row flex-nowrap">
<div class="col-lg-3 col-md-4 col-sm-12 imagen-container">
<img src="
<?php
echo
base_url
(
'recipe/image/'
.
$row
->
id
);
?>
" alt=""
class="img-fluid rounded-start">
</div>
<div class="col-lg-9 col-md-8 col-sm-12">
<div class="filter">
<a class="icon" href="#" data-bs-toggle="dropdown"><i class="bi bi-three-dots"></i></a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
<li class="dropdown-header text-start">
<h6>Opciones</h6>
</li>
<li><a class="dropdown-item" href="#">Guardar</a></li>
<li><a class="dropdown-item" href="#">Compartir</a></li>
</ul>
</div>
<div class="card-body">
<h5 class="card-title">
<?php
echo
$row
->
name
;
?>
<span>|
<?php
echo
$row
->
origin
;
?>
</span>
</h5>
<!--ingredientes-->
<?php
foreach
(
$ingredients
as
$ingredient
)
{
?>
<div class="chip" title="Cantidad:
<?php
echo
$ingredient
->
amount
;
?>
">
<img src="imagenes/ingredientes/
<?php
echo
$ingredient
->
icon
;
?>
">
<b style="font-size: 14px">
<?php
echo
$ingredient
->
name
;
?>
</b>
</div>
<?php
}
?>
<!--fin ingredientes-->
</div>
</div>
</div>
</div>`
;
return
recipeHTML
;
}
document
.
addEventListener
(
'DOMContentLoaded'
,
(
event
)
=>
{
updateRecipeList
();
});
</script>
\ No newline at end of file
app/Views/pages/insertRecipe.php
View file @
0a9b0608
...
...
@@ -42,9 +42,8 @@
<select
id=
"origin"
name=
"origin"
class=
"form-control"
>
<option
value=
"Española"
>
Española
</option>
<option
value=
"Francesa"
>
Francesa
</option>
<option
value=
"Italiana"
>
Italian
a
</option>
<option
value=
"Italiana"
>
Japones
a
</option>
<option
value=
"Mexiana"
>
Mexicana
</option>
<option
value=
"Americana"
>
Americana
</option>
<option
value=
"China"
>
China
</option>
<option
value=
"India"
>
India
</option>
</select>
...
...
app/Views/pages/recipe_view.php
View file @
0a9b0608
<?php
function
getYoutubeVideoId
(
$url
)
{
function
getYoutubeVideoId
(
$url
)
{
$pattern
=
'/^(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i'
;
preg_match
(
$pattern
,
$url
,
$matches
);
return
isset
(
$matches
[
1
])
?
$matches
[
1
]
:
null
;
...
...
@@ -7,112 +8,124 @@ function getYoutubeVideoId($url) {
?>
<style>
body
{
font-family
:
Arial
,
sans-serif
;
margin
:
0
;
padding
:
0
;
}
.container
{
max-width
:
960px
;
margin
:
0
auto
;
padding
:
20px
;
}
.recipe-header
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
margin-bottom
:
30px
;
}
.recipe-header
img
{
width
:
100%
;
max-width
:
600px
;
height
:
auto
;
object-fit
:
cover
;
border-radius
:
8px
;
}
.ingredient-list
{
display
:
flex
;
flex-wrap
:
wrap
;
list-style-type
:
none
;
padding
:
0
;
margin
:
0
;
margin-bottom
:
30px
;
}
.ingredient-item
{
display
:
flex
;
align-items
:
center
;
width
:
50%
;
padding
:
5px
0
;
}
.ingredient-item
img
{
width
:
30px
;
height
:
30px
;
margin-right
:
10px
;
}
.instructions
{
white-space
:
pre-line
;
}
.video-container
{
position
:
relative
;
padding-bottom
:
56.25%
;
/* Relación de aspecto 16:9 */
height
:
0
;
overflow
:
hidden
;
}
.video-container
iframe
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
}
</style>
<main
id=
"mainview"
class=
"mainview"
>
<section
class=
"section dashboard"
>
<div
class=
"container"
>
<div
class=
"recipe-header"
>
<h1>
Receta:
</h1>
<h1>
<?php
echo
$recipe
->
name
;
?>
</h1>
<img
src=
"
<?php
echo
base_url
(
'recipe/image/'
.
$recipe
->
id
);
?>
"
alt=
"
<?php
echo
$recipe
->
name
;
?>
"
/>
</div>
<p>
<?php
echo
$recipe
->
description
;
?>
</p>
<h2>
Ingredientes
</h2>
<ul
class=
"ingredient-list"
>
<?php
foreach
(
$ingredients
as
$ingredient
)
{
?>
<li
class=
"ingredient-item"
>
<img
src=
"../imagenes/ingredientes/
<?php
echo
$ingredient
->
icon
;
?>
"
alt=
"
<?php
echo
$ingredient
->
name
;
?>
"
/>
<span>
<?php
echo
$ingredient
->
name
;
?>
:
<?php
echo
$ingredient
->
amount
;
?>
</span>
</li>
<?php
}
?>
</ul>
<h2>
Instrucciones
</h2>
<p
class=
"instructions"
>
<?php
echo
$recipe
->
instructions
;
?>
</p>
<?php
if
(
!
empty
(
$recipe
->
link
))
:
?>
<?php
$videoId
=
getYoutubeVideoId
(
$recipe
->
link
);
?>
<?php
if
(
$videoId
)
:
?>
<h2>
Video de la receta
</h2>
<div
class=
"video-container"
>
<iframe
width=
"560"
height=
"315"
src=
"https://www.youtube.com/embed/
<?php
echo
$videoId
;
?>
"
title=
"YouTube video player"
frameborder=
"0"
allow=
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
body
{
font-family
:
Arial
,
sans-serif
;
margin
:
0
;
padding
:
0
;
}
.container
{
max-width
:
960px
;
margin
:
0
auto
;
padding
:
20px
;
}
.recipe-header
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
margin-bottom
:
30px
;
}
.recipe-header
img
{
width
:
100%
;
max-width
:
600px
;
height
:
auto
;
object-fit
:
cover
;
border-radius
:
8px
;
}
.ingredient-list
{
display
:
flex
;
flex-wrap
:
wrap
;
list-style-type
:
none
;
padding
:
0
;
margin
:
0
;
margin-bottom
:
30px
;
}
.ingredient-item
{
display
:
flex
;
align-items
:
center
;
width
:
50%
;
padding
:
5px
0
;
}
.ingredient-item
img
{
width
:
30px
;
height
:
30px
;
margin-right
:
10px
;
}
.instructions
{
white-space
:
pre-line
;
}
.video-container
{
position
:
relative
;
padding-bottom
:
56.25%
;
/* Relación de aspecto 16:9 */
height
:
0
;
overflow
:
hidden
;
}
.video-container
iframe
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
}
</style>
<main
id=
"main"
class=
"main"
>
<section
class=
"section dashboard"
>
<div
class=
"container"
>
<div
class=
"recipe-header"
>
<h1>
<?php
echo
$recipe
->
name
;
?>
</h1>
<img
src=
"
<?php
echo
base_url
(
'recipe/image/'
.
$recipe
->
id
);
?>
"
alt=
"
<?php
echo
$recipe
->
name
;
?>
"
/>
</div>
<p>
<?php
echo
$recipe
->
description
;
?>
</p>
<h2>
Ingredientes
</h2>
<ul
class=
"ingredient-list"
>
<?php
foreach
(
$ingredients
as
$ingredient
)
{
?>
<li
class=
"ingredient-item"
>
<img
src=
"../imagenes/ingredientes/
<?php
echo
$ingredient
->
icon
;
?>
"
alt=
"
<?php
echo
$ingredient
->
name
;
?>
"
/>
<span>
<?php
echo
$ingredient
->
name
;
?>
:
<?php
echo
$ingredient
->
amount
;
?>
</span>
</li>
<?php
}
?>
</ul>
<h2>
Instrucciones
</h2>
<p
class=
"instructions"
>
<?php
echo
$recipe
->
instructions
;
?>
</p>
<?php
if
(
!
empty
(
$recipe
->
link
))
:
?>
<?php
$videoId
=
getYoutubeVideoId
(
$recipe
->
link
);
?>
<?php
if
(
$videoId
)
:
?>
<h2>
Video de la receta
</h2>
<div
class=
"video-container"
>
<iframe
width=
"560"
height=
"315"
src=
"https://www.youtube.com/embed/
<?php
echo
$videoId
;
?>
"
title=
"YouTube video player"
frameborder=
"0"
allow=
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
<?php
endif
;
?>
<?php
endif
;
?>
<?php
endif
;
?>
</div>
</div>
</section>
</main>
<!-- End #main -->
\ No newline at end of file
</main>
<!-- End #main -->
app/Views/templates/header.php
View file @
0a9b0608
...
...
@@ -32,8 +32,8 @@
<link
href=
"
<?=
base_url
(
"css/style.css"
)
?>
"
rel=
"stylesheet"
>
<script
src=
"https://code.jquery.com/jquery-3.6.4.min.js"
integrity=
"sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8="
crossorigin=
"anonymous"
></script>
<script
src=
"js/main.js"
></script>
</head>
...
...
@@ -55,15 +55,15 @@
<i
class=
"bi bi-list toggle-sidebar-btn"
></i>
</div>
<!-- End Logo -->
<!-- Barra de búsqueda -->
<div
class=
"search-bar"
>
<form
class=
"search-form d-flex align-items-center"
method=
"POST"
action=
"#"
>
<input
type=
"text"
id=
"search-query"
name=
"query"
placeholder=
"Buscar por receta..."
title=
"Enter search keyword"
>
</form>
<div
id=
"recipe_dropdown"
class=
"recipe-dropdown"
>
<ul
id=
"recipe_list"
class=
"recipe-list list-unstyled"
></ul>
</div>
</div>
<form
class=
"search-form d-flex align-items-center"
method=
"POST"
action=
"#"
>
<input
type=
"text"
id=
"search-query"
name=
"query"
placeholder=
"Buscar por receta..."
title=
"Enter search keyword"
>
</form>
<ul
id=
"recipe_list"
class=
"ingredients-list list-unstyled"
></ul>
</div>
<!-- Fin barra de búsqueda -->
...
...
@@ -154,4 +154,165 @@
</ul>
</nav>
<!-- End Icons Navigation -->
</header>
<!-- End Header -->
\ No newline at end of file
</header>
<!-- End Header -->
<!-- ======= Sidebar ======= -->
<aside
id=
"sidebar"
class=
"sidebar"
>
<ul
class=
"sidebar-nav"
id=
"sidebar-nav"
>
<li
class=
"nav-item"
>
<a
class=
"nav-link "
href=
"index.html"
>
<i
class=
"bi bi-grid"
></i>
<span>
Recetas
</span>
</a>
</li>
<!-- End Dashboard Nav -->
<!-- Filtro 1-->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Filtro Vegano
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"vegan-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxOne"
value=
"Order one"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxOne"
>
Recetas Veganas
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<!-- Filtro 1-->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav2"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Filtro 2
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav2"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"indian-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxFour"
value=
"Order four"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxFour"
>
India
</label>
</li>
</ul>
<ul
class=
"french-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxFive"
value=
"Order five"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxFive"
>
Francia
</label>
</li>
</ul>
<ul
class=
"chinese-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxSix"
value=
"Order six"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxSix"
>
China
</label>
</li>
</ul>
<ul
class=
"mexican-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxSeven"
value=
"Order seven"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxSeven"
>
México
</label>
</li>
</ul>
<ul
class=
"spanish-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxEight"
value=
"Order eigth"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxEight"
>
España
</label>
</li>
</ul>
<ul
class=
"japanese-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxNine"
value=
"Order nine"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxNine"
>
Japón
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
data-bs-target=
"#tables-nav3"
data-bs-toggle=
"collapse"
href=
"#"
>
<i
class=
"bi bi-layout-text-window-reverse"
></i><span>
Estaciones
</span><i
class=
"bi bi-chevron-down ms-auto"
></i>
</a>
<ul
id=
"tables-nav3"
class=
"nav-content collapse "
data-bs-parent=
"#sidebar-nav"
>
<!--Contenido del dropdown-->
<ul
class=
"winter-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxTen"
value=
"Order ten"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxTen"
>
Invierno
</label>
</li>
</ul>
<ul
class=
"spring-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxEleven"
value=
"Order eleven"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxEleven"
>
Primavera
</label>
</li>
</ul>
<ul
class=
"summer-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkboxTwelve"
value=
"Order twelve"
onchange=
"updateRecipeList()"
>
<label
for=
"checkboxTwelve"
>
Verano
</label>
</li>
</ul>
<ul
class=
"autumn-cboxtags"
>
<li>
<input
type=
"checkbox"
id=
"checkbox13"
value=
"Order 13"
onchange=
"updateRecipeList()"
>
<label
for=
"checkbox13"
>
Otoño
</label>
</li>
</ul>
</ul>
</li>
<!-- Fin Filtro 1 -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/insert_recipe"
>
<i
class=
"bi bi-file-earmark"
></i>
<span>
Subir receta
</span>
</a>
</li>
<!-- End Profile Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"https://www.instagram.com/salvaperfectti/"
>
<i
class=
"bi bi-envelope"
></i>
<span>
Contacto
</span>
</a>
</li>
<!-- End Contact Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"/login"
>
<i
class=
"bi bi-box-arrow-in-right"
></i>
<span>
Registro/Login
</span>
</a>
</li>
<!-- End Login Page Nav -->
<li
class=
"nav-item"
>
<a
class=
"nav-link collapsed"
href=
"http://www.homerswebpage.com/"
>
<i
class=
"bi bi-dash-circle"
></i>
<span>
Error 404
</span>
</a>
</li>
<!-- End Error 404 Page Nav -->
</ul>
</aside>
<!-- End Sidebar-->
\ No newline at end of file
public/css/style.css
View file @
0a9b0608
...
...
@@ -360,6 +360,26 @@ h6 {
.header
.search-bar
{
min-width
:
360px
;
padding
:
0
20px
;
position
:
relative
;
}
#recipe_list
{
position
:
absolute
;
top
:
100%
;
left
:
0
;
z-index
:
1
;
width
:
100%
;
max-height
:
200px
;
overflow-y
:
auto
;
background-color
:
#fff
;
border-top
:
none
;
border-radius
:
0
0
.25rem
.25rem
;
padding
:
0
;
margin
:
0
;
}
.recipe-item
{
cursor
:
pointer
;
}
@media
(
max-width
:
1199px
)
{
...
...
@@ -789,10 +809,7 @@ h6 {
}
/* Info Cards */
.dashboard
.info-card
{
padding-bottom
:
10px
;
}
s
.dashboard
.info-card
h6
{
font-size
:
28px
;
color
:
#012970
;
...
...
@@ -904,12 +921,6 @@ h6 {
padding-left
:
0
;
}
.recipe-card-link
{
display
:
block
;
text-decoration
:
none
;
color
:
inherit
;
}
.dashboard
.news
p
{
font-size
:
14px
;
color
:
#777777
;
...
...
public/imagenes/2729270.png
0 → 100644
View file @
0a9b0608
48.8 KB
public/js/insert.js
View file @
0a9b0608
...
...
@@ -11,21 +11,21 @@ const recipeForm = document.querySelector("form.my-form");
recipeForm
.
addEventListener
(
"submit"
,
function
(
event
)
{
const
selectedIngredients
=
Array
.
from
(
document
.
querySelectorAll
(
".selected-ingredient"
));
const
ingredientsData
=
selectedIngredients
.
map
((
ingredientElem
)
=>
{
return
{
id
:
ingredientElem
.
dataset
.
ingredientId
,
amount
:
ingredientElem
.
querySelector
(
".ingredient-amount"
).
textContent
,
};
return
{
id
:
ingredientElem
.
dataset
.
ingredientId
,
amount
:
ingredientElem
.
querySelector
(
".ingredient-amount"
).
textContent
,
};
});
const
hiddenInput
=
document
.
createElement
(
"input"
);
hiddenInput
.
type
=
"hidden"
;
hiddenInput
.
name
=
"selected_ingredients"
;
hiddenInput
.
value
=
JSON
.
stringify
(
ingredientsData
);
recipeForm
.
appendChild
(
hiddenInput
);
});
});
// Array para almacenar palabras clave seleccionadas
let
ingredients
=
[];
...
...
@@ -35,7 +35,7 @@ function searchIngredients(query) {
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'X-Requested-With'
:
'XMLHttpRequest'
// Añadir esta línea
'X-Requested-With'
:
'XMLHttpRequest'
},
body
:
'query='
+
encodeURIComponent
(
query
)
})
...
...
@@ -109,38 +109,38 @@ function removeIngredient(ingredient) {
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-ingredient-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
);
// Agregar el nombre del ingrediente y la cantidad
const
ingredientNameAndQuantity
=
document
.
createElement
(
'span'
);
ingredientNameAndQuantity
.
textContent
=
`
${
ingredient
.
name
}
(
${
ingredient
.
quantity
}
)`
;
ingredientNameAndQuantity
.
classList
.
add
(
'ingredient-amount'
);
ingredientElement
.
appendChild
(
ingredientNameAndQuantity
);
// Agregar el botón para eliminar el ingrediente
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
);
const
ingredientElement
=
document
.
createElement
(
'div'
);
ingredientElement
.
classList
.
add
(
'selected-ingredient'
);
ingredientElement
.
setAttribute
(
'data-ingredient-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
);
// Agregar el nombre del ingrediente y la cantidad
const
ingredientNameAndQuantity
=
document
.
createElement
(
'span'
);
ingredientNameAndQuantity
.
textContent
=
`
${
ingredient
.
name
}
(
${
ingredient
.
quantity
}
)`
;
ingredientNameAndQuantity
.
classList
.
add
(
'ingredient-amount'
);
ingredientElement
.
appendChild
(
ingredientNameAndQuantity
);
// Agregar el botón para eliminar el ingrediente
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
);
});
}
}
...
...
@@ -154,43 +154,43 @@ ingredientSearch.addEventListener('input', function (event) {
var
inputPhoto
=
document
.
getElementById
(
'photo'
);
var
imageUploadContainer
=
document
.
querySelector
(
'.image-upload-container'
);
inputPhoto
.
addEventListener
(
'change'
,
function
(
event
)
{
inputPhoto
.
addEventListener
(
'change'
,
function
(
event
)
{
displayImagePreview
(
event
.
target
.
files
[
0
]);
});
imageUploadContainer
.
addEventListener
(
'dragover'
,
function
(
event
)
{
});
imageUploadContainer
.
addEventListener
(
'dragover'
,
function
(
event
)
{
event
.
preventDefault
();
event
.
stopPropagation
();
event
.
dataTransfer
.
dropEffect
=
'copy'
;
});
imageUploadContainer
.
addEventListener
(
'drop'
,
function
(
event
)
{
});
imageUploadContainer
.
addEventListener
(
'drop'
,
function
(
event
)
{
event
.
preventDefault
();
event
.
stopPropagation
();
if
(
event
.
dataTransfer
.
files
.
length
>
0
)
{
displayImagePreview
(
event
.
dataTransfer
.
files
[
0
]);
inputPhoto
.
files
=
event
.
dataTransfer
.
files
;
displayImagePreview
(
event
.
dataTransfer
.
files
[
0
]);
inputPhoto
.
files
=
event
.
dataTransfer
.
files
;
}
});
function
displayImagePreview
(
file
)
{
});
function
displayImagePreview
(
file
)
{
var
reader
=
new
FileReader
();
reader
.
onload
=
function
()
{
var
output
=
document
.
getElementById
(
'image-preview'
);
output
.
src
=
reader
.
result
;
output
.
style
.
display
=
'block'
;
reader
.
onload
=
function
()
{
var
output
=
document
.
getElementById
(
'image-preview'
);
output
.
src
=
reader
.
result
;
output
.
style
.
display
=
'block'
;
}
reader
.
readAsDataURL
(
file
);
}
}
document
.
getElementById
(
'photo'
).
addEventListener
(
'change'
,
function
(
event
)
{
document
.
getElementById
(
'photo'
).
addEventListener
(
'change'
,
function
(
event
)
{
var
reader
=
new
FileReader
();
reader
.
onload
=
function
()
{
var
output
=
document
.
getElementById
(
'image-preview'
);
output
.
src
=
reader
.
result
;
output
.
style
.
display
=
'block'
;
reader
.
onload
=
function
()
{
var
output
=
document
.
getElementById
(
'image-preview'
);
output
.
src
=
reader
.
result
;
output
.
style
.
display
=
'block'
;
}
reader
.
readAsDataURL
(
event
.
target
.
files
[
0
]);
});
});
public/js/main.js
View file @
0a9b0608
/**
* Template Name: NiceAdmin
* Updated: Mar 09 2023 with Bootstrap v5.2.3
* Template URL: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/
* Author: BootstrapMade.com
* License: https://bootstrapmade.com/license/
*/
(
function
()
{
"use strict"
;
/**
* Easy selector helper function
*/
const
select
=
(
el
,
all
=
false
)
=>
{
el
=
el
.
trim
()
if
(
all
)
{
return
[...
document
.
querySelectorAll
(
el
)]
(
function
()
{
const
recipesSearch
=
document
.
querySelector
(
'#search-query'
);
function
search_recipe
(
query
)
{
fetch
(
'/search_recipe'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'X-Requested-With'
:
'XMLHttpRequest'
},
body
:
'query='
+
encodeURIComponent
(
query
)
})
.
then
((
response
)
=>
response
.
json
())
.
then
((
searchResults
)
=>
{
// Limpiar la lista de recetas coincidentes anterior
const
recipeList
=
document
.
querySelector
(
'#recipe_list'
);
recipeList
.
innerHTML
=
''
;
// Agregar recetas coincidentes a la lista desplegable
searchResults
.
forEach
((
recipe
)
=>
{
const
listItem
=
document
.
createElement
(
'li'
);
listItem
.
classList
.
add
(
'recipe-item'
,
'd-flex'
,
'align-items-center'
,
'p-2'
,
'mb-1'
,
'bg-light'
,
'rounded'
);
const
nameElement
=
document
.
createElement
(
'span'
);
nameElement
.
textContent
=
recipe
.
name
;
nameElement
.
classList
.
add
(
'recipe-name'
,
'flex-grow-1'
);
listItem
.
appendChild
(
nameElement
);
listItem
.
setAttribute
(
'data-id'
,
recipe
.
id
);
listItem
.
setAttribute
(
'title'
,
'Haz clic para seleccionar '
+
recipe
.
name
);
listItem
.
setAttribute
(
'href'
,
'/recipe/'
+
recipe
.
id
);
listItem
.
addEventListener
(
'click'
,
function
()
{
window
.
location
.
href
=
this
.
getAttribute
(
'href'
);
});
recipeList
.
appendChild
(
listItem
);
});
});
}
// Agregar evento para ir a una receta cuando se seleccione
recipesSearch
.
addEventListener
(
'input'
,
function
(
event
)
{
// Llamar a la función search_recipe para buscar y mostrar recetas coincidentes
search_recipe
(
event
.
target
.
value
);
});
"use strict"
;
/**
* Easy selector helper function
*/
const
select
=
(
el
,
all
=
false
)
=>
{
el
=
el
.
trim
()
if
(
all
)
{
return
[...
document
.
querySelectorAll
(
el
)]
}
else
{
return
document
.
querySelector
(
el
)
}
}
/**
* Easy event listener function
*/
const
on
=
(
type
,
el
,
listener
,
all
=
false
)
=>
{
if
(
all
)
{
select
(
el
,
all
).
forEach
(
e
=>
e
.
addEventListener
(
type
,
listener
))
}
else
{
select
(
el
,
all
).
addEventListener
(
type
,
listener
)
}
}
/**
* Easy on scroll event listener
*/
const
onscroll
=
(
el
,
listener
)
=>
{
el
.
addEventListener
(
'scroll'
,
listener
)
}
/**
* Sidebar toggle
*/
if
(
select
(
'.toggle-sidebar-btn'
))
{
on
(
'click'
,
'.toggle-sidebar-btn'
,
function
(
e
)
{
select
(
'body'
).
classList
.
toggle
(
'toggle-sidebar'
)
})
}
/**
* Search bar toggle
*/
if
(
select
(
'.search-bar-toggle'
))
{
on
(
'click'
,
'.search-bar-toggle'
,
function
(
e
)
{
select
(
'.search-bar'
).
classList
.
toggle
(
'search-bar-show'
)
})
}
/**
* Navbar links active state on scroll
*/
let
navbarlinks
=
select
(
'#navbar .scrollto'
,
true
)
const
navbarlinksActive
=
()
=>
{
let
position
=
window
.
scrollY
+
200
navbarlinks
.
forEach
(
navbarlink
=>
{
if
(
!
navbarlink
.
hash
)
return
let
section
=
select
(
navbarlink
.
hash
)
if
(
!
section
)
return
if
(
position
>=
section
.
offsetTop
&&
position
<=
(
section
.
offsetTop
+
section
.
offsetHeight
))
{
navbarlink
.
classList
.
add
(
'active'
)
}
else
{
return
document
.
querySelector
(
el
)
navbarlink
.
classList
.
remove
(
'active'
)
}
}
/**
* Easy event listener function
*/
const
on
=
(
type
,
el
,
listener
,
all
=
false
)
=>
{
if
(
all
)
{
select
(
el
,
all
).
forEach
(
e
=>
e
.
addEventListener
(
type
,
listener
))
})
}
window
.
addEventListener
(
'load'
,
navbarlinksActive
)
onscroll
(
document
,
navbarlinksActive
)
/**
* Toggle .header-scrolled class to #header when page is scrolled
*/
let
selectHeader
=
select
(
'#header'
)
if
(
selectHeader
)
{
const
headerScrolled
=
()
=>
{
if
(
window
.
scrollY
>
100
)
{
selectHeader
.
classList
.
add
(
'header-scrolled'
)
}
else
{
select
(
el
,
all
).
addEventListener
(
type
,
listener
)
select
Header
.
classList
.
remove
(
'header-scrolled'
)
}
}
/**
* Easy on scroll event listener
*/
const
onscroll
=
(
el
,
listener
)
=>
{
el
.
addEventListener
(
'scroll'
,
listener
)
window
.
addEventListener
(
'load'
,
headerScrolled
)
onscroll
(
document
,
headerScrolled
)
}
/**
* Back to top button
*/
let
backtotop
=
select
(
'.back-to-top'
)
if
(
backtotop
)
{
const
toggleBacktotop
=
()
=>
{
if
(
window
.
scrollY
>
100
)
{
backtotop
.
classList
.
add
(
'active'
)
}
else
{
backtotop
.
classList
.
remove
(
'active'
)
}
}
/**
* Sidebar toggle
*/
if
(
select
(
'.toggle-sidebar-btn'
))
{
on
(
'click'
,
'.toggle-sidebar-btn'
,
function
(
e
)
{
select
(
'body'
).
classList
.
toggle
(
'toggle-sidebar'
)
})
window
.
addEventListener
(
'load'
,
toggleBacktotop
)
onscroll
(
document
,
toggleBacktotop
)
}
/**
* Initiate tooltips
*/
var
tooltipTriggerList
=
[].
slice
.
call
(
document
.
querySelectorAll
(
'[data-bs-toggle="tooltip"]'
))
var
tooltipList
=
tooltipTriggerList
.
map
(
function
(
tooltipTriggerEl
)
{
return
new
bootstrap
.
Tooltip
(
tooltipTriggerEl
)
})
/**
* Initiate quill editors
*/
if
(
select
(
'.quill-editor-default'
))
{
new
Quill
(
'.quill-editor-default'
,
{
theme
:
'snow'
});
}
if
(
select
(
'.quill-editor-bubble'
))
{
new
Quill
(
'.quill-editor-bubble'
,
{
theme
:
'bubble'
});
}
if
(
select
(
'.quill-editor-full'
))
{
new
Quill
(
".quill-editor-full"
,
{
modules
:
{
toolbar
:
[
[{
font
:
[]
},
{
size
:
[]
}],
[
"bold"
,
"italic"
,
"underline"
,
"strike"
],
[{
color
:
[]
},
{
background
:
[]
}
],
[{
script
:
"super"
},
{
script
:
"sub"
}
],
[{
list
:
"ordered"
},
{
list
:
"bullet"
},
{
indent
:
"-1"
},
{
indent
:
"+1"
}
],
[
"direction"
,
{
align
:
[]
}],
[
"link"
,
"image"
,
"video"
],
[
"clean"
]
]
},
theme
:
"snow"
});
}
/**
* Initiate TinyMCE Editor
*/
const
useDarkMode
=
window
.
matchMedia
(
'(prefers-color-scheme: dark)'
).
matches
;
const
isSmallScreen
=
window
.
matchMedia
(
'(max-width: 1023.5px)'
).
matches
;
tinymce
.
init
({
selector
:
'textarea.tinymce-editor'
,
plugins
:
'preview importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link media template codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help charmap quickbars emoticons'
,
editimage_cors_hosts
:
[
'picsum.photos'
],
menubar
:
'file edit view insert format tools table help'
,
toolbar
:
'undo redo | bold italic underline strikethrough | fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save print | insertfile image media template link anchor codesample | ltr rtl'
,
toolbar_sticky
:
true
,
toolbar_sticky_offset
:
isSmallScreen
?
102
:
108
,
autosave_ask_before_unload
:
true
,
autosave_interval
:
'30s'
,
autosave_prefix
:
'{path}{query}-{id}-'
,
autosave_restore_when_empty
:
false
,
autosave_retention
:
'2m'
,
image_advtab
:
true
,
link_list
:
[{
title
:
'My page 1'
,
value
:
'https://www.tiny.cloud'
},
{
title
:
'My page 2'
,
value
:
'http://www.moxiecode.com'
}
/**
* Search bar toggle
*/
if
(
select
(
'.search-bar-toggle'
))
{
on
(
'click'
,
'.search-bar-toggle'
,
function
(
e
)
{
select
(
'.search-bar'
).
classList
.
toggle
(
'search-bar-show'
)
})
],
image_list
:
[{
title
:
'My page 1'
,
value
:
'https://www.tiny.cloud'
},
{
title
:
'My page 2'
,
value
:
'http://www.moxiecode.com'
}
/**
* Navbar links active state on scroll
*/
let
navbarlinks
=
select
(
'#navbar .scrollto'
,
true
)
const
navbarlinksActive
=
()
=>
{
let
position
=
window
.
scrollY
+
200
navbarlinks
.
forEach
(
navbarlink
=>
{
if
(
!
navbarlink
.
hash
)
return
let
section
=
select
(
navbarlink
.
hash
)
if
(
!
section
)
return
if
(
position
>=
section
.
offsetTop
&&
position
<=
(
section
.
offsetTop
+
section
.
offsetHeight
))
{
navbarlink
.
classList
.
add
(
'active'
)
}
else
{
navbarlink
.
classList
.
remove
(
'active'
)
}
})
],
image_class_list
:
[{
title
:
'None'
,
value
:
''
},
{
title
:
'Some class'
,
value
:
'class-name'
}
window
.
addEventListener
(
'load'
,
navbarlinksActive
)
onscroll
(
document
,
navbarlinksActive
)
/**
* Toggle .header-scrolled class to #header when page is scrolled
*/
let
selectHeader
=
select
(
'#header'
)
if
(
selectHeader
)
{
const
headerScrolled
=
()
=>
{
if
(
window
.
scrollY
>
100
)
{
selectHeader
.
classList
.
add
(
'header-scrolled'
)
}
else
{
selectHeader
.
classList
.
remove
(
'header-scrolled'
)
}
],
importcss_append
:
true
,
file_picker_callback
:
(
callback
,
value
,
meta
)
=>
{
/* Provide file and text for the link dialog */
if
(
meta
.
filetype
===
'file'
)
{
callback
(
'https://www.google.com/logos/google.jpg'
,
{
text
:
'My text'
});
}
window
.
addEventListener
(
'load'
,
headerScrolled
)
onscroll
(
document
,
headerScrolled
)
}
/**
* Back to top button
*/
let
backtotop
=
select
(
'.back-to-top'
)
if
(
backtotop
)
{
const
toggleBacktotop
=
()
=>
{
if
(
window
.
scrollY
>
100
)
{
backtotop
.
classList
.
add
(
'active'
)
}
else
{
backtotop
.
classList
.
remove
(
'active'
)
}
/* Provide image and alt text for the image dialog */
if
(
meta
.
filetype
===
'image'
)
{
callback
(
'https://www.google.com/logos/google.jpg'
,
{
alt
:
'My alt text'
});
}
window
.
addEventListener
(
'load'
,
toggleBacktotop
)
onscroll
(
document
,
toggleBacktotop
)
/* Provide alternative source and posted for the media dialog */
if
(
meta
.
filetype
===
'media'
)
{
callback
(
'movie.mp4'
,
{
source2
:
'alt.ogg'
,
poster
:
'https://www.google.com/logos/google.jpg'
});
}
},
templates
:
[{
title
:
'New Table'
,
description
:
'creates a new table'
,
content
:
'<div class="mceTmpl"><table width="98%%" border="0" cellspacing="0" cellpadding="0"><tr><th scope="col"> </th><th scope="col"> </th></tr><tr><td> </td><td> </td></tr></table></div>'
},
{
title
:
'Starting my story'
,
description
:
'A cure for writers block'
,
content
:
'Once upon a time...'
},
{
title
:
'New list with dates'
,
description
:
'New List with dates'
,
content
:
'<div class="mceTmpl"><span class="cdate">cdate</span><br><span class="mdate">mdate</span><h2>My List</h2><ul><li></li><li></li></ul></div>'
}
],
template_cdate_format
:
'[Date Created (CDATE): %m/%d/%Y : %H:%M:%S]'
,
template_mdate_format
:
'[Date Modified (MDATE): %m/%d/%Y : %H:%M:%S]'
,
height
:
600
,
image_caption
:
true
,
quickbars_selection_toolbar
:
'bold italic | quicklink h2 h3 blockquote quickimage quicktable'
,
noneditable_class
:
'mceNonEditable'
,
toolbar_mode
:
'sliding'
,
contextmenu
:
'link image table'
,
skin
:
useDarkMode
?
'oxide-dark'
:
'oxide'
,
content_css
:
useDarkMode
?
'dark'
:
'default'
,
content_style
:
'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});
/**
* Initiate Bootstrap validation check
*/
var
needsValidation
=
document
.
querySelectorAll
(
'.needs-validation'
)
/**
* Initiate tooltips
*/
var
tooltipTriggerList
=
[].
slice
.
call
(
document
.
querySelectorAll
(
'[data-bs-toggle="tooltip"]'
))
var
tooltipList
=
tooltipTriggerList
.
map
(
function
(
tooltipTriggerEl
)
{
return
new
bootstrap
.
Tooltip
(
tooltipTriggerEl
)
})
/**
* Initiate quill editors
*/
if
(
select
(
'.quill-editor-default'
))
{
new
Quill
(
'.quill-editor-default'
,
{
theme
:
'snow'
});
}
if
(
select
(
'.quill-editor-bubble'
))
{
new
Quill
(
'.quill-editor-bubble'
,
{
theme
:
'bubble'
});
}
if
(
select
(
'.quill-editor-full'
))
{
new
Quill
(
".quill-editor-full"
,
{
modules
:
{
toolbar
:
[
[{
font
:
[]
},
{
size
:
[]
}],
[
"bold"
,
"italic"
,
"underline"
,
"strike"
],
[{
color
:
[]
},
{
background
:
[]
}
],
[{
script
:
"super"
},
{
script
:
"sub"
}
],
[{
list
:
"ordered"
},
{
list
:
"bullet"
},
{
indent
:
"-1"
},
{
indent
:
"+1"
}
],
[
"direction"
,
{
align
:
[]
}],
[
"link"
,
"image"
,
"video"
],
[
"clean"
]
]
},
theme
:
"snow"
});
}
/**
* Initiate TinyMCE Editor
*/
const
useDarkMode
=
window
.
matchMedia
(
'(prefers-color-scheme: dark)'
).
matches
;
const
isSmallScreen
=
window
.
matchMedia
(
'(max-width: 1023.5px)'
).
matches
;
tinymce
.
init
({
selector
:
'textarea.tinymce-editor'
,
plugins
:
'preview importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link media template codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help charmap quickbars emoticons'
,
editimage_cors_hosts
:
[
'picsum.photos'
],
menubar
:
'file edit view insert format tools table help'
,
toolbar
:
'undo redo | bold italic underline strikethrough | fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save print | insertfile image media template link anchor codesample | ltr rtl'
,
toolbar_sticky
:
true
,
toolbar_sticky_offset
:
isSmallScreen
?
102
:
108
,
autosave_ask_before_unload
:
true
,
autosave_interval
:
'30s'
,
autosave_prefix
:
'{path}{query}-{id}-'
,
autosave_restore_when_empty
:
false
,
autosave_retention
:
'2m'
,
image_advtab
:
true
,
link_list
:
[{
title
:
'My page 1'
,
value
:
'https://www.tiny.cloud'
},
{
title
:
'My page 2'
,
value
:
'http://www.moxiecode.com'
}
],
image_list
:
[{
title
:
'My page 1'
,
value
:
'https://www.tiny.cloud'
},
{
title
:
'My page 2'
,
value
:
'http://www.moxiecode.com'
}
],
image_class_list
:
[{
title
:
'None'
,
value
:
''
},
{
title
:
'Some class'
,
value
:
'class-name'
Array
.
prototype
.
slice
.
call
(
needsValidation
)
.
forEach
(
function
(
form
)
{
form
.
addEventListener
(
'submit'
,
function
(
event
)
{
if
(
!
form
.
checkValidity
())
{
event
.
preventDefault
()
event
.
stopPropagation
()
}
],
importcss_append
:
true
,
file_picker_callback
:
(
callback
,
value
,
meta
)
=>
{
/* Provide file and text for the link dialog */
if
(
meta
.
filetype
===
'file'
)
{
callback
(
'https://www.google.com/logos/google.jpg'
,
{
text
:
'My text'
});
}
/* Provide image and alt text for the image dialog */
if
(
meta
.
filetype
===
'image'
)
{
callback
(
'https://www.google.com/logos/google.jpg'
,
{
alt
:
'My alt text'
});
}
/* Provide alternative source and posted for the media dialog */
if
(
meta
.
filetype
===
'media'
)
{
callback
(
'movie.mp4'
,
{
source2
:
'alt.ogg'
,
poster
:
'https://www.google.com/logos/google.jpg'
});
form
.
classList
.
add
(
'was-validated'
)
},
false
)
})
/**
* Initiate Datatables
*/
const
datatables
=
select
(
'.datatable'
,
true
)
datatables
.
forEach
(
datatable
=>
{
new
simpleDatatables
.
DataTable
(
datatable
);
})
/**
* Autoresize echart charts
*/
const
mainContainer
=
select
(
'#main'
);
if
(
mainContainer
)
{
setTimeout
(()
=>
{
new
ResizeObserver
(
function
()
{
select
(
'.echart'
,
true
).
forEach
(
getEchart
=>
{
echarts
.
getInstanceByDom
(
getEchart
).
resize
();
})
}).
observe
(
mainContainer
);
},
200
);
}
/* function updateRecipeList() {
// Obtén el estado de los checkboxes
var vegan = document.getElementById("checkboxOne").checked;
var countries = ['India', 'Francia', 'China', 'México', 'España', 'Japón'];
var country = '';
for (var i = 0; i < countries.length; i++) {
if (document.getElementById("checkbox" + (i + 4)).checked) {
country = countries[i];
break;
}
},
templates
:
[{
title
:
'New Table'
,
description
:
'creates a new table'
,
content
:
'<div class="mceTmpl"><table width="98%%" border="0" cellspacing="0" cellpadding="0"><tr><th scope="col"> </th><th scope="col"> </th></tr><tr><td> </td><td> </td></tr></table></div>'
},
{
title
:
'Starting my story'
,
description
:
'A cure for writers block'
,
content
:
'Once upon a time...'
},
{
title
:
'New list with dates'
,
description
:
'New List with dates'
,
content
:
'<div class="mceTmpl"><span class="cdate">cdate</span><br><span class="mdate">mdate</span><h2>My List</h2><ul><li></li><li></li></ul></div>'
}
var seasons = ['Invierno', 'Primavera', 'Verano', 'Otoño'];
var season = '';
for (var i = 0; i < seasons.length; i++) {
if (document.getElementById("checkbox" + (i + 10)).checked) {
season = seasons[i];
break;
}
],
template_cdate_format
:
'[Date Created (CDATE): %m/%d/%Y : %H:%M:%S]'
,
template_mdate_format
:
'[Date Modified (MDATE): %m/%d/%Y : %H:%M:%S]'
,
height
:
600
,
image_caption
:
true
,
quickbars_selection_toolbar
:
'bold italic | quicklink h2 h3 blockquote quickimage quicktable'
,
noneditable_class
:
'mceNonEditable'
,
toolbar_mode
:
'sliding'
,
contextmenu
:
'link image table'
,
skin
:
useDarkMode
?
'oxide-dark'
:
'oxide'
,
content_css
:
useDarkMode
?
'dark'
:
'default'
,
content_style
:
'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});
/**
* Initiate Bootstrap validation check
*/
var
needsValidation
=
document
.
querySelectorAll
(
'.needs-validation'
)
Array
.
prototype
.
slice
.
call
(
needsValidation
)
.
forEach
(
function
(
form
)
{
form
.
addEventListener
(
'submit'
,
function
(
event
)
{
if
(
!
form
.
checkValidity
())
{
event
.
preventDefault
()
event
.
stopPropagation
()
}
form
.
classList
.
add
(
'was-validated'
)
},
false
)
})
/**
* Initiate Datatables
*/
const
datatables
=
select
(
'.datatable'
,
true
)
datatables
.
forEach
(
datatable
=>
{
new
simpleDatatables
.
DataTable
(
datatable
);
})
/**
* Autoresize echart charts
*/
const
mainContainer
=
select
(
'#main'
);
if
(
mainContainer
)
{
setTimeout
(()
=>
{
new
ResizeObserver
(
function
()
{
select
(
'.echart'
,
true
).
forEach
(
getEchart
=>
{
echarts
.
getInstanceByDom
(
getEchart
).
resize
();
})
}).
observe
(
mainContainer
);
},
200
);
}
// Enviar una solicitud AJAX a tu controlador de recetas
var xhr = new XMLHttpRequest();
xhr.open("POST", "/recipes/get_filtered_recipes", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
// Actualizar el contenido de la página con las recetas filtradas
var recipes = JSON.parse(this.responseText);
var recipeList = document.getElementById("recipe-list");
recipeList.innerHTML = ''; // Limpiar la lista de recetas
/*
function search_recipe(query) {
if (query.trim() === '') {
document.querySelector('#recipe_dropdown').style.display = 'none';
return;
}
var xhr = new XMLHttpRequest();
xhr.open('POST', '/search_recipe', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
var searchResults = JSON.parse(xhr.responseText);
const recipeList = document.querySelector('#recipe_list');
recipeList.innerHTML = '';
if (searchResults.length > 0) {
document.querySelector('#recipe_dropdown').style.display = 'block';
} else {
document.querySelector('#recipe_dropdown').style.display = 'none';
}
searchResults.forEach((recipe) => {
const listItem = document.createElement('li');
listItem.classList.add('recipe-item');
const nameElement = document.createElement('span');
nameElement.textContent = recipe.name;
listItem.appendChild(nameElement);
recipeList.appendChild(listItem);
});
} catch (error) {
console.error('Error parsing JSON response:', error);
for (var i = 0; i < recipes.length; i++) {
var recipeHTML = generateRecipeHTML(recipes[i]);
recipeList.innerHTML += recipeHTML;
}
} else if (xhr.readyState === 4) {
console.error('Error in request:', xhr.status, xhr.statusText);
}
};
xhr.send('query=' + encodeURIComponent(query));
}
document.addEventListener('click', function (event) {
if (!event.target.closest('.search-bar')) {
document.querySelector('#recipe_dropdown').style.display = 'none';
}
});
*/
function
search_recipe
(
query
)
{
fetch
(
'/search_recipe'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'X-Requested-With'
:
'XMLHttpRequest'
// Añadir esta línea
},
body
:
'query='
+
encodeURIComponent
(
query
)
})
.
then
((
response
)
=>
response
.
json
())
.
then
((
searchResults
)
=>
{
// Limpiar la lista de ingredientes coincidentes anterior
const
recipeList
=
document
.
querySelector
(
'#recipe_dropdown'
);
recipeList
.
innerHTML
=
''
;
// Agregar ingredientes coincidentes a la lista desplegable
searchResults
.
forEach
((
ingredient
)
=>
{
const
listItem
=
document
.
createElement
(
'li'
);
listItem
.
classList
.
add
(
'recipe-item'
,
'd-flex'
,
'align-items-center'
,
'p-2'
,
'mb-1'
,
'bg-light'
,
'rounded'
);
const
nameElement
=
document
.
createElement
(
'span'
);
nameElement
.
textContent
=
ingredient
.
name
;
nameElement
.
classList
.
add
(
'recipe-name'
,
'flex-grow-1'
);
listItem
.
appendChild
(
nameElement
);
listItem
.
setAttribute
(
'data-id'
,
recipes
.
id
);
listItem
.
setAttribute
(
'title'
,
'Haz clic para seleccionar '
+
recipes
.
name
);
// Añade información adicional al ingrediente
recipeList
.
appendChild
(
listItem
);
});
});
};
xhr.send("vegan=" + vegan + "&country=" + country + "&season=" + season);
}
function generateRecipeHTML(recipe) {
var recipeHTML = `
<div class="card info-card sales-card"
onclick="window.location.href='<?php echo base_url('recipe/' . $row->id); ?>'">
<a href="<?php echo base_url('recipe/' . $row->id); ?>">
</a>
<div class="row flex-nowrap">
<div class="col-lg-3 col-md-4 col-sm-12 imagen-container">
<img src="<?php echo base_url('recipe/image/' . $row->id); ?>" alt=""
class="img-fluid rounded-start">
</div>
// Agregar evento para agregar ingredientes cuando se presiona Enter en el campo de búsqueda
ingredientSearch
.
addEventListener
(
'search'
,
function
(
event
)
{
// Llamar a la función searchIngredients para buscar y mostrar ingredientes coincidentes
search_recipe
(
event
.
target
.
value
);
});
<div class="col-lg-9 col-md-8 col-sm-12">
<div class="filter">
<a class="icon" href="#" data-bs-toggle="dropdown"><i class="bi bi-three-dots"></i></a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
<li class="dropdown-header text-start">
<h6>Opciones</h6>
</li>
<li><a class="dropdown-item" href="#">Guardar</a></li>
<li><a class="dropdown-item" href="#">Compartir</a></li>
</ul>
</div>
})();
\ No newline at end of file
<div class="card-body">
<h5 class="card-title">
<?php echo $row->name; ?> <span>|
<?php echo $row->origin; ?>
</span>
</h5>
<!--ingredientes-->
<?php foreach ($ingredients as $ingredient) { ?>
<div class="chip" title="Cantidad: <?php echo $ingredient->amount; ?>">
<img src="imagenes/ingredientes/<?php echo $ingredient->icon; ?>">
<b style="font-size: 14px">
<?php echo $ingredient->name; ?>
</b>
</div>
<?php } ?>
<!--fin ingredientes-->
</div>
</div>
</div>
</div>`;
return recipeHTML;
} */
})();
\ No newline at end of file
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