Hi there,
I’ve created some modules to export some info to Excel XLSX
format using the classes Workbook and Worksheet from Telerik.Web.Spreadsheet.
So far so good, but now I
need to setup the page (paper size and margins) for some Worksheets but I don’t
see any method or property about this functionality in Telerik.Web.Spreadsheet.
Searching the web, I’ve realized
that there’s another API in the assembly Telerik.Windows.Documents.Spreadsheet.dll.
In fact, this link shows the features I need
https://docs.telerik.com/devtools/document-processing/libraries/radspreadprocessing/features/worksheetpagesetup
Right now I’ve a lot of
code written in my exporters to Excel using the API in the Telerik.Web.Spreadsheet.
Is it possible to setup the
page using the Telerik.Web.Spreadsheet API?
If not what are my options?
Thank you.
Hi there,
I have a schedules grid which has 4 columns (2 columns are hidden), server paging is set to true, scrollable is endless and page size is 20. Grid constructor code below.
$(
"#schedules-grid"
).kendoGrid({
dataSource: {
transport: {
read: {
url: `/${window[
"routeContext"
].TenantName}/Scheduler/GetSchedules`,
dataType:
"json"
,
contentType:
"application/json"
,
type:
"GET"
,
headers: window[
"authenticationBearerToken"
]
},
},
autoSync:
true
,
serverFiltering:
false
,
serverPaging:
true
,
serverSorting:
false
,
error: (e: kendo.data.DataSourceErrorEvent) => {
console.log(e);
},
pageSize: 20,
schema: {
model: {
id:
"scheduleId"
},
total: data => {
if
(data && data[0].total) {
return
data[0].total;
}
return
0;
},
data: data => {
if
(data) {
return
data;
}
return
[];
}
}
},
scrollable: {
endless:
true
},
filterable:
true
,
sortable:
true
,
selectable:
true
,
resizable:
true
,
change: (e) => {
var
selectedItem: any = e.sender.dataItem(e.sender.select());
if
(
this
.onScrollToSelectedRow)
this
.onScrollToSelectedRow(selectedItem);
},
columns: [
{
field:
"code"
,
title:
"Code"
,
hidden:
true
},
{
field:
"recurrenceType"
,
title:
"Recurrence"
,
width: 130
},
{
field:
"title"
,
title:
"Name"
},
{
field:
"scheduleId"
,
title:
"Schedule Id"
,
hidden:
true
}
]
});
In the grid, a function "onScrollToSelectedRow" is called when the schedules grid change event fires. Code snippet below which scrolls to and highlight the selected item.
function
(dataItem) {
var
scheduleGrid = $(
"#schedules-grid"
).data(
"kendoGrid"
);
if
(scheduleGrid) {
var
scrollContentOffset = scheduleGrid.element.find(
"tbody"
).offset().top;
var
selectContentOffset = scheduleGrid.select().offset().top;
var
distance = selectContentOffset - scrollContentOffset;
scheduleGrid.element.find(
".k-grid-content"
).animate({
scrollTop: distance
}, 400);
}
}
The issue that I'm struggling with is when a user select a schedule (let's say another grid from another page) and, that selected item is not available in the schedules grid data source first 20 data items, the selectedItem variable in grid's change event will be undefined.
So, what I did I use insert method of schedules grid data source to append the selected item as last item in the data source.
function
selectGridScheduleItem() {
var
schedGrid = window.Scheduler.scheduleGrid;
if
(schedGrid) {
if
(window.az_ScheduleviewModel) {
var
scheduleRowItem = schedGrid.dataSource.get(window.az_ScheduleviewModel.data.az_ScheduleId);
if
(scheduleRowItem) {
schedGrid.select(
"tr[data-uid='"
+ scheduleRowItem.uid +
"']"
);
}
else
{
var
schedule = {
autoTitle: window.az_ScheduleviewModel.data.az_Schedule.az_AutoTitle,
code: window.az_ScheduleviewModel.data.az_Schedule.az_Code,
company: window.az_ScheduleviewModel.data.az_CompanyId,
cultureInfo:
null
,
dateEnd: window.az_ScheduleviewModel.data.az_Schedule.az_EndDate,
dateStart: window.az_ScheduleviewModel.data.az_Schedule.az_StartDate,
desc: window.az_ScheduleviewModel.data.az_Schedule.az_Description,
entityMetadata: window.az_ScheduleviewModel.data.az_EntityMetadataId,
init: window.az_ScheduleviewModel.data.az_InitObject,
jobType: window.az_ScheduleviewModel.data.az_JobType,
linkedJobs: 0,
platformResource: window.az_ScheduleviewModel.data.az_PlatformResourceId,
scheduleId: window.az_ScheduleviewModel.data.az_ScheduleId,
state: window.az_ScheduleviewModel.data.az_Schedule.az_State,
title: window.az_ScheduleviewModel.data.az_Schedule.az_Name,
total: 0
}
var
schedRecurrence = undefined;
var
recurrence = window.az_ScheduleviewModel.data.az_Schedule.az_Recurrence;
if
(recurrence !==
null
|| recurrence !== undefined) {
schedRecurrence = JSON.parse(recurrence);
}
if
(schedRecurrence) {
schedule.recurrence = {
end: schedRecurrence.End,
repeatEvery: schedRecurrence.RepeatEvery,
repeatOn: schedRecurrence.RepeatOn,
time: schedRecurrence.Time,
type: schedRecurrence.Type
};
schedule.recurrenceType = schedRecurrence.Type;
}
schedGrid.dataSource.insert(schedGrid.dataSource.data().length, schedule);
schedGrid.setDataSource(schedGrid.dataSource);
scheduleRowItem = schedGrid.dataSource.get(window.az_ScheduleviewModel.data.az_ScheduleId);
schedGrid.select(
"tr[data-uid='"
+ scheduleRowItem.uid +
"']"
);
}
console.log(scheduleRowItem);
}
else
{
console.log(
"Schedule view model is undefined"
);
}
}
else
{
console.log(
"Schedules grid is undefined"
);
}
}
The function "selectGridScheduleItem" select the schedule row item in schedules grid and fires the change event of the grid if item is available in the data source. Otherwise, it uses insert method to insert the selected item in schedules grid data source and select the data item.
I'm not 100% sure using the insert method (if that solves the problem). If there's a better way to do it please enlighten me.
And another thing I noticed, it doesn't scroll and highlight the row of the selected item.
Cheers,
Junius
@(Html.Kendo().Grid<dynamic>()
.Name(
"Grid"
)
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(
true
)
.Model(cfg =>
{
cfg.Id(
"SsdID"
);
foreach
(var property
in
Model.PropertyDescriptors)
{
cfg.Field(property.Name, property.DataType);
}
})
.Read(cfg => cfg.Type(HttpVerbs.Post)
.Action(
"ReadDataForDefinition"
,
"ManualDataEntry"
,
new
{ id = Model.LDefinitionId }))
.Update(u => u.Type(HttpVerbs.Post).Action(
"UpdateDataForDefinition"
,
"ManualDataEntry"
,
new
{ id = Model.LDefinitionId }))
.Create(u => u.Type(HttpVerbs.Post).Action(
"Create"
,
"ManualDataEntry"
,
new
{ id = Model.LDefinitionId }))
)
.Resizable(resizing => resizing.Columns(
true
))
Columns(columns =>
{
foreach
(var property
in
Model.PropertyDescriptors.Where(desc => desc.DisplayOrder.HasValue))
{
var binding = columns.Bound(property.DataType, property.Name);
if
(property.DataType ==
typeof
(DateTime) || property.DataType ==
typeof
(DateTime?))
binding.Format(
"{0:d}"
);
binding.Column.Title = property.Label;
}
columns.Command(command =>
{
command.Edit();
command.Destroy();
});
})
.ToolBar(toolbar => { toolbar.Create(); })
.Pageable(paging =>
{
paging.ButtonCount(10);
paging.PreviousNext(
true
);
paging.PageSizes(
true
);
})
.Editable(edit => edit.Mode(GridEditMode.InLine))
.Sortable()
.Scrollable()
.Filterable()
)
I am evaluating MVC scheduler for appointment scheduling. I need to show available time slots in different offices and users can pick any time slot and schedule appointment (like a doctors office application) . Do you have any example which is similar to this?
I have a Switch widget and an associated boolean property in my View Model:
@(Html.Kendo().Switch()
.Name("IsImmediateEvent")
.Messages(c => c.Checked("true").Unchecked("false"))
.Events(e => e.Change("onImmediateChange"))
)
View Model Property:
public bool IsImmediateEvent { get; set; }
When my boolean View Model property (IsImmediateEvent) is set to true, the Switch widget is not checked.
How can I get the Switch widget to recognize its backing property and set the Switch widget to "on" when my boolean property is "true?"
Hi there,
I've been searching and reading for 2 days now and I've some doubts about the TreeView that I need to clarify.
1. The tree will have three levels of deep
+ Contenedor "zst"
|
| --- Bulto 1. Largo: 2.6 Ancho: 3.6 Alto: 5.3
| |
| --- Producto: "Table" Cantidad: 32
| --- Producto: "Computer" Cantidad: 25
|
| --- Bulto 2. Largo: 1.3 Ancho: 8.3 Alto: 2.2
| |
| --- Producto: "Mouse" Cantidad: 8
| --- Producto: "Keyboard" Cantidad: 7
|
+ Contenedor "trx"
|
|
--- Bulto 1. Largo: 4.2 Ancho: 13.1 Alto: 15.7
|
--- Producto: "Display" Cantidad: 7.7
--- Producto: "Battery" Cantidad: 2.3
What follows are questions that I don't have answers so far and I don't know whether it's possible to achieve using this widget
1. I need to apply a different template to every level:
a) In the first level (Contenedor) I need to show the word "Contenedor" plus a string specified by the user
b) In the second level (Bulto) I need to show the word "Bulto" plus "Largo" followed by a number then the word "Ancho" followed by a number and the word "Alto" followed by a number
c) In the third level (Producto) I need to show the word "Producto" plus a string then the word "Cantidad" followed by a number
2. In every level of the tree the user can edit the values:
a) In the first level (Contenedor) the user can change the description (a string)
b) In the second level (Bulto) the user can change the "Largo" (decimal), "Ancho" (decimal) and "Alto" (decimal)
c) In the third level (Producto) the user can change "Cantidad" (decimal).
3. The TreeView must support drag & drop between it and a Grid widget so the user can drop the items from the tree in the grid and items from the grid in the Tree.
4. How do I get the model associated to a node in the Tree? If possible I would like to keep in the datasource the same members of the classes defined in the backend for each node in the Tree. I.e.
When I get the model of a node in the second level (Bulto) I would like to get this in the JavaScript object:
{
ID: 1,
NumeroBulto: 2,
Largo: 43,
Ancho: 23.3,
Alto: 2.1,
Volumen: 4.2,
}
Instead of the TreeViewItem object.
Here's my model
01.
public
class
TreeModel
02.
{
03.
public
List<ContenedorModel> Contenedores {
get
;
set
; }
04.
}
05.
06.
public
class
ContenedorModel
07.
{
08.
public
Guid ID {
get
;
set
; }
09.
public
string
Descripcion {
get
;
set
; }
10.
public
List<BultoModel> Bultos {
get
;
set
; }
11.
}
12.
13.
public
class
BultoModel
14.
{
15.
public
Guid ID {
get
;
set
; }
16.
public
int
NumeroBulto {
get
;
set
; }
17.
public
decimal
Largo {
get
;
set
; }
18.
public
decimal
Ancho {
get
;
set
; }
19.
public
decimal
Alto {
get
;
set
; }
20.
public
decimal
Volumen {
get
;
set
; }
21.
public
List<ProductoTreeModel> Productos {
get
;
set
; }
22.
}
23.
24.
public
class
ProductoTreeModel
25.
{
26.
public
Guid ID {
get
;
set
; }
27.
public
string
Descripcion {
get
;
set
; }
28.
public
decimal
Cantidad {
get
;
set
; }
29.
}
Here's my view
01.
@(Html.Kendo().TreeView()
02.
.Name(
"treeView"
)
03.
.TemplateId(
"treeview-template-contenedor"
)
04.
.BindTo((IEnumerable<ContenedorModel>)Model.TreeModel.Contenedores, (NavigationBindingFactory<TreeViewItem> mappings) =>
05.
{
06.
mappings.For<ContenedorModel>(binding => binding.ItemDataBound((item, contenedor) =>
07.
{
08.
item.Text = $
"Contenedor: {contenedor.Descripcion}"
;
09.
})
10.
.Children(x => x.Bultos));
11.
12.
mappings.For<BultoModel>(binding => binding.ItemDataBound((item, bulto) =>
13.
{
14.
item.Text = $
"Bulto: {bulto.NumeroBulto}"
;
15.
})
16.
.Children(x => x.Productos));
17.
18.
mappings.For<ProductoTreeModel>(binding => binding.ItemDataBound((item, producto) =>
19.
{
20.
item.Text = producto.Descripcion;
21.
}));
22.
})
23.
.DragAndDrop(
true
)
24.
)
Here's the template
1.
<script id=
"treeview-template-contenedor"
type=
"text/kendo-ui-template"
>
2.
<span style=
"color:blue"
>
#: item.Text #</span>
3.
<button><span class=
'k-icon k-edit'
/></button>
4.
</script>
However the way I use the template here is applied to all levels.
Can anyone please help me with this?
Thank you.
Currently I read the data needed for the ComboBox like:
$(domNode).kendoComboBox({
dataSource: {
transport: {
read: function(options) {
setReadOptions && setReadOptions(options);
const filters = that.getDataSourceData(options.data);
const serviceUrl = `${trackUrl.includes('?') ? trackUrl + '&' : trackUrl+'?'}${that.encodeData(filters)}`;
ajax.get<any>(serviceUrl)
.then((returnObj) => {
let comboBoxOptions = returnObj;
if (filterOptions) {
comboBoxOptions = filterOptions(returnObj);
}
options.success(comboBoxOptions);
}).fail(() => {
options.error("Could not retrive data for selected document Id.");
})
},
prefix: ''
},
. . . . .
Now there is the possibility of the url that is used could change. Based on that changed url I would like to set new options with a call to something like I do for when the ajax method returns
if (filterOptions) {
comboBoxOptions = filterOptions(returnObj);
}
options.success(comboBoxOptions);
I know I can refresh the comboBox with something like
this.comboBox.dataSource.read()
But I don't know how to also affect the options for the comboBox?
Kevin
How do I remove rows? Currently I do something like:
e.workbook.sheets.forEach(function (sheet) {
sheet.rows = sheet.rows.filter(r => r.type != "group-header");
});
e.sender.saveAsExcel();
But it seems that the saveAsExcel() function is ignoring the rows that I have filtered out?
I've got a bunch of methods client-side that build up a list of all the filters to apply to a grid. However, I'm told it is possible to pass this list over to the server in order to have better control over the filters? In my case, I am trying to create a filter that looks like this:
`(cond || cond || cond) && cond`
I've noticed that Kendo seems to only support cases where it is `cond || cond` or `cond && cond`. Unless there is a way to make the above condition work, how can I pass my filters to the server and the `DataSourceRequest` in order to have that further control?
Hi,
I am new to using KendoUI and am sorry if this has been answered before but I cannot seem to find an answer that works for me. I have a search button and a grid on the page. I am taking to d.3 in the backend (a DMS system) using library calls. The user enters s/he search query in the field and I call the Read method in my Controller to get the data from d.3. What is happening is that I am getting the data back in the request but the grid is not updating.
Here is my MVC code:
@(Html.Kendo()
.Grid(Model)
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Read(r => r.Action("Read", "Search"))
)
.Filterable(f => f.Mode(GridFilterMode.Row))
.Columns(columns =>
{
{
columns.Bound(c => c.DocumentType)
.Filterable(false)
.Width("150px")
.Title(@Localizer["SearchTableHeaderDocumentType"]);
columns.Bound(c => c.DocumentTypeLong)
.Filterable(true)
.Title(@Localizer["SearchTableHeaderDocumentTitle"])
.Filterable(ftb => ftb.Cell(cell => cell.Operator("contains").SuggestionOperator(FilterType.Contains)));
})
)
I have a button on the page that does the submit using the following code:
var search = $("#search-field").val();
if (!search) return;
if (search.trim() === "") return;
var dataSource = $("#grid").data("kendoGrid").dataSource;
var parameters = {
searchFor: search
}
// call the search passing the parameters -> searchFor is the parameter name on the SearchController/Read method
dataSource.read(parameters);
This calls my Read method in the SearchController.cs. The Search method creates the data that is supposed to be passed back to the Grid:
// setup your result for KendoUI
DataSourceResult result = model.Entries.ToDataSourceResult(request);
// return
return Json(result);
I also see the data structure in the response if I check the event after the RequestEnd:
.Events(events => events.RequestEnd("onRequestEnd"))
or if I check the response in Chrome - this is what I get:
+0Object {DocumentId: "GD00000016", DocumentType: "D3CHG", DocumentTypeLong: "D.3 :: Fehler/Request", …}Object
+1Object {DocumentId: "GD00000148", DocumentType: "DEPSU", DocumentTypeLong: "Abteilung :: Leitung", …}Object
+2Object {DocumentId: "GD00000149", DocumentType: "DEPSU", DocumentTypeLong: "Abteilung :: Leitung", …}Object
+3Object {DocumentId: "GD00000150", DocumentType: "DEPSU", DocumentTypeLong: "Abteilung :: Leitung", …}Object
+4Object {DocumentId: "GD00000266", DocumentType: "IDOCU", DocumentTypeLong: "Infrastruktur :: Handbuch", …}Object
+5Object {DocumentId: "GD00000267", DocumentType: "IDOCU", DocumentTypeLong: "Infrastruktur :: Handbuch", …}Object
+6Object {DocumentId: "GD00000268", DocumentType: "IDOCU", DocumentTypeLong: "Infrastruktur :: Handbuch", …}Object
+7Object {DocumentId: "GD00000269", DocumentType: "CKNOW", DocumentTypeLong: "Global :: Wissen", …}Object
+8Object {DocumentId: "GD00000277", DocumentType: "IDOCU", DocumentTypeLong: "Infrastruktur :: Handbuch", …}Object
very odd.
Maybe this helps: If I return dummy data from the Index method (I am currently returning an empty list => return View(new List<SearchEntryModel>());) before using the Read method from the grid everything magically works (except that the number of entries is limited to the return from the Index method).
Sorry about the weird explanation but I don't know how to better explain it.
Thank you in advance
Martin