Angular ng-click works only once - angularjs

I need to switch between to div's. Div class="wrapper" must be visible by default. Div class="form" must be shown after admin approve. The problem is when i click on <a ng-click="toggle()"> it works only once, and no reaction after. If i will add some ng-hide to 'wrapper', ng-click works, but show/hide only 'form'. <a> must be shown after controller response, like class="form".
HTML:
<div class="body" ng-class="{'show': show && showTemp}">
<a ng-click="toggle()"></a>
<div class="form"></div>
<div class="wrapper"></div>
</div>
CSS:
.form {
display: none;
}
.wrapper {
display: block;
}
.show .form {
display: block;
}
.show .wrapper {
display: none;
}
Controller:
$scope.show = false;
$scope.showTemp = true;
// response from admin
$scope.$on('$show', function(e,data) {
$scope.show = true;
$scope.available = data;
});
// this click by user
$scope.toggle = function() {
$scope.showTemp = !$scope.showTemp;
};

Why can't you do something simpler like:
<div class="body" ng-init="showForm = false">
<a ng-click="showForm = available && ? false : !showForm">Click</a>
<div class="form" ng-show="showForm"></div>
<div class="wrapper" ng-hide="showForm"></div>
</div>
By using ngInit I'm setting a default value to showForm to false (You can do it from the controller as-well ($scope.showForm = false;) and then I toggle the ng-hide class (Which is found in angular.css any simply defined as .ng-hide {display: none;}) to show/hide the form and the wrapper DIVs.
When you click on the button the following condition is evaluated: showForm = available && ? false : !showForm - The showForm will always be hidden if there is no data available, and if there is data avalable, it will toggle between the form and the wrapper.
You can also add ng-show="available" to the button so it's only visible once there's data, because before it does nothing. A working example:
angular.module('app',[]).controller('ctrl', function($scope) {
$scope.setData = function(data) {
$scope.available = data;
$scope.showForm = true;
};
});
<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>
<div ng-app="app" ng-controller="ctrl">
<div class="body" ng-init="showForm = false">
<a ng-show="available" ng-click="showForm = !showForm">Click</a>
<br>
<div class="form" ng-show="showForm">THIS IS THE FORM<br>{{available | json}}</div>
<div class="wrapper" ng-hide="showForm">THIS IS THE WRAPPER</div>
<button ng-hide="available" ng-click="setData({val: 'test'})">SET MOCK DATA</button>
</div>
</div>

Related

ng-if="hideDiv" , where hideDiv = false does not hides div

