Angular 7 hide particular attribute inside ngFor loop - javascript

I'm using a ngFor loop angular 7 I need to a hidden particular attribute(example userNo and UserType ) inside a ngFor loop.
emailId: "afsageg#dgvsf"
groupName: "dfsfgfdg"
mobileNo: "+91fyrtyrtyty"
userId: "ttrur"
userName: "srurttuidharan"
userNo: 2
userType: "rrhjty"
userTypeDisplay: "Operator Maker"
<tr *ngFor="let key of formData | keyvalue" >
<td [hidden]="key.userNo">{{key.key | titlecase}}</td>
<td>{{key.value}}</td>
</tr>

<td [hidden]="key.key==='userNo'">{{key.key | titlecase}}</td>
<td [hidden]="key.key==='userNo'">{{key.value}}</td> <!--if you also want to hide the value -->
Or you can use *ngIf instead of [hidden]
I would also suggest to rename your key to object (or something less generic even) as each iteration of the *ngFor holds an object and not just the key (hence why you can access key AND value)
So something like:
<tr *ngFor="let obj of formData | keyvalue" >
<td [hidden]="obj.key==='userNo'">{{obj.key | titlecase}}</td>
<td [hidden]="obj.key==='userNo'">{{obj.value}}</td>
</tr>
Small Stackblitz to illustrate

emailId: "afsageg#dgvsf"
groupName: "dfsfgfdg"
mobileNo: "+91fyrtyrtyty"
userId: "ttrur"
userName: "srurttuidharan"
userNo: 2
userType: "rrhjty"
userTypeDisplay: "Operator Maker"
<tr *ngFor="let key of formData | keyvalue" >
<td [hidden]="key.userNo === true">{{key.key | titlecase}}</td>
<td>{{key.value}}</td>
</tr>

If you want hide an attribute you can do some like
<td [attrib]="key.userNo?'value':null">
If you want not show a text, you can do
<td>{{key.userNo?'':key.key | titlecase}}</td>
Others is use style.display
<td [style.display]="key.userNo?'none':null">
of *ngIf
<td *ngIf="!key.userNo">

Related

Apply additional filter only to one element of ng-repeat

I am working on an existing AngularJS project. I have an object with key, values which displayed on the page.
All keys should be with a capitalized first letter, so I apply a filter. But if the key == 'sku' then I need to make all letters to be capital.
Could you advise how can I do that?
Thank you
HTML
<tr
class="product-characteristics"
ng-repeat="(prop, val) in $ctrl.product.additional_properties"
>
<td class="name">
{{prop | capitalize}}
</td>
<td>
<a ng-click="$ctrl.propertyClicked(prop, val)">{{val| titleCase}}</a>
</td>
</tr>
The easiest way would be to create separate condition for this case.
<td class="name" ng-if="prop === 'sku'">
{{ prop | uppercase }}
</td>
<td class="name" ng-if="prop !== 'sku'">
{{ prop | capitalize }}
</td>
But in the future you may want to extend this solution, therefore better soultion (and much more readable) would be to use switch-case option.
<td class="name" ng-switch="prop">
<span ng-switch-when="sku">{{ prop | uppercase }}</span>
<span ng-switch-default>{{ prop | capitalize }}</span>
</td>

Loop for object n HTML

My code is quite simple. I only want to add John and Marie to my table.
Works great but my issue is if there is no John and Marie I want to create a row and show a - in my td.
How do I know if there was not added any row when the ng-repeat ends?
<tr class="text-center" ng-if="name == 'John' || name == 'Marie'" ng-repeat="name in vm.names track by $index">
<td>{{name}}</td>
</tr>
Use the ng-switch directive:
<tr class="text-center" ng-switch"name" ng-repeat="name in vm.names track by $index">
<td ng-switch-when="John">{{name}}</td>
<td ng-switch-when="Marie">{{name}}</td>
<td ng-switch-when="Paul">{{name}}</td>
<td ng-switch-default>-</td>
</tr>
You could map your original object in the controller with something like this:
this.names = this.names.map(name => {
name ? name : '-';
})

