From 7fc0a327d2a504edab26af969db2ae11e7a068a8 Mon Sep 17 00:00:00 2001 From: CsR Date: Wed, 31 Aug 2022 03:17:18 -0300 Subject: [PATCH 01/10] C018 Fusion del menu desktop y creacion de notas.md --- index.html | 71 ++++++++++++++++++++++++++++ main.js | 7 +++ notas.md | 52 +++++++++++++++++++++ styles.css | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 263 insertions(+) create mode 100644 index.html create mode 100644 main.js create mode 100644 notas.md create mode 100644 styles.css diff --git a/index.html b/index.html new file mode 100644 index 000000000..c04c6a378 --- /dev/null +++ b/index.html @@ -0,0 +1,71 @@ + + + + + + + + + + YardSale + + + + + + + + + \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 000000000..61b4c252d --- /dev/null +++ b/main.js @@ -0,0 +1,7 @@ +const manuEmail = document.querySelector(".navbar-email"); +const desktopMenu = document.querySelector(".desktop-menu"); +manuEmail.addEventListener("click", toogleDesktopMenu); + +function toogleDesktopMenu(){ + desktopMenu.classList.toggle("inactive"); +} \ No newline at end of file diff --git a/notas.md b/notas.md new file mode 100644 index 000000000..1b48b028c --- /dev/null +++ b/notas.md @@ -0,0 +1,52 @@ +# Curso Práctico de JavaScript + +## C018 Fusión del menu en desktop + +Se agrega todo el código del archivo clase11.html al index.html, ya que este tomaremos como base. De ese separamos la parte de los estilos y lo llevamos al archivo styles.css. +Por lo que pudimos ver, este se trata del menu de navegacion. El cual consta de una parte izquierda y otra derecha, que se activara cuand hagamos click en algun lado. +El archivo clase7.html es lo que debe aparecer cuando hacemos click en el email, y este corresponde a la parte derecha. +Agregamos la parte del head que no estaba en el anterior (que vincula las fuentes) al index. Tambien agregamos lo correspondiente a lo que se refiere al desktop-menu adentro de la nav-bar. +Ponemos el estilo de CSS tambien en style.css. +Para que no rompa la estructura, en el codigo de CSS agregamos en la clase del desktop-menu el `position absolute` y la posicion `top` y `right` para que se oriente en la esquina superior derecha y modificamos el color de fondo de la caja, ademas utilizamos las variables creadas: + +```css +position: absolute; +top: 60px; +right: 60px; +background-color: var(--white); +``` + +Para hacer que este menu aparezca y desaparezca haciendo click utilizaremos una clase nueva que crearemos y con JS haremos que esta clase este o no presente en el desktop-menu. +Entonces creamos la siguiente clase en style.css, el cual con este hacemos que no se muestre si tiene esta clase: + +```css +.inactive { + display: none; +} +``` + +En la estructura html, le agregamos esta clase en el div del desktop-menu para que de una no se muestre el menu: + +```html +
+
+``` + +Ahora, por medio de JavaScript, hacemos que si pasa el evento de hacer click en el email, modifique la clase (quitando o agregando) inactive del div desktop-menu. + +```javascript +const manuEmail = document.querySelector(".navbar-email"); +const desktopMenu = document.querySelector(".desktop-menu"); +manuEmail.addEventListener("click", toogleDesktopMenu); + +function toogleDesktopMenu(){ + desktopMenu.classList.toggle("inactive"); +} +``` + +Por último se modifica el CSS para que al pasar el cursor por el email, este cambie de formato y se pueda distinguir que se puede hacer click. Para esto en la clase para ese item le agregamos: + +```css +cursor: pointer; +``` + diff --git a/styles.css b/styles.css new file mode 100644 index 000000000..34a865c4a --- /dev/null +++ b/styles.css @@ -0,0 +1,133 @@ +:root { + --white: #ffffff; + --black: #000000; + --very-light-pink: #c7c7c7; + --text-input-field: #f7f7f7; + --hospital-green: #acd9b2; + --sm: 14px; + --md: 16px; + --lg: 18px; +} +body { + margin: 0; + font-family: "Quicksand", sans-serif; +} + +.inactive { + display: none; +} + +nav { + display: flex; + justify-content: space-between; + padding: 0 24px; + border-bottom: 1px solid var(--very-light-pink); +} +.menu { + display: none; +} +.logo { + width: 100px; +} +.navbar-left ul, +.navbar-right ul { + list-style: none; + padding: 0; + margin: 0; + display: flex; + align-items: center; + height: 60px; +} +.navbar-left { + display: flex; +} +.navbar-left ul { + margin-left: 12px; +} +.navbar-left ul li a, +.navbar-right ul li a { + text-decoration: none; + color: var(--very-light-pink); + border: 1px solid var(--white); + padding: 8px; + border-radius: 8px; +} +.navbar-left ul li a:hover, +.navbar-right ul li a:hover { + border: 1px solid var(--hospital-green); + color: var(--hospital-green); +} +.navbar-email { + color: var(--very-light-pink); + cursor: pointer; + font-size: var(--sm); + margin-right: 12px; +} +.navbar-shopping-cart { + position: relative; +} +.navbar-shopping-cart div { + width: 16px; + height: 16px; + background-color: var(--hospital-green); + border-radius: 50%; + font-size: var(--sm); + font-weight: bold; + position: absolute; + top: -6px; + right: -3px; + display: flex; + justify-content: center; + align-items: center; +} + +.desktop-menu { + position: absolute; + top: 60px; + right: 60px; + background-color: var(--white); + width: 100px; + height: auto; + border: 1px solid var(--very-light-pink); + border-radius: 6px; + padding: 20px 20px 0 20px; +} +.desktop-menu ul { + list-style: none; + padding: 0; + margin: 0; +} +.desktop-menu ul li { + text-align: end; +} +.desktop-menu ul li:nth-child(1), +.desktop-menu ul li:nth-child(2) { + font-weight: bold; +} +.desktop-menu ul li:last-child { + padding-top: 20px; + border-top: 1px solid var(--very-light-pink); +} +.desktop-menu ul li:last-child a { + color: var(--hospital-green); + font-size: var(--sm); +} +.desktop-menu ul li a { + color: var(--back); + text-decoration: none; + margin-bottom: 20px; + display: inline-block; +} + +@media (max-width: 640px) { + .menu { + display: block; + } + .navbar-left ul { + display: none; + } + .navbar-email { + display: none; + } + +} From 2aa68f9f2637c5f03411b9195a7613584c090584 Mon Sep 17 00:00:00 2001 From: CsR Date: Wed, 31 Aug 2022 17:50:26 -0300 Subject: [PATCH 02/10] Se agrego mas informacion en el archivo notas.md --- notas.md | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/notas.md b/notas.md index 1b48b028c..0dc0c8a77 100644 --- a/notas.md +++ b/notas.md @@ -1,5 +1,188 @@ # Curso Práctico de JavaScript +- [Curso Práctico de JavaScript](#curso-práctico-de-javascript) + - [C009 Como conectar con JS con HTML](#c009-como-conectar-con-js-con-html) + - [C010 Leyendo HTML desde JS](#c010-leyendo-html-desde-js) + - [C011 Escribiendo HTML desde JS](#c011-escribiendo-html-desde-js) + - [C012 Eventos con JS, interactuando con usuarios](#c012-eventos-con-js-interactuando-con-usuarios) + - [C013 addEventListener](#c013-addeventlistener) + - [C018 Fusión del menu en desktop](#c018-fusión-del-menu-en-desktop) + +## C009 Como conectar con JS con HTML + +Los entornos de ejecucion son los que permiten ejecutar el código de JS (Los navegadores, nodeJS, ...). +Con la etiqueta `` nos permite: introducir todo el codigo o bien por medio del atributo `src` enlazar el archivo.js. Por ejemplo: + +```html + +``` +## C010 Leyendo HTML desde JS + +Por medio de `document.querySelector` le asignamos a una variable, declarada con `const`, un identificador para poder trabajar sobre un elemento del HTML. A dicha funcion se le pasa como argumento alguna identicacion de dicho elemento, que puede ser la misma etiqueta (con el nombre, por ejemplo h1), con una clase (.clase), un id (#id), como si se tratara de CSS. + +```javascript +const h1 = document.querySelector ("h1"); +const p = document.querySelector ("p"); +const parrafito = document.querySelector (".parrafito"); +const pid = document.querySelector ("#pid"); +const input = document.querySelector ("input"); +``` +Tambien hay otras funciones como `getElementbyId`, `getElementbyClass`, ..., en los cuales no hace falta identicar que es lo que queremos con ., #, ... +Una vez que tenemos estas variables podemos acceder a su contenido. +```javascript +console.log (h1); +console.log ({ + h1, + p, + parrafito, + pid, + input, +}); +console.log (input.value); +``` +Al indicar en `console.log` los parrafos `{}` le estamos diciendo que le estamos pasando un objeto, y lo va a imprimir como tal. + +## C011 Escribiendo HTML desde JS + +También aca utilizaremos las variables asignadas en la clase anterior. +Con el atributo innerHTML podemos cambiar el codigo del HTML, o sea con etiquetas, por ejemplo: + +```javascript +h1.innerHTML = "Cambiando el
h1"; +``` + +Con `innerText` solo se modifica el texto y no va a considerar a las etiquetas como codigo, la insertará como texto común. + +Con `getAttribute()` leo atributo, y si de argumento le paso `class`me trae las clases que tenga. Con `setAttribute()` fijo un atributo, como argumento le debo pasar el atributo y el valor que le asignamos. +Con `classList.add()` agrego una clase, `classList.remove()` lo quito, `classList.toggle()` lo agrego o quito segun este o no, `classList.contains()` es un condicional, que me devuelve true o false si esta esa clase. Como aca ya indicamos que trabajamos con clase no se debe poner el `.`. +Con `document.createElement()` creamos una etiqueta, por ejemplo si le pasamos como argumento `"img"` nos crea ``. Con `append()` agregamos al final dicho elemento. + +```javascript +h1.innerHTML = "Cambiando el
h1"; +h1.innerText = "Cambiando el
h1"; + +console.log (h1.getAttribute("class")); +h1.setAttribute("class", "verde"); +h1.classList.toggle("rojo"); + +const img = document.createElement("img"); +img.setAttribute("src", "https://st3.depositphotos.com/9572786/15657/i/450/depositphotos_156571608-stock-photo-drawn-dark-fantasy-the-city.jpg"); + +pid.innerText="Cambio de texto e imagen anexada"; +pid.append(img); +``` + +## C012 Eventos con JS, interactuando con usuarios + +En un principio podriamos agregar codigo en el mismo HTML, que reaccione ante un evento como el `onchage` (si hay cambios) y aca le indicamos por ejemplo que mande a la consola un mensaje. +```html + +``` +Para mejorar esto, podemos llamar a una funcion en el archivo de JS desde el html en lugar de poner codigo ahi. +En el HTML editamos lo que hace el evento. +```html + +``` +Y en JS agregamos la funcion +```javascript +const input1 = document.querySelector("#calculo1"); +const input2 = document.querySelector("#calculo2"); +const btn = document.querySelector("#btnCalcular"); +const pResult = document.querySelector("#result"); + +function btnOnClick() { + const sumaInputs = input1.value + input2.value; + pResult.innerText= "Resultado: "+sumaInputs; +``` + +## C013 addEventListener + +Lo que se quiere lograr con esto es pasar las escuchas de los eventos a JS, y dejando el codigo html lo mas puro posible. O sea sin poner los eventos, como por ejemplo el `onclick` en el html. Y esto lo vamos a estar haciendo con `addEventListener`. + +```javascript +btn.addEventListener("click",btnOnClick); +``` + +A este le pasamos dos argumentos, uno es el evento en cuestion y el otro la funcion a llamar, como ya debemos pasar el nombre de la funcion lo tenemos que hacer sin comillas y sin parentesis, ya que lo agrega el comando propiamente. +A continuacion vamos a ver un ejemplo de que sucede si usamos la etiqueta `
` y como solucionarlo: + +Tengamos en cuenta que si trabajamos con la etiqueta `form` en html, nos va a considerar que el ultimo boton es del tipo submit. Y si damos click al boton, se va recargar la pagina para enviar los valores del formulario. Hay dos formas de solucionar esto, una simple, que se ve al final del video, como eso del minuto 14:00, que es indicando que el type del boton es del tipo boton y no submit. + +El HTML queda asi: +```html + + + + + + + Manipulacion del DOM basica + + +

