Angular9 Multiple Checkbox Delete - asp.net

I Use Table with selection On Angular Material For Multiple Delete I'm Newbie On angular
Now My Project Use .net C# Angular And Basic CRUD
I Want Return Object or Array For Use on My Controller But On my Code It Return "0"
This My Code
Html
<button (click)="DeleteData()" value="Delete">DELETE</button>
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="select">
<th style="width: 100px;" mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()"></mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)" [aria-label]="checkboxLabel(row)"></mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="Name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element">{{element.Name}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"(click)="selection.toggle(row)"></tr>
</table>
</div>
Component
refreshList() {
this.service.getdetail()
.subscribe(data => {
this.dataSource = new MatTableDataSource(data);
})
}
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = !!this.dataSource && this.dataSource.data.length;
return numSelected === numRows;
}
masterToggle() {
this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach(r => this.selection.select(r));
}
checkboxLabel(row: detail): string {
if (!row) {
return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
}
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.Id + 1}`;
}
DeleteData() {
const numSelected = this.selection.selected;
this.service.deleteData(numSelected).subscribe(result => {
alert(result);
this.refreshList();
})
}
Services
deleteData(num: detail[]): Observable< string > {
return this.http.post< string>(this.rootURL + '/WebAPI/DeleteRecord', num);
}
export class detail {
Id: number;
Name: string;
}
This My Result Picture

Related

Gutenberg removing table tag on save

I am attempting to create a Gutenberg block to track exercise sets. I'm using a RichText component to allow users to edit default values in a table I pre-populate for them.
The block works well on the editor and, after saving, renders correctly in the post. However, when I reload the editor, I receive this error message: Block validation: Expected tag name 'thead', instead saw 'table'. It's almost like Gutenberg is stripping the table tag but leaving everything else.
Of course, that doesn't make sense, but I'm not sure what else it could be.
Here's my code, heavily edited for readability:
const { registerBlockType } = wp.blocks;
const { AlignmentToolbar, BlockAlignmentToolbar, BlockControls, RichText, useInnerBlockProps } = wp.blockEditor;
const { Component } = wp.element;
registerBlockType('bsd-strong-post/training-session', {
title: __('Strong Post', 'bsd-strong-post'),
description: __('Provides a short summary of a training session', 'bsd-strong-post'),
category: 'common',
icon: blockIcons.weight_lifting,
keywords: [
__('strength workout', 'bsd-strong-post'),
__('strong', 'bsd-strong-post'),
__('training', 'bsd-strong-post')
],
supports: {
html: true
},
attributes: {
/* ... */,
dayTemplateContent: {
type: 'string',
source: 'html',
selector: '.bsd-strong-post-training-template'
},
/* ... */
},
/* ... */
edit: class extends Component {
constructor(props) {
super(...arguments);
this.props = props;
/* ... */
this.dayTemplateHandler = this.dayTemplateHandler.bind(this);
this.onChangeBlockTemplate = this.onChangeBlockTemplate.bind(this);
}
/* ... */
dayTemplateHandler(new_val) {
const dayTemplateList = this.state.dayTemplateList;
let selectedDayTemplate = dayTemplateList.filter(item => {
return item.value == new_val;
})
if (selectedDayTemplate[0]['label']) {
this.props.setAttributes({
dayTemplateId: new_val,
dayTemplateName: selectedDayTemplate[0]['label']
});
}
this.getTemplate(new_val);
}
getTemplate(templateId) {
api.getDayTemplate(templateId)
.then((data) => {
if (!data.status || data.status == 0) {
return false;
};
if (!data.day_template) {
return false;
};
this.props.setAttributes({
dayTemplateContent: data.day_template.template_content
});
return data.day_template;
}).catch((err) => {
console.log('getTemplate caught error')
return false;
});
}
onChangeBlockTemplate(value) {
this.props.setAttributes({
dayTemplateContent: value
});
}
/* ... */
render() {
const { dayTemplateHandler, onChangeBlockTemplate, phaseControlHandler, programControlHandler, updateBlockAlignment, updateTextAlignment } = this;
const { block_alignment, dayTemplateId, dayTemplateName, dayTemplateContent, phaseId, phaseName, programAuthor, programId, programName, programPhases, text_alignment } = this.props.attributes;
/* ... */
return [
<InspectorControls>
<PanelBody title={ __('Basics', 'bsd-strong-post') }>
<SelectControl
label={ __('Day', 'bsd-strong-post') }
help={ __('The training session (e.g., Day One)', 'bsd-strong-post') }
value={ dayTemplateId }
options={ this.state.phaseTemplates }
onChange={ dayTemplateHandler }
/>
}
</PanelBody>
</InspectorControls>,
<div className='bsd-strong-post-block-editor'>
<div className={ this.props.className }>
<RichText
placeholder={ __('Log your lifts here') }
value={ dayTemplateContent }
multiline={ false }
onChange={ onChangeBlockTemplate }
className='bsd-strong-post-training-log'
/>
</div>
</div>
];
}
},
save: (props) => {
return (
<div className={ `align${props.attributes.block_alignment}` }>
<ul className='list-unstyled'style={{ textAlign: props.attributes.text_alignment }}>
<li>
<strong>{ __('Program', 'bsd-strong-post') }: </strong>
<span className='bsd-strong-post-program'>{ props.attributes.programName }</span>
</li>
<li>
<strong>{ __('Phase', 'bsd-strong-post') }: </strong>
<span className='bsd-strong-post-phase-ph'>{ props.attributes.phaseName }</span>
</li>
<li>
<strong>{ __('Day', 'bsd-strong-post') }: </strong>
<span className='bsd-strong-post-day-ph'>{ props.attributes.dayTemplateName }</span>
</li>
<li>
<strong>{ __('Author', 'bsd-strong-post') }: </strong>
<span className='bsd-strong-post-author-ph'>{ props.attributes.programAuthor }</span>
</li>
</ul>
<RichText.Content
value={ props.attributes.dayTemplateContent }
className='bsd-strong-post-training-log'
/>
</div>
)
}
});
Here's the console output on reload:
Content generated by 'save' function:
<div class="wp-block-bsd-strong-post-training-session alignwide"><ul class="list-unstyled"><li><strong>Program: </strong><span class="bsd-strong-post-program">Madcow</span></li><li><strong>Phase: </strong><span class="bsd-strong-post-phase-ph">Intermediate</span></li><li><strong>Day: </strong><span class="bsd-strong-post-day-ph">Day 1</span></li><li><strong>Author: </strong><span class="bsd-strong-post-author-ph">Madcow</span></li></ul>
<thead>
<tr>
<th scope="col">Exercise</th>
<th scope="col">Set 1</th>
<th scope="col">Set 2</th>
</tr>
</thead>
<tbody>
<tr class="bsd-strong-post-exercise-one">
<td class="bsd-strong-post-exercise-name">Squat</td>
<td class="bsd-strong-post-set-1">95 x 5</td>
<td class="bsd-strong-post-set-2">135 x 5</td>
</tr>
</tbody>
</div>
Content retrieved from post body:
<div class="wp-block-bsd-strong-post-training-session alignwide"><ul class="list-unstyled"><li><strong>Program: </strong><span class="bsd-strong-post-program">Madcow</span></li><li><strong>Phase: </strong><span class="bsd-strong-post-phase-ph">Intermediate</span></li><li><strong>Day: </strong><span class="bsd-strong-post-day-ph">Day 1</span></li><li><strong>Author: </strong><span class="bsd-strong-post-author-ph">Madcow</span></li></ul><table class='bsd-strong-post-training-template'>
<thead>
<tr>
<th scope='col'>Exercise</th>
<th scope='col'>Set 1</th>
<th scope='col'>Set 2</th>
</tr>
</thead>
<tbody>
<tr class='bsd-strong-post-exercise-one'>
<td class='bsd-strong-post-exercise-name'>Squat</td>
<td class='bsd-strong-post-set-1'>95 x 5</td>
<td class='bsd-strong-post-set-2'>135 x 5</td>
</tr>
</tbody>
</table></div>
I can see that the content displayed below Content generated by 'save' function: is missing the <table> and </table> tags. I've tried to work around this by adding tagName='table' in the RichText.Content properties inside the save function, but then the console shows duplicate <table> and </table> tags.
EDIT: The table is populated when a user makes a change to the Select control in InspectorControls. This action calls dayTemplateHandler, which among other things, calls getTemplate, a function that gets the content of the table from the database. Here's an example of that output (data.day_template.template_content):
<table class='bsd-strong-post-training-template'>
<thead>
<tr>
<th scope='col'>Exercise</th>
<th scope='col'>Set 1</th>
<th scope='col'>Set 2</th>
</tr>
</thead>
<tbody>
<tr class='bsd-strong-post-exercise-one'>
<td class='bsd-strong-post-exercise-name'>Squat</td>
<td class='bsd-strong-post-set-1'>95 x 5</td>
<td class='bsd-strong-post-set-2'>135 x 5</td>
</tr>
</tbody>
</table>
On reviewing the table template and considering the error, I suspect the issue is the selector of the dayTemplateContent attribute, .bsd-strong-post-training-template
The first time the content is saved, it successfully loads the template data from database and saves the complete table structure. When the content is reloaded, the block validator fails as the selector of dayTemplateContent reads in the child nodes of the table's css selector (which is thead) and doesn't match expected content. Ref: HTML example of blockquote/paragraphs
Try wrapping the <table> template with a <div class="bsd-strong-post-training-template"> or changing the selector.

Styling material ui table cells according to their values

I have a material ui table and I would like to colour the different cells according to what value is displayed in them. The cells are populated with json data using map. For example if a cell has the value 1, I would like the colour to be yellow.
{
Name: "A Person",
Attendence: [
{
date: "2019/12/01",
attendence: 1
},
{
date: "2019/12/02",
attendence: 1
},
{
date: "2019/12/03",
attendence: 0
}
]
}
];
return (
<Fragment>
{attendence.map(person => {
return (
<Table>
<thead>
<tr>
<th>Name</th>
{person.Attendence.map(personAttendendance => {
return <th>{personAttendendance.date}</th>;
})}
</tr>
</thead>
<tbody>
<tr>
<td>{person.Name}</td>
{person.Attendence.map(personAttendendance => {
return <td>{personAttendendance.attendence}</td>;
})}
</tr>
</tbody>
</Table>
);
})}
</Fragment>
);
}
export default Test;
That is what the table looks like. I tried
if(value === 1){
return(
<TableCell style={{ background: "red" }}>{value}</TableCell>
)
} else {
return(
<TableCell style={{ background: "red" }}>{value}</TableCell>
)
}
}
But that did not work . It just read the else and made everything red.
Change your tbody in test.js to:
<tbody>
<tr>
<td>{person.Name}</td>
{person.Attendence.map(personAttendendance => {
if(personAttendendance.attendence === 1){
return <td style={{background: "red" }}>{personAttendendance.attendence}</td>;
} else {
return <td style={{background: "blue" }}>{personAttendendance.attendence}</td>;
}
})}
</tr>
</tbody>
or
<tbody>
<tr>
<td>{person.Name}</td>
{person.Attendence.map(personAttendendance => {
return <td style={{background: personAttendendance.attendence === 1 ? "red" : "blue"}}>{personAttendendance.attendence}</td>;
})}
</tr>
</tbody>
Which ever suits you best.
Link to fork here. (using the second example)

Select only one row in mat-table and if select other one then unselect first one

I want to implement table with only one row selection. Now i have multiple selection.
I tried coupe ways to do this and i stayed by this one.
Graphic example:
component.ts
import { Component, OnInit, OnDestroy } from '#angular/core';
import { MatDialogRef } from '#angular/material/dialog';
import { UsersReadRepository } from '../../../../core/services';
import { MatTableDataSource } from '#angular/material';
import { User } from 'domain-models';
import { Observable, Subscription } from 'rxjs';
import { Subscribable } from 'rxjs/Observable';
import { SelectionModel } from '#angular/cdk/collections';
#Component({
selector: 'choose-supervisior',
templateUrl: './chooseSupervisior.component.html',
styleUrls: ['./chooseSupervisior.component.scss']
})
export class ChooseSupervisiorComponent implements OnInit, OnDestroy {
selectedRow: User;
isLoading = true;
dataSource: MatTableDataSource<User> = new MatTableDataSource();
displayedColumns: string[] = ['name', 'surname', 'phone'];
subscription$ : Subscription;
constructor(public dialogRef: MatDialogRef<ChooseSupervisiorComponent>, private userReadRepository: UsersReadRepository) {
}
onCloseDialog(): void {
this.dialogRef.close(this.selectedRow);
}
ngOnInit() {
this.subscription$ = this.userReadRepository.getSupervisiorUsers()
.subscribe(
data =>
{
this.isLoading = false,
this.dataSource.data = data;
}
)
}
highlight(highlighted: boolean) {
highlighted = !highlighted;
}
getSupervisiorRecordFromTable(user: User){
this.selectedRow = user;
}
ngOnDestroy() {
this.subscription$.unsubscribe();
}
}
component.html
<h2 mat-dialog-title>{{'insideChats.chooseSupervisiorHeader' | translate}}</h2>
<mat-divider></mat-divider>
<div mat-dialog-content>
<mat-table #table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.name}} </mat-cell>
</ng-container>
<ng-container matColumnDef="surname">
<mat-header-cell *matHeaderCellDef> Surname </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.surname}} </mat-cell>
</ng-container>
<ng-container matColumnDef="phone">
<mat-header-cell *matHeaderCellDef> Phone </mat-header-cell>
<mat-cell *matCellDef="let user"> {{user.phone}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"
(click)="getSupervisiorRecordFromTable(row)"
[ngClass]="{hovered: row.hovered, highlighted: row.highlighted}" (click)="row.highlighted = !row.highlighted" (mouseover)="row.hovered = true" (mouseout)="row.hovered = false"></mat-row >
</mat-table>
<mat-card class="loading-spinner" *ngIf="isLoading">
<mat-progress-spinner
color="primary"
mode="indeterminate">
</mat-progress-spinner>
</mat-card>
</div>
<mat-divider></mat-divider>
<div mat-dialog-actions>
<button mat-dialog-close (click)="onCloseDialog()" mat-icon-button color="warn">
<mat-icon>close</mat-icon>
</button>
<span class="buttons-spacer"></span>
<button mat-button class="choose-button">{{'insideChats.chooseSupervisiorStartChat' | translate}}</button>
</div>
component.scss
.loading-spinner{
display: flex;
justify-content: center;
align-items: center;
}
.buttons-spacer {
flex: 1 1 auto;
}
.mat-dialog-actions {
justify-content: flex-end;
}
.basic-container {
padding: 5px;
}
.mat-row.hovered {
background: #eee;
}
.mat-row.highlighted {
background: #999;
}
mat-cell.mat-cell, mat-header-cell.mat-header-cell {
overflow: visible;
}
How to implement row selection with unsellecting the last one clicked selection and then this same with other clicking.
The point is just always available select only one row.
Using a SelectionModel with multi-selection disabled will make things easier. See the example: https://material.angular.io/components/table/overview#selection.
Here's a modified version of the example on Stackblitz without the checkboxes and using single selection and some of your table's functionality: https://stackblitz.com/edit/angular-2yv8hk?file=app/table-selection-example.html.
In particular:
TS
export class TableSelectionExample {
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
dataSource = new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
selection = new SelectionModel<PeriodicElement>(false, []);
}
HTML
<mat-row *matRowDef="let row; columns: displayedColumns;"
(click)="selection.toggle(row)"
[ngClass]="{hovered: row.hovered, highlighted: selection.isSelected(row)}"
(mouseover)="row.hovered = true" (mouseout)="row.hovered = false">
</mat-row>
Is there a way to get the index of the row? (I don't really use angular) So you save the index when clicking the row in data as 'pastIndex', define a method for when you click the row, pseudocodeish:
rowClick (index) {
if (this.pastIndex is defined) {
data[this.pastIndex].highlighted = false
}
this.pastIndex = index
data[index].highlighted = true
}
If not, this is not ideal, but you could traverse your whole data and make everything false and then just make the one you need true
rowClick (index) {
for (var i = 0; i < data.length; i++) {
data[i].highlighted = false
}
data[index].highlighted = true
}
Here is the Perfect example of Single and Multiple Checkbox selection with Mat Table
https://stackblitz.com/edit/angular-mat-table-selection
Mat table Selection as a propertenter code herey selection.selected which contains all the selected
Angular Official Documentation
https://material.angular.io/components/table/overview#selection
selectHandler(row: PeriodicElement) {
if (this.displayType == SelectType.single) {
/* Single checkbox Selection*/
if (!this.selection.isSelected(row)) {
this.selection.clear();
}
}
/* Multiple checkbox Selection*/
this.selection.toggle(row);
}

cards stack using angular2 swing module in ionic 3

I'm using angular2 swing in ionic in order make swiping cards. So after building, I'm getting cards one below one not in the stack format(as they get in tinder). Can someone help me in figuring it out. why are the cards are not in stack format? Here is my code.
<div swing-stack #myswing1 [stackConfig]="stackConfig" (throwoutleft)="voteUp(false)" (throwoutright)="voteUp(true)" id="card-stack" >
<ion-card #mycards1 swing-card *ngFor="let job of jdetails">
<div >
<img src="assets/imgs/lap.jpg" (click)="openPage()" id="tagimg">
<div class="textoncard title" >{{ job.company }}</div>
<div class="textoncard subt">{{ job.jobtitle }}</div>
<div class="textoncard time">2 days ago</div>
</div>
<ion-card-content>
<table>
<tr>
<td class="label">Location</td>
<td class="des">{{ job.location }}</td>
</tr>
<tr>
<td class="label">Type</td>
<td class="des">{{ job.jobtype }}</td>
</tr>
<tr>
<td class="label">salary</td>
<td class="des">{{ job.jobtype }}</td>
</tr>
<tr>
<td class="label">Description</td>
<td class="des">{{ job.jobdescrition }}</td>
</tr>
<tr>
<td class="label">Source</td>
<td class="des"><p style="color: purple;font-weight: bold;">Monster</p></td>
</tr>
</table>
<div id="endbtn">
<ion-buttons class="ionrow">
<button ion-button icon-only clear (tap)="tapEvent($event)" [ngStyle]="{'color': buttonColor}">
<ion-icon name="ios-heart"></ion-icon>
</button>
<button ion-button icon-only clear style="color: black" id="sharebtn">
<i class="fas fa fa-share-alt custom-share"></i>
</button>
</ion-buttons>
</div>
</ion-card-content>
</ion-card>
</div>
Here is ts file
export class FeedsPage {
#ViewChild('myswing1') swingStack: SwingStackComponent;
#ViewChildren('mycards1') swingCards: QueryList<SwingCardComponent>;
stackConfig: StackConfig;
recentCard: string = '';
cards: Array<any>;
buttonColor: string = '#F2F0F4';
public press: number = 0;
jobtitletosave: string;
showdropdown: boolean = false;
searchQuery: string = '';
items: string[];
jdetails: any;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public modalCtrl: ModalController,
private nativePageTransitions: NativePageTransitions,
public jobdetail: JobsDataProvider
)
{
this.stackConfig = {
throwOutConfidence: (offsetX, offsetY, element: any) => {
return Math.min(Math.abs(offsetX) / (element.offsetWidth/2), 1);
},
transform: (element, x, y, r) => {
this.onItemMove(element, x, y, r);
},
throwOutDistance: (d) => {
return 800;
}
};
this.initializeItems();
}
ionViewDidLoad() {
console.log('ionViewDidLoad FeedsPage');
this.jobdetail.getJobDetails().then((data) => {
console.log(data);
this.jdetails = data;
});
}
openPage() {
let options: NativeTransitionOptions = {
direction: 'down',
duration: 100,
slowdownfactor: -1,
iosdelay: 50,
androiddelay: 50,
}
this.nativePageTransitions.fade(options);
this.navCtrl.push(JobDetailPage);
}
showAlert() {
let modal = this.modalCtrl.create(ModalPage);
modal.present();
}
ngAfterViewInit() {
// Either subscribe in controller or set in HTML
this.swingStack.throwin.subscribe((event: DragEvent) => {
event.target.style.background = '#ffffff';
});
}
onItemMove(element, x, y, r) {
let color = '';
const abs = Math.abs(x);
const min = Math.trunc(Math.min(16 * 16 - abs, 16 * 16));
const hexCode = this.decimalToHex(min, 2);
if (x > 0) {
color = '#' + hexCode + 'FF' + hexCode;
} else {
color = '#FF' + hexCode + hexCode;
}
element.style.background = color;
element.style['transform'] = `translate3d(0, 0, 0) translate(${x}px, ${y}px) rotate(${r}deg)`;
}
decimalToHex(d, padding) {
let hex = Number(d).toString(16);
const numPadding = typeof (padding) === 'undefined' || padding === null ? 2 : padding;
while (hex.length < numPadding) {
hex = '0' + hex;
}
return hex;
}
voteUp(like: boolean) {
}
tapEvent(e) {
this.press++;
if (this.press % 2 != 0 ) {
this.buttonColor = '#E24B4B';
}
else {
this.buttonColor = '#F2F0F4';
}
}
}
I want the cards
here is how I'm getting tem I want them as

How do I draw a line on an HTML table on a given height

On a bootstrap based web page I'm displaying the following table:
This was generated with the following code:
<div class="row">
<div class="col-lg-12">
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th class="text-right success">Count</th>
<th class="text-right success">Lower</th>
<th class="text-right success">Upper</th>
<th class="text-right success">Price</th>
<th class="text-right success">Cost</th>
</tr>
</thead>
<tbody>
#foreach (var dataRow in staffelData)
{
var differenceWithUpper = 0;
if (dataRow.Upper.HasValue)
{
differenceWithUpper = countValue - dataRow.Upper.Value;
}
else
{
differenceWithUpper = -1;
}
var cost = 0.0;
var inScope = 0;
if (differenceWithUpper >= 0)
{
inScope = dataRow.Upper.Value;
}
else
{
if (countValue >= dataRow.Lower.Value)
{
inScope = countValue - dataRow.Lower.Value;
}
}
cost = inScope * Decimal.ToDouble(#dataRow.PnrFee);
<tr>
<td class="text-right fit">#pnrsInScope</td>
#if (#dataRow.Lower.HasValue)
{
<td class="text-right fit">#dataRow.Lower.Value</td>
}
else
{
<td class="text-right fit">N/A</td>
}
#if (#dataRow.Upper.HasValue)
{
<td class="text-right fit">#dataRow.Upper.Value</td>
}
else
{
<td class="text-right fit">N/A</td>
}
<td class="text-right fit">#dataRow.Fee #dataRow.Currency</td>
<td class="text-right fit">#cost #dataRow.Currency</td>
</tr>
}
</tbody>
</table>)
</div>
</div>
</div>
I still need to add one feature though: I have to display an estimated value in the same table.
The estimated value is based on the average, say we have 25 orders a day, then on day you'd expect to have 250 orders. This 250 is the value I want to display on the same table.
I was thinking to draw a line # the level in the table the estimated value can be found, and adding a label to the line.
Could anyone here explain me how to best get this done?
Not sure if you would count this as a 'line' but I believe it's a suitable solution to your problem. Just change the class of your <tr> for the average row.
#foreach (var dataRow in staffelData)
{
var differenceWithUpper = 0;
if (dataRow.Upper.HasValue)
{
differenceWithUpper = countValue - dataRow.Upper.Value;
}
else
{
differenceWithUpper = -1;
}
var cost = 0.0;
var inScope = 0;
if (differenceWithUpper >= 0)
{
inScope = dataRow.Upper.Value;
}
else
{
if (countValue >= dataRow.Lower.Value)
{
inScope = countValue - dataRow.Lower.Value;
}
}
cost = inScope * Decimal.ToDouble(#dataRow.PnrFee);
#if (...this row is the average...){
<tr class='average-row'>
} else {
<tr>
}
<td class="text-right fit">#pnrsInScope</td>
#if (#dataRow.Lower.HasValue)
{
<td class="text-right fit">#dataRow.Lower.Value</td>
}
else
{
<td class="text-right fit">N/A</td>
}
#if (#dataRow.Upper.HasValue)
{
<td class="text-right fit">#dataRow.Upper.Value</td>
}
else
{
<td class="text-right fit">N/A</td>
}
<td class="text-right fit">#dataRow.Fee #dataRow.Currency</td>
<td class="text-right fit">#cost #dataRow.Currency</td>
</tr>
}
and then add a CSS rule for average-row
.average-row{
background-color: green;
}
UPDATE:
See the answer here
Linethrough/strikethrough a whole HTML table row
So for you
CSS:
table {
border-collapse: collapse;
}
td {
position: relative;
padding: 5px 10px;
}
tr.strikeout td:before {
content: " ";
position: absolute;
top: 50%;
left: 0;
border-bottom: 1px solid #111;
width: 100%;
}
HTML:
#foreach (var dataRow in staffelData)
{
var differenceWithUpper = 0;
if (dataRow.Upper.HasValue)
{
differenceWithUpper = countValue - dataRow.Upper.Value;
}
else
{
differenceWithUpper = -1;
}
var cost = 0.0;
var inScope = 0;
if (differenceWithUpper >= 0)
{
inScope = dataRow.Upper.Value;
}
else
{
if (countValue >= dataRow.Lower.Value)
{
inScope = countValue - dataRow.Lower.Value;
}
}
cost = inScope * Decimal.ToDouble(#dataRow.PnrFee);
#if (...this row is the average...){
<tr class="strikeout">
} else {
<tr>
}
<td class="text-right fit">#pnrsInScope</td>
#if (#dataRow.Lower.HasValue)
{
<td class="text-right fit">#dataRow.Lower.Value</td>
}
else
{
<td class="text-right fit">N/A</td>
}
#if (#dataRow.Upper.HasValue)
{
<td class="text-right fit">#dataRow.Upper.Value</td>
}
else
{
<td class="text-right fit">N/A</td>
}
<td class="text-right fit">#dataRow.Fee #dataRow.Currency</td>
<td class="text-right fit">#cost #dataRow.Currency</td>
</tr>
}

Resources