Foros aprenderaprogramar.com

Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: D.Ohm en 18 de Mayo 2021, 01:52

Título: JavaScript crear calendario de mes dinámico cualquier fecha (eterno) CU01162E
Publicado por: D.Ohm en 18 de Mayo 2021, 01:52
Es la primera resolución de un ejercicio que posteo del curso de JavaScript de aprenderaprogramar que vengo siguiendo, no posteé nada antes porque estaba esperando este tipo de ejercicios integradores, en éste aplico todo lo se ha venido viendo hasta ahora de forma intencional para mi propia práctica, hice lo que se pedia y un poco mas a modo de autodesafío y quizá, llegar a reciclarlo en el futuro. Espero este correcto, y si no, pues tengo tengo todas las ganas de aprender asi que bienvenidas las correcciones.

Gracias por esta increible página, increiblemente clara la información, y el plan de formación es grandioso, y lo mejor libre de acceso. <3<3<3. Gracias, gracias, gracias!!

Código: [Seleccionar]
<!DOCTYPE html>
<html><head> <title>Curso JavaScript aprenderaprogramar.com</title>
<meta charset="utf-8" name="viewport" content="width=device-width,initial-scale=1.0"/>
<style type="text/css">
@media (min-width : 100px) and  (max-width : 4080px) {
body {font-family: Geneva, Tahoma, "Nimbus Sans L", sans-serif; text-align: center;}
h1 {display: flex; margin: auto; justify-content: center;}
#tecla {border-style:solid; margin: auto; height: 500px; width: 400px; background-color: lightgrey; border-radius: 5px; display: flex; justify-content: center; font-size: 25px;}
th, td {height: 43px; width: 42px; border-collapse: collapse; border-radius: 5px;}
</style>
<script type="text/javascript">
function nCalendarioH() {
this.fecha = new Date();
this.año = this.fecha.getFullYear();
this.mes = this.fecha.getMonth();
this.dia = this.fecha.getDay();
this.hoy = this.fecha.getDate();}

nCalendarioH.prototype.mesDia = function(){
var mesCal = document.getElementById("mes");
if (this.mes == 0) {mesCal.innerHTML = "ENERO DE " + this.año;}
else if (this.mes == 1) {mesCal.innerHTML = "FEBRERO DE " + this.año;}
else if (this.mes == 2) {mesCal.innerHTML = "MARZO DE " + this.año;}
else if (this.mes == 3) {mesCal.innerHTML = "ABRIL DE " + this.año;}
else if (this.mes == 4) {mesCal.innerHTML = "MAYO DE " + this.año;}
else if (this.mes == 5) {mesCal.innerHTML = "JUNIO DE " + this.año;}
else if (this.mes == 6) {mesCal.innerHTML = "JULIO DE " + this.año;}
else if (this.mes == 7) {mesCal.innerHTML = "AGOSTO DE " + this.año;}
else if (this.mes == 8) {mesCal.innerHTML = "SEPTIEMBRE DE " + this.año;}
else if (this.mes == 9) {mesCal.innerHTML = "OCTUBRE DE " + this.año;}
else if (this.mes == 10) {mesCal.innerHTML = "NOVIEMBRE DE " + this.año;}
else {mesCal.innerHTML = "DICIEMBRE DE " + this.año;}
}
nCalendarioH.prototype.cal = function(){
var diaM = [0,1,2,3,4,5,6];
var diaH = diaM[this.dia];
var mesD = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
var diasPostF = mesD.slice(0, 27+1);
var diasPostFB = mesD.slice(0, 28+1);
var diasPostMC = mesD.slice(0, 29+1);
var diasPostML = mesD.slice(0, 30+1);
var fila1_6 = document.getElementsByTagName("td");
var semD = 5;
var conMarcV = semD-1;

function bucleMeses(semDi) {
if (this.año % 4 == 0 && this.mes == 1){
for (var j=0; j<=diasPostFB.length; j++){fila1_6[j+semDi].innerHTML = diasPostFB[j]==undefined?"":diasPostFB[j];}}
else if (this.año % 4 != 0 && this.mes == 1){
for (var j=0; j<=diasPostF.length; j++){fila1_6[j+semDi].innerHTML = diasPostF[j]==undefined?"":diasPostF[j];}}
else if(this.mes==3||this.mes==5||this.mes==8||this.mes==10){
for (var j=0; j<=diasPostMC.length; j++){fila1_6[j+semDi].innerHTML = diasPostMC[j]==undefined?"":diasPostMC[j];}}
else{
for (var j=0; j<=diasPostML.length; j++){fila1_6[j+semDi].innerHTML = diasPostML[j]==undefined?"":diasPostML[j];}}
fila1_6[this.hoy+semDi-1].style.backgroundColor='lightblue';}

do{ for (var i=(this.hoy-1);i>=0;i--) {
if(mesD[i] ==1){
switch(diaH){
case 0: semD +=1; bucleMeses.call(this, semD); break;
case 1: semD-=5; bucleMeses.call(this, semD); break;
case 2: semD-=4;bucleMeses.call(this, semD);break;
case 3: semD-=3;bucleMeses.call(this, semD);break;
case 4: semD-=2;bucleMeses.call(this, semD);break;
case 5: semD-=1;bucleMeses.call(this, semD);break;
case 6: bucleMeses.call(this, semD);break;}}
if(diaH==0){diaH+=7;}
diaH-=1;}}while(mesD>0);}

function nCalendarioES(eFecha,eMes,eAño) {
this.fecha2 = new Date();
this.fecha2.setDate(eFecha);
this.fecha2.setMonth(eMes-1);
this.fecha2.setFullYear(eAño);
this.año = this.fecha2.getFullYear();
this.mes = this.fecha2.getMonth();
this.dia = this.fecha2.getDay();
this.hoy = this.fecha2.getDate();}

nCalendarioES.prototype = new nCalendarioH();

window.onload =
function objCalendario() {
alert("Introduzca una fecha para ver el calendario de esa fecha.\nSi no introduce nada, verá según la fecha actual.")
var fechaI = prompt("introduzca el día: ");
var mesI = prompt("introduzca el mes: ");
var añoI = prompt("introduzca el año: ");
fechaI = Number(fechaI);
mesI = Number(mesI);
añoI = Number(añoI);

if(fechaI||mesI||añoI){var defCal2 = new nCalendarioES(fechaI,mesI,añoI);defCal2.mesDia(); defCal2.cal();}
else{ var defCal = new nCalendarioH();defCal.mesDia();defCal.cal();}}


</script>
</head>
<body >
<h1>Calendario</h1>
        <div id="tecla">
<table border="1" cellpadding="4" align="center">
  <caption id="mes" style="font-size: 25px; margin: 30px; "> </caption>
     <tr>
      <th  colspan="1">Lu</th>
      <th  colspan="2">Ma</th>
      <th  colspan="3">Mi</th>
      <th  colspan="4">Ju</th>
      <th  colspan="5">Vi</th>
      <th  colspan="6">Sa</th>
      <th  colspan="7">Do</th>
     </tr>
    <tbody>   
      <tr id="fila1">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>   
      <tr id="fila2">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>   
      <tr id="fila3">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>   
      <tr id="fila4">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>   
      <tr id="fila5">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>
      <tr id="fila6">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>    
    </tbody>      
  </table>
 </div>
</body>
</html>

Saludos!!
Título: Re: JavaScript crear calendario de mes dinámico cualquier fecha (eterno) CU01162E
Publicado por: Ogramar en 18 de Mayo 2021, 21:19
Buenas, tu código funciona bien y tiene una buena maquetación. Como bien indicas, en este código no sólo has dado respuesta a lo que se pedía en el ejercicio sino que has ido más allá (por ejemplo, el ejercicio no planteaba que el usuario pudiera elegir una fecha para que se mostrara el calendario del mes correspondiente). También has usado elementos de CSS que no están explicados en el curso de CSS.
Hay algunas cuestiones que quizás serían mejorables, por ejemplo en lugar de darle estilos a la tabla con atributos <table border="1" cellpadding="4" align="center"> quizás hubiera sido preferible hacerlo con CSS.

Esta definición de array var mesD = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]; normalmente se considerará poco elegante desde el punto de vista de la programación, ya que para hacer algo de este tipo en general se prefieren bucles. Lo cual no significa que no se pueda hacer así si en un momento dado se considera adecuado.

