Angular JS expression not evaluating - angularjs

I have written a simple Angular JS code. I'm a beginner. However, one of my expressions is not getting evaluated. Need help. Please check the code below -
var myAppModule = angular.module('myAppModule', []);
myAppModule.controller('myController', function($scope){
// Hide colors by default
$scope.isHidden = true;
// a function, placed into the scope, which
// can toggle the value of the isHidden variable
$scope.showHideColors = function () {
$scope.isHidden = !$scope.isHidden;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="myAppModule">
<head>
<title>Angular JS</title>
<script src="js/angular.min.js"></script>
<script src="js/myAppModule.js"></script>
<style>
body {
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif;
}
div {
margin: 20px;
padding: 20px;
font-size: 16px;
color:#ffffff;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
#blue {
background-color: blue;
}
#purple {
background-color: purple;
}
#gray {
background-color: gray;
}
#olive {
background-color: olive;
}
</style>
</head>
<body ng-controller="myController">
<h2>AngularJS Socks</h2>
<p>Keep warm this winter with our 100% wool, 100% cool, AngularJS socks!</p>
<button ng-click="showHideColors()" type="button">
{{isHidden ? 'Show Available Colors' : 'Hide Available Colors'}}
</button>
<div id="red" ng-hide="isHidden">Red</div>
<div id="green" ng-hide="isHidden">Green</div>
<div id="blue" ng-hide="isHidden">Blue</div>
<div id="purple" ng-hide="isHidden">Purple</div>
<div id="gray" ng-hide="isHidden">Dark Slate Gray</div>
<div id="olive" ng-hide="isHidden">Olive</div>
</body>
</html>
The expression - {{isHidden ? 'Show Available Colors' : 'Hide Available Colors'}} is not getting evaluated but displaying as is on the button. No clue as to what i missed. Thanks in advance.

The code is missing closing bracket. You can see the working demo here - http://jsfiddle.net/me8j3zyc/
var app = angular.module('myAppModule', []);
app.controller('myController', function($scope) {
$scope.isHidden = true;
// a function, placed into the scope, which
// can toggle the value of the isHidden variable
$scope.showHideColors = function() {
$scope.isHidden = !$scope.isHidden;
} // <- This is missing.
});

This is because you havent closed your function
myAppModule.controller('myController', function($scope){
// Hide colors by default
$scope.isHidden = true;
// a function, placed into the scope, which
// can toggle the value of the isHidden variable
$scope.showHideColors = function() {
$scope.isHidden = !$scope.isHidden;
}})

Your expression is fine, but you have a typo error in your JS file:
var myAppModule = angular.module('myAppModule', []);
myAppModule.controller('myController', function($scope) {
// Hide colors by default
$scope.isHidden = true;
// a function, placed into the scope, which
// can toggle the value of the isHidden variable
$scope.showHideColors = function() {
$scope.isHidden = !$scope.isHidden;
} //MISSING
});

You can try this:
<button ng-if="isHidden" ng-click="showHideColors()" type="button">Show Available Colors</button>
<button ng-if="!isHidden" ng-click="showHideColors()" type="button">Hide Available Colors</button>

Related

disabling a div in angularjs using ng-disabled

