To make onload function in angularjs work - angularjs

I have a made a quiz code that displays 10 questions. I want the function to load as soon as the page loads. In javascript , it was onload, here in angular I have used angular.element(document).ready(function(){....}); after defining in the controller. It is not getting loaded. Also I want to know if my code is proper, I have used an ng-click for submit inside the controller, it worked when I did the program in javascript,not sure of angularjs. Also please check if my foreach in checkAnswer() function is proper. And if any other bug please let me know.
<html ng-app="Swabhav.Quiz">
<head>
<title>Quiz code</title>
<script src="angular.js"></script>
<style>
h1 {
text-align: center;
background-color: lightcoral;
}
#head {
text-decoration: underline;
text-decoration-color: maroon;
}
#select1 {
align-self: center;
text-align: center;
font-family: 'Trebuchet MS';
font-size: 20px;
color: indigo;
margin-top: 30px;
margin-bottom: 50px;
padding: 30px;
}
</style>
</head>
<body>
<div ng-controller="QuizController">
<h1>QUIZ</h1>
<div id="head" ng-bind="head"></div>
<div id="select1" ng-bind="selection"></div>
</div>
<script>
angular.module("Swabhav.Quiz", [])
.controller("QuizController", ["$scope", "$log", function ($scope,
$log) {
angular.element(document).ready(function () {
var choiceA, choiceB, choiceC, choiceD, answer, element,
correct = 0, wrong = 0;
var index = 0, choices, choice, position = 0;
$scope.questions = [
{ question: "How many strokes in the Ashoka Chakra?" },
{ question: "What is 30*2?" },
{ question: " What is largest fish? " },
{ question: "What is the currency of Europe and America
respectively?" },
{ question: "What is the seven wonders of the World
amongst these?" },
{ question: "What is the main source of travel in
Mumbai?" },
{ question: "How many continents in the World?" },
{ question: "What Ocean surrounds India ?" },
{ question: "What station does not come in Mumbai-
Railway-Western-Line?" },
{ question: "Who is the CEO of Google parent company-
Alphabet Inc.?" }
];
$scope.options =
[{ A: "12", B: "24", C: "32", D: "10" },
{ A: "60", B: "50", C: "20", D: "10" },
{ A: "Blue Whale", B: "Megaladon", C: "Hammer-head
shark", D: "All the sharks" },
{ A: "Dollar and Euro", B: "Euro and Dollar", C: "Yen
and Rupees", D: "Rupees and Yen" },
{ A: "Taj Mahal", B: "Great Wall Of China", C: "Victoria
Falls", D: "All of these" },
{ A: "Trains", B: "Aeroplane", C: "Autorickshaw", D:
"Motorcycle" },
{ A: "3", B: "4", C: "5", D: "6" },
{ A: "Indian Ocean", B: "Pacific Ocean", C: "Atlantic
Ocean", D: "Arctic Ocean" },
{ A: "Sandhurst Road", B: "Andheri", C: "Borivali", D:
"Naigaon" },
{ A: "Madhuri Dixit", B: "Narendra Modi", C: "Tim Cook",
D: "Sundar Pichai" }
]
$scope.answers =
[
{ answer: "B" },
{ answer: "A" },
{ answer: "B" },
{ answer: "B" },
{ answer: "D" },
{ answer: "A" },
{ answer: "C" },
{ answer: "A" },
{ answer: "A" },
{ answer: "D" }
]
var row = 0;
$scope.selectQuestion = function (index) {
$scope.choicesIndex = 4;
if (row == $scope.questions.length) {
alert("you have " + correct + " correct answers
and " + wrong + " wrong answers out of 10 !");
return false;
}
$scope.head = "<b>" + "Question " + ++index + " of 10" +
"<b>";
question = $scope.questions[row];
choiceA = options.A[row];
choiceB = options.B[row];
choiceC = options.C[row];
choiceD = options.D[row];
answer = answers.answer[row];
$scope.selection = index + ". " + question + "<br>"
+ "<input type='radio' name='choices' value='A'>" +
choiceA + "<br>"
+ "<input type='radio' name='choices' value='B'>" +
choiceB + "<br>"
+ "<input type='radio' name='choices' value='C'>" +
choiceC + "<br>"
+ "<input type='radio' name='choices' value='D'>" +
choiceD + "<br>";
+"<button type='button' ng-click='checkAnswer()'> Submit
</button>" + "<br>"
}
$scope.checkAnswer = function () {
$scope.choices.push(choiceA);
$scope.choices.push(choiceB);
$scope.choices.push(choiceC);
$scope.choices.push(choiceD);
angular.array.forEach($scope.choices, function (value,
key) {
if ($scope.choicesIndex != 0) {
if
($scope.choices[$scope.choicesIndex].value.checked) {
$scope.selectedChoice =
$scope.choices[$scope.choicesIndex].key;
$log.log("$scope.selectedChoice = " +
$scope.selectedChoice);
$scope.choicesIndex--;
}
}
});
if ($scope.selectedChoice == answer) {
correct++;
}
else if ($scope.selectedChoice == "" ||
$scope.selectedChoice != answer) {
wrong++;
}
row++;
$scope.selectQuestion();
}
});
}]);
</script>
</body>
</html>

As #Arash mentioned, you are coding angularjs in a wrong way.
It will be better if you go through some angularjs kick start tuitorials.
Below is the working angularjs code
<html ng-app="Swabhav.Quiz">
<head>
<title>Quiz code</title>
<script data-require="angular.js#1.6.6" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<style>
h1 {
text-align: center;
background-color: lightcoral;
}
#head {
text-decoration: underline;
text-decoration-color: maroon;
}
#select1 {
align-self: center;
text-align: center;
font-family: 'Trebuchet MS';
font-size: 20px;
color: indigo;
margin-top: 30px;
margin-bottom: 50px;
padding: 30px;
}
.mt-10{
margin-top: 10px;
}
</style>
</head>
<body>
<div ng-controller="QuizController">
<h1>QUIZ</h1>
<!--<div id="head" ng-bind="head"></div>
<div id="select1" ng-bind="selection"></div>-->
<div ng-repeat="question in questions" ng-show="currentQuestion==$index+1">
<h3>Question {{currentQuestion}} of {{questions.length}}</h3>
<h4>{{question.question}}</h4>
<label ng-repeat="(key,value) in options[$index]">
<input type="radio" ng-value="key" name="{{question.question}}" ng-model="question.selected"> {{value}}
<br/>
</label>
</div>
<input class="mt-10" type="button" value="Next"
ng-click="nextQuestion()"
ng-disabled="!(questions.length>=currentQuestion && questions[currentQuestion-1].selected)"
ng-hide="questions.length==currentQuestion || showResult"/>
<input class="mt-10" type="button" value="Submit"
ng-click="checkAnswers()"
ng-show="questions.length==currentQuestion"/>
<div ng-show="showResult">you have {{correctAnswerCount}} correct answers and {{questions.length-correctAnswerCount}} wrong answers out of {{questions.length}} !</div>
</div>
<script>
angular.module("Swabhav.Quiz", [])
.controller("QuizController", ["$scope", "$log", function($scope,
$log) {
$scope.questions = [{"question":"How many strokes in the Ashoka Chakra?"},{"question":"What is 30*2?"},{"question":" What is largest fish? "},{"question":"What is the currency of Europe and America respectively ? "},{"question":"What is the seven wonders of the World amongst these ? "},{"question":"What is the main source of travel in Mumbai ? "},{"question":"How many continents in the World?"},{"question":"What Ocean surrounds India ?"},{"question":"What station does not come in Mumbai-Railway - Western - Line ? "},{"question":"Who is the CEO of Google parent company-Alphabet Inc. ? "}];
$scope.options = [{"A":"12","B":"24","C":"32","D":"10"},{"A":"60","B":"50","C":"20","D":"10"},{"A":"Blue Whale","B":"Megaladon","C":"Hammer-head shark ","D":"All the sharks "},{"A":"Dollar and Euro","B":"Euro and Dollar","C":"Yen and Rupees ","D":"Rupees and Yen "},{"A":"Taj Mahal","B":"Great Wall Of China","C":"Victoria Falls ","D":"All of these "},{"A":"Trains","B":"Aeroplane","C":"Autorickshaw","D":"Motorcycle"},{"A":"3","B":"4","C":"5","D":"6"},{"A":"Indian Ocean","B":"Pacific Ocean","C":"Atlantic Ocean ","D":"Arctic Ocean "},{"A":"Sandhurst Road","B":"Andheri","C":"Borivali","D":"Naigaon"},{"A":"Madhuri Dixit","B":"Narendra Modi","C":"Tim Cook","D":"Sundar Pichai"}];
$scope.answers = [{"answer":"B"},{"answer":"A"},{"answer":"B"},{"answer":"B"},{"answer":"D"},{"answer":"A"},{"answer":"C"},{"answer":"A"},{"answer":"A"},{"answer":"D"}];
$scope.currentQuestion = 1;
$scope.nextQuestion = function(){
if($scope.currentQuestion < $scope.questions.length){
$scope.currentQuestion++;
}
};
$scope.correctAnswerCount = 0;
$scope.checkAnswers = function(){
$scope.correctAnswerCount = 0;
angular.forEach($scope.questions, function(question, index) {
if(question.selected && question.selected == $scope.answers[index].answer){
$scope.correctAnswerCount++;
}
});
$scope.currentQuestion = undefined;
$scope.showResult = true;
};
}]);
</script>
</body>
</html>

Related

Buttons in a panel with "itemArray" binding are not displayed

I want to display a drop-down list of buttons in the left panel, one button for one "need".
Later, the user will be able to add a new need-button to the list.
I use a panel with "itemArray" binding.
But the button is not displayed when sentence: addNeed("My new need"); is executed.
I checked with the "dynamicPorts sample but I can't understand why it doesn't work.
<!DOCTYPE html>
<html>
<head>
<meta name="minimumCode" content="width=device-width, initial-scale=1">
<title>minimumCode</title>
<meta name="description" content="Iso prototype Leon Levy" />
<!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="https://unpkg.com/gojs/release/go-debug.js"></script>
<span id="diagramEventsMsg" style="color: red"></span>
<script id="code">
var ellipseStrokeWidth=3;
var ellipseWidth = 80;
var ellipseHeight = 25;
var myFont = "16px sans-serif";
var myFontMedium = "23px sans-serif";
var myFontLarge = "30px sans-serif";
var needWidth = 170;
var needHeight = 20;
var needStrokeWidth = 0;
var needColor = 'purple';
var portSize = new go.Size(8, 8);
function init() {
var $ = go.GraphObject.make; //for conciseness in defining node templates
myDiagram =
$(go.Diagram, "myDiagramDiv",
{
"undoManager.isEnabled": true
});
myBannerNeeds =
$(go.Diagram, "myBannerNeedsDiv",
{ layout: $(go.GridLayout, { wrappingColumn: 1, alignment: go.GridLayout.Position
})}
);
myBannerNeeds.nodeTemplate =
$(go.Node,
$(go.Panel, "Vertical", //needs list buttons
{ alignment: new go.Spot(0, 0), row: 0, column: 0},
new go.Binding("itemArray", "needsDataArray"),
{ itemTemplate:
$(go.Panel,
$(go.Shape, "Rectangle",
{ stroke: "red", strokeWidth: 2,
height: 30, width: 30}
),
$(go.TextBlock, { text: "...", stroke: "gray" },
new go.Binding("text", "key"))
) // end itemTemplate
}
) // end Vertical Panel
);
// Add a button to the needs panel.
function addNeed(newNeedName) {
myDiagram.startTransaction("addNeed");
var button = $('Button',
$(go.Shape, "Rectangle",
{ width: needWidth, height: needHeight, margin: 4, fill: "white",
stroke: "rgb(227, 18, 18)", strokeWidth: needStrokeWidth}),
$(go.TextBlock, newNeedName, // the content is just the text label
{stroke: needColor, font: myFont }),
{click: function(e, obj) { needSelected(newNeedName); } }
);
var needsNode = needsDataArray; //document.getElementById("ForNeeds");
if (needsNode) { showMessage("needsNode is true; " + button)}
else {showMessage("needsNode is false")};
myDiagram.model.insertArrayItem(needsNode, -1, button);
myDiagram.commitTransaction("addNeed");
}// end function addNeed
var needsDataArray = [];
var linksNeedsDataArray = []; // always empty
myBannerNeeds.model = new go.GraphLinksModel( needsDataArray, linksNeedsDataArray);
myDiagram.grid.visible = true;
myDiagram.model.copiesArrays = true;
myDiagram.model.copiesArrayObjects = true;
addNeed("My new need");
function needSelected(e,obj) {
alert("e:" + e + "; obj:" + obj + ' selected')
}; //end function flowTypeSelected
function showMessage(s) {
document.getElementById("diagramEventsMsg").textContent = s;
}
}// end function init
</script>
</head>
<body onload="init()">
<div id="container" style= "display: grid; grid-template-columns: 1fr 5fr; margin:0 ; height: 800px; width:1080px; font-size:0; position: relative; ">
<div id="ForNeeds">
<div id="myBannerNeedsDiv" style="display: inline-block; width: 200px; min-height: 400px; background: whitesmoke; margin-right: 0px; border: solid 1px purple;">
</div>
</div>
<div id="myDiagramDiv" style="flex-grow: 1; width: 804px;height: 100%; border: solid 1px black;">
</div>
</div>
</body>
</html>
Here's a basic demonstration of what I think you are asking for:
<!DOCTYPE html>
<html>
<head>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="go.js"></script>
<script id="code">
function init() {
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{ "undoManager.isEnabled": true });
myDiagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape,
{ fill: "white" }),
$(go.Panel, "Vertical",
$(go.TextBlock,
{ margin: 4 },
new go.Binding("text")),
$(go.Panel, "Vertical",
new go.Binding("itemArray", "buttons"),
{
itemTemplate:
$("Button",
$(go.TextBlock, new go.Binding("text", "")),
{
click: function(e, button) {
alert(button.data);
}
}
)
}
)
)
);
myDiagram.model = new go.GraphLinksModel(
[
{ key: 1, text: "Alpha", buttons: ["one", "two"] },
{ key: 2, text: "Beta", buttons: ["one"] }
],
[
{ from: 1, to: 2 }
]);
}
function test() {
myDiagram.commit(function(diag) {
diag.selection.each(function(n) {
if (n instanceof go.Node) {
diag.model.addArrayItem(n.data.buttons, "another");
}
})
})
}
</script>
</head>
<body onload="init()">
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
<button onclick="test()">Test</button>
</body>
</html>
Select a Node and then click the HTML "Test" Button. It will add an item to the node's data.buttons Array, which causes a copy of the Panel.itemTemplate to be added to that Panel. In this case, that item template is just a GoJS "Button" which when clicked calls alert with the value of the item, a string.
Note how the value added to the JavaScript Array in the data is just a simple object -- in this case just a string, although it is commonplace to have each Array item be a JavaScript Object with various properties. I think your problem is that you are trying to add GraphObjects to the Array. That's a no-no -- you should not be mixing the Diagram's GraphObjects with the Model data.

Angularjs filter multiple checkbox on map

I want to filter according to the materials in the room in the project. For example: if checked TV checkbox show the rooms on the TV. if checked tv and wifi checkbox just list rooms that are both TV and WiFi. My example shows the TV ones but when I press the wifi button the rooms with TV are still listed even though it is not WiFi.
This is: Fiddle
angular.module('hotelApp', [])
.controller('ContentControler', function ($scope, $timeout) {
var mapOptions = {
zoom: 2,
center: new google.maps.LatLng(40.0000, -98.0000),
mapTypeId: google.maps.MapTypeId.TERRAIN
}
$scope.location_name = "";
$scope.names = [{
prop_Name: 'Location 1',
lat: 43.7000,
long: -79.4000,
amenities: '3'
}, {
prop_Name: 'Location 2',
lat: 40.6700,
long: -73.9400,
amenities: '2'
}, {
prop_Name: 'Location 3',
lat: 41.8819,
long: -87.6278,
amenities: '4'
}, {
prop_Name: 'Location 4',
lat: 34.0500,
long: -118.2500,
amenities: '2'
}, {
prop_Name: 'Location 5',
lat: 36.0800,
long: -115.1522,
amenities: '2, 3'
}];
$scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);
$scope.markers = [];
var infoWindow = new google.maps.InfoWindow();
var createMarker = function (info) {
var marker = new google.maps.Marker({
map: $scope.map,
position: new google.maps.LatLng(info.lat, info.long),
title: info.prop_Name
});
marker.content = '<div class="infoWindowContent"><ul>' + '<li>' + info.prop_Desc + '</li>' + '<li>' + info.prop_Addr + '</li>' + '<li>' + info.prop_Price + '</li>' + '<li>' + info.prop_Dist + '</li>' + '</ul></div>';
google.maps.event.addListener(marker, 'click', function () {
infoWindow.setContent('<h2>' + marker.title + '</h2>' + marker.content);
infoWindow.open($scope.map, marker);
});
$scope.markers.push(marker);
}
for (i = 0; i < $scope.names.length; i++) {
createMarker($scope.names[i]);
}
$scope.openInfoWindow = function (e, selectedMarker) {
e.preventDefault();
google.maps.event.trigger(selectedMarker, 'click');
}
//PROBLEM FILTER HERE
$scope.am_en = function()
{
x = $(".hosting_amenities input:checkbox:checked").map(function(){return $(this).val();}).get();
$scope.ot_Filter = function (location) {
var shouldBeShown = false;
for (var i = 0; i < x.length; i++) {
if (location.amenities.indexOf(x[i]) !== -1) {
shouldBeShown = true;
break;
}
}
return shouldBeShown;
};
}
$scope.$watch('nas',
function (newValue, oldValue) {
for (jdx in $scope.markers) {
$scope.markers[jdx].setMap(null);
}
$scope.markers = [];
for (idx in $scope.nas) {
createMarker($scope.nas[idx]);
}
}, true);
});
#map {
height: 220px;
width: 400px;
}
.infoWindowContent {
font-size: 14px !important;
border-top: 1px solid #ccc;
padding-top: 10px;
}
h2 {
margin-bottom: 0;
margin-top: 0;
}
#total_items
{
margin:0px auto;
padding:0px;
text-align:center;
color:#0B173B;
margin-top:50px;
border:2px dashed #013ADF;
font-size:20px;
width:200px;
height:50px;
line-height:50px;
font-weight:bold;
}
#amount
{
color:#DF7401;
font-size:18px;
font-weight:bold;
}
#slider-range
{
margin:0px auto;
padding:0px;
text-align:center;
width:500px;
}
<script src="https://maps.googleapis.com/maps/api/js?key=&sensor=false&extension=.js"></script>
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<div ng-app="hotelApp" ng-controller="ContentControler">
<div id="map"></div>
<div id="class" ng-repeat="marker in markers"></div>
<ul>
<li ng-repeat="x in nas = (names | filter:{prop_Name:location_name} | filter:pmaxFilter | filter:ot_Filter)">{{ x.prop_Name }}</li>
</ul>
<div class="hosting_amenities">
<h3>Filter:</h3>
<input type="checkbox" name="more_filter[]" value="1">WIFI
<input type="checkbox" name="more_filter[]" value="2">TV
<input type="checkbox" name="more_filter[]" value="3">Cable TV
<input type="checkbox" name="more_filter[]" value="4">Klima
<button ng-click="am_en();">Submit</button>
</div>
With your current script, when you select 2 elements, like TV and WiFi, you are showing the rooms that have TV or WiFi. You should change your code in order to select only the rooms that have TV and WiFi, so your inner function $scope.ot_Filter will be as follows:
$scope.ot_Filter = function (location) {
var shouldBeShown = true;
for (var i = 0; i < x.length; i++) {
if (location.amenities.indexOf(x[i]) === -1) {
shouldBeShown = false;
break;
}
}
return shouldBeShown;
};
I've modified your script, adding WiFi to a location, here
You only check if something is checked and then set shouldBeShown to true and break. So you check for "OR" and not for "AND" with your checkboxes.
See your $scope.am_en = function():
for (var i = 0; i < x.length; i++) {
if (location.amenities.indexOf(x[i]) !== -1) {
shouldBeShown = true;
break;
}
}
return shouldBeShown;
You need to modify your if-statement to check ALL checked checkboxes/filters. Maybe you can think about using binary information for amenities.
Example:
00 = no amenity
01 = only WiFi
10 = only TV
11 = TV and WiFi
Then you can store:
0 for nothing
1 for only WiFi
2 for only TV
3 for TV and Wifi
...
This would make a check easier as you can use the modulo operator.

How can I assign a class to a report not on odd, even rows but on the change of a date column?

I have a very simple report in AngularJS:
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody"
<div class="gridRow" ng-repeat="row in rps.reports">
<div>{{row.user}}</div>
<div>{{row.date}}</div>
<div>{{row.count}}</div>
</div>
</div>
The report works but it's difficult to notice when the date changes.
Is there some way that I could assign a class to the grid row so that one date grid row has one class and the next date the grid row has another class. I think this is already available for odd and even rows with Angular but here I need it to work on every date change.
I've done a different solution (PLUNKER) where whole work is inside the controller. Maybe is a little bit more of code, but you will gain a lot of performance if you have thousand records because you will avoid dirty checking of ng-class. Additionally if your report is static and it won't have any changes, you can disable the two data binding...
CONTROLLER
vm.reports = addReportCssClases();
function addReportCssClases() {
var reportsData = [...];
var classes = ['dateOdd', 'dateEven'];
var index = 0;
reportsData[0].cssClass = classes[index];
for (var i = 1; i < reportsData.length; i++) {
var row = reportsData[i];
index = (row.date !== reportsData[i-1].date) ? (1 - index) : index;
row.cssClass = classes[index] ;
}
return reportsData;
}
HTML
<div ng-repeat="row in vm.reports track by $index" class="gridRow {{::row.cssClass}}">
<div>{{::row.user}}</div>
<div>{{::row.date}}</div>
<div>{{::row.count}}</div>
</div>
You can use ng-class with a function defined in your controller. For example:
var currentColor = "color1";
$scope.getClass = function(index)
{
if (index !== 0 && $scope.data[index].date !== $scope.data[index - 1].date)
{
currentColor = currentColor == "color1" ? "color2" : "color1";
}
return currentColor;
}
And in your template:
<div class="gridRow" ng-repeat="(i, d) in data" data-ng-class="getClass(i)">
See the plunker: http://plnkr.co/edit/PPPJRJJ1jHuJOgwf9lNK
This can be done with a one line given all the dates are actually date with the same format and not date time
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody">
<div ng-repeat="row in rps.reports" class="gridRow" ng-class="{'backblue':$index>0 && row.date!=rps.reports[$index-1].date}">
<div>{{row.user}}</div>
<div>{{row.date}}</div>
<div>{{row.count}}</div>
</div>
</div>
your gridRow class will have to contain the background-color
.gridRow{
//other styles
background-color:red;
}
and the class backblue will have to have only the background-color
.backblue{
background-color:blue !important;
}
IMPORTANT
This will only work if the date field is only date and does not have time. If in any case it does have time you will have to convert each datetime to date
I have created a very simple and working solution for this using angular-filter, only you need to add dynamic class on gridRow.
working jsfiddle
HTML
<div ng-repeat="row in rps.reports"
class="gridRow {{row.date | filterDate}}">
Styles
.even {
background-color: green;
color: #fff;
}
.odd {
background-color: red;
color: #000;
}
Angular-filter
myApp.filter('filterDate', function() {
var lastDate,
count = 0,
calssName = 'even';
return function(date) {
var newDate = new Date(date).toDateString();
!lastDate && (lastDate = newDate);
if (newDate != lastDate) {
if (calssName == 'even') {
calssName = 'odd';
} else {
calssName = 'even';
}
}
lastDate = newDate;
return calssName;
}
});
A modified version of #ssougnez answer by storing the current date also in addition to color:
if(!(currentDate && currentDate === data.date)){
currentColor = currentColor == "color1" ? "color2" : "color1";
currentDate = data.date;
}
Plunker: http://plnkr.co/edit/o3YVBB
This might have less impact on performance than his version.
var app = angular.module('sample', []);
app.controller('SampleController', function($scope)
{
$scope.data = [
{
user: "A",
date: "3/2/2017"
},
{
user: "B",
date: "3/4/2017"
},
{
user: "C",
date: "4/3/2017"
},
{
user: "D",
date: "4/3/2017"
},
{
user: "E",
date: "4/3/2017"
},
{
user: "F",
date: "4/2/2017"
}
];
});
.same{
background-color:#ddd;
}
.differ{
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html ng-app="sample">
<head>
</head>
<body>
<div ng-controller="SampleController">
<table id="myTable">
<thead>
<tr>
<th>User</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td>{{row.user}}</td>
<td class="same" ng-if="data[$index+1].date==row.date || data[$index-1].date==row.date">{{row.date}}</td>
<td class="differ" ng-if="data[$index+1].date!=row.date && data[$index-1].date!=row.date">{{row.date}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
You can add the class with an expression using the ngClass directive in the view:
(function() {
'use strict';
angular.module('app', []);
})();
(function() {
'use strict';
angular.module('app').controller('MainController', MainController);
MainController.$inject = ['$scope'];
function MainController($scope) {
var date = new Date();
$scope.rps = {
reports: [{
user: 'User A',
date: date.setDate(date.getDate() + 1),
count: 5
},
{
user: 'User B',
date: date.setDate(date.getDate() + 2),
count: 10
},
{
user: 'User C',
date: date.setDate(date.getDate()),
count: 8
},
{
user: 'User D',
date: date.setDate(date.getDate() + 2),
count: 6
},
{
user: 'User E',
date: date.setDate(date.getDate()),
count: 20
},
{
user: 'User F',
date: date.setDate(date.getDate() + 3),
count: 6
}
]
};
}
})();
.gridHeader,
.gridRow {
display: table-row;
}
.gridHeader>div,
.gridRow>div {
display: table-cell;
padding: 5px 10px;
}
.className {
background: #ff0000;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<div ng-app="app" ng-controller="MainController as MainCtrl">
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody">
<div class="gridRow" ng-repeat="row in ::rps.reports track by $index" ng-class="::{'className': $index === 0 || $index > 0 && rps.reports[$index - 1].date !== row.date}">
<div>{{::row.user}}</div>
<div>{{::row.date | date: 'dd-MM-yyyy'}}</div>
<div>{{::row.count}}</div>
</div>
</div>
</div>
Or add a boolean in the controller that you can use to trigger the className using the ngClass directive:
(function() {
'use strict';
angular.module('app', []);
})();
(function() {
'use strict';
angular.module('app').controller('MainController', MainController);
MainController.$inject = ['$scope'];
function MainController($scope) {
var date = new Date();
$scope.rps = {
reports: [{
user: 'User A',
date: date.setDate(date.getDate() + 1),
count: 5
},
{
user: 'User B',
date: date.setDate(date.getDate() + 2),
count: 10
},
{
user: 'User C',
date: date.setDate(date.getDate()),
count: 8
},
{
user: 'User D',
date: date.setDate(date.getDate() + 2),
count: 6
},
{
user: 'User E',
date: date.setDate(date.getDate()),
count: 20
},
{
user: 'User F',
date: date.setDate(date.getDate() + 3),
count: 6
}
]
};
// add the classes to the reports
addClasses($scope.rps.reports);
/*
* #name addClasses
* #type function
*
* #description
* Adds a class to a report if the date is different to the previous
*
* #param {array} reports The reports to add classes to
* #return nothing.
*/
function addClasses(reports) {
// loop through the reports to check the dates
for (var i = 0, len = reports.length; i < len; i++) {
// if the previous report a different date then the current report will have a class
reports[i].hasClass = (i === 0 || reports[i - 1].date !== reports[i].date);
}
}
}
})();
.gridHeader,
.gridRow {
display: table-row;
}
.gridHeader>div,
.gridRow>div {
display: table-cell;
padding: 5px 10px;
}
.className {
background: #ff0000;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<div ng-app="app" ng-controller="MainController as MainCtrl">
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody">
<div class="gridRow" ng-repeat="row in ::rps.reports track by $index" ng-class="::{'className': row.hasClass}">
<div>{{::row.user}}</div>
<div>{{::row.date | date: 'dd-MM-yyyy'}}</div>
<div>{{::row.count}}</div>
</div>
</div>
</div>

Setting the values in multi-select isteven of angular js

I'm trying to use Angularjs multi-select into my project.
The following html is my multi-select div.
<div
multi-select
input-model="marks"
output-model="filters.marks"
button-label="name"
item-label="name"
tick-property="ticked"
selection-mode="multiple"
helper-elements="all none filter"
on-item-click="fClick( data )"
default-label="Select marks"
max-labels="1"
max-height="250px"
>
</div>
I know that I can use $scope.marks=data in the controller.
But the problem is $scope.marks is a global variable which I couldn't change..
Is there any way to set the values in multi-select without using the input-model?
Well, doing some tests here, i could get something with multiselecting:
var languages = ["C#", "Java", "Ruby", "Go", "C++", "Pascal", "Assembly"]; //The items.
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.marks = {};
for (lang in languages) {
$scope.marks[lang] = {
name: languages[lang],
marked: false
};
}
$scope.marks[3].marked = true; //mark "Go" and "C++" by default.
$scope.marks[4].marked = true;
$scope.theMarkedOnes = function() {
outp = "";
for (m in $scope.marks) {
if ($scope.marks[m].marked)
outp += $scope.marks[m].name + ", ";
}
if (outp.length == 0) {
return "(none)";
} else {
return outp.substr(0, outp.length - 2);
}
}
$scope.setMark = function(markone) {
markone.marked = !markone.marked;
}
})
*,
*:before,
*:after {
box-sizing: border-box;
}
body {
font-family: sans-serif;
font-size: 0.7em;
}
::-webkit-scrollbar {
width: 7px;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
}
.multiselector {
background-color: #CCCCCC;
overflow-y: scroll;
width: 17em;
height: 13em;
border-radius: 0.7em;
}
.multiselector .item {
cursor: pointer;
padding: 0.2em 0.3em 0.2em 0.0em;
}
.itemtrue {
background-color: #9999AA;
}
.msshow {
background-color: #cccccc;
border-radius: 0.7em;
margin-top: 1em;
padding: 0.6em;
width: 17em;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="multiselector">
<div ng-repeat="mark in marks" class="item item{{mark.marked}}" ng-click="setMark(mark)">{{mark.name}}</div>
</div>
<div class="msshow"> <b>Selected:</b> {{theMarkedOnes()}}</div>
</div>
Set & Get selected values, name and text of Angularjs isteven-multi-select
<div isteven-multi-select
input-model="marks"
output-model="filters.marks"
button-label="name"
item-label="name"
tick-property="ticked"
selection-mode="multiple"
helper-elements="all none filter"
on-item-click="fClick( data )"
default-label="Select marks"
max-labels="1"
max-height="250px">
</div>
Add items
$scope.marks= [
{ name: 'Mark I', value: 'Mark i', text: 'This is Mark 1', ticked: true },
{ name: 'Mark II', value: 'Mark ii', text: 'This is Mark 2' },
{ name: 'Mark III', value: 'Mark iii', text: 'This is Mark 3' }
];
Get selected item (on change)
$scope.fClick = function (data) {
console.log(data.name);
console.log(data.value);
console.log(data.text);
return;
}
Select item (with code)
$scope.abc = function (data) {
console.log(data.element1, data.element2);
angular.forEach($scope.marks, function (item) {
if (item.value == data.element1) {
item.ticked = true;
}
else {
item.ticked = false;
}
});
}
Deselect item (clear)
$scope.ClearClick = function () {
$scope.Filter = { selectMarks: 'Mark i' };
$scope.marks.map(function (item) {
if ($scope.Filter.selectMarks == item.value)
item.ticked = true;
else
item.ticked = false;
});
}

create a decimal star rating for a comment in angularjs

Here is a code which present star rating code in angularjs. In some point I need to have a average of all the rating in whole the system so instead of rate:2 , i will have 2.4 . In such case i am interesting to present 2 star which are complete fill and one which has only half filled. How can I change my code in order to add this functionality?
Moreover, initially I would like to don't specify any star filled. That's also need a modification which I am not sure how should be done?
<div ng-app="app" ng-controller="RatingCtrl" class="container">
<h1>Angular Star Rating Directive</h1>
<div star-rating ng-model="rating1" max="10" on-rating-selected="rateFunction(rating)"></div>
<star-rating ng-model="rating2" readonly="isReadonly"></star-rating>
<label>
<input type="checkbox" ng-model="isReadonly" /> Is Readonly
</label>
<div><strong>Rating 1:</strong> {{rating1}}</div>
<div><strong>Rating 2:</strong> {{rating2}}</div>
</div>
In my directive
angular.module("app", [])
.controller("RatingCtrl", function($scope) {
$scope.rating1 = 1;
$scope.rating2 = 2;
$scope.isReadonly = true;
$scope.rateFunction = function(rating) {
console.log("Rating selected: " + rating);
};
})
.directive("starRating", function() {
return {
restrict : "EA",
template : "<ul class='rating' ng-class='{readonly: readonly}'>" +
" <li ng-repeat='star in stars' ng-class='star' ng-click='toggle($index)'>" +
" <i class='fa fa-star'></i>" + //&#9733
" </li>" +
"</ul>",
scope : {
ratingValue : "=ngModel",
max : "=?", //optional: default is 5
onRatingSelected : "&?",
readonly: "=?"
},
link : function(scope, elem, attrs) {
if (scope.max == undefined) { scope.max = 5; }
function updateStars() {
scope.stars = [];
for (var i = 0; i < scope.max; i++) {
scope.stars.push({
filled : i < scope.ratingValue
});
}
};
scope.toggle = function(index) {
if (scope.readonly == undefined || scope.readonly == false){
scope.ratingValue = index + 1;
scope.onRatingSelected({
rating: index + 1
});
}
};
scope.$watch("ratingValue", function(oldVal, newVal) {
if (newVal) { updateStars(); }
});
}
};
});
and css
.rating {
margin: 0;
padding: 0;
display: inline-block;
}
.rating li {
padding: 1px;
color: #ddd;
font-size: 20px;
text-shadow: .05em .05em #aaa;
list-style-type: none;
display: inline-block;
cursor: pointer;
}
.rating li.filled {
color: #fd0;
}
.rating.readonly li.filled {
color: #666;
}
http://codepen.io/anon/pen/RPLJYW
Thank you for any help.
You could use two identical set of stars to achieve this, position absolute one on top of the other. One fills your background star shapes (gray) and the one position at the top will represent your fill.
The top set of stars are all filled but its container's width can be adjusted to the proportion of stars representing your rate.
var score = 2.4;
var maxStars = 5;
var starContainerMaxWidth = 100; //pixls
var filledInStarsContainerWidth = score / maxStars * starsMaxWidth;
A CSS overflow hidden will hide the portion of stars that are not turned on, in effect allowing you to show 2.4 stars filled.
Update:
I have bashed a quick example http://codepen.io/anon/pen/NqazVa , will need some tidy up and reshuffling but the average rate is calculated and displayed correctly.
Check the AngularUI Bootstrap Rating component.
http://angular-ui.github.io/bootstrap/#/rating

Resources