How to modify value on DOM button? - angularjs

How to modify text on one specific DOM object? Tried the following code but ended up changing for all the DOM text. It changes all the {{content}} values not only 'b1'.
myfunc () {
$scope.content="nothing";
angular.element(document.getElementById('b1')).scope().content ='something';
}
Here is the html:
<button id="b1" type="button" ng-click="myfunc($event)">
{{content}}
</button>
<button id="b2" type="button" ng-click="myfunc($event)">
{{content}}
</button>

You should not use angular.element or do any DOM manipulation whatsoever anywhere else than in directives. What you want to do here is define $scope.contents as an array / object and then update only the index you want:
$scope.contents = Array(2).fill('nothing');
$scope.updateButton = function(index) {
$scope.contents[index] = 'something';
};
As for your template:
<button type="button" ng-click="updateButton(0)">{{ contents[0] }}</button>
<button type="button" ng-click="updateButton(1)">{{ contents[1] }}</button>

Related

AngularJS disable double click

I have a problem with a button which contacts server on click. If you do a double click (or any number of clicks for that matter) you will call the server that number of times.
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'ADMIN.CONTENT.DELIVERIES.BODY.CLOSE' | translate }}</button>
<a class="btn btn-danger" ng-click="vm.markDelivered()" ng-dblclick="return" ng-disabled="flag">{{ 'MANAGER.CONTENT.DELIVERIES.BODY.DELETE_PANEL.CONFIRM' | translate }}</a>
</div>
I have tried with ng-disabled but for some reason it doesn't work, as it is saying that that element is not allowed there. I tried changing a to button, but that seems the same. ng-dblclick="return" does nothing also.
Even I had the same issue,And solved using this approach.
<div class="col-sm-4 form-group pull-right">
<input type="submit" name="Submit" class="btn btn-primary"
value="Submit" data-ng-disabled="myForm.$invalid"
ng-click="myForm.$invalid=true;vm.markDelivered()" />
</div>
So on first click myForm.$invalid=true will be set and button will be disabled. SO you will not have multiple calls to your server side code.
So with Bootstrap buttons you won't be able to use ng-disabled. You would have to do it this way:
<div class="btn btn-default" ng-class="{'disabled': idDisabled}" ng-click="doSomething()">I'm a button!</div>
where you are setting the class disabled on the button. But this does not disable the action itself. So when the button is pressed you would need to check that isDisabled variable and if it is true just return and don't do the intended action.
So for example:
doSomething() {
if (isDisabled) {
return
} else {
// do your server call
// when call is finished set isDisabled = false
}
}
I see a couple of issues here.
First, change the anchor tag to a button.
Second, you seem to be using 'controller as' syntax. So, you are probably setting your flag in the vm. But, in your html, you are looking for the flag in the $scope. Change ng-disabled="flag" to ng-disabled="vm.flag"
Your final button line would look like this:
<button class="btn btn-danger" ng-click="vm.markDelivered()" ng-dblclick="return" ng-disabled="vm.flag">{{ 'MANAGER.CONTENT.DELIVERIES.BODY.DELETE_PANEL.CONFIRM' | translate }}</button>
Adding a working plunker here demonstrating ng-disabled
What about using a simple behaviour directive?
function oneTimeCallDirective($timeout) {
var httpCallMock = (cb = () => 'ok') => $timeout(cb, 5000);
return function oneTimeCallPostLink(iScope, iElement) {
let busy = false;
return iElement
.on('click dblclick', function(event) {
if(busy) {
return event.preventDefault();
}
busy = true;
console.info('Well, Calling.');
return httpCallMock()
.then(() => {
console.log('You Can Start Calling Again');
})
.finally(() => {
busy = false;
})
;
})
;
};
}
angular
.module('test', [])
.directive('oneTimeCall', oneTimeCallDirective)
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<section ng-app="test">
<button one-time-call>Click Here</button>
</section>

How can I add uib-tooltip from within an attribute directive?

Instead of adding uib-tooltip="tooltip text" to the element I want to add only a tooltip attribute.
In the tooltip directive I want to do something along the lines of "on mouseenter if a condition is met then show my full text content in uib-tooltip"
You can use tooltip-enable.
JS
.controller("ctrl", function($scope){
$scope.isToolTipEnabled = false;
$scope.toggleToolTip = function(){
$scope.isToolTipEnabled = !$scope.isToolTipEnabled;
}
});
HTML
<div ng-controller="ctrl">
<div class="label label-info" class="btn btn-default"
tooltip-enable="isToolTipEnabled"
uib-tooltip="This is a conditional tooltip">Conditional Tooltip here</div>
<button type="button" class="btn btn-default" ng-click="toggleToolTip()" ng-class="{'btn-success': isToolTipEnabled, 'btn-danger': !isToolTipEnabled}">Tooltip is {{isToolTipEnabled ? 'enabled' : 'disabled'}}</button>
</div>

