Conditional ng-click on AngularJS - javascript

I have a code inside ng-repeat
<tr ng-repeat="location in assetLocations track">
<span class="fa fa-remove fa-lg text-danger" style="cursor: pointer;"
ng-show="location.isEdit"
ng-click="readOnly===false ? (cancel();location.isEdit = false; updateClicked = false;) : null"></span>
</tr>
Here location.isEdit property is set on the fly.
I want to set a conditional ng-click to span. But the code above gives the following error
angular.js:11598 Error: [$parse:syntax] Syntax Error: Token ';' is unexpected, >>expecting [)] at column 29 of the expression [readOnly===false ? >>(cancel();location.isEdit = false; updateClicked = false;) : null] starting at >>[;location.isEdit = false; updateClicked = false;) : null].
I can set the variables inside the function, but I need to set the variables and call the functions on ng-click
How to use the conditional ng-click for this type of scenario?

You can try something like the below code,
Controller:
$scope.conditionCancelClick = function(location){
if(!$scope.readOnly){
$scope.cancel();
location.isEdit = false;
$scope.updateClicked = false;
}
}
Template:
<tr ng-repeat="location in assetLocations track">
<span class="fa fa-remove fa-lg text-danger" style="cursor: pointer;"
ng-show="location.isEdit" ng-click="conditionCancelClick(location)"></span>
</tr>

try replacing ; to , as
<tr ng-repeat="location in assetLocations track">
<span class="fa fa-remove fa-lg text-danger" style="cursor: pointer;"
ng-show="location.isEdit"
ng-click="readOnly===false ? (cancel(),location.isEdit
= false, updateClicked = false) : null"></span>
</tr>

Related

Is it possible to embed html in a ternary in angular expression?

I need different buttons with icon and text depending on the user.id but the html seems not to be interpreted in a ternary in an angular expression
I can have the result I want with a ngIf and two separated buttons but it would be better to do it in one line of code.
{{
user.id ?
'<i class="far fa-save"></i>Save' :
'<i class="far fa-plus-square"></i>Add'
}}
the expected result is having one icon and the corresponding text, for instance: ICON-ADD Add.
Instead of that, I have the entire expression: "user.id ? 'ICON-SAVE Save' : 'ICON-ADD Add'"
You can use ternary for inner text and ngClass to toggle classes as following:
<i class="far" [ngClass]="{'fa-save' : user.id, 'fa-plus-quare': !user.id}">
{{user.id ? 'Save' : 'Add'}}
</i>
Hope this helps.
Using *ngIf:
<ng-container *ngIf="user.id"> <i class="far fa-save"></i>Save </ng-container>
<ng-container *ngIf="!user.id"> <i class="far faplus-square"></i>Add </ng-container>
Using Ternary Operator
<ng-container>
<i [ngClass]="user.id ? 'far fa-save' : 'far faplus-square'"></i>
{{user.id ? 'Save' : 'Add'}}
</ng-container>
You can use ngif with else clause, here's the documentation:
https://angular.io/api/common/NgIf
In your case it'd look like that:
<i class="far fa-save" *ngIf='user.id; else showAdd'>Save</i>
<ng-template #showAdd>
<i class="far fa-plus-square">Add</i>
</ng-template>

Add styles to function-returned data