Otra cosa que solemos recomendar es no usar eñes en el código, pues a la larga puede dar problemas. Así en lugar de this.año usaríamos this.anyo ó this.anno

Este código

Código: [Seleccionar]
nCalendarioH.prototype.mesDia = function(){
var mesCal = document.getElementById("mes");
if (this.mes == 0) {mesCal.innerHTML = "ENERO DE " + this.año;}
else if (this.mes == 1) {mesCal.innerHTML = "FEBRERO DE " + this.año;}
else if (this.mes == 2) {mesCal.innerHTML = "MARZO DE " + this.año;}
else if (this.mes == 3) {mesCal.innerHTML = "ABRIL DE " + this.año;}
else if (this.mes == 4) {mesCal.innerHTML = "MAYO DE " + this.año;}
else if (this.mes == 5) {mesCal.innerHTML = "JUNIO DE " + this.año;}
else if (this.mes == 6) {mesCal.innerHTML = "JULIO DE " + this.año;}
else if (this.mes == 7) {mesCal.innerHTML = "AGOSTO DE " + this.año;}
else if (this.mes == 8) {mesCal.innerHTML = "SEPTIEMBRE DE " + this.año;}
else if (this.mes == 9) {mesCal.innerHTML = "OCTUBRE DE " + this.año;}
else if (this.mes == 10) {mesCal.innerHTML = "NOVIEMBRE DE " + this.año;}
else {mesCal.innerHTML = "DICIEMBRE DE " + this.año;}
}

