Kendo UI Custom "No Records" message with transalation - kendo-grid

I have a HTML Code snippets displaying a kendo grid.
<kendo-grid [data]="gridHelper.gridData"
[pageSize]="gridHelper.pageSize"
[skip]="gridHelper.skip"
[selectable]="gridHelper.selectable"
[scrollable]="gridHelper.scrollable"
[pageable]="false"
(pageChange)="gridHelper.onPageChange($event)"
(selectionChange)="gridHelper.onSelectRow($event)"
(dataStateChange)="gridHelper.onDataStateChange($event)">
<kendo-grid-messages
noRecords="{{'a.b.No_Data' | translate}}">
</kendo-grid-messages>
<kendo-grid-column title="{{'a.b.No_Data' | translate}}">
<ng-template kendoGridCellTemplate let-dataItem>
<div>{{dataItem.modified_at}}</div>
</ng-template>
</kendo-grid-column>
</kendo-grid>
Here "NoRecords" coming from json file and printing exactly. But my issue is when I change my language from dropdown,
the below kendo grid column "title" is getting changed but this noRecords remain same. How can I achive to transalate?

Kendo Grid has a template when there are no data.
Try following:
<ng-template kendoGridNoRecordsTemplate>
<span>{{'a.b.No_Data' | translate}}</span>
</ng-template>

Related

Dispatch a change event to a Mat Checkbox based on ID

<div *ngFor="let cus of deselectedList | keyvalue"
(click)="clickCheckBox('customer_'+cus.key+'_checkbox')">
{{cus.key}}
<mat-checkbox id="customer_{{cus.key}}_checkbox"
(change)="deselectCheck($event.checked, cus.key, cus.value)">
</mat-checkbox>
</div>
deselectedList is a map. As I have a map and am iterating through it there is no way to use [checked]. I would like to send a (change) event to the mat-checkbox based on the elements ID.
I also worry a change event will not change the visual on the checkbox itself. I was trying something like this with no success:
let box = <HTMLInputElement>document.getElementById(customer);
box.dispatchEvent(new Event("change"));
Is it possible to update the box enabled/disabled status and trigger the (change) event?
Got it:
<div id="customer_{{cus}}"
*ngFor="let cus of deselectedList | keyvalue"
(click)="checkbox.toggle(); deselectCheck(checkbox.checked, cus.key, cus.value)">
{{cus.key}}
<mat-checkbox id="customer_{{cus.key}}_checkbox" class="cus-check float-checkbox-right"
#checkbox>
</mat-checkbox>
</div>
And also add "pointer-events:none" to the css of the check box -> cus-check

Angular 10 - Prevent carriage returns from adding spaces at beginning and end of text literal rendered into HTML

