Usar ng-repeat para mostrar los dias en forma de calendario

publicado por: Anonymous

Tratando de migrar un código a Angular el cual tengo hecho en jquery, el cual es un calendario con datepicker integrado. El problema es que hay que tener en cuenta lo siguiente:

  1. Si el primer día del mes cae cualquier día que no es lunes, entonces se debe rellenar los días anteriores a este para evitar que se desorganice el calendario.
  2. Lo mismo si el ultimo día no es domingo, también hay que rellenar para no desorganizar la forma del calendario.

Aquí un ejemplo del código resumido de lo que yo hacia:

 <div>

<select>
    <option value="nombredelmes o numero del mes">Nombre del mes</option>
</select>

<div id="diasSemana">
    <div class="row">
        <p class="col">L</p>
        <p class="col">M</p>
        <p class="col">M</p>
        <p class="col">J</p>
        <p class="col">V</p>
        <p class="col">S</p>
        <p class="col">D</p>
    </div>
</div>

<div>

    <div class="row" id="uno"></div>
    <div class="row" id="dos"></div>
    <div class="row" id="tres"></div>
    <div class="row" id="cuatro"></div>
    <div class="row" id="cinco"></div>
    <div class="row" id="seis"></div>

</div>

En el codigo anterior en los id que van en ascenso, insertaba mediante append o cualquier otra forma de hacer ir colocando las fechas correspondiente a cada dia, sin olvidar, lo anterior expuesto.

Los días, fechas y demás lo obtenía mediante la librería Moment.js

solución

Esto lo puedes lograr con un filtro customizado. Un filtro es una funcionalidad que básicamente te permite transformar cualquier dato en cualquier cosa.

Puedes usar como entrada una cadena de caracteres 'mes/año' o 'mes' y obtener un arreglo en la salida con los días deseados.

Te dejo un demo:

_x000D_

_x000D_

angular.module('app', [])_x000D_
  .controller('CalendarioCtrl', function() {_x000D_
    var vm = this;_x000D_
    vm.meses = [{_x000D_
      nombre: 'Enero',_x000D_
      numero: 1_x000D_
    }, {_x000D_
      nombre: 'Febrero',_x000D_
      numero: 2_x000D_
    }, {_x000D_
      nombre: 'Marzo',_x000D_
      numero: 1_x000D_
    }, {_x000D_
      nombre: 'Abril',_x000D_
      numero: 4_x000D_
    }, {_x000D_
      nombre: 'Mayo',_x000D_
      numero: 5_x000D_
    }, {_x000D_
      nombre: 'Junio',_x000D_
      numero: 6_x000D_
    }, {_x000D_
      nombre: 'Julio',_x000D_
      numero: 7_x000D_
    }, {_x000D_
      nombre: 'Agosto',_x000D_
      numero: 8_x000D_
    }, {_x000D_
      nombre: 'Septiembre',_x000D_
      numero: 9_x000D_
    }, {_x000D_
      nombre: 'Octubre',_x000D_
      numero: 10_x000D_
    }, {_x000D_
      nombre: 'Noviembre',_x000D_
      numero: 11_x000D_
    }, {_x000D_
      nombre: 'Diciembre',_x000D_
      numero: 12_x000D_
    }];_x000D_
    vm.semana = ['Domingo', 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado'];_x000D_
  })_x000D_
  .filter('calendario', function() {_x000D_
    return function(input) {_x000D_
      if (input) {_x000D_
        var result = [];_x000D_
        var year = moment().year();_x000D_
        var startDay = moment(input + '/01/' + year);_x000D_
        var endDay = startDay.clone().endOf('month');_x000D_
        var prefix = startDay.weekday();_x000D_
        var dayPrevMonth = startDay.clone().day(0).date();_x000D_
        var endPrevMonth = startDay.clone().day(0).endOf('month').date();_x000D_
        if (endPrevMonth - dayPrevMonth < 7) {_x000D_
          for (var i = dayPrevMonth; i <= endPrevMonth; i++) {_x000D_
            result.push({_x000D_
              day: i,_x000D_
              current: false_x000D_
            });_x000D_
          }_x000D_
        }_x000D_
        var days = startDay.daysInMonth();_x000D_
        for (var i = 0; i < days; i++) {_x000D_
          result.push({_x000D_
            day: i + 1,_x000D_
            current: true_x000D_
          });_x000D_
        }_x000D_
_x000D_
        var endNextWeek = endDay.clone().day(7).date();_x000D_
        for (var i = 1; i < endNextWeek; i++) {_x000D_
          result.push({_x000D_
            day: i,_x000D_
            current: false_x000D_
          });_x000D_
        }_x000D_
_x000D_
        return result;_x000D_
      }_x000D_
    };_x000D_
  });

_x000D_

ul {_x000D_
  list-style: none;_x000D_
  margin: 0;_x000D_
  padding: 0;_x000D_
}_x000D_
.header {_x000D_
  font-weight: bolder;_x000D_
  font-size: 12px;_x000D_
}_x000D_
.calendar.header .day {_x000D_
  height: 30px;_x000D_
}_x000D_
.calendar {_x000D_
  position: relative;_x000D_
  width: 100%_x000D_
}_x000D_
.calendar .day {_x000D_
  float: left;_x000D_
  width: 13.8%;_x000D_
  height: 100px;_x000D_
  border: solid 1px lightgray;_x000D_
}_x000D_
.calendar .day.other {_x000D_
  background-color: lightgray;_x000D_
}

_x000D_

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>_x000D_
<script src="http://momentjs.com/downloads/moment.min.js"></script>_x000D_
<div ng-app="app" ng-controller="CalendarioCtrl as vm">_x000D_
  <select ng-options="mes.numero as mes.nombre for mes in vm.meses" ng-model="vm.selected">_x000D_
  </select>_x000D_
  <br>_x000D_
  <br>_x000D_
  <div ng-if="vm.selected">_x000D_
    <ul class="calendar header">_x000D_
      <li class="day" ng-repeat="dia in vm.semana">{{dia}}</li>_x000D_
    </ul>_x000D_
    <ul class="calendar">_x000D_
      <li class="day" ng-class="{other: !item.current}" ng-repeat="item in vm.selected | calendario track by $index">_x000D_
        {{item.day}}_x000D_
      </li>_x000D_
    </ul>_x000D_
  </div>_x000D_
</div>

_x000D_

_x000D_

_x000D_

Por supuesto que el ejemplo tiene algunos problemas como utilizar el primer día de la semana de acuerdo a la configuración regional y el formato de entrada de las fechas por lo que te recomiendo que uses una librería profesional cuando intentes realizar tareas como esta.

Aqui te dejo el link de una muy popular

https://github.com/angular-ui/ui-calendar

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *