Programmatically updating value of a property of PrimeNg component - primeng

I am making use of p-tableHeaderCheckboxavailable in p-table PrimeNG component.
https://www.primefaces.org/primeng-v7-lts/#/table
As per the example over there:-
<p-table [(selection)]="selectedCars">
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr>
<td>
<p-tableCheckbox [value]="rowData"></p-tableCheckbox>
</td>
</tr>
</ng-template>
If I click on the above check box, the `selectedCars` property automatically gets updated and that's great.
The ISSUE
But the thing is I have also added pagination and when making API call, what I do is add the next 10 records and add them in the selectedCars using the below code
ApiCall(){
this.selectedCars.push(...this.gridData); //selectedGridRows
}
This makes the first 10 and now the latest table rows checkbox checked.
BUT p-tableHeaderCheckbox loses it's Check, I figure it will be checked on if table rows are 10 at a time i.e. selectedCars.length == 10
So What I tried is this way:-
Angular - how to get properties?
<p-tableHeaderCheckbox #headerReference>
and then doing this in the .ts
this.headerReference.checked = true; //(A)
Looking through the source code (it has checked property):-
https://github.com/primefaces/primeng/blob/22a7e2699170ab168be12852cd1178f0aa0a3663/src/app/components/table/table.ts#L4051
But unfortunately it doesn't update(as via the (A) statement above) the header checkbox's value if I do it in the same call as the api(when selectedCarsmodel property is getting updated) .
Though it does work if I have a different event which doesn't involve selectedCars
or like adding a time out function then also it works.
I even tried out life cycle hook methods like ngAfterViewChecked() still didn't update.

Related

Angular 12: Cannot find a differ supporting object '[object Object]' of type 'object'

Hopefully someone out there can assist me in this issue.
I have a component in Angular that I am trying have send a list of objects to a modal component to display in a table but I keep getting the error listed in the title. Console logging the data it shows that it is receiving it in an Array but it still won't go.
First this is how I am getting the data from the service:
Plan Service
return this.http.get<BasePartFormatted[]>(
`$apiurl`
);
}
Then in the ngOnInit this is how I am setting the parts list for the table bind:
Part List Component TS
partList$: Observable<BasePartFormatted[]>;
selectedParts: BasePartFormatted[] | null; <-- for primeng selection bind
ngOnInit: void {
this.partList$ = this.planService.getParts(this.flowID);
}
To render the list in the table I use the async pipe. Also I use primeng for the framework and pipe the selected items in the list for the component modal. The selected items get dropped into a n array based on the primeng documentation.
Part List HTML
<p-table
#partsList
[value]="partList$ | async"
[(selection)]="selectedParts"
>
<ng-template #modal_content_go let-modal>
<modal-form
[selectedParts]="selectedParts"
></modal-form>
</ng-template>
In the modal component I try to bring it in as an #Input:
Modal Component TS
#Input() selectedParts: BasePartFormatted[];
And try to render in the modal html:
Modal HTML
<p-table
#selectedParts
[value]="selectedParts"
>
...
<ng-template pTemplate="body" let-part>
<td>{{ part.item1}}</td>
<td>{{ part.item2}}</td>
<td>{{ part.item3}}</td>
<td>{{ part.item4}}</td>
</ng-template>
To check what the selectedParts actually were, I created a button on the Modal html to console.log the output and it says that it is an array for two objects:
Console.log showing an array of two objects
I've tried turning the list into another observable since it worked on the initial one but then I get an async pipe issue for some reason.
Been struggling with this one for a minute and would like suggestions on how to solve this issue.
Any help or ideas is appreciated.
Issue
According to What does Angular 2 hashtags in template mean?
Templates render HTML. In a template you can use data, property binding and event binding. This is accomplished with the following syntax:
# - variable declaration
This selectedParts variable is conflicted for the HTML and component.
Modal HTML
<p-table
#selectedParts
[value]="selectedParts"
>
...
</p-table>
Modal Component
#Input() selectedParts: BasePartFormatted[];
Solution
Remove #selectedParts from HTML or rename it so that it is not conflicted with selectedParts #Input property.
<p-table
[value]="selectedParts"
>
...
</p-table>
Sample Solution on StackBlitz

angularjs bind function call to span without triggering event