Pass a filter with a form in AngularJS?

I'm trying to teach myself AngularJS, and I've been staring at this piece of code for so long, my eyes are starting to cross.
I have a JSON file of cats containing the properties name, sex, color, pattern, and picture for each cat object. (sex in this case is a Boolean; 0 for female and 1 for male. This will come back up soon.)
I use the following code to loop through the JSON file and print out a table of all cat objects, and it works correctly (and even pretties up the formatting a bit):
<table>
<tr>
<th>Name</th>
<th>Sex</th>
<th>Color</th>
<th>Pattern</th>
<th>Picture</th>
</tr>
<tr ng-repeat="kitty in cats">
<td>{{kitty.name|capitalize}}</td>
<td ng-if="kitty.sex == 0">Female</td>
<td ng-if="kitty.sex == 1">Male</td>
<td>{{kitty.color|capitalize}}</td>
<td>{{kitty.pattern|capitalize}}</td>
<td ng-if="kitty.picture"><img ng-src="{{kitty.picture}}" alt="{{kitty.name|capitalize}}"></td>
<td ng-if="!kitty.picture">NO IMAGE</td>
</tr>
</table>
What I would like now is to allow a user to click a checkbox, e.g. "Male", and have the view change to display all cat objects where sex is 1. I can achieve this by replacing:
<tr ng-repeat="kitty in cats">
...with...
<tr ng-repeat="kitty in cats | filter:{'sex': 1}">
...but for obvious reasons, I would much prefer to have this functionality available dynamically, rather than hard-coded.
I've tried various ng-models as well as names, ids, and values on a given checkbox, but I have yet to figure out the correct syntax with which to pass the argument 1 to the repeat function, to have it filter the cats as necessary.
Does anyone have any ideas on how these two should be bound?
you probably want this:
HTML
<table>
<tr>
<th>Name</th>
<th>Sex</th>
<th>Color</th>
<th>Pattern</th>
<th>Picture</th>
</tr>
<tr ng-repeat="kitty in cats | filter : {sex: genderFilter}">
<td>{{ kitty.name }}</td>
<td>{{ kitty.sex ? 'Male' : 'Female' }}</td>
<td>{{ kitty.color }}</td>
<td>{{ kitty.pattern }}</td>
<td ng-if="kitty.picture">
<img ng-src="{{kitty.picture}}" alt="{{kitty.name|capitalize}}">
</td>
<td ng-if="!kitty.picture">NO IMAGE</td>
</tr>
</table>
<label>
<input type="checkbox"
ng-true-value="1"
ng-false-value
ng-model="genderFilter">Male
</label><br>
<label>
<input type="checkbox"
ng-true-value="0"
ng-false-value
ng-model="genderFilter">Female
</label>
PLUNKER: http://plnkr.co/edit/av2cyzJmwxJLkqhSFnOv?p=preview
You can send filter value dynamically based on selected checkbox value.
<table ng-repeat="cat in cats | filter : { sex: selectedGender }" style="width:300px">
verify this sample http://fiddle.jshell.net/w9darn8a/2/

AngularJS on ng-dblclick change input[text]