I'm writing an application where spacing is critical in the output of some of the text I'm rendering. Users are allowed to highlight text with their mouse, then click a button to "mark" the text. I then later re-render the output with text highlighted that has been marked. I recently noticed an off-by-one issue when doing this though and, when looking at the rendered HTML I could see the problem.
This code
<mat-card (mouseup)="mouseUp()" #card>{{article.text}}</mat-card>
Produces this result in the HTML
Whereas this code
<mat-card (mouseup)="mouseUp()" #card>
{{article.text}}
</mat-card>
Produces this result in the HTML
There's a space at the beginning and the end of the text literal in the version with the carriage return in it but I have a couple of issues when trying to remove the carriage return. Firstly, the part of the code where I display the text again with the highlighting shown is much more complex, making it so I can't simply change the carriage returns around. It looks like this.
<mat-card class="te-card">
<ng-container *ngFor="let textGroup of article.textSets; index as i; first as isFirst; last as isLast" >
<ng-container *ngIf="isFirst || article.textSets[i].rangeStart > article.textSets[i - 1].rangeEnd">
{{article.text.substring(i === 0 ? 0 : article.textSets[i - 1].rangeEnd, article.textSets[i].rangeStart)}}
<div class="grouped-text-tab">
<span [ngClass]="{ 'contributed': markExistsForUserAndType(article.textSets[i].textSetId, 'one')}">1 ({{(article.textSets[i].markMetrics || {"oneCount": 0}).oneCount}})</span> |
<span [ngClass]="{ 'contributed': markExistsForUserAndType(article.textSets[i].textSetId, 'two')}">2 ({{(article.textSets[i].markMetrics || {"twoCount": 0}).twoCount}})</span> |
<span [ngClass]="{ 'contributed': markExistsForUserAndType(article.textSets[i].textSetId, 'three')}">3 ({{(article.textSets[i].markMetrics || {"threeCount": 0}).threeCount}})</span>
</div>
<span class="claim grouped-text" [matMenuTriggerFor]="contribute" [matMenuTriggerData]="{textSetId: article.textSets[i].textSetId}" (click)="setActiveGroupIndex(i)">
{{article.text.substring(article.textSets[i].rangeStart, article.textSets[i].rangeEnd)}}
</span>
<ng-container *ngIf="isLast">
{{article.text.substring(article.textSets[i].rangeEnd, article.text.length)}}
</ng-container>
</ng-container>
</ng-container>
</mat-card>
In order to format my code to remove carriage returns I would have to add unwanted spacing at the beginning or end, I'd have to turn this well-structured code into something less readable like what you see below. Note that the grouped-text-tab div has been moved up to be at the end of the previous line. (FYI: everything in grouped-text-tab doesn't contain content sensitive to this issue because I won't be highlighting any of that text and have thus left the carriage returns inside that div intact):
<mat-card class="te-card">
<ng-container *ngFor="let textGroup of article.textSets; index as i; first as isFirst; last as isLast" >
<ng-container *ngIf="isFirst || article.textSets[i].rangeStart > article.textSets[i - 1].rangeEnd">{{article.text.substring(i === 0 ? 0 : article.textSets[i - 1].rangeEnd, article.textSets[i].rangeStart)}}<div class="grouped-text-tab">
<span [ngClass]="{ 'contributed': markExistsForUserAndType(article.textSets[i].textSetId, 'one')}">1 ({{(article.textSets[i].markMetrics || {"oneCount": 0}).oneCount}})</span> |
<span [ngClass]="{ 'contributed': markExistsForUserAndType(article.textSets[i].textSetId, 'two')}">2 ({{(article.textSets[i].markMetrics || {"twoCount": 0}).twoCount}})</span> |
<span [ngClass]="{ 'contributed': markExistsForUserAndType(article.textSets[i].textSetId, 'three')}">3 ({{(article.textSets[i].markMetrics || {"threeCount": 0}).threeCount}})</span>
</div>
<span class="claim grouped-text" [matMenuTriggerFor]="contribute" [matMenuTriggerData]="{textSetId: article.textSets[i].textSetId}" (click)="setActiveGroupIndex(i)">{{article.text.substring(article.textSets[i].rangeStart, article.textSets[i].rangeEnd)}}</span>
<ng-container *ngIf="isLast">{{article.text.substring(article.textSets[i].rangeEnd, article.text.length)}}</ng-container>
</ng-container>
</ng-container>
</mat-card>
But that's not even the biggest problem I see because if someone just tells their code editor to auto format the code, the functionality will actually break. I see this as the biggest issue really. Functionality actually dependent on code layout.
So, I'd like to find a cleaner way to do this. The reason I'm tagging Angular in the title and keywords is because, although this is an HTML issue, if I didn't have Angular involved in the mix <pre></pre> would possibly be an OK solution. However, with the complexity of my second example and with Angular in the mix, I can't really use that as an option.
I've also tried using the following CSS directives on the mat-card element to no avail.
whitespace: pre;
whitespace: pre-wrap;
whitespace: pre-line;
Faced a similar problem on Angular 9. As a result, I was able to decide as follows:
<mat-card (mouseup)="mouseUp()" #card [innerHTML]="article.text">
</mat-card>

Ngx-datatable wrongly in (component) HTML how do I sort table by column name with a dropdown box (Angular 7)

I am needing to have a dropdown box that sits above a Ngx-datatable and that dropdown box needs to sort the Ngx-datatable by the values in the dropdown box. I am still new to Angular, so as I discovered that it is wrong to have the ngx-datatable in the component.html. How might I bootleg the datatable so that I can sort the rows by the values in the dropdown box?
Thinking that the method in the component.ts was linked to the datatable I was going to call that method in the dropdown box to sort it. It is completely separate!
component.html
<ngx-datatable class="expandable"
[rows]="rows"
[columns]="columns"
[headerHeight]="40"
[rowHeight]="'auto'"
[columnMode]="'force'" [limit]="20" [footerHeight]="50">
<ngx-datatable-column name="Header">
<ng-template let-value="value" let-row="row" ngx-datatable-cell-template>
<span class="custom-cell"><a (click)="method(content, id, false)">{{value}}</a></span>
</ng-template>
</ngx-datatable-column>
My dropdown box
<div ngbDropdown class="filter-dropdown-wrapper">
<button class="btn btn-light filter-button" id="input1" ngbDropdownToggle>Select an option</button>
<div ngbDropdownMenu aria-labelledby="inputmethod">
<!--<select (change)="getColumnNames($event.target.value)">
<option *ngFor="let element of rows" value="{{element.header}}"></option>
</select>-->
component.ts
columns = [
{ prop: 'header', name: 'Header' },
{ prop: 'notrelavant', name: 'Not Relevant' }, ];
What I need is: On click of the header value in dropdown box sort the datatable.
I have came up with a solution for yours. It is actually not very difficult if we break down the steps:
1) On the ngbDropdown, we populate the menu items with the columns of the datatable. we attach a click event binding on each individual menu items, and we bind them to the sort() method, which takes in the column property (column.prop) as a parameter.
<div ngbDropdown class="d-inline-block">
<button class="btn btn-light filter-button" id="input1" ngbDropdownToggle>Select an option</button>
<div ngbDropdownMenu aria-labelledby="inputmethod">
<button ngbDropdownItem *ngFor="let column of columns" (click)="sort(column.prop)">
{{ column.prop }}
</button>
</div>
</div>
2) Now, on our component.ts, we define our sort() method. rows represent the data in the datatable. We use localeCompare
to sort it in alphanumerical order. We create a shallow copy of rows to explicitly trigger change detection within the datatable to update the order of the data.
sort(prop) {
this.rows.sort((a, b) => a[prop].localeCompare(b[prop], 'en', { numeric: true }));
this.rows = [...this.rows];
}
I have created a working demo over here. Hope it helps in my explanation!