I'm trying to add CSS styles to a string computed in Javascript. It goes through a series of transformation functions:
var fieldSetTransformation = setFieldTransformation(iteration);
fieldSetTransformation = stylePropertyName(fieldSetTransformation);
This value then is passed to a table generated in a directive through AngularJS's ng-repeat:
<tbody class="tableBody">
<tr ng-repeat="line in linesArray">
<td ng-repeat="column in ::columns" width="{{::column.width}}" ng-class="{
'center-text' : (!line[column.key] || line[column.key].length === 0)
}">{{line[column.key] !== undefined ? line[column.key] : '--'}}<span ng-if="column.key == 'user'">
<i id="plus-icon-styling"
class="fa fa-plus-circle action-icon">
</i>
</span>
</td>
</tr>
</tbody>
So I'm struggling to append it to an existing container.
What I have tried so far?
Injecting the HTML directly into the returned value:
var htmledField = [
'<span class="propertyNameHighlight">' + fieldSetTransformation,
'<span>'].join("\n");
];
No use, since this does not seem to be accepted anymore by current navigators (correct me if wrong) since it's a security issue.
The thrown result is just <span class="propertyNameHighlight">000000</span>
appearing in the table.
Creating the element, then appending it in the view
Also a no-go:
function stylePropertyName(data){
var newSpan = document.createElement('span');
newSpan.setAttribute('class', 'propertyNameHighlight');
document.getElementsByClassName("tableBody").appendChild(newSpan);
newSpan.innerHTML = data;
return data;
}
This returns a null function exception.
I have also checked this question, which seemed the closest to my query, but in my case there is no clear container neither to wrap up the resulting string.
TL;DR: What I'm trying to achieve?
This green text over here:
That represents a cell. The data is not directly passed, it's generated dynamically through a series of functions and ng-repeats.
Any help or related disregarded question that I could get is greatly appreciated. Thanks!
As suggested by commenter Stanislav Kvitash (thanks!), I solved this by using ngBindHtml :
<tbody class="tableBody">
<tr ng-repeat="line in linesArray">
<td ng-repeat="column in ::columns" width="{{::column.width}}" ng-class="{'center-text' : (!line[column.key] || line[column.key].length === 0)}">
<span ng-bind-html="line[column.key] !== undefined ? line[column.key] : '--'"></span>
<span ng-if="column.key == 'user'">
<i id="plus-icon-styling"
class="fa fa-plus-circle action-icon">
</i>
</span>
</td>
</tr>
</tbody>

How to invoke method on double click in angularJs?

I have a list of files populated in modal window when user click on file i have invoked downloadServerFile method that is happening on single click , How can i invoke this method on double click using AngularJs ?
main.html
<td ng-click="downloadServerFile(file.filename)" class="noBorder"><span class="glyphicon glyphicon-file"></span>{{file.filename}}
<span class="pull-right text-danger" style="padding-left: 25px" ng-if="file.mostRecent">*</span></td>
you can use ngDblclick instead of ng-click which will allows you to specify custom behavior on a dblclick event.
<td ng-dblclick="downloadServerFile(file.filename)" class="noBorder"><span class="glyphicon glyphicon-file"></span>{{file.filename}} <span class="pull-right text-danger" style="padding-left: 25px" ng-if="file.mostRecent">*</span></td>
DEMO APP
Use ng-dblclick angular directive instead of ng-click. You can check the documentation here
<td ng-dblclick="downloadServerFile(file.filename)" class="noBorder"><span class="glyphicon glyphicon-file"></span>{{file.filename}}<span class="pull-right text-danger" style="padding-left: 25px" ng-if="file.mostRecent">*</span>
you can use ng-dblclick
<element ng-dblclick="expression"></element>
<div ng-controller="SampleController">
<a ng-dblclick="showAlert()">Double Click Here </a>
</div>
app.controller('SampleController', ['$scope', function ($scope) {
$scope.showAlert = function () {
alert("This is an example of ng-dblclick");
}
}]);

Conditional ng-class on icon in table cell

I have a table and using ng-repeat to bind my cells with the data. One cell has edit, save, delete icons. If an order has been posted then the delete/ save icons should be disabled and the icons also should be a different color. I am able to disable the click event of the delete/save icons but can not figure out how to change the css class. With this code the save and delete can not be clicked. I'd like to turn them light gray or some obviously different color.
Here is the HTML:
<tbody>
<tr ng-repeat="order in vm.orders track by $index" ng-dblclick="vm.editOrder(order)" style="cursor:pointer" ng-class="{'class':order.invoiceStatus, 'disabled-order': !order.invoiceStatus}">
<td ng-bind="(order.dtInvoiced | date:'MM/dd/yyyy' )"> </td>
<td ng-bind="order.invoiceNumber"></td>
<td ng-bind="order.invoiceItems.mdbsPoNumber"></td>
<td align="center" ng-bind="order.lines"></td>
<td ng-bind="(order.total | number:2)"></td>
<td align="center" ng-bind="order.carrier"></td>
<td>
<a ng-click="vm.editOrder(order)"><i class="fa fa-pencil fa-2x"></i></a>
<a ng-click="order.disabledToggle || vm.saveOrder(order)"><i class="fa fa-check fa-2x"></i></a>
<a ng-click="order.disabledToggle || vm.removeOrder(order)"><i class="fa fa-trash fa-2x link-icon"></i></a>
</td>
</tr>
</tbody>
Here is the JS to disable the click event of save and delete icons:
function orderItems() {
var orders;
if (vm.Criteria != null) {
orderService.getOrderData(vm.Criteria)
.then(function (result) {
vm.data = result.data;
orders = vm.data;
for (var i = 0; i < vm.data.length; i++) {
orders[i].disabledToggle = false;
if (orders[i].invoiceStatus == "RCV") {
orders[i].disabledToggle = true;
}
else {
orders[i].disabledToggle = false;
}
vm.orders.push(orders[i]);
}
});
}
}
I've also tried in the icon:
<i ng-class="order.invoiceStatus = order.disabledToggle ? 'disabled-order class' : 'class' "></i>
You can use ng-class to evaluate a variable for true. If the variable is true then a class selector will be injected into the element:
<a ng-click="order.disabledToggle || vm.saveOrder(order)"><i ng-class="{ 'cssCheckDisabled': jsCheckDisabled } class="fa fa-check fa-2x"></i></a>
In this case we are evaluating jsCheckDisabled. Once it is try the cssCheckDisabled class selector is injected into the element.
Then is as easy as making a class selector in your CSS to do what you want:
cssCheckDisabled {
color: red;
}