posiblemente se viera más elegante si metieras los nombres de los meses en un array y seleccionaras el índice. Algo así como

mesCal.innerHTML = arrayDeMeses[indice] + " DE " + this.año;

En general la repetición de código está mal vista en programación (sobre todo si hay forma de evitarla).

Una cosa que echo en falta son comentarios explicativos, creo que no hay ni un comentario en el código. Esto no es obligatorio, pero suele ser bueno para poder comprenderlo, incluso para que puedas comprenderlo tú si lo miras dentro de un tiempo (seguro que dentro de unos meses ya no te acuerdas de muchas cosas).

Pero más allá de cosas mejorables, creo que lo que hay que destacar es que has usado muchos elementos distintos de programación, que demuestras un buen nivel de JavaScript y que esto no es sólo una solución al ejercicio, sino que has ido más allá.

Una cosa que sería interesante es que fueras explicando paso a paso lo que hace tu código y cómo lo has organizado. Creo que esto sería de utilidad para otras personas. Así que si quieres hacerlo adelante, te lo agradeceremos.

Y gracias por tus comentarios sobre la página.

Salu2
Título: Re: JavaScript crear calendario de mes dinámico cualquier fecha (eterno) CU01162E
Publicado por: D.Ohm en 19 de Mayo 2021, 00:29
Muchas gracias Ogramar por la devolución, pego acá el código con las correcciones.