Need to show the ng-option in two lines angular 6

I need to show data in select with two lines each. I am using ng-select.
<ng-select [(ngModel)]="selectedData" placeholder="Select Data">
<div *ngFor="let data of Data">
<ng-option [value]="data.id">
{{data.name}} - {{data.price | currency}}
{{data.description}} - {{data.code}}
</ng-option>
</div>
</ng-select>
I am using ng-select and trying to show the data in ng-option, it is showing the data in one line. already tried br and /n.
Thanks in advance.
No, you can't!
None browser will allow doing this formatting of text.
But yes you can use some another alternate for show text if needed may be using title which will show data as a tooltip.
This is not supported.
Try this instead,
Data.forEach(element => {
dropDownDataSource.push(id: element.name, value: element.name)
dropDownDataSource.push(id: element.description, value: element.description)
});
<ng-select [(ngModel)]="selectedData" placeholder="Select Data">
<option *ngFor="let data of dropDownDataSource" value="{{data.value}}">
{{data.id}}
</option>
</ng-select>

Angular4+ show/hide child element in HTML template

I am trying to implement a simple "hover on a comment to show a reply button" implementation in my angular application. Is there a way to achieve this effect by using template reference variables only?
Something along the lines of...
<mat-list>
<mat-list-item *ngFor="let comment of comments" #SomeRefToThisParticularElement (mouseenter)="SomeRefToThisParticularElement=true" (mouseleave)="SomeRefToThisParticularElement=false">
<h4>{{comment.text}}</h4>
<p> 3 replies </p>
<mat-icon *ngIf="SomeRefToThisParticularElement==true">reply</mat-icon>
</mat-list-item>
</mat-list>
Obviously, the above doesn't work cause angular won't let you assign or set template variables the way I have shown in the snippet above. But I would like to explore options to achieve this at the html template level.
Is this a good approach to do this?
Edit
Click here for a summary of possible solutions.
try this, Hide and show based on the hover index of an array.
<mat-list>
<mat-list-item *ngFor="let comment of comments; let i = index" (mouseenter)="commentIndex= i" (mouseleave)="commentIndex = -1">
<h4 mat-line>{{comment.text}}</h4>
<p mat-line style="font-size:x-small; color:rgba(0, 0, 0, 0.54)"> 3 replies </p>
<mat-icon *ngIf="commentIndex == i">reply</mat-icon>
</mat-list-item>
</mat-list>
Use a dynamic object to do this, like comment.isVisible. Now the isVisible object is dynamically created and it will be modify the value while hover in/out.
Please try this way
<mat-list>
<mat-list-item *ngFor="let comment of comments" (mouseenter)="comment.isVisible = true" (mouseleave)="comment.isVisible= false" >
<h4 mat-line >{{comment.text}}</h4>
<p mat-line style="font-size:x-small; color:rgba(0, 0, 0, 0.54)"> 3 replies </p>
<mat-icon *ngIf="comment.isVisible">reply</mat-icon>
</mat-list-item>
</mat-list>
Simplest Solution (Credit: Rahul Sharma) - use index of the element and set that as the value of a dynamic variable that is used within an *ngIf statement for show/hide behavior of an element.
Next Best Solution (Credit: Ramesh Rajendran) - Add a dynamic property to the iterable object. This assumes that the iterable object is not immutable.
Thanks to the respective contributors. Hope this helps someone in the future.
you can use css:
mat-icon{
color: transparent;
}
mat-icon:hover, mat-icon:active{
color:black;
}