AngularJS Custom Directive Isolated Scope is not working - angularjs

I'm trying to create a Spinner,
I have a custom directive in AngularJS
var app = angular.module('plunker', [])
.directive('spinner', function() {
return {
restrict: 'EA',
scope: {
jump:'=jump'
},
link: function (scope, element, attrs) {
scope.jump = 0;
scope.spinning = function(action) {
var jumps = document.getElementById("jumps").value;
var spinn = document.getElementById("spinn").innerText;
var convt = Number(spinn);
var jumpconvt = Number(jumps);
if(jumps === '' && action === "add") {
convt= convt +1;
}
else if(jumps === '' && action === "sub") {
convt= convt - 1;
}
else if(jumps !== '' && action === "sub") {
convt = convt - Number(jumps);
}
else{
convt = jumpconvt + convt;
}
document.getElementById("spinn").innerHTML = convt;
};
},
templateUrl: 'spinnerDirective.html'
};
});
in spinnerDirective.html will contain
<div>
<div> Jumps: <input type='text' id="jumps" ng-model='count'/> </div>
<div style="float: left; width:120px; margin-top:10px;" >
<div style="border-color: red; border-style: solid; border-width: 1px 1px 1px 1px; margin-left: 10px; text-align: center; height: 30px; line-height: 2px;" >
<label style="vertical-align: top;line-height: normal;" ng-click="spinning('add');" >+</label>
</div>
<div style="margin-top: -12px; text-align: center; height:12px;margin-left: 7px;">
<span id="spinn" style="background-color: #fff;font-size:18px;">{{jump}}</span>
</div>
<div style="border-color: red; border-style: solid; border-width: 0 1px 1px 1px; margin-left: 10px; text-align: center; height: 30px;line-height: 27px;">
<label style="vertical-align: bottom;line-height: normal;" ng-click="spinning('sub');">-</label>
</div>
</div>
</div>
Which will be rendered as:
<div>
<div>Spinner</div>
<div style="float: left;">
<spinner jump="jump"></spinner>
</div>
<div style="float: left;">
<spinner jump="jump"></spinner>
</div>
</div>
The problem is: if I use one spinner it works fine. But When I have multiple spinners it's not working, when i do click on + or - button in 2nd spinner, count is getting change in 1st spinner.
Result should be: onlick on + or - without giving any value in textbox, value should get increment or decrement by 1, and by giving value in textbox should get add or substract by textbox value.
when i do click on + or - button on 1st Spinner changes should happen only in 1st spinner and when i do click on + or - button on 2nd Spinner changes should happen only in 2nd spinner.
I have tried isolated scope in directive but still no effect.
Here's my code (Edit): Plunker
Please if someone could guide me how to do it right.
Thanks in advance.

Related

I want to show a modal window on selecting a list item in angular js