error with an angularjs filter

Based on this jsfiddle : http://jsfiddle.net/2ZzZB/56/
i add the filter solution for my app : http://www.monde-du-rat.fr/zombieReport/popup.html#/ratousearch (ctrl : http://www.monde-du-rat.fr/zombieReport/resources/js/controllers/RatousearchCtrl.js )
//We already have a limitTo filter built-in to angular,
//let's make a startFrom filter
app.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
Look console, error is getting at the started :
TypeError: undefined is not a function
at http://www.monde-du-rat.fr/zombieReport/resources/js/baseChrome.js:368:22
at http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:180:297
at B.| (http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:169:248)
at B.constant (http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:179:161)
at B.| (http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:169:253)
at B.constant (http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:179:161)
at Object.c (http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:101:146)
at m.$digest (http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:114:386)
at m.$apply (http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:118:12)
at k (http://www.monde-du-rat.fr/zombieReport/resources/libs/angularjs/angular-1.3.0-rc.0/angular.min.js:76:374)
The line is
return input.slice(start);
what's wrong ? i didn't see error in the jsfiddle example
HTML :
<div id="results" ng-show="successLordZR">
<p class="myTitle">{{ 'TRS_CTRL3_TEXT1' | translate }} :</p>
<ul class="list-group">
<li class="list-group-item" ng-repeat="post in posts | startFrom:currentPage*pageSize | limitTo:pageSize">
<div class="myClearfix">
<p style="float: left;"><span ng-class="{'girl' : post.sex == 'F', 'boy' : post.sex == 'M'}">#</span> {{post.prefixe}} {{post.name}} ({{post.idLord}})</p>
<p style="float: right;"><i class="fa fa-link"></i> fiche</p>
</div>
</li>
</ul>
<div id="pagination">
<button type="button" class="btn btn-primary btn-xs" ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1"><i class="fa fa-arrow-circle-o-left"></i> {{ 'TRS_CTRL3_PREV' | translate }} </button>
<span> {{currentPage+1}}/{{numberOfPages()}} </span>
<button type="button" class="btn btn-primary btn-xs" ng-disabled="currentPage >= posts.length/pageSize - 1" ng-click="currentPage=currentPage+1"> {{ 'TRS_CTRL3_NEXT' | translate }} <i class="fa fa-arrow-circle-o-right"></i></button>
</div>
</div>
Data json example from laravel : http://www.monde-du-rat.fr/lordrest/public/posts_jsonforced
EDIT 2 , filter in controller:
// populate scope
$scope.posts = response;
$scope.posts = $filter('startFrom')($scope.currentPage*$scope.pageSize);
filter is here : http://www.monde-du-rat.fr/zombieReport/resources/js/filtersZR.js
Seems the posts model in scope comes from RatousearchCtrl? In that controller the scope.posts was initially set to be an empty object and never updated.
That seems to be the reason why post as in ng-repeat 'post in posts' is undefined, which is the value got passed to the startFrom filter.
Can you re-check how posts are supposed to be loaded?
Input might not exist at that exact moment, just change your code to this:
app.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return (typeof input == 'string') ? input.slice(start) : "";
}
});

Categories

Resources