primeng p-virtualScroller empty list items and scrollbar issue - primeng

I am using primeng p-virtualScroller for implementing loading data with scroller.It is working fine.But I am facing the below issue:
When the search result is less still it shows the scroller and emplty list items.
Below is the code I am using in Html:
<p-virtualScroller [(value)]="employeeList" scrollHeight="300px" [itemSize]="20" [rows]="pageSize"
[(lazy)]="lazyLoading" (onLazyLoad)="loadCarsLazy($event)" [(totalRecords)]="totalEmployees">
<ng-template let-emp pTemplate="emptymessage" *ngIf="searchResultMsg">
<span>{{searchResultMsg}}</span>
</ng-template>
<ng-template let-emp pTemplate="item" let-odd = odd *ngIf="searchResultMsg===''">
<div (click)="selectEmployee(emp)" class="pl-2 search-list" [class.odd-row]="odd">{{emp.name}} </div>
</ng-template>
</p-virtualScroller>
Below is the issue I want to explain(see the screen shot)

I got the solution to fix the above issue. I update the value of pageSize variable according to the total records available return by API(COUNT)
Code:
callAPIToSearch(searchValue, rowOffset) {
if (!this.isProcessing) {
this.isProcessing = true;
this.empService.searchEmployees(searchValue, rowOffset, this.pageSize).subscribe((apiResp: EmployeeSearchAPIResponse) => {
if (rowOffset == 0 && apiResp.response.COUNT === 0) {
this.searchResultMsg = `No record found, Please enter Relationship Manager's Surname and try again.`;
} else {
this.totalEmployees = apiResp.response.COUNT;
if (apiResp.response.COUNT <= 100) {
this.pageSize = apiResp.response.COUNT
} else{
this.pageSize =100;
}
this.employeeList = apiResp.response.employees;
}
this.isProcessing = false;
})
} }

Related

Angular 6 *ngFor display different styles for first, odd, even and last

I am learning Angular 6 and just trying to put togheter some of the stuff I have learned and I am currently running into an issue that I cannot find an answer to. I am trying to change the style of a LI using *ngFor depending if the index is First, Last, Odd or Even. So far everything works but I can't figure out how to do it for the Last because everything I add a new object to my list, it is obviously the last so it render the color for the last.
I understand how to do it but the real problem is that I am adding stuff dynamicly to my list from a form and I'm not sure how to evaluate the Last so that the others become to right color.
Keep in mind that I am still a newb and it might look messy and I also understand that some client-side validations I am doing are probably not optimal or required since HTMl5 but I made it to learn.
Here is my code for my component HTML
>
<h1>List of courses :</h1><br>
<div *ngIf="courses.length > 0; then coursesList else noCourses"></div>
<ng-template #coursesList>
<h2>List of Courses :</h2>
<ul *ngFor="let course of courses; index as i;">
<li [ngStyle]="{'background-color':getColor(i)}" style="color: white;">
<strong>Index : </strong>{{i}} <strong>ID : </strong>{{course.id}} <strong>Name</strong> : {{course.name}}
<button (click)="onRemove(i)">Remove</button>
<button (click)="onModify(i)">Modify</button>
</li>
</ul>
</ng-template>
<ng-template #noCourses>
<h5>There are no courses in this list. Use the form bellow to add some.</h5>
</ng-template>
<div (keyup.enter)="onAdd()">
<span>ID : <input type="number" (keypress)="checkNumber($event)" [(ngModel)]="fields.id" placeholder="Enter an ID"></span>
<span>Name : <input type="text" [(ngModel)]="fields.name" placeholder="Enter a NAME"></span>
<button (click)="onAdd()">Add</button>
<button (click)="onClear()">Clear</button>
</div>
<div *ngIf="isNotNumber" style="background-color: red; color:black"><strong>ID can only be numbers !</strong></div>
<div *ngIf="noValues" style="background-color: red; color:black"><strong>Please fill all fields !</strong></div>
<div *ngIf="noModifyValues" style="background-color: red; color:black"><strong>To modify enter all informations!</strong></div>
Code for .TS
>
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
noValues: boolean;
noModifyValues: boolean;
isNotNumber: boolean;
fields: Courses = {id: null, name: null};
courses: Array<Courses> = [];
viewMode: string = null;
checkNumber($event) {
if ($event.keyCode != 13) {
isFinite($event.key) ? this.isNotNumber = false : this.isNotNumber = true;
}
}
onAdd() {
if (!this.fields.id || !this.fields.name) {
this.noValues = true;
} else {
this.courses.push({id: this.fields.id, name: this.fields.name});
this.fields.id = null;
this.fields.name = null;
this.noValues = false;
}
}
onRemove(i) {
this.courses.splice(i, 1);
}
onClear() {
this.courses = [];
this.fields.id = null;
this.fields.name = null;
this.noValues = false;
}
onModify(i) {
if (!this.fields.id || !this.fields.name) {
this.noModifyValues = true;
} else {
this.courses[i].name = this.fields.name;
this.courses[i].id = this.fields.id;
this.noModifyValues = false;
}
}
getColor(i){
if (i % 2 === 0 && i != 0){i = 'odd';}
switch (i) {
case i = 0 : return 'orange';
case i = 'odd' : return 'blue';
}
return 'red';
}
}
interface Courses {
id: number;
name: string;
}
Image of the code in action for better understanding.
If you only want change the background-color you can use [style.background-color] and you can use ternary operator in the .html
<ul *ngFor="let course of courses; let index=i;
let odd=odd;
let last=last;
let first=first">
<li [style.backgound-color]="first?'orange':last?'purple':odd?'blue':'red'">
...
</li>
</ul>
Try something like this
getColor(i){
if (i % 2 === 0 && i != 0){i = 'odd';}
if (this.courses && (this.courses.length - 1 === i)) {i = 'last'}
switch (i) {
case i = 0 : return 'orange';
case i = 'odd' : return 'blue';
}
return 'red';
}
Hope it works - Happy coding !!
Thanks Rahul. The part I was missing is evaluating if there is something in courses. However, I had to had a few more lines to Odd and Last as follow :
getColor(i){
if (this.courses && i != 0 && (this.courses.length - 1 === i)) {i = 'last'}
if (i % 2 === 0 && i != 0 && i != 'last'){i = 'odd';}
switch (i) {
case i = 0 : return 'orange';
case i = 'odd' : return 'blue';
case i = 'last' : return 'purple';
}
return 'red';
}
Quick question. It seems like a whole lot of IF and && and checking specific things. Is that the way to do it properly?
You could use if else ladder instead of mixing up if else and switch and assignments like given below
getColor(i)
{
if(this.courses)
{
if(i==0)
return "orange";
else if(i==this.courses.length-1)
return "purple";
else if (i%2==0)
return "red";
else
return "blue";
}
}

