Button flickering on mouseover with ng-clip and ng-show/ng-hide - angularjs

I'm seeing weird flickering when mousing over the ng-clip enhanced button. I've got the ng-clip enhanced button being shown/hid when the enclosing div is moused over. As the user moves the mouse over the button, it flickers. I'm assuming it's something to do with event handling between Zeroclipboard and the Angular code?
Here is a Plunker page displaying the issue: http://plnkr.co/4gFy9U
The code from Plunker:
<!doctype html>
<html>
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/zeroclipboard/2.1.6/ZeroClipboard.min.js"></script>
<script src="//rawgit.com/asafdav/ng-clip/master/src/ngClip.js"></script>
</head>
<body>
<div ng-app="myapp">
<div class="container" ng-controller="myctrl" ng-mouseover="isHovering = true" ng-mouseout="isHovering = false">
<div class="page-header">
<h1>ngClip <small>example</small></h1>
</div>
<form>
<div style="background:red;" class="form-group">
<label >Copy #1</label>
<input type="text" class="form-control" placeholder="Enter text to copy" ng-model="copy1">
<button ng-if="isHovering" class="btn btn-default" clip-copy="copy1">Copy!</button>
</div>
<br/><br/><br/>
<textarea class="form-control" rows="3" placeholder="paste here"></textarea>
</form>
</div>
</div>
<script>
var myapp = angular.module('myapp', ["ngClipboard"]);
myapp.config(['ngClipProvider', function(ngClipProvider) {
ngClipProvider.setPath("//cdnjs.cloudflare.com/ajax/libs/zeroclipboard/2.1.6/ZeroClipboard.swf");
ngClipProvider.setConfig({
bubbleEvents: false
})
}]);
myapp.controller('myctrl', function ($scope) {
$scope.fallback = function(copy) {
window.prompt('Press cmd+c to copy the text below.', copy);
};
$scope.showMessage = function() {
console.log("clip-click works!");
};
});
</script>
</body >
</html>

I was also having this issue. I fixed by using ng-mouseenter on an outer div instead of using ng-mouseover and ng-mouseleave on an inner div instead of ng-mouseout. No flicker!
So:
<div ng-app="myapp" ng-mouseenter="isHovering = true">
<div class="container" ng-controller="myctrl" ng-mouseleave="isHovering = false">
<div class="page-header">
<h1>ngClip <small>example</small></h1>
</div>
<form>
<div style="background:red;" class="form-group">
<label >Copy #1</label>
<input type="text" class="form-control" placeholder="Enter text to copy" ng-model="copy1">
<button ng-if="isHovering" class="btn btn-default" clip-copy="copy1">Copy!</button>
</div>
<br/><br/><br/>
<textarea class="form-control" rows="3" placeholder="paste here"></textarea>
</form>
</div>
</div>

Related

ng-if does not work

