AngularJS function if else - angularjs

I am trying to do a function inside of a controller that uses an if else to change the return. And it works until I change the drop down, and then stops working completely. It does not seem to be working, not sure if I am doing something wrong, or you just cannot do this type of function. Any help would be appreciated.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-sanitize.js"></script>
<script>
var app = angular.module('newApp', ['ngSanitize']);
app.controller('player1ctrl', function ($scope) {
$scope.playerName = "Hero";
$scope.playerCard = "A<br />♠";
$scope.color = function () {
//return $scope.playerName;
var arr = $scope.playerCard.split("<br />");
var rtn = "";
if (arr[1] == "♠" || arr[1] == "♣") {
return "Black";
}
else {
return "Red";
}
};
});
</script>
<title>test ngbindhtml</title>
<meta charset="utf-8" />
</head>
<body ng-app="newApp">
<div ng-controller="player1ctrl">
Card selected: <p ng-bind-html="playerCard"></p>
Suit Color: {{color()}}
<select name="playerCard" ng-model="playerCard">
<option value="2<br /> &spades;">2 ♠</option>
<option value="3<br /> &spades;">3 ♠</option>
<option value="4<br /> &hearts;">4 ♥</option>
</select>
</div>
</body>
</html>

First of all - You have space in ♠:
if(arr[1] == " ♠" || arr[1] == " ♣")
Second - You need use:
ng-bind-html-unsafe="playerCard"
in Your template or use trustAsHtml in controller;
Plunker

