2

I am attempting to make a calendar in angular.js.

Let's say I have the following data in the scope:

$scope.events = [{"date":"2016-07-23","name":"Bob's Birthday"},
    {"date":"2016-07-24","name":"Doc appt"},
    {"date":"2016-07-25","name":"Date with Shannon"}]

I also have a calendar in the HTML with a div corresponding to each date in the month. How do I go about having each date show the corresponding events.

I am new to angular, and my kneejerk reaction is to have each date div have an attribute in each date div containing the date, and loop through the list of events and append an event-div for each event to the corresponding date div using jQuery. But the issue with this is that when the scope changes, the view wont.

Is there a good way to do this using angular? I know you can have directives that loop through data or be hidden depending on the data, but I can't seem to find anything about using angular to determine the location of a div

Madhawa Priyashantha
  • 9,633
  • 7
  • 33
  • 60
quantumbutterfly
  • 1,815
  • 4
  • 23
  • 38

2 Answers2

1

You could do something like this:

"use strict";
var app = angular.module("testApp", [], function() {});

app.controller("appCtrl", function($scope) {
  $scope.events = [
    { "date": "2016-07-23", "name": "Bob's Birthday" },
    { "date": "2016-07-24", "name": "Doc appt" },
    { "date": "2016-07-25", "name": "Date with Shannon" }
  ];

  $scope.$watch("events", function(newValue, oldValue) {
    console.log("entireScope has changed", newValue, oldValue);
    $.each(newValue, function(index, value) {
      $("[data-date=" + value.date + "]").html(value.name);
    });
  }, true);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="testApp">
  <div ng-controller="appCtrl" id="appCtrl">
    <div class="fc-day fc-widget-content fc-mon fc-past" data-date="2016-07-23"></div>
  </div>
</body>
Nhan
  • 3,595
  • 6
  • 30
  • 38
Gaurav Srivastava
  • 3,232
  • 3
  • 16
  • 36
1

But the issue with this is that when the scope changes, the view wont.

$watch is provided by angularjs specifically to deal with this situation.

You can use $watch on your $scope.events. Whenever there will be a change in $scope.events, it will run a function defined by you. You can place your logic inside that function that will update your calendar accordingly.

See this Plunker that I've created for you.

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  
  $scope.events = [{"date":"2016-07-23","name":"Bob's Birthday"},
    {"date":"2016-07-24","name":"Doc appt"},
    {"date":"2016-07-25","name":"Date with Shannon"}];
    

  $scope.changeEvent = function() {
    var nameDOM = document.getElementById("name");
    var dateDOM = document.getElementById("date");
    
    var event = {
      "date": dateDOM.value,
      "name": nameDOM.value
    };
    
    $scope.events.push(event);
    
    nameDOM.value = dateDOM.value = ""
  }
  
  $scope.$watch('events', function() {
    alert("hey, events variable has changed! It's time to put some logic here that will update the calendar accordingly");
  }, true);

  
});
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <input id="name" name="name" placeholder="name"/><br>
    <input id="date" name="date" placeholder="date"/><br>
    <button ng-click="changeEvent()">addEvents</button>
    
  </body>

</html>
Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71