ag-grid onGridReady not working - javascript

I want to load ag-grid inside a button click. I have tried two approaches but none is working
My code : First Method
onBtnClick(){
this.gridOptions ={
onGridReady : function(){
console.log("print");
}
}
}
Second method:
onBtnClick(){
this.onGridReady();
}
onGridReady(){
this.gridApi = params.api;
console.log("print");
}
First method not working. Second method says api is not defined

You can have this approach.
Have a flag in your component when to display the grid.
Use this flag to conditionally display the grid using *ngIf
Set this flag value on button click
This way, the template having ag-grid won't be rendered until the flag is set. When it's set, the template will be rendered and onGridReady will be called.
<button (click)="btnClick()">Display grid</button>
<ag-grid-angular *ngIf="displayGrid"
#agGrid
......
></ag-grid-angular>
btnClick(){
this.displayGrid = true;
}
Check this working example: ag-grid display on button click

Have you checked if ag-gridis connected to onGridReady?
It should look something like that:
<ag-grid-angular
...
(gridReady)="onGridReady($event)"
>
</ag-grid-angular>

You should share more of you code, it's unclear what you are doing.
You must make sure your gridOptions are fully set up BEFORE the grid initializes. (Doing this on a button is too late)
ngOnInit(): void {
this.gridOptions.onGridReady = gridReadyHandler;
}
gridReadyHandler = (params: GridReadyEvent) => {
this.gridApi = params.api;
console.log("grid is done loading", this.gridApi);
}

Related

Two mat-paginator with single or multiple datasource is not working