I want to show a pop up window when a user selects an element from the dropdown list. But instead im getting a plain text no modal window is being shown. Please help: below is the referece for my code-
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.value = '';
$scope.accntDetails = {
accnt01: { bankName: "HDFC", bankbranch: "delhi", accntNumber: "12345" },
accnt02: { bankName: "ICICI", bankbranch: "mumbai", accntNumber: "12346" },
accnt03: { bankName: "IDBI", bankbranch: "pune", accntNumber: "12347" }
};
$scope.modalShown = false;
$scope.toggleModal = function() {
$scope.modalShown = true;
};
$scope.changedValue = function(bank) {
$scope.value = bank.bankName;
$scope.toggleModal();
console.log($scope.value);
}
angular.module('myApp').directive('modalDialog', function() {
return {
restrict: 'E',
scope: {
show: '='
},
transclude: true,
link: function(scope, element, attrs) {
console.log('attrs: ', attrs);
scope.dialogStyle = {};
if (attrs.boxWidth) {
scope.dialogStyle.width = attrs.boxWidth;
}
if (attrs.boxHeight) {
scope.dialogStyle.height = attrs.boxHeight;
}
scope.hideModal = function() {
scope.modalShown = false;
};
},
template: `<div class='ng-modal' ng-show='modalShown'>
<div class='ng-modal-overlay' ng-click='hideModal()'></div>
<div class='ng-modal-dialog' ng-style='dialogStyle'>
<div class='ng-modal-close' ng-click='hideModal()'>X</div>
<div class='ng-modal-dialog-content' ng-transclude></div>
</div>
</div>`
};
});
});
/* Custom CSS- this is the css code for showing up a modal */
.ng-modal-overlay {
/* A dark translucent div that covers the whole screen */
position: absolute;
z-index: 9999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #808080;
opacity: 0.8;
}
.ng-modal-dialog {
background-color: #fff;
box-shadow: 10px 10px #595554;
border-radius: 4px;
z-index: 10000;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.ng-modal-dialog-content {
padding: 10px;
text-align: left;
}
.ng-modal-close {
position: absolute;
top: 3px;
right: 5px;
padding: 5px;
cursor: pointer;
font-size: 120%;
display: inline-block;
font-weight: bold;
font-family: 'arial', 'sans-serif';
}
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<p>Select account number:</p>
<!-- <select ng-model="accnt" ng-options="y.bankName for (x, y) in accntDetails">
</select> -->
<select ng-model="bankSelected" ng-change=" toggleModal();"
data-ng-options="bank as bank.bankName for bank in accntDetails">
<option value="">Select Account</option>
</select>
<h1>You selected: {{bankSelected.bankName}}</h1>
<h2>branch: {{bankSelected.bankbranch}}</h2>
<h3>Number: {{bankSelected.accntNumber}}</h3>
<div ng-show="modalShown">
<modal-dialog box-width="400px" box-height="150px">
<div class="row">
<div class="col-md-12">
<h3>Header</h3>
<hr style="border-top:1px solid darkblue" />
</div>
</div>
<div class="row">
<div class="col-md-12">
This is an important message
</div>
</div>
</modal-dialog>
</div>
</div>
</body>
when a user click on any element of the list a modal window should popup. I have tried this code. If i use it onClick event it works fine the modal opens but if i use it with ng-select it doesnt works:
Okay, I think there are two problems here. One is that your JSON is not valid to run on a repeat. It should be an array of Object to get the details. I was able to run the same when I tried that with the JSON as :
CODEPEN
like accntDetails = [{BankDetails1},{BankDetails2},{BankDetails}]

angularJS toggle button how to get ng-model value

Can i know how to get value from toggle button in angularjs. I need to get value as Principle or contractor.
<div style="float: left; margin-top: 4px">Principal</div>
<div style="margin-left: 10px; float: left; margin-right: 10px"
class="btn-switch"
ng-class="{'btn-switch--on':toggle.switch}"
ng-model="toggle.switch"
ng-click="toggle.switch = !toggle.switch">
<div class="btn-switch-circle"
ng-class="{'btn-switch-circle--on':toggle.switch}"
ng-model="toggle.switch"
ng-click="!toggle.switch = toggle.switch"></div>
</div>
<div style="float: left; margin-top: 4px">Contractor</div>
can you check like this..?
var result;
if(!toggle.switch){
result = 'Contractor'
}
else{
result = 'Principal'
}

change CSS based on value Angularjs

I want to change label color and cursor type based on ng-model
index.html
<button ng-click="changeType()">Change</button>
<label class="fee-type" ng-style="feeType ==='one' && {'class':'disabled-class'}" for="fixed2">Client Contengency Fee</label>
<label class="fee-type" ng-style="feeType ==='one' && {'class':'disabled-class'}" for="fixed1">Fixed Fee Per Property</label>
The default class is fee-type but when then button get clicked its class should change to disabled-class
index.css
.fee-type {
float: left;
clear: none;
display: block;
padding: 2px 1em 0 0;
color: black;
}
.disabled-class {
color:gray;
cursor: not-allowed;
}
index.js
$scope.feeType= two;
$scope.changeType= function(){
$scope.feeType=one;
}
You should use ng-class instead of ng-style and add condition in ng-class to apply css class in your label.
HTML:
<button ng-click="changeType()">Change</button>
<label class="fee-type" ng-class="{'disabled-class':feeType ==='one'}" for="fixed2">Client Contengency Fee</label>
<label class="fee-type" ng-class="{'disabled-class':feeType ==='two'}" for="fixed1">Fixed Fee Per Property</label>
and controller
$scope.feeType = 'two';
$scope.changeType = function() {
$scope.feeType = 'one';
};

validate the custom checkbox in angularjs

hi i am trying to validate custom checkbox but it is not working. what i want to acquire when the checkbox is unchecked and i submit the data by clicking on send button there will show a error message, like other fields. and when i checked the checkbox the error message should be disappear...
here is the code Link https://jsfiddle.net/epn9s55x/
Html
<div class="form-row">
<div class="privacy-container">
<input type="checkbox" id="check1">
<label class="privacy-text" for="check1">If you are bussiness to bussiness (B2B) customer,tick the box</label>
</div>
<div class="privacy-container sumsung-privacy">
<input type="checkbox" id="check2">
<label class="privacy-text" for="check2">I acknowladge my information will be processed in accordance with the Sumsung Privacy Policy</label>
</div>
</div>
js
var myApp = angular.module('myApp', []);
myApp.directive('match', function($parse) {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
scope.$watch(function() {
return $parse(attrs.match)(scope) === ctrl.$modelValue;
}, function(currentValue) {
console.log("mismatched directive");
ctrl.$setValidity('mismatch', currentValue);
});
}
};
});
myApp.controller("myController", ['$scope', '$location','$anchorScroll',function($scope,$location, $anchorScroll){
$scope.showMsgs = false;
$scope.send = function(form){
if ($scope[form].$valid) {
$scope.showMsgs = false;
} else {
$scope.showMsgs = true;
$location.hash('mainContainer');
$anchorScroll();
}
}
}]);
Css
/*css for check box*/
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
position: absolute;
}
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
position: relative;
padding-left: 2.75em;
cursor: pointer;
min-width: 300px;
width: 95%;
box-sizing: border-box;
font-size: 14px;
display: block;
font-weight: bold
}
/* checkbox aspect */
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 1.35em;
height: 1.35em;
border: 2px solid #000;
background: #fff;
}
/* checked mark aspect */
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
content: "";
position: absolute;
top: .18em;
left: .18em;
font-size: 1.3em;
line-height: 0.8;
color: #09ad7e;
width: .86em;
height: .86em;
background: #000;
transition: all .2s;
}
/* checked mark aspect changes */
[type="checkbox"]:not(:checked) + label:after {
opacity: 0;
transform: scale(0);
}
/*End of css of check boxes*/
You could just put a model on your checkbox and and test for the value:
<input type="checkbox" id="check2" ng-model="checkbox2">
<label class="privacy-text" for="check2">I acknowladge my information will be processed in accordance with the Sumsung Privacy Policy</label>
</div>
</div>
<div ng-show="!checkbox2">
This is required
</div>
Here is an update to your fiddle
Here's an update per your comment:
You can still use ng-model to do that. Just use a different $scope variable like this:
In your HTML:
<div ng-show="checkInvalid">
This is required
</div>
In your Controller on your click event:
$scope.checkInvalid = true;
Here is an updated Fiddle. Happy coding!