How to remove duplicate value in an array Angular 2

I have checkbox (with selected value by user, checked ). So I need to edit this checkbox and get all the selected value into an array and send it to post.
Html
<div *ngFor="let item of officeLIST">
<div *ngIf ="item.officeID== userdata.officeID">
<input #office type="checkbox" id="office" name="office" class="form-control" value="{{item.officeName}}" checked (click)="officeSelection($event,$event.target.value)" > {{(item.officeName== "" ? "--No data--" : item.officeName)}}
</div>
<div *ngIf ="item.officeID!= userData.officeID">
<input #office type="checkbox" id="office" name="office" class="form-control" value="{{item.officeName}}" (click)="officeSelection($event,$event.target.value)"> {{(item.officeName== "" ? "--No data--" : item.officeName)}}
</div>
</div>
<button type="button" class="btn btn-primary"(click)="updateOffice(userData.officeID)"> Save </button>
Click function (to add selected value and to remove unselected value)
officeSelection(event: any, value) {
if (event.target.checked === true)
{
this.officeArray.push(value);
}
else {
this.officeArray.splice(this.officeArray.indexOf(value), 1);
}
}
Update Function
updateOfficeDetail(officeid) {
if(officeid= 1)
{
this.officeArray.push('stars dept');
}
else if(officeid= 2)
{
this.officeArray.push('moon dept');
}
else
{
this.officeArray.push('Sun dept');
}
}
Problem is
if I update the data without changing current value of checkbox,eg: sun dept, this sun dept will be push into officeArray .
but if again I want to update the data by editing the checkbox(choose another value), so the previous selected value and current selected value will be push into this officeArray
if user did not edit the checkbox (just proceed with current selected value)>>>> the officeArray will look like this
["sun"]
and if the user tried to update the checkbox by clicking one more checkbox, the array will look like this
["sun","moon","sun"]
I just want ["sun","moon"] in the officeArray. should i remove? or clear something?
I tried to do some research and a lot questions similar to me. but somehow all the solutions did not work for me. any idea?
Thank you
I recommend using HashMap instead of array:
Map<String,String> officeMap = new HashMap<>();
officeMap.put(index, value);
in your if expression in updateOfficeDetail method:
if(officeid === 1)
instead of
if(officeid= 1)
I recommand in your case to use Set instead of Array:
class youComponent{
//...
officeSelection(event: any, value) {
if (event.target.checked === true)
{
if(this.officeArray.includes(value.trim())){
this.officeArray.push(value);
}
}
else {
this.officeArray.splice(this.officeArray.indexOf(value), 1);
}
}
updateOfficeDetail(officeid) {
if(officeid === 1)
{
if(this.officeArray.includes('stars dept')){
this.officeArray.push('stars dept');
}
}
else if(officeid === 2)
{
if(this.officeArray.includes('moon dept')){
this.officeArray.push('moon dept');
}
}
else
{
if(this.officeArray.includes('Sun dept')){
this.officeArray.push('Sun dept');
}
}
}
}

Didn't get multiple checked checkbox on button click and on load page : ionic

