Angular2 - Kendo Grid kendoGridCellTemplate - kendo-ui

I have a Kendo-Grid with pagination and kendo-grid-checkbox-column,
and I want to be able to check the checkboxes according to the backend data.
Though it seems its impossible to use [kendoGridSelectionCheckbox] combined with [checked].
`
<kendo-grid #factoring
[data]="factoringSites"
[pageSize]="factoringSitesPageSize"
[skip]="skipFactoring"
[pageable]="true"
(pageChange)="pageChange($event, 'factoring')"
[height]="300"
[selectable]="{enabled: true, checkboxOnly: true }"
kendoGridSelectBy="id"
[(selectedKeys)]="myFactoringSitesSelection"
(selectedKeysChange)="onSelectedKeysChange($event, 'factoring')"
disabled="!factoringChecked">
<kendo-grid-checkbox-column [width]="40">
<ng-template kendoGridHeaderTemplate let-dataItem>
<input type="checkbox" kendoCheckBox id="selectAllFactoringCheckboxId" kendoGridSelectAllCheckbox
[state]="selectAllFactoringState"
(selectAllChange)="onSelectAllChange($event, 'factoring')"
[disabled]="selectAllReverseFactoringState == 'checked'">
<label class="k-checkbox-label" for="selectAllFactoringCheckboxId"></label>
</ng-template>
<ng-template kendoGridCellTemplate let-dataItem let-factoringidx="rowIndex">
<input type="checkbox"
kendoCheckBox
[kendoGridSelectionCheckbox]="factoringidx"
[checked]="true"
(change)="selectionChangeHandler($event, dataItem,'factoring')"
/>
</ng-template>
</kendo-grid-checkbox-column>
Selecting checkboxes without [kendoGridSelectionCheckbox] selects the same placed row in the next page, even though the index of the row is completely different..
So how can I use the combination of both, or just not selecting the the row of the next page
Example - https://stackblitz.com/edit/angular-rssxbc

Related

How to implement dropdown list in a grid for kendoUI for angular. Can't find any documentation

Something like this. But this example is for kendoUI for jquery. I need documentation for kendoUI for angular.
I do it in my application. Here is a simple version of it:
HTML Template
<kendo-grid [data]="someData" [height]="750">
<kendo-grid-column field="LaborType" title="Task" width="120">
<ng-template kendoGridCellTemplate let-dataItem>
{{ GetLaborTypeDesc(dataItem.LaborType)?.LaborTypeDesc }}
</ng-template>
<ng-template kendoGridEditTemplate>
<kendo-dropdownlist [defaultItem]="{LaborTypeID: null, LaborTypeDesc: 'Select a task...'}" [data]="LaborTypes"
textField="LaborTypeDesc" valueField="LaborTypeID" [valuePrimitive]="true">
</kendo-dropdownlist>
</ng-template>
</kendo-grid-column>
</kendo-grid>
Typescript
LaborTypes: Array<{ LaborTypeDesc: string, LaborTypeID: number }> = [];
public GetLaborTypeDesc(id: number): any {
return this.LaborTypes.find(x => x.LaborTypeID === id);
}
I have Add, Edit, and Delete commands in my grid that involves a form not seen here. I populate the LaborTypes object array in my ngOnInit function as well, so the user has options to choose in the dropdown.

Is there any way to define maximum and minimum date for a date column of a kendo grid?

I have a kendo grid with in-cell editing and a pair of date columns. I want to specify a maximum and a minimum date for the datepickers inside the cell the user is editing, but it doesn't seem to exist any property for that.
I tried to do it with templates:
<kendo-grid-column field="StartDate" title="Start Date">
<ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex">
<kendo-datepicker
format="{0:dd/MM/yyyy}"
[(ngModel)]="dataItem"
></kendo-datepicker>
</ng-template>
</kendo-grid-column>
But I'm getting a bunch of errors. How can I make this work?
EDIT: I created a stackblitz example based on one of the in-cell editing examples that I found in the documentation:
https://stackblitz.com/edit/angular-ewvsh5
Here, I discovered that I wasn't specifying the property ngModel has to connect to:
[(ngModel)]="dataItem"
Should be:
[(ngModel)]="dataItem.Date"
Ok, I changed it, but now, when I click on the date cell, instead of appearing a datepicker, it appears a regular input. Please, check this part in the components template, it's where the problem is:
<!-- This doesn't work -->
<kendo-grid-column field="Date" title="Date">
<ng-template
kendoGridCellTemplate
let-dataItem
let-rowIndex="rowIndex"
let-isEdited="isEdited"
*ngIf="editingDateCell"
>
<kendo-datepicker [(ngModel)]="dataItem.Date"></kendo-datepicker>
</ng-template>
<ng-template
kendoGridCellTemplate
let-dataItem
let-rowIndex="rowIndex"
let-isEdited="isEdited"
*ngIf="!editingDateCell"
>
{{ dataItem.Date | date }}
</ng-template>
</kendo-grid-column>
What am I doing wrong?
EDIT II: All the solutions so far show the datepicker inside the cell. That's fine, I know how to do it. The problem is that before the user clicks to edit the cell, that cell must be like a label, when the user clicks on that label, it has to become a datepicker. If the user changes the date and clicks away, the grid has to know that the data has been updated and act accordly. In summary, I need to preserve the in-cell editing behavior.
You need to use the min and max date picker properties. Please refer to this API reference link for date picker min max example.
Also refer to this forum link for an example of a date picker column template.
#Component({
selector: 'my-app',
template: `
<form novalidate #myForm="ngForm">
<kendo-grid
[data]="view | async"
[height]="533"
[pageSize]="gridState.take" [skip]="gridState.skip" [sort]="gridState.sort"
[pageable]="true" [sortable]="true"
(dataStateChange)="onStateChange($event)"
(edit)="editHandler($event)" (cancel)="cancelHandler($event)"
(save)="saveHandler($event)" (remove)="removeHandler($event)"
(add)="addHandler($event)"
[navigable]="true"
>
<ng-template kendoGridToolbarTemplate>
<button kendoGridAddCommand type="button">Add new</button>
</ng-template>
<kendo-grid-column field="ProductName" title="Product Name">
<ng-template kendoGridEditTemplate let-dataItem="dataItem">
<input [(ngModel)]="dataItem.ProductName" kendoGridFocusable name="ProductName" class="k-textbox" required/>
</ng-template>
</kendo-grid-column>
<kendo-grid-column field="date" title="Date" format="{0:yyyy-MM-dd}">
<ng-template kendoGridEditTemplate let-dataItem="dataItem">
<kendo-datepicker
[format]="'yyyy-MM-dd'"
[(ngModel)]="dataItem.date"
[min]="min"
[max]="max"
name="date"></kendo-datepicker>
</ng-template>
</kendo-grid-column>
<kendo-grid-command-column title="command" width="220">
<ng-template kendoGridCellTemplate let-isNew="isNew">
<button kendoGridEditCommand type="button" class="k-primary">Edit</button>
<button kendoGridRemoveCommand type="button">Remove</button>
<button kendoGridSaveCommand type="button" [disabled]="myForm.invalid">{{ isNew ? 'Add' : 'Update' }}</button>
<button kendoGridCancelCommand type="button">{{ isNew ? 'Discard changes' : 'Cancel' }}</button>
</ng-template>
</kendo-grid-command-column>
</kendo-grid>
</form>
`
})
export class AppComponent implements OnInit {
public min: Date = new Date(2018, 2, 10);
public max: Date = new Date(2018, 11, 25);
}
Finally, what I had to do is to use the kendoGridEditTemplate instead of the kendoGridCellTemplate and use [formControl] instead of [(value)] or [(ngModel)]. If you follow the example found in the documentation, and you want to add a custom date column so you have full access to the datepicker's properties, the markup to add is this one:
<kendo-grid-column
field="StartDate"
title="Start Date"
[format]="{ date: 'dd/MM/yyyy' }"
>
<ng-template
kendoGridEditTemplate <!-- Important -->
let-column="column"
let-formGroup="formGroup"
>
<kendo-datepicker
format="dd/MM/yyyy"
[formControl]="formGroup.get(column.field)" <!-- Important -->
[min]="minimumDate"
>
</kendo-datepicker>
</ng-template>
</kendo-grid-column>
To set a minimum and maximum of a datepicker use [min] and [max]. See this demo for an example.
Here's an example code that does what you require:
#Component({
selector: 'my-app',
template: `
<p>Date</p>
<kendo-grid [data]="gridData">
<kendo-grid-column field="ProductID"></kendo-grid-column>
<kendo-grid-column field="ProductName"></kendo-grid-column>
<kendo-grid-column field="date" [format]="{ date: 'long' }">
<ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex">
<kendo-datepicker [(value)]="dataItem.date" [min]="minDate" [max]="maxDate">
</kendo-datepicker>
</ng-template>
</kendo-grid-column>
</kendo-grid>
`
})
export class AppComponent {
public minDate = new Date(2018, 4, 1);
public maxDate = new Date(2018, 4, 31);
const products = [{
"ProductID": 1,
"ProductName": "Chai",
"UnitPrice": 18.0000,
"Discontinued": true,
date: new Date("2018-05-05T00:00:00-05:00")
}, {
"ProductID": 2,
"ProductName": "Chang",
"UnitPrice": 19.0000,
"Discontinued": false,
date: new Date("2018-05-07T00:00:00-05:00")
}
];
public gridData: any[] = products.map(item => {
item.date = new Date(item.date);
return item;
});
}

Represent boolean values in the form of 2 different icons (one for true, one for false) in PrimeNG DataTable

I want to represent boolean values in the form of icons for a column field in data table primeng. Following is a piece of code:
<p-dataTable [value]="ARRAY_METADATA" rowHover="true">
<p-column field="id" header="Field ID" [sortable]="true"></p-column>
<p-column field="booleanField" header="Boolean Field" [sortable]="true"></p-column>
</datatable>
How am I supposed to show maybe a "Tick" for true values and "cross" for false values for the booleanField?
<span class="badge">BOOLEAN VAUE</span>
I guess the above code works well in case of pure HTML. But again how am I suppose to put the conditional statement to output two different icons for different boolean values?
Any quick thoughts??
I tried using ngIf but it still does not display the way I need. It simply displays the content of ng-template:
<p-column field="someStringField" header="Some String Field">
<div *ngIf="someStringField; else elseBlock">
<button type="button" pButton icon="fa-check"></button>
</div>
<ng-template #elseBlock pTemplate="body" >
<button type="button" pButton icon="fa-times"></button>
</ng-template>
</p-column>
I believe you have to put any content you want to be visible in the column to be in the ng-template
<ng-template let-col="rowData" pTemplate="body">
<button *ngIf="col.someValue" type="button" pButton icon="fa-check"></button>
<button *ngIf="!col.someValue" type="button" pButton icon="fa-times"></button>
</ng-template>

Form validation on radio buttons Codeigniter

I am trying to add validation for radio buttons on a html form in Codeigniter. The form is prepopulated with data from a database, including a list of uploaded documents (this field may be empty if the item has no associated docs). The user can upload a new document, adding it to the existing docs or adding a new doc deleting the current ones.
So I have a text field containing the org doc names and a file upload field for new:
<label for="orgdocs">Documents</label>
<input type="text" id="orgdocs" readonly="readonly" value="<?php echo $fetched_row['pdocs']; ?>" />
<input type="file" id="newdocs" name="newdocs[]" multiple="multiple" />
and radio buttons: (ignore the bad attempt at Spanish names)
<label for="mas"><b>Añada mas</b></label>
<input type="radio" name="docsacion" style="margin-right: 0" <?php if (isset($docsacion) && $docsacion=="mas") echo "checked";?> value="mas" title="Add another document to existing docs"><br />
<label for="otra"><b>Borrar y añada otra</b></label>
<input type="radio" name="docsacion" style="margin-right: 0" <?php if (isset($docsacion) && $docsacion=="otra") echo "checked";?> value="otra" title="Remove all current docs and add new">
I just want to add validation. IF a new document has been selected(newdocs is not empty), dosacion is required.
I have tried:
if(isset($_FILES['newdocs']['name']) && (!empty($_FILES['newdocs']['name'])))
{$this->form_validation->set_rules('docascion','Documentation upload', 'required');}
but this gives the error even if the newdocs field is empty and I´ve no idea why!?
Try this
if(!empty($_FILES['newdocs']['name'])){
$this->form_validation->set_rules('docascion','Documentation upload', 'required');
}

react-bootstrap ButtonGroup as radio buttons

I'm trying to make a group of react-bootstrap buttons into a radio button set. I can easily do this with bootstrap with <input type="radio"> elements, but can't figure out how to do this with react-bootstrap. The following code allows the user to select every button, instead of just one.
JS:
const operationButtons = (
<ButtonGroup>
<Button active>Radio 1</Button>
<Button>Radio 2</Button>
</ButtonGroup>
);
React.render(operationButtons, document.getElementById('operationButtonsDiv'));
HTML:
<div name="operationButtonsDiv" id="operationButtonsDiv" data-toggle="buttons"/>
The framework has changed since the accepted answer and they have now replicated the option group behavior of Bootstrap framework. All you need to do now is to add a group name to each option in the group:
<Radio name="groupOptions">Option 1</Radio>
<Radio name="groupOptions">Option 2</Radio>
<Radio name="groupOptions">Option 3</Radio>
So I ended up nesting a radio Input in the Button like you would normally do in Bootstrap.
render() {
return (
<ButtonGroup>
<Button active>Radio 1
<Input ref="input1" type="radio" name="radioButtonSet" value='input1' standalone defaultChecked/>
</Button>
<Button>Radio 2
<Input ref="input2" type="radio" name="radioButtonSet" value='input2' standalone/>
</Button>
</ButtonGroup>
)
}
I also overrode the default .radio css to fix how it's displayed.
.radio {
margin-top: 0;
margin-bottom: 0;
}
React-bootstrap has plans to implement RadioGroup eventually:
https://github.com/react-bootstrap/react-bootstrap/issues/342
Some of the answers on this page don't work. Maybe things have changed since then.
I put together this with the help of React Bootstrap website.
<Col>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Radio name="group1"/>
<InputGroup.Text >London</InputGroup.Text>
</InputGroup.Prepend>
<FormControl/>
</InputGroup>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Radio name="group1"/>
<InputGroup.Text >New York</InputGroup.Text>
</InputGroup.Prepend>
<FormControl/>
</InputGroup>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Radio name="group1"/>
<InputGroup.Text >Colombo</InputGroup.Text>
</InputGroup.Prepend>
<FormControl/>
</InputGroup>
To make the radio button set function as a single group you have to give them a name (so that only one radio button is selected at any given time).
Adding a form control makes the edges of the input nicely rounded off but it also makes the radio button label editable. If this is a problem you can leave out the form control.
If you want a different look and feel you can try this.
<Form.Check
type="radio"
label="London"
name="group2"
id="radio1"
/>
<Form.Check
type="radio"
label="New York"
name="group2"
id="radio2"
/>
<Form.Check
type="radio"
label="Colombo"
name="group2"
id="radio3"
/>
However with these getting the value and handling onChange was difficult. Eventually I used another control.
This is a npm package called react-radio-group. You have to install it by running this line on the command.
npm install react-radio-group
Then import it in your file.
import { Radio, RadioGroup} from 'react-radio-group'
Here's the code for the button group.
<RadioGroup name="fruits" onChange={(e) => handleOnChange(e)}>
<div className="radio-button-background">
<Radio value="Apple" className="radio-button" />Apple
</div>
<div className="radio-button-background">
<Radio value="Orange" className="radio-button" />Orange
</div>
<div className="radio-button-background">
<Radio value="Banana" className="radio-button" />Banana
</div>
</RadioGroup>
classNames are where I have given the styles.
I've just encountered the same problem and solved it by using the the component's state:
_onOptionChange(option) {
this.setState({
option: option
});
}
render() {
render (
<ButtonGroup>
<Button onClick={this._onOptionChange.bind(this, 'optionA')} active={this.state.option === 'optionA'}>Option A</Button>
<Button onClick={this._onOptionChange.bind(this, 'optionB')} active={this.state.option === 'optionB'}>Option B</Button>
</ButtonGroup>
);
}
Just using the tags worked for me. Make sure they all have the same name="radio-group-value-here". To get one of the buttons to be selected on render use checked={bool}. I also used disabled={bool} to show but disallow some choices. I settled on using onClick which seems to be working. Lastly, this is all in a dialog and the offset was needed to keep the radio buttons from smushing up against the left edge.
<Row>
<Col sm={11} smOffset={1} >
<Radio name="changeset-chooser"
checked={this.state.checked === 'current'}
disabled={this.props.changeset.status === "pending"}
onClick={ (e) => { /* event handler */ } } >
Current Data
</Radio>
</Col>
</Row>
<Row>
<Col sm={3} smOffset={1} >
<Radio name="changeset-chooser"
onClick={ (e) => { /* event handler */ } } >
History
</Radio>
</Col>
<Col sm={7} >
<NotPartOfSample />
</Col>
</Row>
This is in 2022, so the library has moved.
Here is how yo would create a yes/no radio:
<Form>
<Form.Check
type="radio"
name="group1"
id={`default-radio`}
label={`Yes!`}
/>
<Form.Check
type="radio"
name="group1"
id={`default-radio`}
label={`No`}
/>
</Form>
The name="group1" makes the buttons TOGGLE. If you don't want to toggle, give them different names or no names.
Hope this helps someone who might stumble across this question like I did.

Resources