You cannot bind an HTML string without "trusting" it in Angular. Your "playerCard" variable, with the <br /> is causing the issue. You need to inject $sce into your controller and then call the trustAsHtml function:
...
app.controller('player1ctrl', function ($scope, $sce) {
...
$scope.playerCard = $sce.trustAHtml("A<br />♠");
Doing this should allow you to still use [the correct] ng-bind-html like you currently are. You can also turn this into a directive quite easily.

Related

Why custom unique is not working using angularjs

I am trying to create a new custom filter which will remove duplicates from the array of numbers , there's no error but no output as well , can someone please tell me what is wrong.
HTML CODE :
<!DOCTYPE>
<html>
<head>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="myCont">
<div ng-repeat="num in uniqueArray | unique">
checking numbers :
{{num}}
</div>
</div>
</div>
<script src="jquery-3.0.0.js"></script>
<script src="angular.js"></script>
<script src="angular_try.js"></script>
</body>
</html>
Angular js code :
var myApp = angular.module("myApp",[])
myApp.controller("myCont",["$scope","$filter",function($scope,$filter){
$scope.uniqueArray = [5,10,500,2,6,5,4,10,20,5]
}])
myApp.filter("unique",function(){
var arrNumb = [];
var arrNumb2 =[];
return function(input){
angular.forEach(input,function(value,index,obj){
if(arrNumb.indexOf(value)==-1)
{
arrNumb.push(index);
arrNumb2.push(value);
}
})
}
return arrNumb2;
})
But there's nothing on the screen what am I doing wrong ???
You've probably just misplaced a return statement. Put return arrNumb2; inside the inner returned function (move it up one line)
Also, as suggested in the comments, try moving the declarations inside as well.
var myApp = angular.module("myApp",[])
myApp.controller("myCont",["$scope","$filter",function($scope,$filter){
$scope.uniqueArray = [5,10,500,2,6,5,4,10,20,5]
}])
myApp.filter("unique",function(){
return function(input){
var arrNumb = [];
var arrNumb2 =[];
angular.forEach(input,function(value,index,obj){
console.log("protima koo koo ")
//arrNumb.push(value[name])
if(arrNumb.indexOf(value)==-1)
{
arrNumb.push(index);
arrNumb2.push(value);
}
})
return arrNumb2;
}
})

Input will not update onblur with ng-blur

I am trying to do something that should be pretty simple. When a user tabs out of an input field, I want to take their value and change the value to contain two decimal places for each number even .00
I have a working plunkr
Here is the HTML
<input type="text" class="form-control" only-digits ng-blur="vm.cleanNumbers(vm.order.frameInformation.A)" ng-model="vm.order.frameInformation.A">
The controller is getting called and the value is changed but the input never reflects the change
function cleanNumbers(value) {
if (value !== 0) {
var hasDecimal = value.indexOf('.') > -1;
value = value.replace('$', '');
value = value.replace(/[,]+/g, '');
value = parseFloat(value);
if (isNaN(value)) {
return 0;
}
value = value.toFixed(2);
}
}
In the plunkr I'm logging the values and seeing what I would hope for the input to update with.
Here is your required answer.
The first issue is to use the controller as Syntax,
ng-controller="test as vm"
Since you are converting the value to Float and trying to display it in the text field,
you are getting the same value since the text value of a float is same as the text.
You have to convert the float back to string to display as you like.
Here is the revised code,
// Code goes here
(function () {
'use strict';
angular
.module('admin', [])
.controller('test', test);
test.$inject = ['$log'];
function test($log) {
$log.debug('controller loaded');
/*jshint validthis: true */
let vm = this;
vm.order = {};
vm.cleanNumbers = cleanNumbers;
function cleanNumbers(test) {
$log.debug(test);
let value = vm.order[test];
if (value != 0 && value != undefined) {
var hasDecimal = value.indexOf('.') > -1;
value = value.replace('$', '');
value = value.replace(/[,]+/g, '');
value = parseFloat(value);
if (isNaN(value)) {
return 0;
}
//value = value.toFixed(2);
function toNumberString(num) {
return value.toString() + ".00"
}
vm.order[test] = toNumberString(value);
console.log(value);
console.log(vm.order);
}
}
}
})();
<!DOCTYPE html>
<html ng-app="admin">
<head>
<script data-require="angularjs#1.5.5" data-semver="1.5.5" src="https://code.angularjs.org/1.5.5/angular.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="test as vm">
<div class="col-md-4">
{{vm.order}}
<div class="form-group">
<label class="control-label">A</label>
<input type="text" class="form-control" ng-blur="vm.cleanNumbers('A')" ng-model="vm.order.A" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">B</label>
<input type="text" class="form-control" ng-blur="vm.cleanNumbers('B')" ng-model="vm.order.B" />
</div>
</div>
</body>
</html>
PLEASE run above SNIPPET
HERE IS A WORKING DEMO
First of all, I encourage you to use the latest version of AngularJS (1.6.2 for now). There is still some bug fixes and good changes.
Secondly you are using "vm" controller prefix, but you are not saying that to your controller binder. In your index.html(plunkr) this line;
<body ng-controller="test">
Is I believe intended to be;
<body ng-controller="test as vm">
Also, even this is not handling the actual behaviour that you are trying to do, but I'm sure you can figure the rest of it out by yourself.

How to $watch multiples properties simultaneous and interpolate into one expression?

Suppose two input fields - name and text. How to simultaneous watch this two fields and interpolate their value into one expression?
Thanks!
Update 9/7/2014:
I did this Plunkr with a working version of the code :)
Thanks Mohammad Sepahvand!
Code:
<!doctype html>
<html ng-app="myApp">
<head>
<title>Interpolate String Template Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.js"></script>
<script type="text/javascript">
angular.module('myApp', ['emailParser']).controller('MyController', ['$scope', 'EmailParser', function ($scope, EmailParser) {
// init
$scope.to = '';
$scope.emailBody = '';
$scope.$watchCollection('[to, emailBody]', function (newValues, oldValues) {
// do stuff here
// newValues and oldValues contain the new and respectively old value
// of the observed collection array
if (newValues[0] && newValues[1]) { // there's name and some text?
$scope.previewText = EmailParser.parse(newValues[1], {to: $scope.to});
}
});
}]);
angular.module('emailParser', []).config(['$interpolateProvider', function ($interpolateProvider) {
$interpolateProvider.startSymbol('__');
$interpolateProvider.endSymbol('__');
}]).factory('EmailParser', ['$interpolate', function ($interpolate) { // create service
return {
parse: function (text, propertiesToBeInterpolated) { // handle parsing
var template = $interpolate(text);
return template(propertiesToBeInterpolated);
}
};
}]);
</script>
</head>
<body>
<h3>Instructions in readme.md file - please read before!</h3>
<div id="emailEditor" ng-controller="MyController">
<label>*Name:</label>
<input ng-model="to" type="text" placeholder="Ex.: John"/>
<br><br>
<label>*Text:</label><br>
<textarea ng-model="emailBody" cols="25" rows="10" placeholder="Write something"></textarea>
<p style="color:red;">*required</p>
<div>
<pre>__previewText__</pre>
</div>
</div>
</body>
</html>
You can use the $watchGroup method that was added in angular 1.3:
$scope.$watchGroup(['prop1', 'prop2'], function(newValues, oldValues, scope) {
var prop1 =newValues[0];
var prop2 =newValues[1];
});
Or you could use $watchCollection which has been available since angular 1.1.4:
scope.$watchCollection('[prop1, prop2]', function(newValues, oldValues){
});

Angular - default value for model

Say I have some html as follows:
<html>
<head> angular etc. </head>
<body ng-app>
<div ng-controller="MyCtrl">
<input ng-model="weight" type="number" min="{{minWeight}}" max="{{maxWeight}}">
<p>{{weight}}</p>
</div>
</body>
</html>
and the following controller:
function MyCtrl($scope){
$scope.weight = 200;
$scope.minWeight = 100.0;
$scope.maxWeight = 300.0;
}
The "min" and "max" will show the user their input is bad, and if I hard code them to say, 100 and 300, it will make sure the value is never bound to the model at all (why isn't the behavior the same??). What I'd like to do is only actually change the "weight" if the value meets the input requirements. Any thoughts?
I don't fully understand what are you trying to do.
HTML:
<html>
<head> angular etc. </head>
<body ng-app="MyApp">
<div ng-controller="MyCtrl">
<input ng-model="weight" type="number" min="{{minWeight}}" max="{{maxWeight}}">
<p>{{weight}}</p>
</div>
</body>
</html>
Angular: [Edit]
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function MyCtrl($scope){
$scope.weight = 200;
$scope.minWeight = 100.0;
$scope.maxWeight = 300.0;
$scope.$watch('weight', function (newValue, oldValue) {
if(typeof newValue === 'number') {
if(newValue > $scope.maxWeight || newValue < $scope.minWeight) {
$scope.weight = oldValue;
}
}
});
}]);
But here is an example I made in jsFiddle. I hope this was a solution you were looking for.
[Edit]
http://jsfiddle.net/migontech/jfDd2/1/
[Edit 2]
I have made a directive that does delayed validation of your input field.
And if it is incorrect then it sets it back to last correct value.
This is totally basic. You can extend it to say if it is less then allowed use Min value, if it is more then allowed use Max value it is all up to you. You can change directive as you like.
http://jsfiddle.net/migontech/jfDd2/2/
If you have any questions let me know.