Angular ng-click function requiring two clicks to take effect

I have the following directive
app.directive('replybox', function ($timeout, $window, $compile, $sce) {
var linkFn = function (scope, element, attrs) {
var exampleText= element.find('p');
var btn = element.find('button');
var windowSelection="";
scope.okOrCancel="None";
exampleText.bind("mouseup", function () {
scope.sel = window.getSelection().toString();
windowSelection=window.getSelection().getRangeAt(0);
if(scope.sel.length>0) {
scope.showModal = true;
scope.$apply();
}
});
btn.bind("click", function () {
if(scope.okOrCancel=='ok'){
range = windowSelection;
var replaceText = range.toString();
range.deleteContents();
var div = document.createElement("div");
div.innerHTML = '<poper>' + replaceText + '<button type="button" class="btn btn-danger btn-xs">×</button></poper>';
var frag = document.createDocumentFragment(), child;
while ((child = div.firstChild)) {
frag.appendChild(child);
}
$compile(frag)(scope);
range.insertNode(frag);
scope.showModal=false;
}
if(scope.okOrCancel=='cancel'){
scope.showModal=false;
}
scope.selection="None";
scope.okOrCancel='None';
});
};
return {
link: linkFn,
restrict: 'A',
scope: {
entities: '=',
selection:'='
},
template: `<ng-transclude></ng-transclude>
<div class="modal fade in" style="display: block;" role="dialog" ng-show="showModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
{{sel}}
</div>
<div class="radio">
<div ng-repeat="x in entities">
<div class="radio">
<label>
<input type="radio" name="choice" ng-model="$parent.selection" ng-value = "x">
{{x}}
</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="okOrCancel='ok'">
Ok
</button>
<button type="button" class="btn btn-primary" ng-click="okOrCancel='cancel'">
Cancel
</button>
</div>
</div>
</div>
</div>`,
transclude: true
};
});
So there is a modal in the template which contains an "Ok" and a "Cancel" button. There is an ng-click on these buttons which sets scope.okOrCancel to the appropriate value. btn binds to a button click and performs different actions depending on the state of scope.okOrCancel. When the "Ok" button is clicked everything works as expected. But the "Cancel" button requires two clicks in order for the modal to dissappear. I would think this would happen immediately within
if(scope.okOrCancel=='cancel'){
scope.showModal=false;
}
Can anyone tell me why the cancel button requires two clicks to close the modal?
Currently you have a mix of jQuery and angularjs for your ok and cancel click. Probably that is the reason to require two clicks to take effect.
If I were you, I would have write click like below:
Template:
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="okClick()"> Ok </button>
<button type="button" class="btn btn-primary" ng-click="cancelClick()"> Cancel </button>
</div>
In JS:
scope.okClick = function() {
range = windowSelection;
var replaceText = range.toString();
range.deleteContents();
var div = document.createElement("div");
div.innerHTML = '<poper>' + replaceText + '<button type="button" class="btn btn-danger btn-xs">×</button></poper>';
var frag = document.createDocumentFragment(), child;
while ((child = div.firstChild)) {
frag.appendChild(child);
}
$compile(frag)(scope);
range.insertNode(frag);
scope.showModal=false;
}
scope.cancelClick = function() {
scope.showModal=false;
}
scope.selection="None";
scope.okOrCancel='None';
I hope this helps you!
Cheers
Completely agree with varit05's answer. Most likely it's because you do not trigger digest cycle in the click event handler. But in any way, the point is: it's not very good idea to mix jquery and angular stuff, unless: a) you absolutely sure it's necessary; b) you understand very well what you're doing and why; otherwise it will lead to such an unexpected consequences.
Just another a small addition. Another problem is here:
$compile(frag)(scope);
range.insertNode(frag);
The correct approach would actually be to insert new nodes into real DOM and only then $compile() them. Otherwise, any directives with require: "^something" in the DOM being inserted will fail to compile because they would not be able to find necessary controllers in upper nodes until new nodes actually make it to the "main" DOM tree. Of course, if you absolutely sure you don't have that then you can leave it as is and it will work... But then the problem will just wait out there for its "finest hour".

Angularjs getting the button value