I have a mat-table that might show up to 5/10/15 entries per page. At first, I had one mat-paginator at the bottom that worked fine. Now I'm being asked to set a paginator at the top and another one at the bottom of the table, so the user won't have to scroll all the way down to reach the paginator if they are looking for an entry that is at the top.
I tried to link both paginator to the same data source. But it didn't worked. So, tried to create 2 datasource, but it also has one limitation.
The only limitation is that the paginator at the bottom can't change items per page, since there isn't a method that lets me control that property.
Also, I couldn't set the page index or items per page properties directly (the table was not refreshing), so all the movements are achieved with some logic and paginator methods like previousPage() or lastPage().
Can anyone help me with this? I'm fine with the solution with either single or multiple datasource.
Working code -> STACKBLITZ
<mat-paginator #paginatorTop (page)="pageEvent = handlePageTop($event)" [length]="length" [pageSizeOptions]="[5, 10, 15]" showFirstLastButtons></mat-paginator>
<mat-paginator #paginatorBottom (page)="pageEvent = handlePageBottom($event)" [length]="length" [pageSizeOptions]="[5, 10, 15]" showFirstLastButtons></mat-paginator>
app.component.ts
ngOnInit() {
this.dataSource2.paginator = this.bottomPaginator;
this.dataSource.paginator = this.topPaginator;
this.topPaginator.length = this.dataSource.data.length;
this.bottomPaginator.length = this.dataSource2.data.length;
}
public handlePageTop(e: any) {
let {pageSize} = e;
this.bottomPaginator.pageSize = pageSize;
if(!this.topPaginator.hasNextPage()){
this.bottomPaginator.lastPage();
}else if(!this.topPaginator.hasPreviousPage()){
this.bottomPaginator.firstPage();
}else{
if(this.topPaginator.pageIndex < this.bottomPaginator.pageIndex){
this.bottomPaginator.previousPage();
} else if(this.topPaginator.pageIndex >this.bottomPaginator.pageIndex){
this.bottomPaginator.nextPage();
}
}
}
public handlePageBottom(e: any) {
if(!this.bottomPaginator.hasNextPage()){
this.topPaginator.lastPage();
}else if(!this.bottomPaginator.hasPreviousPage()){
this.topPaginator.firstPage();
}else{
if(this.bottomPaginator.pageIndex < this.topPaginator.pageIndex){
this.topPaginator.previousPage();
} else if(this.bottomPaginator.pageIndex > this.topPaginator.pageIndex){
this.topPaginator.nextPage();
}
}
}
No need to use two paginators made some changes in your code, please check it.
Here is my stackblitz code :- https://stackblitz.com/edit/multiple-paginators-svwwfj
Hope this helps!
This solution works if you want to show one paginator at a time
To solve the above problem, I created a directive scroll-to. In this directive i listened for scroll events and compared the window.pageYOffset with element's nativeElement.offsetTop
if (pageYOffset of window < element's offsetTop) im was setting the property showUpperOne true else property showLowerOne true.
import {Directive,HostListener,ElementRef} from '#angular/core'
#Directive(
{
selector:"[scrolledTo]",
exportAs:"scrolledTo"
}
)
export class ScrollDirective {
showUpperOne=true;
showLowerOne=false;
constructor(private el:ElementRef){}
#HostListener("window:scroll",['$event'])
onScroll(){
const elementPosition = this.el.nativeElement.offsetTop;
const scrollPosition = window.pageYOffset;
this.showUpperOne=scrollPosition<elementPosition
this.showLowerOne = scrollPosition>= elementPosition;
}
}
I used this directive on div which contains two paginators having the same template reference and one mat table
<div #mainDiv="scrolledTo" scrolledTo class="example-container mat-elevation-z8">
<mat-paginator *ngIf="mainDiv.showUpperOne" #paginator
[pageSize]="currentPageSize"
[pageSizeOptions]="[5, 10, 20]"
(page)="pageEvents($event)"
[showFirstLastButtons]="true">
</mat-paginator>
<mat-table #table [dataSource]="dataSource">...
</mat-table>
<mat-paginator *ngIf="mainDiv.showLowerOne" #paginator
[pageSize]="currentPageSize"
[pageSizeOptions]="[5, 10, 20]"
(page)="pageEvents($event)"
[showFirstLastButtons]="true">
</mat-paginator>
I did set the template reference variable for div #mainDiv="scrolledTo"
and accessed the properties of directive to show and hide paginators *ngIf="mainDiv.showLowerOne" , *ngIf="mainDiv.showUpperOne" respectively.
This will show or hide the paginators on scroll but there will be problem with giving the paginator functionality to other paginator once one paginator hides. It has to be set to datasource again.
In order to solve this,i added currentPageSize property and did set the default value as
10 currentPageSize=10;. In order to reassign the paginator to datasource, i listened for the page events using (page)="pageEvents($event)" in template of paginator.
and in pageEvents function
pageEvents(event){
this.currentPageSize=event.pageSize;
}
also on scroll
#HostListener("window:scroll",['$event'])
onScroll(){
setTimeout(()=> this.dataSource.paginator = this.paginator,0)
}
Stackblitz: https://stackblitz.com/edit/angular-nbtcgz

Replace class using javascript is not working in reactjs

I want to change the class of dynamic element on click function for that I tried below solutions but none of these working
handleClick=(event,headerText)=>{
document.getElementsByClassName('sk-reset-filters')[0].className = 'jjjj';
}
handleClick=(event,headerText)=>{
var reset = document.querySelectorAll('.sk-reset-filters.is-disabled')[0];
console.log(reset)
if(reset){
reset.className = 'sk-reset-filters';
console.log(reset)
}
I just want to remove the is-disabled when click. I also tried using setTimout function but doesn't work. Is there anything wrong?
When I console.log(reset) I'm getting below html.
<div class="sk-reset-filters is-disabled">
<div class="sk-reset-filters__reset">Clear all</div>
</div>
You can handle disable or show dom elements with react state in this way:
state={isDisabled:true} // set a state property
handleClick=(e)=>{
e.preventDefault
this.setState({isDisabled:false}) //change !isDisabled to false when clicked
}
render() {
{isDisabled} = this.state
let disabledMarkup = isDisabled ? <div>something</div> : null}
return (<React.Fragment>{disabledMarkup}
<button onClick={this.handleClick}></button>
</React.Fragment>)}

Primeng paginator cannot reset page 1 after call API