On page load I checked few of check boxes . using following code
<li ng-repeat="template in alltest" >
<input type="checkbox" name="template" ng-model="template.isselected" value="{{template.id}}" id="{{template.id}}" ng-checked="isChecked(template.id)">
<label for="{{template.id}}" class="position-relative"><span></span>
</label>
</li>
isChecked function
$scope.isChecked = function(id){
var match = false;
if($scope.alltest!=null)
{
for(var i=0 ; i < $scope.alltest.length; i++) {
if($scope.alltest[i].tmp_id == id){
match = true;
}
}
}
return match;
};
When I click on button to get those checkboxes then didn't get those check boxes
angular.forEach($scope.alltest, function(template){
if (template.isselected)
{
alert(template.id)
}
})
If I again deselected those check boxes and again select then i get value..but on page load by default few of check boxes coming with true option and directly i click on submit button then didn't get those checked check box
what is wrong with this code? please help me to solve this
ng-model is defult undefined. When checkbox is checked ng-model create property. that is why you get only checked checkbox when form submitted. You need define false checkboxes also inside isChecked function
ng-checked="isChecked(template.id, $index)">
js
$scope.isChecked = function(id, index) {
var match = false;
if ($scope.alltest != null) {
for (var i = 0; i < $scope.alltest.length; i++) {
if ($scope.alltest[i].tmp_id == id) {
match = true;
}
}
}
if (!match) $scope.alltest[index].isselected = false
return match;
};

ng-class calling function on page load - AngularJS

This may be very simple but I can't seem to be able to successfully get the logic I want.
<div class="group-title" ng-class="{'group-hasError': !isValid(orderItem)}">
As you can see I'm adding a class group-hasError if the function isValid(orderItem) returns false.
Now the issue is that this is called on page load. But I don't want to call this function on page load rather when a submit button is called
<button id="add_modified_item" ng-click="isValid(orderItem)" class="btn btn-primary btn-fixed-medium pull-right">
How can I achieve this?
This is the function;
$scope.isValid = function(orderItem) {
var count = 0;
//By default make it true
var IsAllSelected = true;
angular.forEach(orderItem.menu_modifier_groups, function(group) {
var count = 0;
angular.forEach(group.menu_modifier_items, function(item) {
count += item.selected ? 1 : 0;
});
if (count == group.max_selection_points) {
IsAllSelected = true;
} else {
//if one item failed All select do return false
IsAllSelected = false;
}
});
return IsAllSelected;
}
Any advice appreciated
Defalut set
$scope.setValidClass=false;
View
<div class="group-title" ng-class="(setValidClass)? 'group-hasError':'')}">
set model with
//if IsAllSelected=false then set IsAllSelected to true
$scope.setValidClass=!IsAllSelected;
return IsAllSelected;

how to do filter using range slider in angularjs

In my application, I have used pricing slider. When I change minimum and maximum value of pricing slider, I need to filter based on the range. In angularjs, how to do this one. Can you please any one help me.
$scope.min_price = 0;
$scope.max_price = 10000;
$scope.priceFilter = function (hotel) {
console.log(hotel.AvailableRoom[0]);
if(hotel.AvailableRoom[0] !== null && hotel.AvailableRoom[0].HotelRoom.Price != null){
console.log(hotel);
return (hotel.AvailableRoom[0].HotelRoom.Price.Amount >= $scope.min_price && hotel.AvailableRoom[0].HotelRoom.Price.Amount <= $scope.max_price);
}
else if(hotel.AvailableRoom.HotelRoom[0].Price != null) {
console.log(hotel);
return (hotel.AvailableRoom.HotelRoom.Price.Amount >= $scope.min_price && hotel.AvailableRoom.HotelRoom.Price.Amount <= $scope.max_price);
}
};
and I have added filter:priceFilter in ng-repeat. It is called whenever reload page. But I want to call this one when price range is changed.
<div id="rangeslider" range-slider min="0" max="1000" model-min="min" model-max="max" ></div>
above is pricing slider.
Have you tried adding an ng-mouseup (https://docs.angularjs.org/api/ng/directive/ngMouseup) to your rangeslider div and calling your priceFilter method from there?
i have same problme.. and i finding the mouse-release event, but still not got exact.
but i solve this problem by $watch and it's just slow but working properly..
$scope.$watch( '[demo7.maxPrice, demo7.minPrice]', function() {
$scope.filterByPriceRange();
});
$scope.filterByPriceRange = function() {
$rootScope.filteredRooms = [];
angular.forEach(
$rootScope.filteredRoomsByPricingType,
function(availableRoom) {
for (i in availableRoom.roomPricings) {
if (availableRoom.roomPricings[i].price >= $rootScope.demo7.minPrice
&& availableRoom.roomPricings[i].price <= $rootScope.demo7.maxPrice
&& availableRoom.roomPricings[i].pricingType.pricingType == $rootScope.pricingType) {
$rootScope.filteredRooms
.push(availableRoom);
}
}
});
};

Resources