<div class="list-wrapper" ng-class="{'error' : allTasks=='error'}" ng-app="todoApp" ng-controller="todoCtrl">
<div class="list" ng-hide="allTasks=='error'" ng-cloak>
<h1 class="heading">Don't Forget To...</h1>
<form>
<div class="item" ng-repeat="task in taskList">
<input type="checkbox" id="task-{{$index}}" ng-true-value="'completed'" ng-false-value="'todo'" ng-model="task.status" ng-change="completeTask(task)" />
<label for="task-{{$index}}">{{ task.descrip }}<span></span></label>
</div>
</form>
</div>
<div class="switchMessage" ng-switch="allTasks">
<h3 class="count" ng-switch-default>{{completedTasks}} out of {{taskList.length}} tasks completed</h3>
<h3 class="done" ng-switch-when="done">You're done!</h3>
<h4 class="error" ng-switch-when="error">Error loading data :(<h4>
</div>
</div>
$header-font: "Nunito";
$main-font: "Open Sans";
* { box-sizing: border-box; }
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
body, html { height: 100%; }
body {
display: flex;
align-items: center;
justify-content: center;
background-color: skyblue;
}
.list-wrapper {
position: relative;
min-width: 45%;
padding: 30px;
border-radius: 5px;
box-shadow: 6px 6px 2px rgba(0, 0, 0, 0.1);
color: rgba(black, 0.7);
background-image: repeating-linear-gradient(
180deg,
darken(#fff, 10%),
darken(#fff, 10%) 1px,
#fff 1px,
#fff 30px
);
&:before {
position: absolute;
content: "";
display: block;
width: 155px;
height: 50px;
top: 11px;
left: -43px;
background-color: rgba(236, 236, 236, 0.5);
border-left: 2px dotted skyblue;
border-right: 2px dotted skyblue;
transform: rotate(-45deg);
}
}
.heading {
border-bottom: 3px solid;
font-family: $header-font;
font-size: 3em;
padding: 15px 0;
text-transform: uppercase;
text-align: center;
color: #CD4B4B;
}
form { padding: 15px 0; }
.item {
margin: 18px;
position: relative;
label {
font-family: $main-font;
font-size: 1.1em;
cursor: pointer;
}
}
// Actual checkbox
input[type="checkbox"] { visibility: hidden; }
// Fake checkbox
input[type="checkbox"] + label span {
width: 19px;
height: 19px;
position: absolute;
top: 0;
left: -5px;
background-color: #fff;
border: 1px solid #888;
border-radius: 4px;
cursor: pointer;
}
// Cross out the item once it's been checked off
input[type="checkbox"]:checked + label {
color: #ccc;
text-decoration: line-through;
span { border: none; }
// Fake X
span:before, span:after {
content: "";
width: 3px;
height: 21px;
position: absolute;
top: -2px;
left: 7px;
background-color: lightgreen;
}
span:before { transform: rotate(-45deg); }
span:after { transform: rotate(45deg); }
}
.count, .done {
@extend .heading;
font-family: $main-font;
border-top: 3px solid #CD4B4B;
border-bottom: none;
font-size: 1.7em;
}
// When the JSON file doesn't load
.list-wrapper.error {
min-width: 350px;
}
h4.error {
font-size: 1.4em;
text-align: center;
}
View Compiled
var app = angular.module("todoApp", []);
app.controller("todoCtrl", function($scope, $http) {
$scope.taskList = [];
$http.get("https://api.myjson.com/bins/2avds")
.success(function(result) {
$scope.taskList = result.data;
})
.error(function (data, status, headers, config) {
$scope.allTasks = "error";
});
$scope.completedTasks = 0;
$scope.completeTask = function(task) {
if (task.status == "completed") {
$scope.completedTasks++;
}
else if (task.status == "todo") {
$scope.completedTasks--;
}
if ($scope.completedTasks == $scope.taskList.length) {
$scope.allTasks = "done";
}
else {
$scope.allTasks = "count";
}
}
$scope.messages = ['count', 'done', 'error'];
$scope.displayMessage = $scope.messages[0];
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.