I have a table that is populated with ngRepeat and I have a input[text] where you can filter the table.
This works fine but now I came up with the idea to have the possibility to double-click on an element in the table and add the text to the search input[text] so the filter is applied straight when you double-click on the text.
Unfortunately it does not work as expected.
I have done this:
<input type="text" placeholder="Search..." data-ng-model="userinput" />
<p data-ng-dblclick="userinput='query'">Double click to use query to search</p>
And in the ngRepeat I use the ng-model "userinput" to filter but the value of the text input is not changing.
I also tried to specify the model "userinput" as variable in the controller and then change it per function but it is not working.
Is there something I'm missing?
Normally I would change the variable in the controller and it should automatically change the text input since it uses this variable as model. Then with this it should change the filter too but nothing happens.
WORKING
Code ngRepeat
<tr data-ng-repeat="dat in data | filter: userInput | filter: tsSelect | filter: advSelect | filter: checkedFilter | orderBy: ['client', 'ssrstatus'] | limitTo: totalDisplay" id="{{ dat.bannerid }}"> <!-- | unique: 'bannerid' | filter: errorSelect| -->
<td>
<input type="checkbox" id="checked" data-ng-model="dat.checked" data-ng-change="updateCheckedStatus(dat._id['$id'], dat.checked)">
<label for="checked">Checked</label>
</td>
<td data-ng-dblclick="search(dat.clientid)">{{ dat.clientid }}</td>
<td data-ng-dblclick="search(dat.client)" class="txtleft">{{ dat.client }}</td>
<td data-ng-dblclick="search(dat.tsengineer)">{{ dat.tsengineer }}</td>
<td data-ng-dblclick="search(dat.bannerid)">{{ dat.bannerid }}</td>
<td data-ng-dblclick="search(dat.bannertype)" class="txtleft">{{ dat.bannertype }}</td>
<td data-ng-dblclick="search(dat.width + 'x' + dat.height)">{{ dat.width == 0 ? 0 : dat.width - 50 }}x{{ dat.height == 0 ? 0 : dat.height - 50 }}</td>
<td data-ng-dblclick="search(dat.ssrstatus)" class="txtleft">{{ dat.ssrstatus }}</td>
<td data-ng-dblclick="search(dat.datebegin)">{{ dat.datebegin }}</td>
<td data-ng-dblclick="search(dat.dateupdated)">{{ dat.dateupdated }}</td>
<td>
<button class="preview {{ dat.bannerid }}" data-ng-click="showPreview(dat.bannerid, dat.clicktotestbanner, dat.width, dat.height)"></button>
</td>
<!-- <td id="{{ dat.bannerid }}" class="banner-preview"></td> -->
Controller
$scope.userInput = "";
$scope.search = function(query){
$scope.userInput = query;
}
I think it's because of your userinput='query' evaluated inside ng-repeat.
Let's name your outer scope "scopeA". The ng-model="userinput" of the search input would be referencing scopeA.userinput.
As we know, a new scope is created for every ng-repeat items. If you run userinput='query' in one of these scopes (name it scopeB), you would be assigning 'query' to scopeB.userinput instead of scopeA.userinput.
In this situation, scopeB is likely to be a child of scopeA. If you use angular-batarang Chrome extension to have a look at the scope tree, you would find both scopes to have userinput field.
One solution would be to use a function to assigning value to userinput instead of ng-dblclick expression. Like:
<p data-ng-dblclick="setUserinput('query')">Double click to use query to search</p>
And add a function setUserinput to your scope:
$scope.setUserinput = function(newValue) {
$scope.userinput = newValue;
}

How Do I Render Table With Meteor Spacebars Template and Row Number For Each Row?

How can I render a table with a meteor spacebars {{#each}} in a template and for each row add row number in first column like below:
| | title header | content header |
| 1 | first title | first content |
| 2 | second title | second content |
| 3 | third title | third content |
This is my each code now:
<table class="table table-bordered table-hover">
<thead>
<tr>
<th></th>
<th>title</th>
<th>content</th>
</tr>
</thead>
<tbody>
{{#each posts}}
<tr>
<td>
*** need index for each row in this column ***
</td>
<td>
{{ title }}
</td>
<td>
{{ content }}
</td>
</tr>
{{/each}}
</tbody>
</table>
Is there a way to get the array index within the {{#each}} or define extra property named index myself and index++ in each iteration?
In your helper that returns the cursor of values, instead of just doing a collection.find() do a collection.find().fetch() This will give you you an array of objects instead of a cursor. Then simply .forEach() through that an add an index key! Or you could just use collection.map() and add the key directly to each element as you map the cursor into an array. Docs

Categories

Resources