I wanted to disable a div section using ng-disabled, but it dint work. I've also tried using fieldset in place of div.
ng-disabled seems not working.
Below is the view part:
<div ng-disabled="model.disableDate">
<div>Date</div>
<div ion-datetime-picker ng-model="model.timeEntryDate" ng-change="onTimeEntryDateChange()" date="true" time="false" monday-first="true" am-pm="true">{{model.timeEntryDate|| "Select" | date: "dd/MM/yyyy"}} <i class="icon ion-ios-calendar-outline"></i> </div>
</div>
This is the controller part:
if ($scope.model.pageState === condition) {
$scope.model.disableDate = true;
}
Any way this calender is being popped even on the disabling condition.
You can't disable DIV. Disable work with button and input types only. You can try with css. Use ng-class.
<div ng-class="{ 'div-disabled': model.disableDate}"> // give condition here as per your scenario
.div-disabled
{
pointer-events: none;
opacity: 0.5;
background: #CCC;
}
You can create an attribute directive to disable any div. See below:
var app = angular.module("myApp", []);
app.directive("disableSection", function() {
return {
restrict : "A",
link:function(scope,element,attr,ctrl){
element.css({
cursor :"not-allowed",
opacity: "0.5",
background: "#CCC"
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div disable-section>This is disabled div</div>
</body>
You can use pointer-events: none for disabling the div:-
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.obj = {};
$scope.obj.disabled = false;
$scope.clickMe = function(){
alert('div is enabled');
}
});
.disabled {
pointer-events: none;
}
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-class="(obj.disabled)?'disabled':''" style="width:100px;height:100px;border:1px solid black">
<a style="cursor:pointer" ng-click="clickMe()">Click Me</a>
</div>
<button ng-click="obj.disabled = !obj.disabled">{{(obj.disabled)?'Enable':'Disable'}}</button>
</div>

how to add style in angularjs based on condition in html itself

I have the above page structure . i want to check a conditon to apply style in div with id if the buttonlayout has a class proceed.
<div>
<div id="main">
</div>
<div id='buttonlayout" class="proceed">
</div>
I am displaying the <div id='buttonlayout" class="proceed"></div> based on some conditions. so if the div doesnt exist I dont want to apply sty;e. How can I check this in angular js?
So the logic I am looking for is
if (.div-proceed) exist add an extra style to div (with id main). Is it possible to check in my html page itself (ng-class)?
You can set conditions in ng-class, as sample $scope.proceed default is false our condition is when $scope.proceed is true add class proceed to the element.
This mean if $scope.proceed = false the class not exist, and if it true class is exist.
var app = angular.module("app", []);
app.controller("ctrl", ["$scope", "$filter", function($scope, $filter) {
$scope.change = function() {
$scope.proceed = !$scope.proceed;
}
}]);
body {
padding-top: 50px;
}
a{cursor: pointer}
#buttonlayout {
width: 100px;
height: 100px;
transition: all 0.5s;
background-color: #ccc;
}
#buttonlayout.proceed {
width: 200px;
height: 200px;
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<a ng-click="change()">click to remove/add 'proceed' class</a>
<div id="buttonlayout" ng-class="{'proceed': proceed}"></div>
</div>

Restore scope when browser back button is clicked

I am using angular for rendering view like this:
var app = angular.module("demo", []);
app.controller('demoCtrl', ["$scope",function ($scope) {
$scope.current_step = 1;
$scope.step_two = function(){
$scope.current_step = 2;
};
$scope.step_one = function(){
$scope.current_step = 1;
};
}]);
.button {
background: #fb6648;
color: #fff;
display: inline-block;
padding: 18px 0px;
max-width: 150px;
width: 100%;
text-align: center;
border-radius: 3px;
font-size: 18px;
transition: all 0.5s;
outline: none;
border: none;
-webkit-appearance: none!important;
}
.area {
width: 100px;
height: 100px;
display: block;
border: 1px solid;
text-align: center;
margin-bottom: 20px;
}
<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="demo">
<div ng-controller="demoCtrl" id="demoCtrl">
<div ng-if="current_step==1">
<span class="area" >Step One</span>
<a class="button" ng-click="step_two()" >go to Step Two</a>
</div>
<div ng-if="current_step==2">
<span class="area">Step Two</span>
<a class="button" ng-click="step_one()" >Back to Step One</a>
</div>
</div>
</body>
i want this button to work when browser back and froward button are pressed.
i tried changing hash but it didn't worked.
It seems that you need to store the value of scope as cookie.
That can be done as shown below.
Case-1: Cookies More $cookies
Provides read/write access to browser's cookies.
angular.module('cookieStoreExample', ['ngCookies'])
.controller('ExampleController', ['$cookieStore', function($cookieStore) {
// Put cookie
$cookieStore.put('myFavorite','oatmeal');
// Get cookie
var favoriteCookie = $cookieStore.get('myFavorite');
// Removing a cookie
$cookieStore.remove('myFavorite');
}]);
Case-2: ngStorage More ngStorage
An AngularJS module that makes Web Storage working in the Angular Way.
var app = angular.module('MyApp', ["ngStorage"])
app.controller('MyController', function ($scope, $localStorage, $sessionStorage, $window) {
$scope.Save = function () {
$localStorage.LocalMessage = "LocalStorage: My name is XXX.";
$sessionStorage.SessionMessage = "SessionStorage: My name is XXX.";
}
$scope.Get = function () {
$window.alert($localStorage.LocalMessage + "\n" + $sessionStorage.SessionMessage);
}
});
More help
how-to-use-ngstorage-in-angularjs
Use $localStorage,
angular.module('myApp')
.controller('MyCtrl',function($scope,$localStorage){
window.onhashchange = function() {
console.log("triggered");
if($localStorage.user != null){
//get value from $localStorage and set it to scope variable
$scope.user = JSON.parse($localStorage.user);
}
}
});
In someother controller you need to set $localStorage.user value as
$localStorage.user = JSON.stringify({'name':'Geo','age':22});
If it is not null you can reassign it to the $scope.user variable.

toggling one directive effects other dircetive inside ngrepeat

I wrote an angularjs directive to show and hide ajax spinners. The visibility of the spinner is toggled by show and hide buttons whose functionality is written inside the MainController. There is a variable inside the controller which is set to true and false based on the button click. This variable is passed to the directive using isolate scope. When I try to toggle one spinner, all the other spinners are also visible. How can I change my code to only toggle the particular spinner.
https://plnkr.co/edit/AFmBVbHaBPk66T7UjPC5?p=preview
// Code goes here
angular.module('app',[])
.controller('MainController',[MainController])
.directive('loadingDirective',[loadingDirective]);
function MainController(){
var mc = this;
mc.showMe = showMe;
mc.hideMe = hideMe;
mc.loading = false;
function showMe(){
mc.loading = true;
}
function hideMe(){
mc.loading = false;
}
}
function loadingDirective() {
return {
restrict: 'E',
replace:true,
scope:{
loading:"=loading"
},
template: '<span class="spinner">Loading…</span>',
link: function (scope, element, attr) {
scope.$watch('loading', function (val) {
if (val)
$(element).show();
else
$(element).hide();
});
}
};
}
/* Styles go here */
.spinner {
position: relative;
/* [1] */
display: inline-block;
width: 1em;
/* [2] */
height: 1em;
/* [2] */
font-size: 32px;
/* [3] */
border-bottom: 1px solid;
/* [4] */
vertical-align: middle;
overflow: hidden;
/* [5] */
text-indent: 100%;
/* [5] */
-webkit-animation: 0.5s spinner linear infinite;
animation: 0.5s spinner linear infinite;
/**
* 1. Make the spinner a circle.
*/
/**
* The (optically) non-spinning part of the spinner.
*
* 1. Border around entire element fills in the rest of the ring.
* 2. Paler than the part that appears to spin.
*/
}
.spinner, .spinner:after {
border-radius: 100%;
/* [1] */
}
.spinner:after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 1px solid;
/* [1] */
opacity: 0.5;
/* [2] */
}
/**
* Size variants (built by adjusting `font-size`).
*/
.spinner--small {
font-size: 16px;
}
.spinner--large {
font-size: 64px;
}
/**
* Color overrides.
*/
.spinner--light {
color: #fff;
}
.spinner--dark {
color: #333;
}
#-webkit-keyframes spinner {
to {
-webkit-transform: rotate(360deg);
}
}
#keyframes spinner {
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
<!DOCTYPE html>
<html ng-app="app">
<head>
<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>
</head>
<body>
<h1>Hello Plunker!</h1>
<div ng-controller="MainController as mc">
<div ng-repeat="i in [1,2,3,4,5]">
<loading-directive loading="mc.loading"></loading-directive>
<button ng-click="mc.showMe()">show</button>
<button ng-click="mc.hideMe()">hide</button>
</div>
</div>
</body>
</html>
If you want the spinners to have their own states, then they should be controlled by different variables.
In your example it is achievable by using an array to hold the variables
<div ng-repeat="i in [1,2,3,4,5]">
<loading-directive loading="mc.loading[i]"></loading-directive>
<button ng-click="mc.show(i)">show</button>
<button ng-click="mc.hide(i)">hide</button>
</div>
mc.loading = {};
function show(i){
mc.loading[i] = true;
}
function hide(i){
mc.loading[i] = false;
}
In a more real case example where you have some data and you use ng-repeat over them, you should assign the loading states inside the elements themselves.
This is a common technique to assign state to each items in ng-repeat
mc.fruits = [
{name:"apple"},
{name:"orange"},
{name:"starfruit"}
]
function load(fruit) { fruit.loading = true; }
function noLoad(fruit) { fruit.loading = false; }
<div ng-repeat="fruit in mc.fruits">
<loading-directive loading="fruit.loading"></loading-directive>
{{fruit.name}}
<button ng-click="mc.load(fruit)">show</button>
<button ng-click="mc.noLoad(fruit)">hide</button>
</div>
Working Plunkr: https://plnkr.co/edit/peGDxYJzKJgiHuPp4zmQ
You needed to define the isolated scope in the directive correctly. Essentially, your directive was still dependent on the controller as you were using the same variable mc.loading to determine the state of all directive instances.
By moving the deterministic variable $scope.loading as well as the buttons inside the directive, we are completely isolating each directive instance and making them all completely independent units.
HTML:
<div ng-controller="MainController as mc">
<div ng-repeat="i in [1,2,3,4,5]">
<loading-directive></loading-directive>
</div>
</div>
JS:
angular.module('app',[])
.controller('MainController',[MainController])
.directive('loadingDirective',[loadingDirective]);
function MainController(){
}
function loadingDirective() {
return {
restrict: 'E',
replace:true,
scope:{},
template: '<div><span ng-if="loading" class="spinner">Loading…</span>'
+ '<button ng-click="showMe()">show</button>'
+ '<button ng-click="hideMe()">hide</button></div>',
controller: function($scope) {
$scope.showMe = showMe;
$scope.hideMe = hideMe;
function showMe(){
$scope.loading = true;
}
function hideMe(){
$scope.loading = false;
}
}
};
}
The loading variable watched is common for all the directives used, hence when the model is changed the watch condition runs 5 times in your case, removing all the spinners.
I used the index to see what is being hidden or shown,
Updated fiddle: https://plnkr.co/edit/Jjfk6v7TJZHlQicM45ln?p=preview
HTML
<div ng-repeat="i in [1,2,3,4,5]">
<loading-directive data-index="{{$index}}" loading="mc.loading" offset="mc.offset"></loading-directive>
<button ng-click="mc.showMe($index)">show</button>
<button ng-click="mc.hideMe($index)">hide</button>
</div>
Angular
angular.module('app',[])
.controller('MainController',[MainController])
.directive('loadingDirective',[loadingDirective]);
function MainController(){
var mc = this;
mc.showMe = showMe;
mc.hideMe = hideMe;
mc.loading = false;
mc.offset =-1;
function showMe(offset){
mc.loading = true;
mc.offset = offset;
}
function hideMe(offset){
mc.loading = false;
mc.offset = offset;
console.log(offset);
}
}
function loadingDirective() {
return {
restrict: 'E',
replace:true,
scope:{
loading:"=loading",
offset:"=offset"
},
template: '<span class="spinner">Loading…</span>',
link: function (scope, element, attr) {
scope.$watch('[loading, offset]' , function (val) {
if(attr.index == scope.offset || scope.offset == -1){
if (val[0])
element.show();
else
element.hide();
}
});
}
};
}
SCRIPT:
function showMe(i){
mc.loading = true;
i=true;
}
IN HTML ADD THIS
<div ng-repeat="i in [1,2,3,4,5]">
<span><loading-directive loading="mc.loading" ng-show="i==true"></loading-directive>
<button ng-click="mc.showMe(i)">show</button></span>
<button ng-click="mc.hideMe()">hide</button>
</div>

a simple SPA example in backbone

I have a little problem in configuring the mistake in my code.
I have written index.html which includes the template, and a jscript file which includes the model, collection and view.
please let me know where i am doing wrong. I particularly doubt whether i am using el tag wrongly.. or is it wrong in fetching the json data or in render function.
index.php
<head>
<meta charset="utf-8">
<title>Backbone.js News List</title>
<link rel="stylesheet" href="newsList.css"/>
</head>
<body>
<script src="../../test/vendor/json2.js"></script>
<script src="../../test/vendor/jquery.js"></script>
<script src="../../test/vendor/underscore.js"></script>
<script src="../../backbone.js"></script>
<script src="newsList.js"></script>
<header>
<h1 id="center_text">News List</h1>
</header>
<h2>News Trending</h2>
<div id="news-list"></div>
<div id="footer">
<h3 id="center_text" >Copy Right</h3>
</div>
<!-- Templates -->
<script type="text/template" id="item-template">
<div class="container" id="news">
<img id="img" src = <%- img %> >
<section>
<b id="title" ><%- title %> </b>
<br><%- snippet %>
<p><small id ="date"> <%- date%> </small></p>
</section>
</div>
</script>
</body>
</html>
JavaScript code
newsList.js
$(function(){
var NewsList = Backbone.Model.extend({
// Default attributes for the todo item.
defaults: {
id:"",
title: "empty NewsList...",
img:"",
snippet:"",
date:""
},
initialize: function(){
console.log("model initialized");
}
});
var NewsListColln = Backbone.Collection.extend({
// Reference to this collection's model.
model: NewsList,
url: 'http://api.divum.in/training/json/newslist.php',
initialize: function(){
console.log("colln initialized");
}
});
//VIEW
// The DOM element for a news item...
var NewsListView = Backbone.View.extend({
//... is a list tag.
el:"#news-list",
template: _.template($('#item-template').html()),
initialize: function() {
console.log("in view");
this.render;
},
render: function(eventName) {
console.log("in render");
var n = newsLists.content;
$.each(n.news, function(newslist){
var newsTemplate= this.template(newslist.toJson());
$(this.el).append(newsTemplate);
}, this);
return this;
}
});
var AppView = Backbone.View.extend({
el: "body",
initialize: function() {
var newsLists = new NewsListcolln();
var newsView = new NewsListView({model: newsLists});
newsLists.bind('reset', function () { newsView.render();});
newsLists.fetch();
}
});
var App = new AppView();
/* var newsLists = new NewsListColln;
var newsListView = new NewsListView({model: newsLists});
newsLists.fetch({ url: "http://api.divum.in/training/json/newslist.php", success: function() {
console.log(newsLists);
}});
newsLists.bind('reset', function () { newsListView.render(); });*/
/*
render:function(){
this.$("news-list").append(newsView.render().el);
}*/
});
css-- newsList.css file
body {
padding:0px;
margin: 0px;
background-color: black;
color:white;
}
h1 {
padding:5px;
margin: 0;
background-color: #FFFF00;
color:black;`enter code here`
}
h3{
margin: 0;
background-color:#FFFF00;
color:black;
}
h2{
padding:5px;
margin:0px;
background-color: white;
color:black;
}
.container {
color:white;
}
div img {
float: left;
width: 128px;
height:: 85%;
}
.container section{
margin-left:128px;
}
#footer{
position: fixed;
width: 100%;
bottom: 0px;
}
#center_text{
text-align:center;
}
#left_text{
text-align:left;
}
div p{
text-align: right;
}
.clearfix{
overflow: auto;
}
Errors:
The site returns a object, but collections are arrays. You need to use the models in this case.
render is a function, so you have to call it: this.render();
After passing a model to a view, access it via this.model.
A model needs either a url or a urlRoot set if you want to fetch it seperately
fetch is asynchronous you have to wait until it finishes.
Use .get() to access model properties
Working code: http://jsfiddle.net/FHsrL/1/

Resources