Código: [Seleccionar]
<!DOCTYPE html>
<html><head> <title>Curso JavaScript aprenderaprogramar.com</title>
<meta charset="utf-8" name="viewport" content="width=device-width,initial-scale=1.0"/>
<style type="text/css">
@media (min-width : 100px) and  (max-width : 4080px) {
body {font-family: Geneva, Tahoma, "Nimbus Sans L", sans-serif; text-align: center;}
h1 {display: flex; margin: auto; justify-content: center;}
#tecla {border-style:solid; margin: auto; height: 500px; width: 400px; background-color: lightgrey; border-radius: 5px; display: flex; justify-content: center; font-size: 25px;}
th, td {height: 43px; width: 42px; border-collapse: collapse; border-radius: 5px;}
</style>
<script type="text/javascript">
//Declaro el tipo de objeto y sus propiedades vinculadas al Objeto Date
function nCalendarioH() {
this.fecha = new Date();
this.anyo = this.fecha.getFullYear();
this.mes = this.fecha.getMonth();
this.dia = this.fecha.getDay();
this.hoy = this.fecha.getDate();}
//Declaro un método para definir el mes y año del calendario, vinculado al prototipo con la finalidad de poder heredarlo.
nCalendarioH.prototype.mesDia = function(){
var mesCal = document.getElementById("mes");
var meses = ['ENERO','FEBRERO','MARZO','ABRIL','MAYO','JUNIO','JULIO','AGOSTO','SEPTIEMBRE','OCTUBRE','NOVIEMBRE','DICIEMBRE']
for (var i=0; i<=11; i++){
if (this.mes == i) {mesCal.innerHTML = meses[i]+ " DE " + this.anyo;}}
}
//Creo otro método vinculado al prototipo, en cual establezco un una función anidada que de acuerdo al mes, vincula cada fecha con su día correspondiente, y un bucle 'do-while' que de acuerdo a cual sea el primer día del mes completa el resto de dias subsiguientes a partir del mismo.
nCalendarioH.prototype.cal = function(){
var diaM = [0,1,2,3,4,5,6];
var diaH = diaM[this.dia];
var mesD = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
var diasPostF = mesD.slice(0, 27+1);
var diasPostFB = mesD.slice(0, 28+1);
var diasPostMC = mesD.slice(0, 29+1);
var diasPostML = mesD.slice(0, 30+1);
var fila1_6 = document.getElementsByTagName("td");
var semD = 5;
var conMarcV = semD-1;

function bucleMeses(semDi) {
if (this.anyo % 4 == 0 && this.mes == 1){
for (var j=0; j<=diasPostFB.length; j++){fila1_6[j+semDi].innerHTML = diasPostFB[j]==undefined?"":diasPostFB[j];}}
else if (this.anyo % 4 != 0 && this.mes == 1){
for (var j=0; j<=diasPostF.length; j++){fila1_6[j+semDi].innerHTML = diasPostF[j]==undefined?"":diasPostF[j];}}
else if(this.mes==3||this.mes==5||this.mes==8||this.mes==10){
for (var j=0; j<=diasPostMC.length; j++){fila1_6[j+semDi].innerHTML = diasPostMC[j]==undefined?"":diasPostMC[j];}}
else{
for (var j=0; j<=diasPostML.length; j++){fila1_6[j+semDi].innerHTML = diasPostML[j]==undefined?"":diasPostML[j];}}
fila1_6[this.hoy+semDi-1].style.backgroundColor='lightblue';}

do{ for (var i=(this.hoy-1);i>=0;i--) {
if(mesD[i] ==1){
switch(diaH){
case 0: semD +=1; bucleMeses.call(this, semD); break;
case 1: semD-=5; bucleMeses.call(this, semD); break;
case 2: semD-=4;bucleMeses.call(this, semD);break;
case 3: semD-=3;bucleMeses.call(this, semD);break;
case 4: semD-=2;bucleMeses.call(this, semD);break;
case 5: semD-=1;bucleMeses.call(this, semD);break;
case 6: bucleMeses.call(this, semD);break;}}
if(diaH==0){diaH+=7;}
diaH-=1;}}while(mesD>0);}

// Creo otro objeto tipo que hereda los métodos del prototipo de 'nCalendarioH'
function nCalendarioES(eFecha,eMes,eAño) {
this.fecha2 = new Date();
this.fecha2.setDate(eFecha);
this.fecha2.setMonth(eMes-1);
this.fecha2.setFullYear(eAño);
this.anyo = this.fecha2.getFullYear();
this.mes = this.fecha2.getMonth();
this.dia = this.fecha2.getDay();
this.hoy = this.fecha2.getDate();}

nCalendarioES.prototype = new nCalendarioH();

// Instancio el objeto 'defCal' y 'defCal2' dependiendo de si el usuario introduce una fecha o no
window.onload =
function objCalendario() {
alert("Introduzca una fecha para ver el calendario de esa fecha.\nSi no introduce nada, verá según la fecha actual.")
var fechaI = prompt("introduzca el día: ");
var mesI = prompt("introduzca el mes: ");
var añoI = prompt("introduzca el año: ");
fechaI = Number(fechaI);
mesI = Number(mesI);
añoI = Number(añoI);

if(fechaI||mesI||añoI){var defCal2 = new nCalendarioES(fechaI,mesI,añoI);defCal2.mesDia(); defCal2.cal();}
else{ var defCal = new nCalendarioH();defCal.mesDia();defCal.cal();}}


</script>
</head>
<body >
<h1>Calendario</h1>
        <div id="tecla">
<table border="1" cellpadding="4" align="center">
  <caption id="mes" style="font-size: 25px; margin: 30px; "> </caption>
     <tr>
      <th  colspan="1">Lu</th>
      <th  colspan="2">Ma</th>
      <th  colspan="3">Mi</th>
      <th  colspan="4">Ju</th>
      <th  colspan="5">Vi</th>
      <th  colspan="6">Sa</th>
      <th  colspan="7">Do</th>
     </tr>
    <tbody>   
      <tr id="fila1">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>   
      <tr id="fila2">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>   
      <tr id="fila3">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>   
      <tr id="fila4">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>   
      <tr id="fila5">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>
      <tr id="fila6">
      <td colspan="1" class="lu"> </td>
      <td colspan="2" class="ma"> </td>
      <td colspan="3" class="mi"> </td>
      <td colspan="4" class="ju"> </td>
      <td colspan="5" class="vi"> </td>
      <td colspan="6" class="sa"> </td>
      <td colspan="7" class="do"> </td>
      </tr>    
    </tbody>      
  </table>
 </div>
</body>
</html>

Corregí todo lo marcado excepto lo del array 'mesD' ni lo del 'CSS' porque, si bien entendí el punto, creo que por ahora prefiero dejarlo así, sin embargo, lo tendré en cuenta de ahora en más.

Muchas gracias nuevamente y ojalá a otr@ alumn@ le sea ilustrativa la forma en que resolví el ejercicio planteado!

Saludos!!