How Do I disable a clicked button in AngularJS? - angularjs

//here we crate the module for the CRUD application here
var app= angular.module("shoppingApp", []);
app.controller("UserController", ['$rootScope', '$scope','$filter','$window',
function($scope,$rootScope, $filter, $window) {
/**
* #Summary:addProductInCart , to get the wishList of the userSection.
* #param: pname,bname
* #return: count $scope.pricerange =" 0 - 5000"
* #Description:
*/
$scope.prouctInCartList = [];
$scope.item = {};
$scope.prouctInCartList = [];
$scope.totalAmountDisplay = 0;
$scope.countProducts = 0;
$scope.isDisabled = false;
$scope.addProductInCart = function(index, item) {
$scope.isDisabled = true;
var data = {
index :index,
cart : item
}
$rootScope.prouctInCartList.push(data);
localStorage.setItem('productObject', JSON.stringify($rootScope.prouctInCartList));
for(index in $scope.prouctInCartList) {
var orderDto = $scope.prouctInCartList[index];
var totalAmount = 0;
if(orderDto != undefined && orderDto != null) {
totalAmount = totalAmount + orderDto.cart.range * orderDto.cart.quantity;
}
}
$scope.totalAmountDisplay = $scope.totalAmountDisplay + totalAmount;
$scope.countProducts ++;
}}
]);
<!DOCTYPE html>
<html ng-app="shoppingApp">
<title>W3.CSS Template</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="app/controller.js"></script>
<script data-require="jquery#*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<link rel="stylesheet" href="https://www.w3schools.com/lib/w3.css">
<link rel="stylesheet" href="my.css">
<link rel="stylesheet" href="cmn.css">
<div w3-include-html="myFilter.html"></div>
<div w3-include-html="shoppinCart.html"></div>
<div w3-include-html="signup.html"></div>
<body class="topShop" ng-controller="UserController">
<div class="marginSet w3-row">
<div id="hideSlowProduct" class="productInfo w3-col m3 w3-card-4 w3-margin-left"
ng-repeat="list in filtered = (show | filter: product)filter:brandFilter
| filter :colorFilter">
<span ng-click="removeItem($event,list)" title="Remove product">
<i class="fa fa-close" style="font-size:20px; float:right"> </i>
</span>
<div class="w3-container">
<div calss="hover-effect">
<div class="hover-div">
<img class="imageSet" src="{{list.img}}"
onclick="document.getElementById('openProduct').style.display='block'"
ng-click="currentImage($index)">
</div>
</div>
<div id="openProduct" class="w3-modal" onclick="this.style.display='none'">
<div class="openModal w3-modal-content w3-animate-zoom">
<div class="minSet w3-container w3-twothird">
<img class="modelOpenImg" src="{{imageOpen.img}}">
</div>
<div class=" w3-container w3-third">
<table class="w3-table-all w3-hoverable">
<thead>
<tr class="w3-red">
<th>Pname</th>
<th>Brand</th>
<th>range</th>
<th>color</th>
</tr>
</thead>
<tr>
<td>{{imageOpen.pname}}</td>
<td>{{imageOpen.brand}}</td>
<td>{{imageOpen.range}}</td>
<td> {{imageOpen.color}}</td>
</tr>
</table>
</div>
</div>
</div>
<div class="container">
<div class="fa fa-heart" ng model="removedInWishList[$index]"
ng-show="addedInWishList[$index]"
ng-click= "removeInWishList($index, list)">
</div>
<div class="fa fa-heart-o" ng-model="addedInWishList[$index]"
ng-show="!addedInWishList[$index]"
ng-click= "addInWishList($index, list)">
</div>
<a class="w3-btn w3-red" ng-model="item"
ng-click="item.isDisabled || addProductInCart($index, list)"
ng-disabled="item.isDisabled">Add To Cart
</a>
<span type="radio" class="colorCode w3-right" style="background-color:{{list.colorCode}};"></span>
<b>₹{{list.range}}</b>
</p>
</div>
</div>
</div>
</div>
</body>
</html>
I have create a shopping website in which user click on the addToCart button product is add into the cart and i have to disabled a clicked button but in my case all the button is disabled how to fix this issue?
/**
* #Summary:addProductInCart , to get the addProduct in cart
* #param: index,item
* #return: NA
* #Description:
*/
$scope.item = {};
$scope.prouctInCartList = [];
$scope.totalAmountDisplay = 0;
$scope.countProducts = 0;
$scope.isDisabled = false;
$scope.addProductInCart = function(index, item) {
$scope.isDisabled = true;
var data = {
index :index,
cart : item
}
$rootScope.prouctInCartList.push(data);
//Here we will store product array into the localStorage for use another page
localStorage.setItem('productObject',JSON.stringify($rootScope.prouctInCartList));
}
<a class="w3-btn w3-red" ng-model="item.cart"
ng-click="isDisabled || addProductInCart($index,list)"
ng-disabled="isDisabled">Add To Cart
</a>

