I'm trying to have a group of 3 radio buttons (each button in different column but the same row) in my Kendo grid but without success. I looked at the Kendo RowTemplate doc, but it's not directing me to any solution.
it works fine with checkboxes, but when i change the template to "radio" type, it changes to checkbox the second I click the edit button. any thoughts?
below is my kendoGrid properties, I put ** next to the 'template' line in the field property.
div.kendoGrid({
dataSource:
{ error: function (e) {
alert("An error occured: "+ e.xhr.responseText);
this.cancelChanges();
},
type:"json",
transport: {
read: {
url: "/users/read",
cache: false,
dataType: "json"
},
update: {
url: function(user){
var grid = $("#grid").data("kendoGrid");
var model = grid.dataItem(grid.select());
var roleIs;
if (user.Admin) {
roleIs="admin"
}
else if (user.Manager) {
roleIs="manager"
}
else if (user.User) {
roleIs="user"
};
return "users/update/"+model.id+"/"+roleIs+"/"+user.name
},
type: "PUT"
},
destroy: {
url: function(user){
return "/users/destroy/"+user.id+"/"+user.name
},
type: "DELETE"
},
create: {
url: function(user){
var roleIs;
if (user.Admin) {
roleIs="admin"
}
else if (user.Manager) {
roleIs="manager"
}
else if (user.User) {
roleIs="user"
};
return "users/create/"+user.login+"/"+user.name+"/"+roleIs+"/"
},
type: "POST"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
schema: {
model:
{ id: "id",
fields: {
id:{ type: "number",editable: false},
role:{ type: "string"},
login: { type: "string",editable: false},
name:{type: "string",editable: false},
Admin: { type: "boolean"},
Manager: { type: "boolean"},
User: { type: "boolean"}
}
}
},
pageSize: 30,
serverPaging: false,
serverFiltering: false,
serverSorting: false
},
selectable: "row",
navigatable: true,
pageable: true,
height: 400,
columns: [//{field: "id"},
{
field: "name",
title:"User Name",
filterable: true,
nullable: false,
editable: false
},{
field: "Admin",
**template: '<input type="checkbox" #= Admin ? "checked=checked" : "" # disabled="disabled"></input>'**,
width: 75
},{
field: "Manager",
**template: '<input type="checkbox" #= Manager ? "checked=checked" : "" # disabled="disabled"></input>'**,
width: 75
},{
field: "User",
**template: '<input type="checkbox" #= User ? "checked=checked" : "" # disabled="disabled"></input>',**
width: 75
},{
command: ["edit", "destroy"], title: "", width: "195px"
}],
editable:{mode: "inline"}
});
}
}
}
The formatting for edition is controlled by columns.editor
You need to write an editor function that defines the input as a radio button.
Related
I'm trying to get a count of docs having level: 2, completed: true. However, I'm having trouble wrapping my head around introducing another criteria in the query function. Currently, as evident from the code; it is just printing out docs having completed: true. How can I extend this query to support another query parameter like level too?
[{
_id: 1,
name: 'Test_01',
level: 1,
completed: false
},
{
_id: 2,
name: 'Test_02',
level: 2,
completed: true
},
{
_id: 3,
name: 'Test_01',
level: 3,
completed: false
}]
const myMapReduceFun = {
map: (doc) => {
emit(doc.completed);
}.toString(),
reduce: '_count'
};
db.query(myMapReduceFun, {
key: true, reduce: true
})
.then((result) => {
console.log(result)
})
This is easily done with map/reduce. One strategy is to use complex keys, the other using clever demarcations in a string.
I prefer complex keys as it does not require having to assemble the key or other string based monkey business.
Consider the design document in the demo:
{
_id: "_design/my_index",
views: {
completed_str: {
map: `function (doc) {
emit(doc.completed + '/' + doc.level + '/')
}`,
},
completed_complex: {
map: `function (doc) {
emit([doc.completed,doc.level])
}`,
},
},
}
completed_str uses concatenation and a '/' to create two fields for completed and level
completed_complex uses an array to create a complex key
In the snippet below I've included an example of both approaches. The key (no pun intended) is to emit the 'completed' field first, then the 'level' field.
When toying with the queries, do note the difference in the value Key field returned by the view.
const gel = id => document.getElementById(id);
const g_view_result = 'view_result';
function getQuery() {
let view = gel('view').value;
let completed = gel('completed').value === 'true';
let level = parseInt(gel('level').value, 10);
if (view === 'complex') {
// use complex key view
return {
view: "my_index/completed_complex",
params: {
reduce: false,
include_docs: false,
start_key: [completed, level],
end_key: [completed, level],
}
}
}
// use simple string view
return {
view: "my_index/completed_str",
params: {
reduce: false,
include_docs: false,
start_key: [completed, level, ''].join('/'),
end_key: [completed, level, ''].join('/'),
}
}
}
async function query() {
try {
let html = [];
const view_result = gel(g_view_result);
view_result.innerText = '';
let query = getQuery();
let docs = await db.query(query.view, query.params);
html.push(['ID', 'Key'].join('\t'));
html.push(['----', '--------'].join('\t'));
docs.rows.forEach(row => {
html.push([row.id, row.key].join('\t'));
})
view_result.innerText = html.join('\n');
} catch (e) {
console.log('err: ' + e);
}
}
// canned test documents
function getDocsToInstall() {
return [{
_id: "1",
name: 'Test_01',
level: 1,
completed: false
},
{
_id: "2",
name: 'Test_02',
level: 2,
completed: true
},
{
_id: "3",
name: 'Test_01',
level: 3,
completed: false
},
{
_id: "4",
name: 'Test_4',
level: 3,
completed: true
},
{
_id: "5",
name: 'Test_05',
level: 2,
completed: true
},
{
"_id": "_design/my_index",
"views": {
"completed_str": {
"map": `function (doc) {
emit(doc.completed + '/' + doc.level + '/')
}`
},
"completed_complex": {
"map": `function (doc) {
emit([doc.completed,doc.level])
}`
}
}
}
]
}
let db;
async function initDb() {
db = new PouchDB('test', {
adapter: 'memory'
});
return db.bulkDocs(getDocsToInstall());
}
(async() => {
try {
await initDb();
} catch (e) {
console.log(e);
}
})();
<script src="https://cdn.jsdelivr.net/npm/pouchdb#7.1.1/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.1.1/pouchdb.memory.min.js"></script>
<label for="completed">Completed:</label>
<select name="completed" id="completed">
<option value="true">True</option>
<option value="false">False</option>
</select>
<label for="level">Level:</label>
<select name="level" id="level">
<option value="0">0</option>
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>
<label for="view">View:</label>
<select name="view" id="view">
<option value="complex">Complex Key</option>
<option value="simple">Simple String Key</option>
</select>
<button id="query" onclick="query()">Query</button>
<div style='margin-top:2em'></div>
<pre id='view_result'>
</pre>
Here's my code:
public add() {
let alert = Alert.create({
title: "Add Date & Time",
message: "Enter the date and time of your donation.",
inputs: [
{
name: "date",
placeholder: "DD/MM/YYYY"
},
{
name: "time",
placeholder: "HH:MM AM/PM"
}
],
buttons: [
{
text: "Cancel"
},
{
text: "Save",
handler: data => {
this.donationHistoryList.push({
date: data.date,
time: data.time
});
}
}
]
});
this.navCtrl.present(alert);
}
Here are the errors I am getting
Property 'create' does not exist on 'type of Alert'.
And
Property 'present' does not exist on 'type of 'NavController'.
Use this code.
import {AlertController} from 'ionic-angular';
In your constructor fn
constructor(private alertCtrl: AlertController) {
}
public add() {
let alert = alertCtrl.create({
title: "Add Date & Time",
message: "Enter the date and time of your donation.",
inputs: [ { name: "date", placeholder: "DD/MM/YYYY" }, { name: "time", placeholder: "HH:MM AM/PM" } ],
buttons: [ { text: "Cancel" }, { text: "Save", handler: data => { this.donationHistoryList.push({ date: data.date, time: data.time }); } }]
});
alert.present(); }
Hope this helps you. Thanks.
Just add (this before alertCtrl variable).
this.alertCtrl.create(...)
I have a kendo pivot grid defined in this way:
<div kendo-pivot-grid
id="pivotGrid"
k-excel="{ fileName: reportCtrl.CurrentReport.DS_REPORT + '.xlsx' }"
k-height="'100%'"
k-sortable="true"
k-filterable="true"
k-row-header-template="'#= rowTemplate #'"
kx-data="resultCtrl.ReportResult"
kx-data-source-options="{
data: resultCtrl.ReportResult,
schema: {
fields: {
DT_MEASURE: { type: 'shortDate' }
},
cube: {
dimensions: {
ID_MEASURE_A: { caption: 'Measure A' },
ID_MEASURE_B: { caption: 'Measure B' },
},
measures: {
'AverageA': { field: 'ID_MEASURE_A', aggregate: 'average' },
'AverageB': { field: 'ID_MEASURE_B', aggregate: 'average' }
}
},
},
columns: [
{ name: 'ID_PRODUCT', expand: true }
],
rows: [
{ name: 'DT_MEASURE', expand: true },
],
measures: ['AverageA', 'AverageB']
}"
kx-vertical-stretch="true">
</div>
And here the script rowTemplate:
<script id="rowTemplate" type="text/x-kendo-template">
# if (member.name.indexOf("DT_MEASURE") === 0 && member.name !== "DT_MEASURE") { #
#: kendo.toString(kendo.parseDate(member.caption), "dd-MM-yyyy") #
# } else { #
#: member.caption.toString() #
# } #
</script>
I want to define my rowHeaderTemplate to show the correct format of a date but every attempt to do it doesn't work.
Any suggestion?
While trying to perform batch update, I am not able to post values to MVC WEB API controller neither I am getting Record IDs in mu PUT controller.
I have already visited some of the links egarding same problem but got no solution.
$(document).ready(function () {
debugger;
var webapiUrl = (My webapi);
dataSource = new kendo.data.DataSource({
type: "json",
transport: {
read: {
url: webapiUrl + api/GetProductsByShipID/1",
contentType: "application/json",
},
update: {
url: webapiUrl + api/OpportunityProducts/1",
contentType: "application/json",
type: "PUT"
},
destroy: {
url: webapiUrl + /api/OpportunityProducts/",
contentType: "application/json",
type: "DELETE"
},
create: {
url: webapiUrl + /api/OpportunityProducts/",
contentType: "application/json",
type: "POST"
},
parameterMap: function (options, operation) {
if (operation !== "read") {
return options;
}
}
},
batch: true,
pageSize: 10,
schema: {
model: {
id: "ID",
fields: {
ID: { editable: false, nullable: true },
ProductDesc: { type: "string" },
Quantity: {type: "number"},
UnitPrice: { type: "number"}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
toolbar: ["create", "save", "cancel"],
columns: [
"ProductName",
{ field: "ProductDesc", title: "Product Desc"},
{ field: "Quantity", title: "Quantity" },
{ field: "UnitPrice", width: 120 },
{ command: "destroy", title: " ", width:150 }],
editable: true
});
});
</script>
Well after some workaround, late night I was able to modify parameterMap section of my kendo grid which lead me to expected output.
This is how I updated my parameterMap section...
Previous
parameterMap: function (options, operation) {
if (operation !== "read") {
return options;
}
}
Updated
parameterMap: function (options, operation) {
debugger;
if (operation !== "read" && options.models) {
var webapiUrl = (my webapi);
var i = 0;
for (i = 0; i < options.models.length; i++) {
$.ajax({
cache: false,
async: true,
type: "PUT",
url: webapiUrl + "/api/OpportunityProducts/" + options.models[i].Id,
data: {
ID: options.models[i].ID,
ProductDesc: options.models[i].ProductDesc,
Quantity: options.models[i].Quantity
},
success: function (data) {
},
error: function (jqXHR, exception) {
alert(exception);
}
});
}
Is there a straightforward way to enable an entire row of ng-grid to edit mode, in the click of a button. I know if you set gridOptions for enableCellEditOnFocus or enableCellEdit, you can click/doubleclick to edit a particular cell. But what I want is to have a button in each row, and when clicked on that the whole row should be editable.
The code I have right now is this, but it doesn't achieve what I want.
vm.grid.childServicesGridOptions = {
data: "vm.grid.childServices",
rowHeight: 35,
enableCellSelection: false,
enableRowSelection: true,
multiSelect: false,
columnDefs: [
{ field: 'serviceId', displayName: 'Service Id', visible: false },
{ field: 'location.locationName', displayName: 'Location Name', width: "25%" },
{ field: 'serviceDisplayName', displayName: 'Product/Service Display Name', width: "25%" },
{ field: 'duration', displayName: 'Duration', width: "10%" },
{
field: '', displayName: 'Action', width: "10%",
cellTemplate: '<button ng-click="vm.grid.editChildService(row)"><span class="glyphicon glyphicon-pencil"></span></button>'
}
],
pagingOptions: { pageSizes: [10, 20, 30], pageSize: 10, currentPage: 1 },
totalServerItems: 'vm.grid.childServices.length',
};
vm.grid.editChildService = function (row) {
row.entity.edit = !row.entity.edit;
}
It seems like there's no straightforward way to do this, I had to add a cell template and set it to edit in the [Edit] button click. Following is what I did:
vm.holidayProperties.childHolidayGridOptions = {
data: "holidayProperties.selectedHoliday.childHolidays",
rowHeight: 35,
enableCellSelection: false,
enableRowSelection: true,
multiSelect: false,
columnDefs: [
{ field: 'holidayId', displayName: localize.getLocalizedString('_HolidayId_'), visible: false },
{ field: 'location.locationName', displayName: localize.getLocalizedString('_LocationName_'), width: "15%" },
{ field: 'holidayName', displayName: localize.getLocalizedString('_Holidayname_'), width: "15%" },
{
field: 'isAllDay', displayName: localize.getLocalizedString('_IsAllday_'), width: "10%",
cellTemplate: '<input type="checkbox" ng-model="row.entity.isAllDay" ng-change="holidayProperties.setEndDateDisabled()" ng-disabled="!row.editable">'
},
{
field: '', displayName: localize.getLocalizedString('_Action_'), width: "10%",
cellTemplate: '<button ng-show="!row.editable" ng-click="holidayProperties.setRowEditable(row)"><span class="glyphicon glyphicon-pencil"></span></button>' +
'<button ng-show="row.editable" ng-click="holidayProperties.reset(row)"><span class="glyphicon glyphicon-arrow-left"></span></button>'
}
],
enablePaging: true,
showFooter: true,
showFilter: true,
pagingOptions: { pageSizes: [10, 20, 30], pageSize: 10, currentPage: 1 },
totalServerItems: 'holidayProperties.selectedHoliday.childHolidays.length',
};
vm.holidayProperties.setRowEditable = function (row) {
row.editable = true;
}
vm.holidayProperties.reset = function (row) {
clientcontext.rejectChangesForEntity(row.entity);
row.editable = false;
}
Using the row.editable field, I set the disabled property of the field to be edited to true or false.