I have to hide a div on click .
<div ng-if="hideDiv">
<div>text text text text</div>
<a ng-click="hideMe(false)">Click Me To Hide</a>
</div>
Controller
this.hideMe = function(action){
$scope.hideDiv = action;
}
tested results are
console.log($scope.hideDiv) // Is false
{{hideDiv}} <!--Is false-->
But still ng-if doesn't hide div ?
Please, test the snippet below. I'm pretty sure your problem is due to some angularJS configuration failure
(function(){
angular.module("app", []).controller("testController", function($scope)
{
$scope.showDiv = true;
$scope.hideMe = function(IsVisible)
{
$scope.showDiv = IsVisible;
}
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="testController">
<div ng-if="showDiv">
<a ng-click="hideMe(false)">Click Me To Hide</a>
</div>
</div>

I have the following code for a popover however when I resize the page, i want to close the popover

My html
<div id="deviceInputContainer">
<div class="row noMarg">
<div class="form col-xs-12" style='padding-left:0px;margin-right:15px;'>
<div class="form col-xs-12 noPad left">
<h2 class="page-title">Certification Projects
<span class='icon-settings-big' style='cursor:pointer;float:right;margin-top:-10px;' title='settings' uib-popover-template="dynamicPopoverPageSettings.templateUrl"
popover-placement="bottom-right" popover-trigger="click outsideClick" popover-class="settingsClass" ></span>
</h2>
</div>
<div class="helpMessage" style="margin-left:-15px;margin-right:-15px;" ng-show="dashboardData.userPreferences.showHelpTextEnabled">
<p class="help-text-content col-sm-12 helpText-color helpText-size" style='margin-bottom:15px;'>Your open projects are listed below- but you can search for other projects if you want. Just
set the search criteria below.</p>
</div>
</div>
</div>
</div>
My controller code to toggle popover and on window resize close popover.
But popover hide is not working on window rezise, can somebody please help me where am i doing wrong
$scope.dynamicPopoverPageSettings = {
templateUrl: 'myPopoverTemplatePageSetting.html',
title: 'Page Settings',
isPopOpen: false,
setIsPopOpen: function() {
$scope.dynamicPopoverPageSettings.isPopOpen = !$scope.dynamicPopoverPageSettings.isPopOpen;
console.log("$scope.dynamicPopoverPageSettings.isPopOpen == " + $scope.dynamicPopoverPageSettings.isPopOpen);
},
setIsPopFalse: function() {
$scope.dynamicPopoverPageSettings.isPopOpen = false;
console.log("$scope.dynamicPopoverPageSettings.isPopOpen == " + $scope.dynamicPopoverPageSettings.isPopOpen);
}
};
var w = angular.element($window);
w.bind('resize', function () {
$('.settingsClass ').popover('hide');
});
When using angular if not using it already id recommend using Angular-Bootstrap-native AngularJS directives based on Bootstrap's markup and CSS. I've included this link to their site, it's the 0.14.3 docs. Also including this Codepen with an example of what I think you're trying to accomplish. Hope it helps, I can always help and modify it further.
function exampleController($scope, $window) {
$scope.popoverVisible = false;
function onResize() {
$scope.popoverVisible = false;
// manuall $digest required as resize event
// is outside of angular
$scope.$digest();
}
function cleanUp() {
angular.element($window).off("resize", onResize);
}
angular.element($window).on("resize", onResize);
$scope.$on("$destroy", cleanUp);
}
angular
.module("example", ["ui.bootstrap"])
.controller("exampleController", exampleController);
html,
.container,
.container-fluid {
width: 100%;
height: 100%;
background-color: #333;
color: #fff;
text-align: center;
button {
margin-top: 10%;
font-weight: bold;
}
button:focus {
outline: 0;
}
.popover {
.popover-title,
.popover-content {
color: #333;
}
}
}
<div class="container-fluid" ng-app="example">
<div class="container" ng-controller="exampleController">
<button uib-popover="I have a title!" popover-title="The title." popover-placement="bottom-right" popover-is-open="popoverVisible" type="button" class="btn btn-primary">
CLICK ME
</button>
</div>
</div>

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 select first element in every page in pagination like $event click in angular?

I have created a pagination example dynamically in angular. Now ng-click event works fine with ng-repeat. when I click on any row element I styled it dynamically using ng-style(with red border). After that if I click on collapse button the selected row collapses. Now I want this selection to inherit to every first row element with border red without clicking it by default on pageload. just by directly clicking on collapse button, the first row should collapse just like how ng-click is working for every row. when I click on prev, next buttons in both gold and silver links how can I make this work only for every first element selected with red border & be also able to work with collapse button to it. do I have to use data-ng-init="";? Any help would be grateful. I have my plunkr link demo below including json file
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<style>
body{background:#fff;height:100%}h2{text-transform:capitalize;font-size:14px;color:#636363;font-weight:700}.small{width:100%;text-align:left;float:left;background:#efefef;line-height:50px;border-bottom:1px solid #bfbfbf}#btns{float:right;z-index:0;position:relative}#gold,#hide,#leftBtn,#rightBtn,#silver{width:auto;min-width:48px;height:48px;border:none;outline:0;float:left;border-radius:7px;margin:10px 10px 10px 0}#hide{margin:10px 0}#rightBtn{float:right}#gold,#silver{background:pink}.link{color:#2196F3;cursor:pointer}button[disabled],html input[disabled]{cursor:default;opacity:.4}div.caption{font-family:Oswald,sans-serif;color:#000;text-transform:uppercase;font-size:15px;margin:0;float:left}
</style>
<div ng-app="myApp" ng-controller="tabCtrl">
<div class="col-md-12" id="main">
<div class="row">
<button id="gold" class="active" ng-click="gold()">gold</button>
<button id="silver" class="" ng-click="silver()">silver</button>
<button id="hide" ng-click="hide()" class="pull-right"> collapse </button>
<div class="small" ng-repeat="x in myData | startFrom:(currentPage)*pageSize | limitTo:pageSize" ng-click="setActive(x, $event)" ng-style="activeMenu === x && divStyle">
<h2 class="col-md-4 pull-left"> {{ x.caption }} </h2>
<div class="col-md-4 pull-left"> {{ x.description }} </div>
<div class="col-md-4 link text-right">view site</div>
</div>
</div>
<!--previous, next buttons-->
<div id="btns">
<button id="rightBtn" ng-disabled="currentPage >= myData.length/pageSize - 1" ng-click="currentPage=currentPage+1;">next</button>
<button id="leftBtn" ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1">prev</button>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('tabCtrl', function ($scope, $http, $timeout) {
$scope.currentPage = 0;
$scope.pageSize = 5;
$scope.myData = [];
for (var i = 0; i < $scope.myData; i++) {
$scope.myData.push(i);
}
$scope.numberOfPages = function () {
return Math.ceil($scope.myData.length / $scope.pageSize);
}
var x, y;
$http.get("category.json").then(function (response) {
$scope.myData = response.data.gold;
$scope.gold = function () {
$scope.currentPage = 0;
$scope.myData = response.data.gold;
}
$scope.silver = function () {
$scope.currentPage = 0;
$scope.myData = response.data.silver;
}
$scope.setActive = function (list, $event) {
$scope.activeMenu = list;
y = '';
y = angular.element($event.target).prop('clientHeight');
$scope.divStyle = {
"border": '2px solid red',
"pointer-events": "none"
}
}
$scope.hide = function () {
$scope.divStyle = {
"height": y * 2 + 'px',
"border": '2px solid green',
"pointer-events": "none"
}
}
});
});
app.filter('startFrom', function () {
return function (input, start) {
/*if (!angular.isArray(input)) { return []; }*/
if (!input || !input.length) {
return;
}
start = +start; //parse to int
return input.slice(start);
};
});
</script>
PLUNKR
I think that this should be your solution, I think I have understood your requirements, please go through and let me know if you have any issues with the code.
Plunkr Demo
I am using the condition $index === 0, but I am also adding another condition where if there is any selection, the first row will get disabled. This gets reset when you press the buttons gold and silver
There was another issue in your code, you had declared the style object inside the $scope.setActive function, I have moved it out, only then the style will get applied by default.
Apart from this, this is how I implemented the functionality!
<div class="small" ng-repeat="x in myData | startFrom:(currentPage)*pageSize | limitTo:pageSize" ng-click="setActive(x, $event)"
ng-style="$index === 0 && testBool ? divStyle : activeMenu === x ? divStyle: ''">
<h2 class="col-md-4 pull-left"> {{ x.caption }} </h2>
<div class="col-md-4 pull-left"> {{ x.description }} </div>
<div class="col-md-4 link text-right">view site</div>
</div>
This testBool scope variable is intially set to true. Then when any of the elements is clicked its set to false using the function.
$scope.setActive = function (list, $event) {
$scope.testBool = false;
$scope.activeMenu = list;
y = '';
y = angular.element($event.target).prop('clientHeight');
}
Then finally when the user presses the gold or the silver button, the variable is reset to true so that the first element will be selected again.
<button id="gold" class="active" ng-click="gold();testBool = true;">gold</button>
<button id="silver" class="" ng-click="silver();testBool = true;">silver</button>
I hope my explanation was understandable, please let me know if you have any queries.
To select by default 1st element you can write something like:
ng-style="$index === 0 ? divStyle : ''"
You can also make your code simple by put out and write something like:
<div id="btns">
<button id="rightBtn" ng-disabled="currentPage >= myData.length/pageSize - 1"
ng-click="currentPage=currentPage+1;activeMenu=myData[currentPage*5];">next</button>
<button id="leftBtn" ng-disabled="currentPage == 0"
ng-click="currentPage=currentPage-1;activeMenu=myData[currentPage*5];">prev</button>
</div>
Demo PLunker
You can use $first property with ng-class in ng-repeat like
<div class="small" ng-class="$first?'active':''" ng-repeat="x in myData | startFrom:(currentPage)*pageSize | limitTo:pageSize" ng-click="setActive(x, $event)" ng-style="activeMenu === x && divStyle">

How to bind an alert message with the controller?

Hi guys I've been experimenting with a simple commenting app with AngularJS and I'm stuck on how to get an alert message popup in the view if a user inputs an empty string into an input field.
The HTML view and ng-show logic as below:
<div ng-show="alert===true" class="alert alert-warning alert-dismissible inner" role="alert">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×
</span><span class="sr-only">Close</span></button>
<strong>Warning!</strong> You did not submit a comment.
</div>
The controller view and $scope logic as below:
// pushes data back to Firebase Array
$scope.addComment = function(){
if ($scope.newComment.text === ''){
$scope.alert = true;
}
else {
$scope.alert = false;
}
$scope.comments.$add($scope.newComment);
$scope.newComment = {text: '', date: ''};
};
The problem is that although I can bind the alert message logic to the HTML view, the alert message only shows up once and cannot be re-used again if the user types in an empty string again.
Should I use a while loop or something for this? Any help would be much appreciated!
EDIT:
Thanks to meriadec's feedback, I have made a fix using a more simple codebase, as follows.
The HTML view and ng-show logic as below:
<div ng-show="alert===true" class="alert alert-warning inner" role="alert">
<button type="button" class="btn" ng-click="alert=false"><span aria-hidden="true">×
</span><span class="sr-only">Close</span></button>
<strong>Warning!</strong> You did not submit a comment.
</div>
The controller view and $scope logic as below:
// pushes data back to Firebase Array
$scope.addComment = function(){
if ($scope.newComment.text === ''){
return $scope.alert = true;
};
$scope.comments.$add($scope.newComment);
$scope.newComment = {text: '', date: ''};
};
You can re-set your alert property to false when clicking the close button. BUT, as you got an ngShow directive, your alert is in a child scope so you need to use an object for having a correct data binding between scopes. More info here.
See this :
angular.module('demo', []);
angular.module('demo')
.controller('DemoCtrl', function ($scope) {
$scope.ui = { alert: false };
$scope.addComment = function () {
if (!$scope.myComment) {
$scope.ui.alert = true;
} else {
alert('well !');
}
}
});
.alert {
position: absolute;
top: 15px;
left: 20%;
right: 20%;
width: 300px;
background: white;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo" ng-controller="DemoCtrl">
<div class="alert" ng-show="ui.alert">
<button ng-click="ui.alert = false">close</button>
You did not enter any comment
</div>
<form ng-submit="addComment()">
<input type="text" ng-model="myComment">
<input type="submit">
</form>
</div>

Resources