broadcasting model changes

I'm trying to set up a little POC to see whether or not angular would work for something I'm in the middle of.
I set up a REST server which I am able to CRUD with via angular. However, as the documentation and tutorials out there are so all over the place (read: SUPER inconsistent), I am not sure that the behavior I'm not seeing is the result of incorrect code or it's not something I can do like this.
I've gleaned from the docs that two-way binding is available, but it isn't clear how it works. NB I've read dozens of articles explaining how it works at a low level a'la https://stackoverflow.com/a/9693933/2044377 but haven't been able to answer my own question.
I have angular speaking to a REST service which modifies a sql db.
What I am wondering about and am trying to POC is if I have 2 browsers open and I change a value in the db, will it reflect in the other browser window?
As I said, I have it updating the db, but as of now it is not updating the other browser window.
app.js
angular.module('myApp', ['ngResource']);
var appMock = angular.module('appMock', ['myApp', 'ngMockE2E']);
appMock.run(function($httpBackend) {});
controllers.js
function MainCtrl($scope, $http, $resource) {
$scope.message = "";
$scope.fruits = [];
$scope.fruit = {};
$scope.view = 'partials/list.html';
var _URL_ = '/cirest/index.php/rest/fruit';
function _use_$resources_() { return false; }
function _fn_error(err) {
$scope.message = err;
}
$scope.listFruits = function() {
$scope.view = 'partials/list.html';
var fn_success = function(data) {
$scope.fruits = data;
};
$http.get(_URL_).success(fn_success).error(_fn_error);
}
function _fn_success_put_post(data) {
$scope.fruit = {};
$scope.listFruits();
}
function createFruit() {
$http.post(_URL_, $scope.fruit).success(function(data){
$scope.listFruits()
}).error(_fn_error);
}
function updateFruit() {
$http.post(_URL_, $scope.fruit).success(_fn_success_put_post).error(_fn_error);
}
function deleteFruit() {
$http.put(_URL_, $scope.fruit).success(_fn_success_put_post).error(_fn_error);
}
$scope.delete = function(id) {
if (!confirm("Are you sure you want do delete the fruit?")) return;
$http.delete("/cirest/index.php/rest/fruit?id=" + id).success(_fn_success_put_post).error(_fn_error);
}
$scope.newFruit = function() {
$scope.fruit = {};
$scope.fruitOperation = "New fruit";
$scope.buttonLabel = "Create";
$scope.view = "partials/form.html";
}
$scope.edit = function(id) {
$scope.fruitOperation = "Modify fruit";
$scope.buttonLabel = "Save";
$scope.message = "";
var fn_success = function(data) {
$scope.fruit = {};
$scope.fruit.id = id;
$scope.view = 'partials/form.html';
};
$http.get(_URL_ + '/' + id).success(fn_success).error(_fn_error);
}
$scope.save = function() {
if ($scope.fruit.id) {
updateFruit();
}
else {
createFruit();
}
}
$scope.cancel = function() {
$scope.message = "";
$scope.fruit = {};
$scope.fruits = [];
$scope.listFruits();
}
$scope.listFruits();
}
MainCtrl.$inject = ['$scope', '$http', '$resource'];
list.html
{{message}}
<hr/>
New Fruit
<ul ng-model="listFruit">
<li ng-repeat="fruit in fruits">
id [{{fruit.id}}] {{fruit.name}} is {{fruit.color}}
[X]
</li>
</ul>
index.html
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>FRUUUUUUUUUUUUUUUUUUUUUUUUUUUIT</title>
<link rel="stylesheet" href="css/bootstrap/css/bootstrap.css"/>
</head>
<body>
<div class="navbar">NAVBARRRRRRRRRRR</div>
<div class="container">
<div class="row">
<div ng-controller="MainCtrl">
<button ng-click="listFruits()">ListFruit()</button>
<button ng-click="cancel()">Cancel()</button>
<ng-include src="view"></ng-include>
</div>
</div>
</div>
<!-- In production use:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script>
-->
<script src="lib/angular/angular.js"></script>
<script src="lib/angular/angular-resource.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
</body>
</html>
form.html
<h3>{{fruitOperation}}</h3>
<hr/>
<form name="fruitForm">
<input type="hidden" name="" ng-model="fruit.id" />
<p><label>name</label><input type="text" name="name" ng-model="fruit.name" value="dfgdfgdfg" required="true" /></p>
<p><label>color</label><input type="text" name="color" ng-model="fruit.color" value="fruit.color" required="true" /></p>
<hr/>
<input type="submit" ng-click="save()" value="{{buttonLabel}}" /> <button ng-click="cancel()">Cancel</button>
</form>
Thanks for any insight or pointers.
Two-way binding refers to changes occurring in your controller's scope showing up in your views and vice-versa. Angular does not have any implicit knowledge of your server-side data. In order for your changes to show up in another open browser window, for example, you will need to have a notification layer which pushes changes to the client via long polling, web sockets, etc.

Resources