I use ng-repeat to populate my table. One of the columns in the table should be dynamically populated again by a different function call.
Below is my code snippet.
<tr ng-repeat="item in ctrl.items">
<td><span ng-bind="item.name"></span></td>
<td><span ng-bind="getItemDetails(item.id)"></span></td>
</tr>
I have array of items. I need to display those items in a table. Item name will be present in the item object, however, item details will be populated by another function call which needs item id.
On using ng-bind (like in the code above) I face 2 issues.
Multiple calls to function even if array has 1 items. Sometimes it goes on thereby freezing my browser and server out of memory issue
The item id doesn't get passed to function always. Sometimes it is undefined.
I am not sure if ng-bind is the right directive to be used. ng-model doesn't work though. Is there any other directive or other way to do it?
How can I achieve this?
EDIT:
Here is the jsfiddle url: https://jsfiddle.net/grubxaur/
If you check browser console, you can see the function is called twice. I guess it is called N no. of times where N is no. of columns in the table.
I have tweaked my implementation a bit to get rid of this issue. Rather than calling a function within ng-repeat, I modified the items array within the controller using angular.forEach before ng-repeat is invoked.
Something like code below.
angular.forEach(self.items, function(item){
item.details = $scope.getItemDetails(item.id);
});

Unable to click this ExtJS button using Selenium WebDriver

<td id="ext-gen383" class="x-toolbar-cell">
<table id="ext-comp-1144" class="x-btn x-btn-icon" cellspacing="0">
<tbody class="x-btn-small x-btn-icon-small-left">
<tr>
<tr>
<td class="x-btn-ml">
<td class="x-btn-mc">
<em class=" x-unselectable" unselectable="on">
**<button id="ext-gen384" class="x-btn-text x-tbar-page-last" type="button">** </button>
</em>
I tried to click the button. Please see the html above. Tried so many ways.
eg:
//*[contains(#class,'x-btn-text x-tbar-page-last')] or
//button[contains(#class,'x-btn-text x-tbar-page-last')]
But still not working.
I'm guessing that only the number at the end is generated. Try:
By.cssSelector("em.x-unselectable > button[id^='ext-gen']")
Also, looking at that <em>, are you sure that that class isn't making the button NOT clickable? By the name, it looks like it disables clicks.
Its hard to tell without seeing the full html of the page. Since ExtJS generates random ids, there really are not any good properties to use for finding the element.
I would recommend just using an XPath, and then use an index (if your page has multiple button elements):
//button[1]
And adjust the index accordingly until you get the correct button to click.
Likewise, you could use the WebDriver API for driver.findElements, which will return a collection of all matching items, and then you could apply the index to that collection to get the correct button.

Angular JS Skip OrderBy Value

I have the following code
<tr>
<th ng-click="predicate='-name'; reverse=false;">Name</th>
<th ng-click="predicate='age'; reverse=true;">Age<th>
<tr>
<tr ng-repeat="user in users | orderBy:predicate:reverse">
<td>{{user.name}}<td>
<td>{{user.age}}</td>
</tr>
My aim here is whenever i click on the table header, then the corresponding column has to be sorted based on particular predicate and reverse. And that is happening perfectly. But I have a scenario where, when i click on an external object, then my age value in table changes here and hence as a result the table sort order is getting disturbed. But i don't want sort to get disturbed. How can i skip table to not obey sort on other actions and have it only on click of table column headers? Can anyone help me with this?
I don't think this is possible. Whenever "users" changes, Angular will notice (since that scope property (i.e., "users") is bound (one-way data binding) to the ng-repeat directive), and Angular will update the view.

How to update properties of an array of beans while iterating in jspx

The model returns a list of beans which are displayed in a table using <c:forEach tag>. Some properties are of type input, so the user can edit these inline (optional).
The question is how to set a corresponding beanObject[by row index] when user clicks on checkbox? If clicked, then the appropriate bean needs to be updated via AJAX, I think.
So, how can we do that?
Normal Master-Detail approach has way too many clicks, that is why I need "update-able" tables.
Controller:
return new ModelAndView("daily","daily", dailyListOfBeansRecords;
Jspx:
form submit...
...
<c:forEach var="week" items="${Daily}" varStatus="loopIteratorValue">
<tr class="${loopIteratorValue.index % 2 == 0 ? 'd4' : 'd3'}">
<td><checkbox id="present" onchange="ProcessedUpdated(this,${loopIteratorValue.index})" value="${week.processed}"/></td>
</tr>
</c:forEach>
It seems to me you totally misunderstand jsp. jsp(x) is executed on the server side. you need javascript to do client-side processing.

Resources