I need to get the button id value using angularjs.I have written the code but i am getting the value as "undefined".So please suggest me the code which i need to use.
My code is:
<button type="button" class="btn btn-primary ole" data-toggle="tooltip" id="buttonvalue" name="rdoResult" value="SUN" ng-click="addvalue()" ng-model="testDate23" data-placement="left" data-original-title="this is a left tooltip">
SUN
</button>
<button type="button" ng-value="2" class="btn btn-primary ole two" data-toggle="tooltip" ng-click="addvalue()"
ng-model="testDate23" value="MON" id="buttonvalue" data-placement="top" data-original-title="this is a top tooltip">
MON
</button>
Script code:
$scope.addvalue = function() {
var datevaluee=$scope.testDate23;
}
You need to pass the $event in ng-click function like below..
ng-click="addvalue($event)"
below will be the function implementation
$scope.addvalue = function(element) {
$scope.testDate23 = element.currentTarget.value; // this will return the value of the button
console.log( $scope.testDate23)
};
you can try this.
<button ng-click="addvalue(testDate23='SUN')">
button
</button>
or
<button ng-click="addvalue(testDate23='MON')">
btn2
</button>
Find fiddle Fiddle example
Hope it will help.
Button is an input for submitting data, not setting data.
You need use directive.
Live example on jsfiddle.
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.getValue = function() {
$scope.value = $scope.testDate23;
}
});
myApp.directive('buttonValue', function() {
return {
restrict: 'A',
scope: {
buttonValue:"="
},
link: function(scope, element, attr) {
scope.$watch(function(){return attr.ngValue},function(newVal){
scope.buttonValue = newVal;
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<input ng-model="btnValue">
<button ng-value="{{btnValue}}" ng-click="getValue()" button-value="testDate23">
MON
</button>
<br>
<pre>testDate23= {{testDate23}}</pre>
<pre>value= {{value}}</pre>
</body>
If you want to set hardcoded value then use ng-init
<button type="button" ng-init="value=2" class="btn btn-primary ole two" data-toggle="tooltip" ng-click="addvalue()"
ng-model="testDate23" value="MON" id="buttonvalue" data-placement="top" data-original-title="this is a top tooltip">
MON
</button>
You can use value aywhere in your same template.

ng-model is not updated in ng-if

I'm failing to retrieve the actual value of my selected option (ng-model=filter) in my select html bloc.
Note that if I don't set $scope.filter then $scope.filter stay undefined even if I select an option in the dropdown list.
My html template, filters.html :
<div ng-if="!showFilterTemplatePlz">
<button class="btn btn-primary" ng-click="showFilterTemplate()" type="button">Add Filter</button>
</div>
<div ng-if="showFilterTemplatePlz" class="inline">
<button class="btn btn-primary" ng-click="closeFilters()" type="button">Close filters</button>
<label>filters</label>
<select ng-model="filter" ng-options="filter.name for filter in filterOptions" class="form-control">
</select>
<p>{{filter.name}}</p>
<button ng-click="addFilter()" id="addFilterButton" class="btn btn-primary btn-sm btn-default" type="button"><i class="fa fa-plus"></i> Add</button>
</div>
In my directive:
.directive('filters', ['retrieveStaticDatasService','usersService', function(datasService, usersService) {
return {
restrict: 'E',
scope: false,
controller: function ($scope) {
/* init */
$scope.filterOptions = [
{name: "languages"},
{name: "nationality"},
{name: "location"}
];
$scope.filter = $scope.filterOptions[0];
/* end init */
$scope.showFilterTemplate = function(){
$scope.showFilterTemplatePlz=true;
}
$scope.closeFilters = function(){
$scope.showFilterTemplatePlz=false;
}
$scope.addFilter = function(){
console.log("filter to add : " + $scope.filter.name);
}
},
templateUrl: '/partials/components/filters.html'
}
}])
Result :
I can see the actual value appears in my html but i will always show "languages" for$scope.filter.name in my console, whatever option I selected! I took a screenshot to show you : http://hpics.li/4a37ae3
Thanks for your help.
[Edit : I made some test and my model are setted and updated only if they are not inside the "<div ng-if="..."></div>"]. Is it not allowed to put a ng-if directly in the directive?
Answer : Angularjs ng-model doesn't work inside ng-if
I found the solution, the problem was that ng-if creates a child scope. So I changed filter to $parent.filter in
<select ng-model="$parent.filter" ng-options="option.name for option in filterOptions" class="form-control">
</select>
I think you are confusing it by having to objects named 'filter'. You might be overwriting the ng-options object rather than your controller one.
Try changing to
<select ng-model="filter" ng-options="option.name for option in filterOptions" class="form-control"></select>
<p>{{filter.name}}</p>
<button ng-click="addFilter()" id="addFilterButton" class="btn btn-primary btn-sm btn-default" type="button"><i class="fa fa-plus"></i> Add</button>

Resources