I am following the tutorial Codepen example here to do Angularjs search on table:
https://codepen.io/sevilayha/pen/AmFLE
Let's say the tastiness numbers that I am receiving from server are like 255, 65551, 32322 , where the last two digits are supposed to be decimals.
So in order to display them in comprehensive way for user, i did on html:
{{ roll.tastiness/100 | number : 2}}
in the table:
<tr ng-repeat="roll in sushi | orderBy:sortType:sortReverse | filter:searchFish">
<td>{{ roll.name }}</td>
<td>{{ roll.fish }}</td>
<td>{{ roll.tastiness/100 | number : 2}}</td>
Note that I didn't modify the code in codepen because it's not mine, but you can try the modifications there.
and I changed the data value in controller (again, without saving the codepen) to this:
$scope.sushi = [
{ name: 'Cali Roll', fish: 'Crab', tastiness: 255 },
{ name: 'Philly', fish: 'Tuna', tastiness: 466 },
{ name: 'Tiger', fish: 'Eel', tastiness: 7 },
{ name: 'Rainbow', fish: 'Variety', tastiness: 6 }
];
The issue is, that even though the numbers are being displayed like 2.55 and 4.66, in the search i have to put 255 instead of 2.55 in order to find the record.
What should I do in order to make the search detects the values as how they're displayed on page instead of the values as presented in $scope.sushi array of objects?
That is because the filter is filtering on the actual values and the pipe is transforming those values for display only. The values the filter is working on stayed the same, without the decimal places.
You can modify the search filter or modify the values. It depends do you need to keep the same values for some other purposes. If not I would go for modifying the values and removing the pipe.
Lowest level vanilla here compatibile with all JS versions is simple for loop:
for (var i=0; i<sushi.length; i++){
sushi[i].tastiness = sushi[i].tastiness/100;
}
Execute BEFORE displaying. And remove pipe when displaying.
<td>{{ roll.tastiness/100 | number : 2}}</td>
Angular JS with use of PIpe only modifies UI display value but your JSON value is still 255 only that is why it is not searching with 2.55
I think while filter just provide same PIPE logic values so that i t can did search properly
Related
Help with filter function!
I have a table with phone number and name as columns.
The JSON object would look something like this :
Details = [
{PN : '123-456-7890',
NAME : 'PERSON A',
},{
PN: '192-453-7655',
NAME: 'PERSON B',
}
]
I need to search on keyup and filter the data. The user can search in any of these patterns:
xxxxxxxxxx,
xxx-xxx-xxxx,
xxx-xxxxxxx,
xxxxxx-xxxx.
and still needs to get the data having xxx-xxx-xxxx as phone number in the table. Search should start as soon as the keyup triggers.
I tried using match and test methods, but couldn't make connection between search input, regex and the elements from table.
Can anyone suggest how I can tackle this situation?
Please use this regex -
/^\d{3}-\d{3}-\d{4}$|^\d{3}-\d{7}$|^\d{6}-\d{4}|^\d{10}$/
Angular Code -
matchNumber(){
var str = "12311111455";
var res = str.match(/^\d{3}-\d{3}-\d{4}$|^\d{3}-\d{7}$|^\d{6}-\d{4}|^\d{10}$/);
if(res.length > 0){
console.log('Matched);
}}
Valid Numbers
1234567890
123-456-7890
123-4567890
123456-7890
Invalid Numbers
123453647564756876
111223-234234
Check DEMO -
Check Valid Numbers
i want to create football matches using this JSON:
export const teams: Array<any> = [
{
name: 'A',
teams: [
{
name: 'France',
},
{
name: 'Portugual',
},
{
name: 'india',
},
{
name: 'china',
}
]
},
]
so for example i want to make matches france vs india than france vs china .
so i am using Angular 8 , and i have some issues if anyone can help me in that code .
HTML:
<div class="col-3" *ngFor="let group of group1">
<h5>{{ group }}</h5>
</div>
TypeScript:
this.group1 = this.teams;
this.teams.forEach((item, index) => {
this.groupList.push(item.name);
item.teams.forEach((item, index) => {
this.group1.push(item.name);
});
});
What I believe you want to do is display a list of all possible matches within this JSON, and I assume that since the teams array is in it's own array of objects with a name tag, that there may be separate groups of matches that you wish to display.
I have created a Stackblitz project you can view here to see my implementation of what I believe it is you are looking for.
I will explain my code below.
HTML:
<div class="col-3" *ngFor="let group of groupList">
<h5>{{ group }}</h5>
</div>
I wasn't sure what the difference between 'group1' and 'groupList' were supposed to be in your code, so I have selected groupList as my display value, and use 'group1' as a property in the TS.
TS:
for (let teamGroup of this.group1) {
this.groupList.push("Group: " + teamGroup.name); // show the group
for (let team1 of teamGroup.teams) {
for (let team2 of teamGroup.teams) {
// iterate over every possibility of two teams facing each other
if (
this.groupList.indexOf(
String(team1.name + " vs. " + team2.name)
) === -1 &&
this.groupList.indexOf(
String(team2.name + " vs. " + team1.name)
) === -1
) {
// filter out matchups already pushed to the array
if (team1.name !== team2.name) {
// filter out self-matches
this.groupList.push(team1.name + " vs. " + team2.name);
}
}
}
}
}
In the Stackblitz implementation, I'm using 'teams' as a property of my component, assigned to the JSON you provided, but you can get this JSON dynamically and use this code, just make sure to assign the value to the 'group1' property.
The 'groupList' property is an empty array, which we will .push() the values we wish to display to. By looping over the 'teams' array within the first (and only) entry in your JSON, we can decide on a display format for the string (I have chosen 'Team1 vs. Team2') and compare all possible matchups between two teams within the group against entries in 'groupList'. If the matchup does not exist, we will push the matchup to 'groupList'.
The end result is this:
Results
I hope this was what you were looking for. I would have asked a clarifying question in the comments first, but I'm too new to the website to be able to.
I am converting a shopping basket to an immutable structure.
Is there an easy way with immutablejs to see if an immutable object already exists within an immutable list EXCEPT for one object property 'quantity' which could be different? List example:
[{
id: 1,
name: 'fish and chips',
modifiers: [
{
id: 'mod1',
name: 'Extra chips'
}
],
quantity: 2
},{
id: 2,
name: 'burger and chips',
modifiers: [
{
id: 'mod1',
name: 'No salad'
}
],
quantity: 1
}]
Now, say I had another object to put in the list. But I want to check if this exact item with modifiers exists in the list already? I could just do list.findIndex(item => item === newItem) but because of the possible different quantity property then it wont work. Is there a way to === check apart from one property? Or any way to do this without having to loop through every property (aside from quantity) to see if they are the same?
Currently, I have an awful nested loop to go through every item and check every property to see if it is the same.
Well this should work-
list.findIndex(item => item.delete("quantity").equals(newItem.delete("quantity"))
The equals method does deep value comparison. So once you delete the quantity, you are comparing all values that matter.
PS: please ignore code formatting, I am on SO app.
PPS: the above code is not optimal, you should compare a pre-trimmed newItem inside the arrow function instead of trimming it there.
I have a json file which contains different prices for a service, depending on the day of the week (in the weekend it's more expensive)
I use angular to show these prices using a lines like this:
<div ng-repeat="arr in arrangementen | filter:'_1'" >Mon-Fri: € {{arr.prijs_ma_vr | number :2 }} </div>
<div ng-repeat="arr in arrangementen | filter:'_1'" >Sat: € {{arr.prijs_za | number :2 }} </div>
json:
{
"id": "_1",
"arrangement": "Vriendinnendag",
"prijs_ma_vr": 99.95,
"prijs_za": 103.95,
"prijs_zo": 104.95,
},
{
"id": "_2",
"arrangement": "Vipdag",
"prijs_ma_vr": 199.95,
"prijs_za": 205.95,
"prijs_zo": 209.95,
}
I wonder if there is more smart and easier way to display these prices or other elements from this json. Sometimes I just want to display one element (i.e. one price)
(Example in this site: wellness example
I would rework the json and do it this way:
{
"id": "_1",
"arrangement": "Vriendinnendag",
"prijs":[ 99.95, 103.95, 104.95 ],
“day”:['Mon-Fri','Sat','Sun']
},
{
"id": "_2",
"arrangement": "Vipdag",
"prijs":[ 199.95, 203.95, 204.95 ],
“day”:['Mon-Fri','Sat','Sun']
}
<div ng-repeat="arr in arrangementen | filter:'_1'" >
day[0] € {{arr.prijs[0] | number :2 }}<br>
day[1] € {{arr.prijs[1] | number :2 }}<br>
day[2] € {{arr.prijs[2] | number :2 }}
</div>
I see you already accepted the other answer, but I wanted to give you another option, which is to create your own filter.
angular.module('demo',[])
.controller('MainCtrl', ['$scope', function($scope){
$scope.arr = [{ "id": "_1",
"arrangement": "Vriendinnendag",
"prijs_ma_vr": 99.95,
"prijs_za": 103.95,
"prijs_zo": 104.95, },
{ "id": "_2",
"arrangement": "Vipdag",
"prijs_ma_vr": 199.95,
"prijs_za": 205.95,
"prijs_zo": 209.95, }];
}])
.filter('weekdayPrice', function(){
return function(obj, id) {
var rtnval;
angular.forEach(obj, function(value){
if (value.id === id) {
return rtnval = value.prijs_ma_vr;
};
});
return rtnval;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo" ng-controller="MainCtrl">
<div>Weekday Price: {{arr | weekdayPrice: '_2' | number: 2 | currency: '€'}}</div>
</div>
So this custom filter takes an id and returns just the weekday price from the object whose id matches the id you passed into the filter. You can use it just like any other filter so you can chain them together just like the built in filters, allowing you to add additional filters such as currency or number to the value that is returned by the custom weekday filter.
The benefits are that you can reuse your custom filters throughout your application; you don't have to change your current json format; and more importantly, you don't have to figure out the array index of the item which is definitely prone to errors.
I am building a CSV file parser through node and Angular . so basically a user upload a csv file , on my server side which is node the csv file is traversed and parsed using node-csv
. This works fine and it returns me an array of object based on csv file given as input , Now on angular end I need to display two table one is csv file data itself and another is cross tabulation analysis. I am facing problem while rendering data, so for a table like
I am getting parse responce as
For cross tabulation we need data in a tabular form as
I have a object array which I need to manipulate in best possible way so as to make easily render on html page . I am not getting a way how to do calculation on data I get so as to store cross tabulation result .Any idea on how should I approach .
data json is :
[{"Sample #":"1","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"2","Gender":"Male","Handedness;":"Left-handed;"},{"Sample #":"3","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"4","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":"5","Gender":"Male","Handedness;":"Left-handed;"},{"Sample #":"6","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":"7","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"8","Gender":"Female","Handedness;":"Left-handed;"},{"Sample #":"9","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":";"}
There are many ways you can do this and since you have not been very specific on the usage, I will go with the simplest one.
Assuming you have an object structure such as this:
[
{gender: 'female', handdness: 'lefthanded', id: 1},
{gender: 'male', handdness: 'lefthanded', id: 2},
{gender: 'female', handdness: 'righthanded', id: 3},
{gender: 'female', handdness: 'lefthanded', id: 4},
{gender: 'female', handdness: 'righthanded', id: 5}
]
and in your controller you have exposed this with something like:
$scope.members = [the above array of objects];
and you want to display the total of female members of this object, you could filter this in your html
{{(members | filter:{gender:'female'}).length}}
Now, if you are going to make this a table it will obviously make some ugly and unreadable html so especially if you are going to repeat using this, it would be a good case for making a directive and repeat it anywhere, with the prerequisite of providing a scope object named tabData (or whatever you wish) in your parent scope
.directive('tabbed', function () {
return {
restrict: 'E',
template: '<table><tr><td>{{(tabData | filter:{gender:"female"}).length}}</td></tr><td>{{(tabData | filter:{handedness:"lefthanded"}).length}}</td></table>'
}
});
You would use this in your html like so:
<tabbed></tabbed>
And there are ofcourse many ways to improve this as you wish.
This is more of a general data structure/JS question than Angular related.
Functional helpers from Lo-dash come in very handy here:
_(data) // Create a chainable object from the data to execute functions with
.groupBy('Gender') // Group the data by its `Gender` attribute
// map these groups, using `mapValues` so the named `Gender` keys persist
.mapValues(function(gender) {
// Create named count objects for all handednesses
var counts = _.countBy(gender, 'Handedness');
// Calculate the total of all handednesses by summing
// all the values of this named object
counts.Total = _(counts)
.values()
.reduce(function(sum, num) { return sum + num });
// Return this named count object -- this is what each gender will map to
return counts;
}).value(); // get the value of the chain
No need to worry about for-loops or anything of the sort, and this code also works without any changes for more than two genders (even for more than two handednesses - think of the aliens and the ambidextrous). If you aren't sure exactly what's happening, it should be easy enough to pick apart the single steps and their result values of this code example.
Calculating the total row for all genders will work in a similar manner.