Manipulacion del DOM basica - Curso Practico de JavaScript

+ + + + + + + +

+
+ + + + +``` +La otra opcion es la siguiente, y el html y javascript quedara como se vera mas abajo. Tener en cuenta que uso el id del `form` para capturar el evento `submit`. Ademas, tengo que ver el evento que recibo de `addEventListener` con `event`, y utilizar el atributo `preventDefault()` para que no recargue. Si vemos lo que muestra en consola, vemos que este se encuentra en `true`, y por esto no llama a lo que tenia que hacer por default, porque ya lo llamamos en teoria. + +html: + +```html + + + + + + + Manipulacion del DOM basica + + +

Manipulacion del DOM basica - Curso Practico de JavaScript

+ +
+ + + + + +

+
+ + + + +``` + +javascript +```javascript +const form = document.querySelector("#form"); +const input1 = document.querySelector("#calculo1"); +const input2 = document.querySelector("#calculo2"); +const btn = document.querySelector("#btnCalcular"); +const pResult = document.querySelector("#result"); + +form.addEventListener("submit", sumarInputValues); + +function sumarInputValues(event) { + console.log({event}); + event.preventDefault(); + const sumaInputs = input1.value + input2.value; + pResult.innerText= "Resultado: "+sumaInputs; +} +``` + + ## C018 Fusión del menu en desktop Se agrega todo el código del archivo clase11.html al index.html, ya que este tomaremos como base. De ese separamos la parte de los estilos y lo llevamos al archivo styles.css. From 431d994c07e591049d8154d76858777156a1c43f Mon Sep 17 00:00:00 2001 From: CsR Date: Wed, 31 Aug 2022 19:13:54 -0300 Subject: [PATCH 03/10] C019. Fusion del menu en mobile --- index.html | 45 +++++++++++++++++++++++++++++++++++++++++++++ main.js | 12 ++++++++++-- notas.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ styles.css | 45 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 146 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index c04c6a378..a25a7ee36 100644 --- a/index.html +++ b/index.html @@ -48,6 +48,7 @@
+
  • @@ -63,6 +64,50 @@
+ +
+ + + + + +
diff --git a/main.js b/main.js index 61b4c252d..af3fc52d1 100644 --- a/main.js +++ b/main.js @@ -1,7 +1,15 @@ -const manuEmail = document.querySelector(".navbar-email"); +const menuEmail = document.querySelector(".navbar-email"); const desktopMenu = document.querySelector(".desktop-menu"); -manuEmail.addEventListener("click", toogleDesktopMenu); +const menuHamIcon = document.querySelector(".menu"); +const mobileMenu = document.querySelector(".mobile-menu"); + +menuEmail.addEventListener("click", toogleDesktopMenu); +menuHamIcon.addEventListener("click", toogleMobileMenu); function toogleDesktopMenu(){ desktopMenu.classList.toggle("inactive"); +} + +function toogleMobileMenu(){ + mobileMenu.classList.toggle("inactive"); } \ No newline at end of file diff --git a/notas.md b/notas.md index 0dc0c8a77..d2ad9db9f 100644 --- a/notas.md +++ b/notas.md @@ -7,6 +7,7 @@ - [C012 Eventos con JS, interactuando con usuarios](#c012-eventos-con-js-interactuando-con-usuarios) - [C013 addEventListener](#c013-addeventlistener) - [C018 Fusión del menu en desktop](#c018-fusión-del-menu-en-desktop) + - [C019 Fusión del menú mobile](#c019-fusión-del-menú-mobile) ## C009 Como conectar con JS con HTML @@ -232,4 +233,50 @@ Por último se modifica el CSS para que al pasar el cursor por el email, este ca ```css cursor: pointer; ``` +## C019 Fusión del menú mobile + +Se hace un trabajo parecido al anterior, con el archivo clase8.html + +En la clase `.mobile-menu`agregamos: +```css +position: absolute; +top: 60px; +``` + +En JavaScript: + +```javascript +const menuHamIcon = document.querySelector(".menu"); +const mobileMenu = document.querySelector(".mobile-menu"); + +function toogleMobileMenu(){ + mobileMenu.classList.toggle("inactive"); +} +``` + +En el codigo html se agrego la clase `inactive` en el `div` del mobile-menu, para que de inicio no aparezca. + +```html +
+``` + +Para solucionar el error de que no desaparece una vez activado tanto el desktop-menu y el mobile-menu cuando se cambia de tamaño del navegador, modificamos los medias queries en el CSS. Con `@media (max-width: 640px) {}` se ejecuta solamente cuando va de 0px a 640px, y en este le agregamos `display:none` para el desktop-menu. Con `@media(min-width: 641px){}` se ejecuta de 641px para arriba, y hacemos lo mismo pero con el mobile-menu. Esto se podria hacer con JS tambien, pero en este curso no. + +```css +@media (max-width: 640px) { + .desktop-menu { + display:none; + } + +} + +@media(min-width: 641px){ + .mobile-menu{ + display: none; + } +} +``` + + + diff --git a/styles.css b/styles.css index 34a865c4a..a5ae3eb0c 100644 --- a/styles.css +++ b/styles.css @@ -1,3 +1,4 @@ +/* General */ :root { --white: #ffffff; --black: #000000; @@ -12,11 +13,11 @@ body { margin: 0; font-family: "Quicksand", sans-serif; } - .inactive { display: none; } +/* NavBar (general) */ nav { display: flex; justify-content: space-between; @@ -81,6 +82,7 @@ nav { align-items: center; } +/* Menu en desktop */ .desktop-menu { position: absolute; top: 60px; @@ -119,6 +121,39 @@ nav { display: inline-block; } +/* Menu en mobile */ +.mobile-menu { + position: absolute; + top: 60px; + padding: 24px; +} +.mobile-menu a { + text-decoration: none; + color: var(--black); + font-weight: bold; + /* margin-bottom: 24px; */ +} +.mobile-menu ul { + padding: 0; + margin: 24px 0 0; + list-style: none; +} +.mobile-menu ul:nth-child(1) { + border-bottom: 1px solid var(--very-light-pink); +} +.mobile-menu ul li { + margin-bottom: 24px; +} +.email { + font-size: var(--sm); + font-weight: 300 !important; +} +.sign-out { + font-size: var(--sm); + color: var(--hospital-green) !important; +} + +/* media */ @media (max-width: 640px) { .menu { display: block; @@ -129,5 +164,13 @@ nav { .navbar-email { display: none; } + .desktop-menu { + display:none; + } +} +@media(min-width: 641px){ + .mobile-menu{ + display: none; + } } From d11ee70584e57a833c8e19c9233bf257710ba8a8 Mon Sep 17 00:00:00 2001 From: CsR Date: Wed, 31 Aug 2022 20:59:24 -0300 Subject: [PATCH 04/10] C020. Carrito de compras --- index.html | 48 ++++++++++++++++++++++++++++++ main.js | 29 +++++++++++++++++++ notas.md | 52 ++++++++++++++++++++++++++++++++- styles.css | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 212 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index a25a7ee36..cbb0d51b5 100644 --- a/index.html +++ b/index.html @@ -109,6 +109,54 @@
+ +
+ diff --git a/main.js b/main.js index af3fc52d1..f6c9359e8 100644 --- a/main.js +++ b/main.js @@ -2,14 +2,43 @@ const menuEmail = document.querySelector(".navbar-email"); const desktopMenu = document.querySelector(".desktop-menu"); const menuHamIcon = document.querySelector(".menu"); const mobileMenu = document.querySelector(".mobile-menu"); +const menuCarritoIcon = document.querySelector(".navbar-shopping-cart"); +const aside = document.querySelector(".product-detail"); menuEmail.addEventListener("click", toogleDesktopMenu); menuHamIcon.addEventListener("click", toogleMobileMenu); +menuCarritoIcon.addEventListener("click", toogleCarritoAside); function toogleDesktopMenu(){ + const isAsideClosed = aside.classList.contains("inactive"); + + if(!isAsideClosed){ + aside.classList.add("inactive"); + } + desktopMenu.classList.toggle("inactive"); } function toogleMobileMenu(){ + const isAsideClosed = aside.classList.contains("inactive"); + + if(!isAsideClosed){ + aside.classList.add("inactive"); + } + mobileMenu.classList.toggle("inactive"); +} + +function toogleCarritoAside(){ + const isMobileMenuClosed = mobileMenu.classList.contains("inactive"); + const isDesktopMenuClosed = desktopMenu.classList.contains("inactive"); + + if(!isMobileMenuClosed){ + mobileMenu.classList.add("inactive"); + } + if(!isDesktopMenuClosed){ + desktopMenu.classList.add("inactive"); + } + + aside.classList.toggle("inactive"); } \ No newline at end of file diff --git a/notas.md b/notas.md index d2ad9db9f..64b30c2c1 100644 --- a/notas.md +++ b/notas.md @@ -8,6 +8,7 @@ - [C013 addEventListener](#c013-addeventlistener) - [C018 Fusión del menu en desktop](#c018-fusión-del-menu-en-desktop) - [C019 Fusión del menú mobile](#c019-fusión-del-menú-mobile) + - [C020 Carrito de compras](#c020-carrito-de-compras) ## C009 Como conectar con JS con HTML @@ -19,7 +20,7 @@ Con la etiqueta `` nos permite: introducir todo el codigo o bie ``` ## C010 Leyendo HTML desde JS -Por medio de `document.querySelector` le asignamos a una variable, declarada con `const`, un identificador para poder trabajar sobre un elemento del HTML. A dicha funcion se le pasa como argumento alguna identicacion de dicho elemento, que puede ser la misma etiqueta (con el nombre, por ejemplo h1), con una clase (.clase), un id (#id), como si se tratara de CSS. +Por medio de `document.querySelector` le asignamos a una variable, declarada con `const`, un identificador o selector para poder trabajar sobre un elemento del HTML. A dicha funcion se le pasa como argumento alguna identicacion de dicho elemento, que puede ser la misma etiqueta (con el nombre, por ejemplo h1), con una clase (.clase), un id (#id), como si se tratara de CSS. ```javascript const h1 = document.querySelector ("h1"); @@ -277,6 +278,55 @@ Para solucionar el error de que no desaparece una vez activado tanto el desktop- } ``` +## C020 Carrito de compras +Trabajo parecido a los dos anteriores pero ahora con el archivo clase13.html. Ahora tambien vamos a considerar cerrar el mobile-menu si está abierto al momento de abrir el carrito, y de cerrar el del carrito si es que esta abierto al momento de abrir el mobile-menu. Y asi con el desktop-menu. Para esto vamos a estar usando `classList.contains()`. + +```javascript +const menuEmail = document.querySelector(".navbar-email"); +const desktopMenu = document.querySelector(".desktop-menu"); +const menuHamIcon = document.querySelector(".menu"); +const mobileMenu = document.querySelector(".mobile-menu"); +const menuCarritoIcon = document.querySelector(".navbar-shopping-cart"); +const aside = document.querySelector(".product-detail"); + +menuEmail.addEventListener("click", toogleDesktopMenu); +menuHamIcon.addEventListener("click", toogleMobileMenu); +menuCarritoIcon.addEventListener("click", toogleCarritoAside); + +function toogleDesktopMenu(){ + const isAsideClosed = aside.classList.contains("inactive"); + + if(!isAsideClosed){ + aside.classList.add("inactive"); + } + + desktopMenu.classList.toggle("inactive"); +} + +function toogleMobileMenu(){ + const isAsideClosed = aside.classList.contains("inactive"); + + if(!isAsideClosed){ + aside.classList.add("inactive"); + } + + mobileMenu.classList.toggle("inactive"); +} + +function toogleCarritoAside(){ + const isMobileMenuClosed = mobileMenu.classList.contains("inactive"); + const isDesktopMenuClosed = desktopMenu.classList.contains("inactive"); + + if(!isMobileMenuClosed){ + mobileMenu.classList.add("inactive"); + } + if(!isDesktopMenuClosed){ + desktopMenu.classList.add("inactive"); + } + + aside.classList.toggle("inactive"); +} +``` diff --git a/styles.css b/styles.css index a5ae3eb0c..ddb8d2182 100644 --- a/styles.css +++ b/styles.css @@ -123,8 +123,9 @@ nav { /* Menu en mobile */ .mobile-menu { + background-color: var(--white); position: absolute; - top: 60px; + top: 61px; padding: 24px; } .mobile-menu a { @@ -153,6 +154,84 @@ nav { color: var(--hospital-green) !important; } +/* Aside (product detail y carrito) */ + +.product-detail { + background-color: var(--white); + width: 360px; + padding: 0px 24px; + box-sizing: border-box; + position: absolute; + right: 0; +} +.title-container { + display: flex; +} +.title-container img { + transform: rotate(180deg); + margin-right: 14px; +} +.title { + font-size: var(--lg); + font-weight: bold; +} +.order { + display: grid; + grid-template-columns: auto 1fr; + gap: 16px; + align-items: center; + background-color: var(--text-input-field); + margin-bottom: 24px; + border-radius: 8px; + padding: 0 24px; +} +.order p:nth-child(1) { + display: flex; + flex-direction: column; +} +.order p span:nth-child(1) { + font-size: var(--md); + font-weight: bold; +} +.order p:nth-child(2) { + text-align: end; + font-weight: bold; +} +.shopping-cart { + display: grid; + grid-template-columns: auto 1fr auto auto; + gap: 16px; + margin-bottom: 24px; + align-items: center; +} +.shopping-cart figure { + margin: 0; +} +.shopping-cart figure img { + width: 70px; + height: 70px; + border-radius: 20px; + object-fit: cover; +} +.shopping-cart p:nth-child(2) { + color: var(--very-light-pink); +} +.shopping-cart p:nth-child(3) { + font-size: var(--md); + font-weight: bold; +} +.primary-button { + background-color: var(--hospital-green); + border-radius: 8px; + border: none; + color: var(--white); + width: 100%; + cursor: pointer; + font-size: var(--md); + font-weight: bold; + height: 50px; +} + /* media */ @media (max-width: 640px) { .menu { @@ -167,6 +246,10 @@ nav { .desktop-menu { display:none; } + + .product-detail { + width: 100%; + } } @media(min-width: 641px){ From f482473b9cf60b7320cd1f73a0b22817efb130d2 Mon Sep 17 00:00:00 2001 From: CsR Date: Fri, 2 Sep 2022 01:21:32 -0300 Subject: [PATCH 05/10] C021. Lista de productos, HTML a partir de arrays --- index.html | 25 +++++++++++++++++++ main.js | 60 ++++++++++++++++++++++++++++++++++++++++++++- notas.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ styles.css | 55 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 210 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index cbb0d51b5..820a1a8c9 100644 --- a/index.html +++ b/index.html @@ -157,6 +157,31 @@ + +
+
+ + + + + +
+
diff --git a/main.js b/main.js index f6c9359e8..12f0e24d5 100644 --- a/main.js +++ b/main.js @@ -4,6 +4,7 @@ const menuHamIcon = document.querySelector(".menu"); const mobileMenu = document.querySelector(".mobile-menu"); const menuCarritoIcon = document.querySelector(".navbar-shopping-cart"); const aside = document.querySelector(".product-detail"); +const cardsContainer = document.querySelector(".cards-container"); menuEmail.addEventListener("click", toogleDesktopMenu); menuHamIcon.addEventListener("click", toogleMobileMenu); @@ -41,4 +42,61 @@ function toogleCarritoAside(){ } aside.classList.toggle("inactive"); -} \ No newline at end of file +} + +const productList = []; + +productList.push({ + name: 'Bike', + price: 120, + image: 'https://images.pexels.com/photos/276517/pexels-photo-276517.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940', +}); +productList.push({ + name: 'Skate', + price: 60, + image: 'https://images.pexels.com/photos/165236/pexels-photo-165236.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1', +}); +productList.push({ + name: 'Dron', + price: 300, + image: 'https://images.pexels.com/photos/1809576/pexels-photo-1809576.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1', +}); + + +function renderProducts(arr) { + for (product of arr) { + const productCard = document.createElement("div"); + productCard.classList.add("product-card"); + + const productImg = document.createElement("img"); + productImg.setAttribute("src", product.image); + + const productInfo = document.createElement("div"); + productInfo.classList.add("product-info"); + + const productInfoDiv = document.createElement("div"); + const productPrice = document.createElement("p"); + productPrice.innerText = "$" + product.price; + const productName = document.createElement("p"); + productName.innerText = product.name; + + productInfoDiv.appendChild(productPrice); + productInfoDiv.appendChild(productName); + + const productInfoFigure = document.createElement("figure"); + const productImgCard = document.createElement("img"); + productImgCard.setAttribute("src", "./icons/bt_add_to_cart.svg"); + + productInfoFigure.appendChild(productImgCard); + + productInfo.appendChild(productInfoDiv); + productInfo.appendChild(productInfoFigure); + + productCard.appendChild(productImg); + productCard.appendChild(productInfo); + + cardsContainer.appendChild(productCard); + } +} + +renderProducts(productList); \ No newline at end of file diff --git a/notas.md b/notas.md index 64b30c2c1..438006a38 100644 --- a/notas.md +++ b/notas.md @@ -9,6 +9,7 @@ - [C018 Fusión del menu en desktop](#c018-fusión-del-menu-en-desktop) - [C019 Fusión del menú mobile](#c019-fusión-del-menú-mobile) - [C020 Carrito de compras](#c020-carrito-de-compras) + - [C021 Lista de productos, HTML a parti de arrays](#c021-lista-de-productos-html-a-parti-de-arrays) ## C009 Como conectar con JS con HTML @@ -328,5 +329,75 @@ function toogleCarritoAside(){ aside.classList.toggle("inactive"); } ``` +## C021 Lista de productos, HTML a parti de arrays + +Como primera medida integramos el componentes de lista de productos del archivo clase6.html, como en las clases anteriores. + +En este caso tenemos hardcodeado cada uno de los productos en el html. Lo que vamos a hacer es borrarlo todos (dejamos uno como comentario para ver como se forma su estructura) y generalos a traves del codigo de javascript a partir de un array con los datos de los productos a mostrar. En este caso vamos a tener tambien hardcodeado el array con algunos productos, pero mas adelante estos datos deberian ser tomados a través de consultas en el backend en bases de datos. +La lista donde vamos a contener los productos, que deberia obtenerse a partir de peticiones realizadas al backend, la vamos a estar hardcodeando de la siguiente manera: +```javascript +const productList = []; + +productList.push({ + name: 'Bike', + price: 120, + image: 'https://images.pexels.com/photos/276517/pexels-photo-276517.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940', +}); +productList.push({ + name: 'Skate', + price: 60, + image: 'https://images.pexels.com/photos/165236/pexels-photo-165236.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1', +}); +productList.push({ + name: 'Dron', + price: 300, + image: 'https://images.pexels.com/photos/1809576/pexels-photo-1809576.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1', +}); +``` +Para recorrer el array tenemos dos formas mas de recorrerlo a los ya conocido con el atributo length, y es por medio del `for (item of object)` o `for (item in object)`. Con el **of** el **item** va a ser cada uno de los objetos en si, pero con **in** el **item** va a ser el indice de cada uno de los objetos. +Por cada recorrido del `for`vamos a ir creando cada uno de los elementos, y una vez creado todos, lo vamos a ir anexando al padre correspondiente (mediante `append` o `appendChild`) y por ultimo anexandolo al HTML. +Y a todo este `for` lo encapsulamos en una función principalmente para un ordenamiento de codigo. Ademas me permite poder llamar a esta con algun evento en particular. +```javascript +function renderProducts(arr) { + for (product of arr) { + const productCard = document.createElement("div"); + productCard.classList.add("product-card"); + + const productImg = document.createElement("img"); + productImg.setAttribute("src", product.image); + + const productInfo = document.createElement("div"); + productInfo.classList.add("product-info"); + + const productInfoDiv = document.createElement("div"); + const productPrice = document.createElement("p"); + productPrice.innerText = "$" + product.price; + const productName = document.createElement("p"); + productName.innerText = product.name; + + productInfoDiv.appendChild(productPrice); + productInfoDiv.appendChild(productName); + + const productInfoFigure = document.createElement("figure"); + const productImgCard = document.createElement("img"); + productImgCard.setAttribute("src", "./icons/bt_add_to_cart.svg"); + + productInfoFigure.appendChild(productImgCard); + + productInfo.appendChild(productInfoDiv); + productInfo.appendChild(productInfoFigure); + + productCard.appendChild(productImg); + productCard.appendChild(productInfo); + + cardsContainer.appendChild(productCard); + } +} + +renderProducts(productList); +``` +En la proxima clase vamos a estar agregando eventos a este codigo, ya que ahora resolvimos generar el HTML a traves de JS. + + diff --git a/styles.css b/styles.css index ddb8d2182..04f60cf0a 100644 --- a/styles.css +++ b/styles.css @@ -232,6 +232,50 @@ nav { height: 50px; } +/* Product list */ + +.cards-container { + display: grid; + grid-template-columns: repeat(auto-fill, 240px); + gap: 26px; + place-content: center; + margin-top: 20px; +} +.product-card { + width: 240px; +} +.product-card img { + width: 240px; + height: 240px; + border-radius: 20px; + object-fit: cover; +} +.product-info { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 12px; +} +.product-info figure { + margin: 0; +} +.product-info figure img { + width: 35px; + height: 35px; +} +.product-info div p:nth-child(1) { + font-weight: bold; + font-size: var(--md); + margin-top: 0; + margin-bottom: 4px; +} +.product-info div p:nth-child(2) { + font-size: var(--sm); + margin-top: 0; + margin-bottom: 0; + color: var(--very-light-pink); +} + /* media */ @media (max-width: 640px) { .menu { @@ -250,6 +294,17 @@ nav { .product-detail { width: 100%; } + + .cards-container { + grid-template-columns: repeat(auto-fill, 140px); + } + .product-card { + width: 140px; + } + .product-card img { + width: 140px; + height: 140px; + } } @media(min-width: 641px){ From 99765cbdbadc4a45a0acd5aa3d1ca5ae2976d4a9 Mon Sep 17 00:00:00 2001 From: CsR Date: Fri, 2 Sep 2022 03:02:25 -0300 Subject: [PATCH 06/10] C022. Detalle de un producto --- index.html | 21 ++++++++++++-- main.js | 20 ++++++------- notas.md | 14 +++++++++ styles.css | 84 ++++++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 119 insertions(+), 20 deletions(-) diff --git a/index.html b/index.html index 820a1a8c9..d9aead9f7 100644 --- a/index.html +++ b/index.html @@ -110,7 +110,7 @@ - +``` + +Y por ultimo, cuando en JS se ejecuta la funcion abrir el product-detail, que detecte el id de la imagen en la que se hizo click, lo convierta en tipo numero para utilizarlo como indice del array y a traves de este modificar el HTML. + +```javascript +// Se agrego los siguientes selectores +const productInfoDetailImage = document.querySelector(".product-info-detail-image"); +const productInfoDetailPrice = document.querySelector(".product-info-detail-price"); +const productInfoDetailTitle = document.querySelector(".product-info-detail-title"); +const productInfoDetailDescription = document.querySelector(".product-info-detail-description"); + +// En la funcion openProductDetailAside(event) se agrego +//Obtengo el id de la imagen clickeada y lo utilizo como indice del string + const idCard = parseInt(event.path[1].id.substring(2)); + + productInfoDetailImage.setAttribute("src", productList[idCard].image); + productInfoDetailPrice.innerText = "$"+ productList[idCard].price; + productInfoDetailTitle.innerText = productList[idCard].name; + productInfoDetailDescription.innerText = productList[idCard].description; +``` \ No newline at end of file From 030352201bd0db156310e4b9bf450d7e1554572f Mon Sep 17 00:00:00 2001 From: csrodriguez <106087704+csrodriguez@users.noreply.github.com> Date: Fri, 2 Sep 2022 11:56:40 -0300 Subject: [PATCH 10/10] Rename notas.md to README.md --- notas.md => README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename notas.md => README.md (99%) diff --git a/notas.md b/README.md similarity index 99% rename from notas.md rename to README.md index 20cc37fe0..f17417e30 100644 --- a/notas.md +++ b/README.md @@ -632,4 +632,4 @@ const productInfoDetailDescription = document.querySelector(".product-info-detai productInfoDetailPrice.innerText = "$"+ productList[idCard].price; productInfoDetailTitle.innerText = productList[idCard].name; productInfoDetailDescription.innerText = productList[idCard].description; -``` \ No newline at end of file +```