In my project I am facing an issue that ng-if is not working. I want to remove/add text field when value of $scope.edit changes.
I have created a simplest of example in the jsfiddle below.
HTML
<div ng-app>
<div ng-controller="TodoCtrl">
<input type="checkbox" ng-model="edit" ng-init="edit = true">
<div ng-bind="edit"></div>
<div ng-if="edit">
<input type="text" ng-model="name" size="30" placeholder="New Name" />
</div>
</div>
</div>
JS
function TodoCtrl($scope) {
$scope.name = "Johny";
}
http://jsfiddle.net/U3pVM/32009/
Your Fiddle may not work because you are using Angular 1.0.1 which has some issue in ng-if.
Solution 1
If you are really using this version, you can replace ng-if by ng-show (which will create hidden elements in the DOM).
<div ng-show="edit">
Demo on JSFiddle using ng-show
Solution 2
Anyway, the best solution would be to use Angular 1.2+ which fixes ng-if bugs in ng-repeat. As you can see in the following snippet, I didn't change your code, and it works.
Demo on JSFiddle using ng-if
Some observations :
Seems that your angular version is old. hence, ng-if is not working.
If you want to use only existing angular version then you can use ng-show instead of ng-if.
Demo with ng-if :
function TodoCtrl($scope) {
$scope.name = "Johny";
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="TodoCtrl">
<input type="checkbox" ng-model="edit" ng-init="edit = true">
<div ng-bind="edit"></div>
<div ng-if="edit">
<input type="text" ng-model="name" size="30" placeholder="New Name" />
</div>
</div>
</div>
Demo with ng-show :
function TodoCtrl($scope) {
$scope.name = "Johny";
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<div ng-app>
<div ng-controller="TodoCtrl">
<input type="checkbox" ng-model="edit" ng-init="edit = true">
<div ng-bind="edit"></div>
<div ng-show="edit">
<input type="text" ng-model="name" size="30" placeholder="New Name" />
</div>
</div>
</div>
Use ng-show instead
<div ng-show=edit>
<input type="text" ng-model="name" size="30" placeholder="New Name" />
</div>
DEMO
Update the angular version with 1.2 or above with ng-if
angular.module('myApp', [])
.controller('TestCtrl', function($scope) {
$scope.name = "Johny";
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS </title>
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="TestCtrl">
<input type="checkbox" ng-model="edit" ng-init="edit = true">
<div ng-bind="edit"></div>
<div ng-show=edit>
<input type="text" ng-model="name" size="30" placeholder="New Name" />
</div>
</body>
</html>

Input Fields update AFTER submit button is clicked in angularjs

The input fields should NOT directly update the fields (meaning when I type in the input box you should NOT see the badge field update - only after the Submit button is pressed will the fields populate).
//index.html
<!DOCTYPE html>
<html lang="en" ng-app="MyApp">
<head>
<meta charset="UTF-8">
<title>Name Badge</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body ng-controller="MainController">
<div class="container">
<div class="row">
<div class="col-md-6">
<input class="text" placeholder="First Name" ng-model="fName"><br>
<input class="text" placeholder="Email" ng-model="email"><br>
<input class="text" placeholder="Phone" ng-model="phone">
</div>
<div class="col-md-6">
<input class="text" placeholder="Last Name" ng-model="lName"><br>
<input class="text" placeholder="Place of Birth" ng-model="birth"><br>
<input class="text" placeholder="Favorite Food" ng-model="food">
</div>
</div>
<textarea ng-model="about">Tell us about yourself</textarea><br>
<button class="btn" type="submit" ng-submit="info()">Submit</button>
<br><br>
<br><br><br><br>
<div class="row">
<div class="col-xs-6">
<h3>Name: {{fName}} {{lName}}</h3>
<h3>Place of Birth: {{birth}}</h3>
<h3>Email: {{email}}</h3>
</div>
<div class="col-xs-6">
<h3>Phone: {{phone}}</h3>
<h3>Favorite Food: {{food}}</h3>
</div>
</div>
<textarea>{{about}}</textarea>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
Here is my app.js
var app = angular.module("MyApp", []);
app.controller("MainController", ['$scope', function ($scope) {
$scope.info = function () {
$scope.fName = fName;
$scope.email = '';
$scope.phone = '';
$scope.lName = '';
$scope.birth = '';
$scope.food = '';
$scope.about = '';
}
}])
Can someone look at my code and help me see what's wrong.
<!DOCTYPE html>
<html lang="en" ng-app="MyApp">
<head>
<meta charset="UTF-8">
<title>Name Badge</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body ng-controller="MainController">
<div class="container">
<div class="row">
<div class="col-md-6">
<input class="text" placeholder="First Name" ng-model="fName"><br>
<input class="text" placeholder="Email" ng-model="email"><br>
<input class="text" placeholder="Phone" ng-model="phone">
</div>
<div class="col-md-6">
<input class="text" placeholder="Last Name" ng-model="lName"><br>
<input class="text" placeholder="Place of Birth" ng-model="birth"><br>
<input class="text" placeholder="Favorite Food" ng-model="food">
</div>
</div>
<textarea ng-model="about">Tell us about yourself</textarea><br>
<button class="btn" type="submit" ng-submit="info()">Submit</button>
<br><br>
<br><br><br><br>
<div class="row">
<div class="col-xs-6">
<h3>Name: {{fName1}} {{lName1}}</h3>
<h3>Place of Birth: {{birth1}}</h3>
<h3>Email: {{email1}}</h3>
</div>
<div class="col-xs-6">
<h3>Phone: {{phone1}}</h3>
<h3>Favorite Food: {{food1}}</h3>
</div>
</div>
<textarea>{{about}}</textarea>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
js file is
var app = angular.module("MyApp", []);
app.controller("MainController", ['$scope', function ($scope) {
$scope.info = function () {
$scope.fName1 = $scope.fName1;
$scope.email1 = $scope.email;
$scope.phone1 = $scope.phone;
$scope.lName1 = $scope.lName;
$scope.birth1 = $scope.birth;
$scope.food1 = $scope.food;
$scope.about1 = $scope.about;
}
}])

Angular expression doesn't work with ng-disabled

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.js"></script>
<body ng-app="myApp">
<div ng-controller="toDoCtrl">
<div>
<hr>
<form class="form" name="commentForm" ng-submit="vm.submitCommentForm()">
<div class="form-group">
<label for="fieldBody">Comment:</label>
<textarea name="body" id="fieldBody" class="form-control" rows="3"
ng-change="vm.changeCommentForm()"
ng-model="vm.commentForm.body"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" ng-disabled="!vm.validCommentForm">Comment</button>
</div>
</form>
<hr>
</div>
</div>
Script
var app = angular.module('myApp', []);
app.controller('toDoCtrl', function () {
var vm = this;
vm.validCommentForm = true;
})
The "comment" button appears disabled when vm.validCommentForm = true
Meanwhile if I hardcode ng-disabled=0comment button appears working, as supposed. What did I get wrong?
You are using controllerAs methodology but not setting the alias in view
Try changing
<div ng-controller="toDoCtrl">
To
<div ng-controller="toDoCtrl as vm">

Parent ngForm dirty status based on children forms

I'm having some problems trying to keep my parent ngForm status updated; it should be set to "Pristine" when all its children are cleaned and set to "Pristine" them selves... but it seems not happen automatically.
I created a plunk here to better explain the problem: http://plnkr.co/edit/vCX7ltOb8fgl3fkEpvzy?p=preview
<body ng-controller="MainCtrl">
<div ng-form="parentForm1" class="parent-form">
parentForm1.dirty: <b>{{parentForm1.$dirty}}</b>
<form name="childForm1" class="child-form" novalidate>
childForm1.dirty: <b>{{childForm1.$dirty}}</b>
<br/>
<input type="text" ng-model="field1">
<br/>
<button ng-click="reset1()">Clean and setPristine</button>
</form>
<form name="childForm2" class="child-form" novalidate>
childForm2.dirty: <b>{{childForm2.$dirty}}</b>
<br/>
<input type="text" ng-model="field2">
<br/>
<button ng-click="reset2()">Clean and setPristine</button>
</form>
</div>
</body>
Where am I wrong? I found solutions using external modules... I'd like to solve it with less code as possible (perhaps a directive?).
I found my own answer with "angular-input-modified" here is the updated plunk: http://plnkr.co/edit/vCX7ltOb8fgl3fkEpvzy?p=preview
HTML:
<!DOCTYPE html>
<html ng-app="test">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="//rawgit.com/betsol/angular-input-modified/master/dist/angular-input-modified.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-controller="MainCtrl">
<div ng-form="parentForm1" class="parent-form">
parentForm1.dirty: <b>{{parentForm1.$dirty}}</b>
<br/>
parentForm1.modified: <b>{{parentForm1.modified}}</b>
<form name="childForm1" class="child-form" novalidate>
childForm1.dirty: <b>{{childForm1.$dirty}}</b>
<br/>
<input type="text" ng-model="field1">
<br/>
<button ng-click="reset1()">Clean and setPristine</button>
</form>
<form name="childForm2" class="child-form" novalidate>
childForm2.dirty: <b>{{childForm2.$dirty}}</b>
<br/>
<input type="text" ng-model="field2">
<br/>
<button ng-click="reset2()">Clean and setPristine</button>
</form>
</div>
<form name="exChildForm1" class="child-form" novalidate>
exChildForm1.dirty: <b>{{exChildForm1.$dirty}}</b>
<br/>
<input type="text" ng-model="exfield1">
<br/>
<button ng-click="exreset1()">Clean and setPristine</button>
</form>
</body>
</html>
JS:
var app = angular.module('test', ['ngInputModified']);
app.controller('MainCtrl', function($scope) {
$scope.reset1 = function() {
$scope.field1 = null;
$scope.childForm1.$setPristine();
}
$scope.reset2 = function() {
$scope.field2 = null;
$scope.childForm2.$setPristine();
}
$scope.exreset1 = function() {
$scope.exfield1 = null;
$scope.exChildForm1.$setPristine();
}
});

In Angularjs / Bootstrap why does my cancel button invoke the submit event

I have an Angular / Bootstrap form with a button type=submit and a plain button to cancel - and hide the form. When I click on the cancel, it calls the cancel event handler and then it calls the submit handler. ?? Here's the code as if have it in Plunker: http://plnkr.co/edit/Nsqy4DuVaoI04VObS2Zd?p=preview
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example33-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
</head>
<body ng-app="submitExample">
<script>
angular.module('submitExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.list = [];
$scope.text = 'hello';
$scope.cancel = function(){
alert('cancelling');
}
$scope.submitNewAccountForm = function(isValid){
alert('in submit');
}
}]);
</script>
<form ng-controller="ExampleController" name="newAccountForm" ng-submit="submitNewAccountForm(newAccountForm.$valid)" class="form-horizontal" novalidate>
<fieldset>
<!-- Form Name -->
<legend>Account</legend>
<!-- Text input-->
<div class="control-group">
<label class="control-label" for="name">Account name</label>
<div class="controls">
<input ng-model="name" id="name" name="name" type="text" placeholder="account" class="input-medium" required="">
<p class="help-block">Required.</p>
</div>
</div>
<!-- Select Basic -->
<div class="control-group">
<label class="control-label" for="type">Account type</label>
<div class="controls">
<select ng-model="type" id="type" name="type" class="input-medium">
<option>client</option>
<option>provider</option>
</select>
</div>
</div>
<!-- Button (Double) -->
<div class="control-group">
<label class="control-label" for="cancelaccountadd"></label>
<div class="controls">
<button type="submit" id="doaccountadd" name="doaccountadd" class="btn btn-success">Save</button>
<button ng-click="cancel()" id="cancelaccountadd" name="cancelaccountadd" class="btn btn-danger">Cancel</button>
</div>
</div>
</fieldset>
</form>
</body>
</html>
On button elements, submit is the default type attribute. change that to type="button" and it will no longer call the submit event.
Plunker

Resources