AngularJS directives with HTML5 drag and drop -- issue with scope object

I'm fairly new to angular and I'm having a hard time wrapping my head around where the items are being pushed to. I am not sure if I am correctly setting up the functions to be used with drag/drop and if its getting bound to an older scope object and the ng-repeat isn't being updated properly. I'm thinking there is some slight issue with the way I have this setup. Any pointers or help would be much appreciated.
What should happen is when you drag a color from the Draggable container into the Droppable container it should update the text which is linked to the scope object items. I am successfully pushing an item onto the scope object but ng-repeat isn't picking it up. I am not sure if I need a watch or what to do to get it to pay attention to the newly added items.
JS Fiddle Here: http://jsfiddle.net/RV23R/
HTML CODE:
<div ng-app="my-app" ng-controller="MainController">
<div class="container">
<header><h1>Draggables</h1></header>
<section>
<div draggable="true" ng-repeat="drag_type in drag_types">{{drag_type.name}}</div>
</section>
</div>
<div class="container">
<header><h1>Drop Schtuff Here</h1></header>
<section droppable="true">
<div><span>You dragged in: </span><span ng-repeat="items in items">{{item.name}},</span></div>
</section>
</div>
ANGULAR CODE:
var module = angular.module('my-app', []);
module.directive('draggable', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element[0].addEventListener('dragstart', scope.handleDragStart, false);
element[0].addEventListener('dragend', scope.handleDragEnd, false);
}
}
});
module.directive('droppable', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element[0].addEventListener('drop', scope.handleDrop, false);
element[0].addEventListener('dragover', scope.handleDragOver, false);
}
}
});
function MainController($scope)
{
$scope.drag_types = [
{name: "Blue"},
{name: "Red"},
{name: "Green"},
];
$scope.items = [];
$scope.handleDragStart = function(e){
this.style.opacity = '0.4';
e.dataTransfer.setData('text/plain', this.innerHTML);
};
$scope.handleDragEnd = function(e){
this.style.opacity = '1.0';
};
$scope.handleDrop = function(e){
e.preventDefault();
e.stopPropagation();
var dataText = e.dataTransfer.getData('text/plain');
$scope.items.push(dataText);
console.log($scope.items);
};
$scope.handleDragOver = function (e) {
e.preventDefault(); // Necessary. Allows us to drop.
e.dataTransfer.dropEffect = 'move'; // See the section on the DataTransfer object.
return false;
};
}
CSS (if anyone cares)
.container {
width: 600px;
border: 1px solid #CCC;
box-shadow: 0 1px 5px #CCC;
border-radius: 5px;
font-family: verdana;
margin: 25px auto;
}
.container header {
background: #f1f1f1;
background-image: -webkit-linear-gradient( top, #f1f1f1, #CCC );
background-image: -ms-linear-gradient( top, #f1f1f1, #CCC );
background-image: -moz-linear-gradient( top, #f1f1f1, #CCC );
background-image: -o-linear-gradient( top, #f1f1f1, #CCC );
box-shadow: 0 1px 2px #888;
padding: 10px;
}
.container h1 {
padding: 0;
margin: 0;
font-size: 16px;
font-weight: normal;
text-shadow: 0 1px 2px white;
color: #888;
text-align: center;
}
.container section {
padding: 10px 30px;
font-size: 12px;
line-height: 175%;
color: #333;
}
There are a couple of typos in the fiddle, but the basic problem is that your drag events are outside an angular digest cycle. You should wrap your changes in $scope.$apply (code sample coming). This forked and bugfixed (FIDDLE) shows that when you click the button, angular shows the changes and refreshes the display with new values.
Fix: (FIDDLE)
$scope.$apply(function() {
$scope.items.push(dataText);
});
A bug you had is in this code:
<span ng-repeat="items in items">{{item.name}},</span>
This should probably be ng-repeat="item in items", also items only contains the dropped text so it is an array of strings and not the original item objects.

Resources