I have 2 functions to load data: when init page and search page.
When init page, the data display with 5 pages. I click page 3, the data show with paging is Ok. After that, enter data search. The data table is reload, but the page number does not reset to 1, it's still page 3.
in html:
<p-paginator rows="5" totalRecords="{{totalRecords}}" (onLazyLoad)="paginate($event)"
(onPageChange)="paginate($event)" [rowsPerPageOptions]="[2,5,10,20]"></p-paginator>
ts:
defaultPage:0;
defaultSize:2
paginate(event) {
let currentPage: number;
this.defaultPage = event.first / event.rows;
this.defaultSize = event.rows;
this.listData = [];
if (this.isSearch == 1) {
this.getLoadPageSearch(this.defaultSize, this.defaultPage);
} else {
this.getLoadPage(this.defaultSize, this.defaultPage);
}
}
Please adivice me how to reset the paginator after call another API
The p-paginator component contains the changePageToFirst function. To access this function, we will need to obtain a ViewChild reference to the component. For example, in our template we define the component:
<p-paginator rows="10" totalRecords="100" #p></p-paginator>
<button (click)="reset($event)">Reset</button>
And in our component, we can handle the reset event as follows:
#ViewChild('p', {static: false}) paginator: Paginator;
reset($event) {
this.paginator.changePageToFirst($event);
}
Here is a demo: https://plnkr.co/edit/FxwTHK0W2WuTCjuqhLp6?p=preview
EDIT: The above demo is no longer working on plunkr. Here is an updated version:
https://stackblitz.com/edit/angular-u9nqf5
Another useful method is changePage.
In template:
<p-paginator #pp></p-paginator>
In the component:
#ViewChild('pp') paginator: Paginator;
this.paginator.changePage(0);
For those using the dataTable primeng component and using its lazy pagination feature,
we can reset the page to '1' by using
this.tableTemplateName.first = 0;
where setting first=0 means first page

Custom filter: can I have custom buttons for filter?

I am trying to have my own custom filter on ag-grid angular.
Apart from Apply button, I also want to have other buttons for the filter. i.e. if I can explain this in some sort of UI,
|--Custom Filter-------------------.
| Filter Text: _____________ |
| Apply | Clear | Clear All|
|_______________________|
By using default filter component of ag-grid, I know that I can have two buttons I need if I provide filterParams in ColDef.
filterParams: {
applyButton: true,
clearButton: true
}
But what about the other custom (Clear All) button? Is there any way I can achieve it?
Achieved it after few hours of search and trial-error.
Have a look at the example given here: ag-Grid Angular Custom Filter Component
Have a look at the PartialMatchFilterComponent and its code.
After some code updates for template and component, we can achieve it.
Update the template:
<button (click)="apply()">Apply</button>
<button (click)="clear()">Clear</button>
<!-- any other buttons you want to keep -->
Little update in the component code: Just need to call this.params.filterChangedCallback() on Apply button click.
apply(): void {
this.params.filterChangedCallback();
}
clear(): void {
this.text = '';
this.params.filterChangedCallback();
}
onChange(newValue): void {
if (this.text !== newValue) {
this.text = newValue;
// this.params.filterChangedCallback(); - remove
}
}

How to hide row after changing status in angularjs

I'm now trying to hide clicked row after changing status in angularjs. Here is my coding and please let me know how to do it?
table.table
tr(data-ng-repeat="application in job.applications", ng-hide="application.hideApplication")
td.status
div.bold #{getMessage('Change Status:')}
div.normal
a(ng-class="app_status === 'shortlist' ? 'admin_edit_bold' : 'admin_edit_normal'", ng-click="changeApplicationStatus(application.id, 'shortlist', application)") #{getMessage('Shortlist')}
td.rating
div(ng-init='rating = application.app_rating')
.star-rating(star-rating='', rating-value='rating', data-max='5', on-rating-selected='rateFunction(application.id, rating)')
Here is controllerjs.
$scope.changeApplicationStatus = function (appId, app_status, application) {
return jobsService.changeApplicationStatus(appId, app_status).then(
function () {
application.hideApplication = false;
}
);
};
Put this attribute on whichever element you're wanting to show/hide
ng-hide="application.hideApplication"
Edit subsequent to comment:
That attribute wouldn't work on the same element as the ng-repeat, I don't think the application variable would be in scope...
Instead, you could change your repeat to:
application in job.applications | filter: { hideApplication : false }

Categories