You have one variable, $scope.isDisabled for all of your buttons. So, when you set your $scope.isDisabled to true, all of your buttons will have disabled attribute. I made some changes on your code. See it below
/**
* #Summary:addProductInCart , to get the addProduct in cart
* #param: index,item
* #return: NA
* #Description:
*/
$scope.item = {};
$scope.prouctInCartList = [];
$scope.totalAmountDisplay = 0;
$scope.countProducts = 0;
$scope.isDisabled = false;
$scope.addProductInCart = function(index, item) {
//$scope.isDisabled = true;
item.isDisabled = true; // since you are passing your item here, you can make it disabled.
var data = {
index :index,
cart : item
}
$rootScope.prouctInCartList.push(data);
//Here we will store product array into the localStorage for use another page
localStorage.setItem('productObject',JSON.stringify($rootScope.prouctInCartList));
}
<a class="w3-btn w3-red" ng-model="item.cart"
ng-click="item.isDisabled || addProductInCart($index,item)"
ng-disabled="item.isDisabled">Add To Cart
</a>

Related

To change the background color of only a particular button out of multiple buttons in angularjs

I have made a game that has 50 buttons. You have three tries to click on a button. If you clicked the correct one, that is the 25th one you win the game!. I want the only the button no.25 background color to change on click . How to do that. My program changes the color of all the buttons when the 25th button is clicked.
<html ng-app="Bluebox">
<head>
<title>BlueBox</title>
<script src="angular.js"></script>
<style>
.red{
background-color:brown;
}
</style>
</head>
<body>
<div ng-controller="BoxController">
<strong ng-repeat="x in boxes track by $index">
<button ng-style="{'color':x.color}" ng-class="bgcolor" ng-
click="pressed($index)" type="button">
Button {{x.Id}}
</button>
</strong>
</div>
<script>
angular.module("Bluebox",[])
.controller("BoxController",
["$scope","$log",function($scope,$log){
var limit = 50;
var arr = []; // populate in your controller
for (var index = 0; index <= limit; index++) {
arr.push({
"color":"green",
"Id": index
})
}
$scope.boxes = arr;
$scope.tries=3;
$scope.pressed = function(index){
if($scope.tries<=3 & $scope.tries!=0){
$log.log("Button "+(index)+" was pressed");
$scope.tries=$scope.tries-1;
if(index==25){
$scope.bgcolor="red";
$log.log("you won the game");
$scope.tries=0;
}
if($scope.tries==0 && index!=25){
$log.log("you lost the game");
}
}
else{
$log.log("Please restart the game");
}
}
}])
</script>
</body>
</html>
Just add class bgcolor to only 25th button and set win flag like ng-class="{bgcolor: ($index==24 && win)}" so it will solved your issue.
if (index == 25) {
$scope.win = true;
Currently you are adding bgcolor to all button which is wrong.
angular.module("Bluebox", [])
.controller("BoxController", ["$scope", "$log", function($scope, $log) {
var limit = 50;
var arr = []; // populate in your controller
for (var index = 0; index <= limit; index++) {
arr.push({
"color": "green",
"Id": index
})
}
$scope.boxes = arr;
$scope.tries = 3;
$scope.win = false;
$scope.pressed = function(index, event) {
if ($scope.tries <= 3 & $scope.tries != 0) {
$log.log("Button " + (index) + " was pressed");
$scope.tries = $scope.tries - 1;
if (index == 25) {
$scope.win = true;
$scope.bgcolor = "red";
$log.log("you won the game");
$scope.tries = 0;
angular.element(event.currentTarget).addClass('red')
}
if ($scope.tries == 0 && index != 25) {
$log.log("you lost the game");
}
} else {
$log.log("Please restart the game");
}
}
}])
.red {
background-color: brown;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<html ng-app="Bluebox">
<head>
<title>BlueBox</title>
<script src="angular.js"></script>
</head>
<body>
<div ng-controller="BoxController">
<strong ng-repeat="x in boxes track by $index">
<button ng-style="{'color':x.color}" ng-class="{bgcolor: ($index == 24 && win)}"
ng-click="pressed($index, $event)" type="button">
Button {{x.Id}}
</button>
</strong>
</div>
</body>
</html>
<strong ng-repeat="x in boxes track by $index">
<button ng-style="{'color':x.color}" ng-class="{bgcolor: $index==24}" ng-click="pressed($index)" type="button"> Button {{x.Id}}
</button>
</strong>
Well, this is how I would have done it. You can just catch the clicked event and add style/class to that particular clicked element.
I like JS so this can be achieved in the same fashion.
angular.element() lets you select the element on your DOM and you can pass any reference to angular.element(reference) to select the DOM element. For example event.currentTarget in this case gives you the reference of clicked element and you can use traditional JS/Jquery on it to do other things.
Hope this helps
Thanks
angular.module("Bluebox",[])
.controller("BoxController",
["$scope","$log","$timeout",function($scope,$log,$timeout){
var limit = 50;
var arr = []; // populate in your controller
for (var index = 0; index <= limit; index++) {
arr.push({
"color":"green",
"Id": index
})
}
$scope.boxes = arr;
$scope.tries=3;
$scope.won = false;
$scope.pressed = function(index,event){
if($scope.tries<=3 & $scope.tries!=0){
$log.log("Button "+(index)+" was pressed");
$scope.tries=$scope.tries-1;
if(index==25){
$scope.bgcolor="red";
$log.log("you won the game");
$scope.tries=0;
$scope.won = true;
angular.element(event.currentTarget).addClass('red')
}
if($scope.tries==0 && index!=25){
$log.log("you lost the game");
}
}
else{
$log.log("Please restart the game");
}
}
}])
.red{
background-color:brown;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<html ng-app="Bluebox" ng-cloak>
<head>
<title>BlueBox</title>
<script src="angular.js"></script>
</head>
<body>
<div ng-controller="BoxController">
<strong ng-repeat="x in boxes track by $index">
<button ng-style="{'color':x.color}"
ng-click="pressed($index, $event)" type="button">
Button {{x.Id}}
</button>
</strong>
<h1 ng-show="won">You won</h1>
</div>
</body>
</html>

select list box of type mutiple unable to set selectidex to zero or first element

i am using simple angular js select listbox with multiple selection, i used to add the elements into the select by clicking add button, which will dynamically add the server name in the listbox, also the select is multiple type, i can multi select and remove the item by clicking on the remove button.
The problem is that i cannot set the selected index to zero or first element upon removing the items... also i cannot able to select any items after that..
in simple after i remove the elements i need to set selected index to "NO SELECTION" or first element.
ServerPing.jsp
<!DOCTYPE html>
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="/LDODashBoard/js/scripts.js" language="JavaScript" type="text/javascript"></script>
<script src="/LDODashBoard/js/PingServerPage.js" language="JavaScript" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.8/angular-filter.min.js"></script>
<link rel="stylesheet" type="text/css" href="/LDODashBoard/css/mystyle.css" />
<link rel="stylesheet" type="text/css" href="/LDODashBoard/css/ServerPing.css" />
<body>
<div ng-app="myApp" ng-controller="myCtrl" style="color:white" div align="left">
<br/><br/>
<form name = "ServerPing" novalidate>
<label for="marketArraySel" >Server Name:</label>
<input type = "text" id="serverName" name="serverName" ng-model="serverName"></input>
<input type="button" ng-click="addServerName()" value="Add"></input>
<br/><br/>
<span id="tab"></span>
<span id="tab"></span>
<select name="serverNameList" id="serverNameList" data-ng-model="serverNameList" data-ng-options="server.SERVER for server in serverListArray" multiple data-ng-multiple="true">
</select>
<input type="button" ng-click="remove(serverNameList)" value="Remove"></input>
<br/><br/>
{{serverNameList}}
<br/><br/>
<input type="reset" ng-click="reset()" value="RESET"></input>
<input type="button" ng-click="submitfunction()" value="SUBMIT"></input>
</form>
<br><br>
<span id="tab"></span><span id="tab"></span><span id="tab"></span><span id="tab"></span><span id="tab"></span><span id="tab"></span><span id="tab"></span><span id="tab"></span>
<c:url value="/L1OutputDisplayPage?gcmmLink2=true" var="messageUrl2" />
Click Here
to Close
</div>
</body>
</html>
PingServerPage
angular.module("myApp", ['angular.filter'])
.controller("myCtrl", function ($scope,$http,$compile)
{
$scope.serverListArray = [{COUNT:0,SERVER:"NO SELECTION"}];
$scope.count = 0;
$scope.addServerName = function() {
//window.alert("$scope.serverName:" + $scope.serverName);
//window.alert("length of array:" + $scope.serverListArray.length);
//this is to remove the first element which is dummy
/**
if ($scope.serverListArray.length == 1 && $scope.count == 0) {
//$scope.serverNameList.splice($serverNameList.COUNT, 1);
$scope.serverListArray.splice(searchpart($scope.serverListArray,""), 1);
}
**/
$scope.serverListArray.push({COUNT:$scope.count,SERVER:$scope.serverName});
$scope.count = $scope.count + 1;
//reset to the empty value in the text box
$scope.serverName = "";
};
$scope.reset = function() {
$scope.serverName = "";
$scope.serverListArray = [];
$scope.count = 0;
};
$scope.remove = function(arr) {
//$scope.serverName = "";
//$scope.serverListArray = [];
window.alert("INSIDE REMOVE2");
window.alert("serverNameList:" + arr.length);
for (var val = 0, len = arr.length; val < len; val += 1) {
window.alert(arr[val].COUNT);
var removeIndex = searchpart($scope.serverListArray,arr[val].SERVER);
$scope.serverListArray.splice(removeIndex, 1);
}
//set selection index to first element
window.alert("before set.")
$scope.serverNameList = {COUNT: 0};
window.alert("after set set.")
};
function searchpart(arr,serverTmp) {
for (var d = 0, len = arr.length; d < len; d += 1) {
if( arr[d].SERVER.toLowerCase().indexOf(serverTmp) >= 0 ) {
window.alert("return:"+ d);
return d;
}
}
}
});
You have a few problems with the code:
The function searchpart does not work correctly.
Initialize the first value after the removal of the elements are not working properly.
Live example on jsfiddle.
angular.module('ExampleApp', [])
.controller('ExampleController', function($scope) {
$scope.indexValue = "2";
$scope.serverListArray = [{
COUNT: 0,
SERVER: "NO SELECTION"
}, {
COUNT: 1,
SERVER: "First"
}, {
COUNT: 2,
SERVER: "Second"
}, {
COUNT: 2,
SERVER: "Third"
}];
$scope.remove = function(arr) {
for (var val = 0, len = arr.length; val < len; val += 1) {
var removeIndex = searchpart($scope.serverListArray, arr[val].SERVER);
console.log(removeIndex);
$scope.serverListArray.splice(removeIndex, 1);
}
$scope.serverNameList = [$scope.serverListArray[0]];
};
function searchpart(arr, serverTmp) {
for (var d = 0, len = arr.length; d < len; d += 1) {
if (arr[d].SERVER.toLowerCase().indexOf(serverTmp.toLowerCase()) >= 0) {
return d;
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<select name="serverNameList" id="serverNameList" data-ng-model="serverNameList" data-ng-options="server.SERVER for server in serverListArray" multiple data-ng-multiple="true">
</select>
<input type="button" ng-click="remove(serverNameList)" value="Remove" />
<div>
Selected: <pre>{{serverNameList|json}}</pre>
</div>
</div>
</div>

ngTable Detect Sorting in View

Is there a way to detect whether or not ngTable currently has a sort applied? Binding to the sorting table parameter does not work correctly.
<!--- Never shows---->
<label ng-if="tableParams.$params.sorting === {}">No sort applied</label>
<!--- Never shows---->
<label ng-if="tableParams.$params.sorting() === {}">No sort applied</label>
Oddly enough this simple binding example works as expected:
<label>settings={{ tableParams.$params.sorting }}</label>
When a sort is applied a value of: {"sortColumn":"sortDirection"} appears:
{"Id":"desc"}
or if a sort is not applied:
{}
Any help would be appreciated.
You can do something like this:
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.angular = angular;
$scope.tableParams = {
$params: {
sorting: {}
}
};
$scope.sort = function() {
$scope.tableParams.$params.sorting[1] = true;
};
$scope.unsort = function() {
delete $scope.tableParams.$params.sorting[1];
};
$scope.isSorted = function(tableParams) {
return !angular.equals({}, tableParams.$params.sorting);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="myController">
<div ng-show="!isSorted(tableParams)">No sort applied</div>
<button ng-click=sort()>sort</button>
<button ng-click=unsort()>unsort</button>
<br>{{ tableParams }}
</div>
</div>
You can also make the angular object accessible in templates by making it available to the scope.
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.angular = angular;
$scope.tableParams = {
$params: {
sorting: {}
}
};
$scope.sort = function() {
$scope.tableParams.$params.sorting[1] = true;
};
$scope.unsort = function() {
delete $scope.tableParams.$params.sorting[1];
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="myController">
<div ng-show="angular.equals({}, tableParams.$params.sorting)">No sort applied</div>
<div>
<button ng-click=sort()>sort</button>
<button ng-click=unsort()>unsort</button>
</div>
<div><br>{{ tableParams }}</div>
</div>
</div>
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.angular = angular;
$scope.tableParams = {
$params: {
sorting: {}
}
};
$scope.sort = function() {
$scope.tableParams.$params.sorting[1] = true;
};
$scope.unsort = function() {
delete $scope.tableParams.$params.sorting[1];
};
$scope.strictlyEqualsEmptyObject = function(obj) {
return {} === obj;
};
$scope.equalsEmptyObject = function(obj) {
return {} == obj;
};
$scope.angularEqualsEmptyObject = function(obj) {
return angular.equals({}, obj);
};
$scope.objectKeysLength = function(obj) {
return Object.keys(obj).length === 0;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="myController">
<div>{{ tableParams }}</div>
<div>
<button ng-click=sort()>sort</button>
<button ng-click=unsort()>unsort</button>
</div>
<table>
<th>Not sorted check using:</th>
<tr>
<td>strict </td>
<td>{{ strictlyEqualsEmptyObject(tableParams.$params.sorting) }}</td>
</tr>
<tr>
<td>equals </td>
<td>{{ equalsEmptyObject(tableParams.$params.sorting) }}</td>
</tr>
<tr>
<td>angular </td>
<td>{{ angularEqualsEmptyObject(tableParams.$params.sorting) }}</td>
</tr>
<tr>
<td>Object.keys </td>
<td>{{ objectKeysLength(tableParams.$params.sorting) }}</td>
</tr>
</table>
</div>
</div>

Custom directive breaking code in AngularJS

I need to add a custom directive to my code, but every time I add it, it breaks my code. I checked the console and is giving me the following error
Error: Argument 'guessGameController' is not a function, got undefined
at Error (native)
Now I am not sure if I am not setting my code right or if I am not adding the directive where is supposed to go. Here is my code, I appreciate all the help.
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="guessGameApp">
<head>
<title>Word Game 2.0 - AngularJS</title>
<!--Encoding-->
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<!-- JQuery -->
<script src="js/jquery-1.11.0.min.js"></script>
<!--Scripts-->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js" type="text/javascript"></script>
<script src="js/controllers/app.js" type="text/javascript"></script>
<script src="js/controllers/maincontroller.js" type="text/javascript"></script>
<!--Styles-->
<link rel="stylesheet" type="text/css" href="css/magicWord.css">
<!--<script src="js/jquery-1.11.0.min.js"></script>-->
</head>
<body>
<div ng-controller="guessGameController">
<p>
<header id="masthead">
<h2 align="center">{{appTitle}}</h2>
</header>
</p>
<div ng-controller="wordController">
<p>
<table align="center" width="300px" height="150px" border="solid 2px">
<tr>
<td id="guessBox">
<p align="center">
<input value="" type="text" id="guestGuess" placeholder="Enter Guess" ng-model="guestGuess"/>
</p>
<p align="center"><button ng-click="addGuess()" id="guessButton">Click to Check</button></p>
</td>
</tr>
<tr>
<td>
<h3 align="center">Your guesses so far are: </h3>
<p align="center" ng-repeat="words in guesses">{{words}}</p>
</td>
</tr>
<tr>
<td>
<p align="center">You have guessed:<b>{{guessed}}</b> times out {{allowed}} chances.</p>
<p align="center">You have <b>{{allowed - guessed}}</b> guesses left.</p>
</td>
</tr>
<tr>
<td>
<a custom-button>Click me</a>
<br />
<button custom-button>Hello</button>
</td>
</tr>
</table>
</p>
</div>
</div>
</body>
</html>
app.js
var gameApp = angular.module('guessGameApp', []);
var gameTemplate = angular.module('guessGameApp', []);
maincontroller.js
gameApp.controller("guessGameController", function($scope)
{
$scope.appTitle = "WELCOME TO THE GUESS GAME!";
});
gameApp.controller('wordController', function($scope)
{
$scope.guess = '';
$scope.guesses = [];
$scope.guessed= '';
$scope.allowed = 6;
$scope.wordToGuess = "Just";
$scope.pushGuess = function () {
$scope.guesses.push($scope.guestGuess);
$scope.guessed = $scope.guesses.length;
$scope.resetGuess();
}
$scope.resetGuess = function() {
$scope.guestGuess = '';
}
$scope.addGuess = function()
{
if ($scope.guestGuess == null || $scope.guestGuess == '')
{
$("input[type=text]").ready(function () { $("#guestGuess").addClass("blur"); });
$scope.result = " Please enter a guess\n\nDon't leave the box empty.";
alert($scope.result);
}
else if ($scope.guestGuess.toLowerCase() == $scope.wordToGuess.toLowerCase())
{
$("input[type=text]").ready(function () { $("#guestGuess").removeClass("blur"); });
$scope.pushGuess(guestGuess);
$scope.result = "You have guessed the correct word. Way to go!\n\n\t\t The word was: ";
alert($scope.result + $scope.wordToGuess);
}
else if ($scope.guestGuess != $scope.wordToGuess & ($scope.allowed - $scope.guessed) > 1)
{
$("input[type=text]").ready(function () { $("#guestGuess").removeClass("blur"); });
$scope.pushGuess(guestGuess);
$scope.result = "Please try again!";
alert($scope.result);
}
else if (($scope.allowed - $scope.guessed) <= 1)
{
$("input[type=text]").ready(function () { $("#guestGuess").addClass("doneBlur"); });
$scope.guesses.push($scope.guestGuess);
$scope.guessed = $scope.guesses.length;
$scope.result = "Game over! The word was: ";
alert($scope.result + $scope.wordToGuess);
}
$scope.guess = '';
}
});
gameApp.directive('customButton', function ()
{
$scope.wordToGuess = "Just";
return {
restrict: 'A',
replace: true,
transclude: true,
templateUrl: '../../templates/customTemplate.HTML',
link: function (scope, element, attrs)
{
element.bind("click",function()
{
alert("The value of 'guessWord' is " + scope.wordToGuess);
})
}};
});
customTemplate.html
<a href="" class="myawesomebutton" ng-transclude>
<i class="icon-ok-sign"></i>
</a>
In app.js remove the second module declaration
var gameApp = angular.module('guessGameApp', []);
//var gameTemplate = angular.module('guessGameApp', []); --> remove this line
You are also modifying DOM from the controller, this is not the angular way. If you want to add classes when some condition occurs, then have a look at ng-class

AngularJS Items selection and DOM manipulation

I have a list of items populated from a JSON, then i need to pick their values and populate another list of selected items, but, in case the particular item is already selected, add one more to count.
app.controller("NewPizza", function($scope, ingredients) {
$scope.selectedIngredients = [];
ingredients.get().then(function(response){
$scope.ingredients = response.data;
});
function _ingredientExist(id) {
return $scope.selectedIngredients.some(function(el) {
return el._id === id;
});
}
function _addMore(selectedIngredient) {
console.log(selectedIngredient)
}
$scope.addIngredient = function(selectedIngredient) {
if($scope.selectedIngredients.length == 0) {
$scope.selectedIngredients.push(selectedIngredient);
}else{
if(_ingredientExist(selectedIngredient._id)) {
_addMore(selectedIngredient._id);
return false;
}
$scope.selectedIngredients.push(selectedIngredient);
}
};
});
The result should be like this
Items to select
Cheese
Bacon
ham
Items selected
2 Cheese (In case user select cheese multiple times)
Bacon
HTML
<div class="">
<h1>New Pizza</h1>
<input ng-model="name"/>
<a>Save pizza</a>
<ul >
<li class="selectIngredients" ng-repeat="ingredient in ingredients" ng-click="addIngredient(ingredient)" id="{{ingredient._id}}">
{{ingredient.name}}
</li>
</ul>
<ul ng-model="selectedIngredients">
<li data-id="{{selectedIngredient._id}}" ng-repeat="selectedIngredient in selectedIngredients track by $index">
<span>1</span> {{selectedIngredient.name}}
</li>
</ul>
</div>
The problem is i dont know how exactly approach this feature because inside a controller DOM manipulation is considered a bad practice, but if i make a directive to deal with i dont know how to populate $scope.selectedIngredients properly.
Thanks!!
One way is that you can add a count to your items model, then copy that model and increment the number.
Created a fiddle: http://jsfiddle.net/ztnep7ay/
JS
var app = angular.module('itemsApp',[]);
app.controller('ItemsCtrl',function($scope) {
$scope.items = [
{name:'Cheese',num:0},
{name:'Bacon',num:0},
{name:'Ham',num:0}
];
$scope.my_items = angular.copy($scope.items);
$scope.addItem = function(item) {
var idx = $scope.items.indexOf(item);
var num = $scope.my_items[idx].num;
$scope.my_items[idx].num = num + 1;
};
$scope.removeItem = function(my_item) {
var idx = $scope.my_items.indexOf(my_item);
var num = my_item.num;
if (num > 0) {
$scope.my_items[idx].num = num -1;
}
};
});
HTML
<div ng-app="itemsApp" ng-controller="ItemsCtrl">
<h4>Available Items</h4>
<table>
<tr ng-repeat="i in items">
<td>{{i.name}}</td>
<td><button ng-click="addItem(i)">+</button></td>
</tr>
</table>
<hr>
<h4>My Items</h4>
<table>
<tr ng-repeat="i in my_items" ng-show="i.num > 0">
<td>{{i.name}} ({{i.num}})</td>
<td><button ng-click="removeItem(i)">Remove 1</button></td>
</tr>
</table>
</div>
You are right that it is considered wrong to update the DOM from a controller in the Angular world.
The reason for that is because you don't need to -- if you update your data - for example, the selectedIngredients array -- angular will update the DOM for you.
One way to accomplish this is to keep track of the count of each ingredient as well as what ingredient was added. You can do this without touching the Ingredient json that you get back from the server.
Then, when you change the count, angular will update the DOM for you.
Here's am example: Live Plnkr Example
HTML
<!DOCTYPE html>
<html ng-app="test">
<head>
<script data-require="angular.js#1.3.0-beta.5" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="PizzaCtrl">
<h4>Toppings</h4>
<ul>
<li ng-repeat="i in ingredients">
{{i.name}} - <a href ng-click="addIngredient(i)">Add</a>
</li>
</ul>
<h4>Selected Toppings</h4>
<ul>
<li ng-repeat="t in toppings">
{{t.ingredient.name}}
<span ng-if="t.count > 1">
x{{t.count}}
</span>
<a href ng-click="removeTopping(t, $index)">Remove</a>
</li>
</ul>
</body>
</html>
JS
angular.module('test', [])
.controller('PizzaCtrl', function($scope) {
/* let's protend we called ingredients.get() here */
$scope.ingredients = [
{ name: 'Cheese', id: 1 },
{ name: 'Bacon', id: 2 },
{ name: 'Ham', id: 3 }
];
/* this will hold both an Ingredient and a Count */
$scope.toppings = [];
/* Check if the ingredient already exists in toppings[], and if so,
* return it. */
function findTopping(ingredient) {
for(var i = 0; i < $scope.toppings.length; ++i) {
if ($scope.toppings[i].ingredient.id == ingredient.id) {
return $scope.toppings[i];
}
}
return null;
}
/* If the ingredient is already there, increment it's count,
* otherwise add it. */
$scope.addIngredient = function(ingredient) {
var t = findTopping(ingredient);
if (t) {
t.count++;
} else {
$scope.toppings.push({ingredient: ingredient, count: 1});
}
};
/* Opposite of the above! */
$scope.removeTopping = function(t, index) {
if (t.count > 1) {
t.count--;
} else {
$scope.toppings.splice(index, 1);
}
};
})

Resources