Hi Guys,
I have a custom button in a nested grid. I want when the user clicks the button to download a file saved in my database and save it to the local disk.
Whats the best approach? And could you provide a sample of how to call the controller action for download, how to pass ASSIGNMENT_DOCUMENT_ID, and after returning the file from the controller to ask the user where to save it? Not sure how to do post and get or do I need to do a get with the custom button..
Here is my nested grid:
@using PartnerLink.Models
@using Telerik.OpenAccess.SPI
@model Tuple<
TBL_ASSIGNMENT
, IQueryable<TBL_ASSIGNMENT_EXPENDITURE_VALUE>, IQueryable<
TBL_ASSIGNMENT_INCOME_VALUE
>, IQueryable<
TBL_ASSIGNMENT_VEHICLE
>>
<
div
style
=
"height:500px"
>
@(Html.Kendo().Grid<
AssignmentDocTypesExt
>()
.Name("gridCaseDocuments")
.Columns(columns =>
{
columns.Bound(p => p.ASSIGNMENT_DOCUMENT_TYPE_ID).Hidden(true);
columns.Bound(p => p.ASSIGNMENT_ID).Hidden(true);
columns.Bound(p => p.DOCUMENT_TYPE_ID).Hidden(true);
columns.Bound(p => p.WHICH_APPLICANT).Hidden(true);
columns.Bound(p => p.DOCUMENT_TYPE_STATUS_ID).Hidden(true);
columns.Bound(p => p.CREDITOR_ID).Hidden(true);
columns.Bound(p => p.numOfUploadedFiles).Hidden(true);
columns.Bound(p => p.documentDescription).Title("Document").Width(350);
columns.Bound(p => p.whichApplicant).Title("Applicant").Width(100);
columns.Bound(p => p.documentTypeStatusDescription).Title("Type Status").Width(200);
columns.Bound(p => p.COMPLETE_FLAG).Title("Complete").ClientTemplate("<
input
type
=
'checkbox'
#= COMPLETE_FLAG ?
checked
=
'checked'
:'' # disabled />").Width(90);
columns.Bound(p => p.autoCompleteOnUpload).Title("Auto Complete").ClientTemplate("<
input
type
=
'checkbox'
#= autoCompleteOnUpload ?
checked
=
'checked'
:'' # disabled />").Hidden(true);
columns.Command(command => { command.Edit().Text("Upload"); }).Width(230);
})
.Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("ClientDocumentUpload").Window(w => w.Events(e => e.Close("onCloseClientDocumentUpload"))))
.Sortable()
.Scrollable()
.ClientDetailTemplateId("gridCaseDocumentsDetails")
.Pageable(pager => pager.Refresh(true))
.Resizable(resize => resize.Columns(true))
.HtmlAttributes(new { style = "height:500px;" })
.Events(clientEvents => clientEvents.DataBound("onRowDataBoundgridCaseDocuments"))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handlerCaseDocuments"))
.Model(model => model.Id(p => p.ASSIGNMENT_DOCUMENT_TYPE_ID))
.Read(read => read.Action("CaseDocuments_Read", "Home", new { id = Model.Item1.ASSIGNMENT_ID }))
.Update(update => update.Action("CaseDocuments_Update", "Home"))
)
)
</
div
>
<
script
id
=
"gridCaseDocumentsDetails"
type
=
"text/kendo-tmpl"
>
@(Html.Kendo().Grid<
ClientDocumentsExt
>()
.Name("gridCaseDocuments_#=ASSIGNMENT_DOCUMENT_TYPE_ID#")
.Columns(columns =>
{
columns.Bound(m=>m.ASSIGNMENT_DOCUMENT_ID).Hidden(true);
columns.Bound(m => m.FILE_NAME).Title("File Name");
columns.Bound(m => m.uploadedBy).Title("Uploaded By").Width(210);
columns.Bound(m => m.DATE_CREATED).Title("Upload Date").Format("{0:dd/MM/yyyy}").Width(110);
columns.Command(c => c.Custom("Download").Click("onClickDownloadClientDoc")).Width(110);
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.Model(model => model.Id(m => m.ASSIGNMENT_DOCUMENT_ID))
.Read(read => read.Action("gridCaseDocumentsDetails_Read", "Home", new { id = "#=ASSIGNMENT_DOCUMENT_TYPE_ID#" }))
)
.Pageable(pager => pager.Refresh(true))
.Sortable()
.Scrollable()
.ToClientTemplate()
)
</
script
>
<
script
type
=
"text/javascript"
>
function error_handlerCaseDocuments(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
$("#gridCaseDocuments").find(".k-grid-content").height(421);
function onClickDownloadClientDoc(e)
{
alert(e.ASSIGNMENT_DOCUMENT_ID);
}
function onRowDataBoundgridCaseDocuments(e) {
var grid = $("#gridCaseDocuments").data("kendoGrid");
var gridData = grid.dataSource.view();
for (var i = 0; i <
gridData.length
; i++) {
var
currentUid
=
gridData
[i].uid;
if (gridData[i].COMPLETE_FLAG) {
var
currenRow
=
grid
.table.find("tr[
data-uid
=
'" + currentUid + "'
]");
$(currenRow).css("background-color", "rgb(164,198,57)");
} else if (gridData[i].numOfUploadedFiles > 0)
{
var currenRow = grid.table.find("tr[data-uid='" + currentUid + "']");
$(currenRow).css("background-color", "rgb(255,191,0)");
}
}
}
function onCloseClientDocumentUpload()
{
alert("onCloseClientDocumentUpload");
}
</
script
>
Hello,
What I am trying to achieve is add a placeholder in a dropdownlist that will display the binded model's property. When trying to use DisplayTextFor in the OptionLabel, I get "undefined" first option in the DropDownList. Is there a way to achieve this? I don't want to hardcode the OptionLabel.
Thanks
When I build a server bound grid with a pager and you click to go to the next page, it returns you to the top of the page (full page refresh). With an ajax grid, it keeps you at the same location on the page that you were on originally. This is not unexpected behavior, but is there a way to get around it?
Thanks!
Laurie
@(Html.Kendo().TabStrip()
.Name("tabstrip1")
.Items(tabstrip =>
{
tabstrip.Add().Text("Customer Information")
.Content(@<
div
>
@using (Ajax.BeginForm("AddData", "Customer", new AjaxOptions { HttpMethod = "post" }))
{
<
input
type
=
"button"
class
=
"k-button"
value
=
"Submit"
onclick
=
"checkValues()"
/>
}
</
div
>
);
})
)
@(Html.Kendo().TabStrip()
.Name("tabstrip2")
.Items(tabstrip =>
{
tabstrip.Add().Text("Customer Information")
.Content(@<
div
>
<
form
action
=
"/Customer/AddData"
data-ajax
=
"true"
data-ajax-method
=
"post"
id
=
"form0"
method
=
"post"
novalidate
=
"novalidate"
>
<
input
type
=
"button"
class
=
"k-button"
value
=
"Submit"
onclick
=
"checkValues()"
/>
</
form
>
</
div
>
);
})
)
@model PASS.ViewModels.Proposals.UpdateViewModel
@{
ViewBag.Title = "My Proposal";
}
<
h2
>My Proposal</
h2
>
@(Html.Kendo().TabStrip()
.Name("tsProposal")
.SelectedIndex(0)
.Items(items =>
{
items.Add().Text("General").LoadContentFrom("_General", "Proposals", new { proposalID = Model.ID });
items.Add().Text("Required Information").LoadContentFrom("_Required", "Proposals", new { proposalID = Model.ID });
items.Add().Text("Associates").LoadContentFrom("_Experimenters", "Proposals", new { proposalID = Model.ID });
items.Add().Text("Research").LoadContentFrom("_Questions", "Proposals", new { proposalID = Model.ID });
items.Add().Text("Attachments").LoadContentFrom("_Attachments", "Proposals", new { proposalID = Model.ID });
items.Add().Text("Time Request").LoadContentFrom("_TimeRequests", "Proposals", new { proposalID = Model.ID });
items.Add().Text("Errors").LoadContentFrom("_Errors", "Proposals", new { proposalID = Model.ID });
})
)
<
script
type
=
"text/javascript"
>
$(document).ready(function () {
var errorCount = @Html.Raw(Json.Encode(Model.Error_Count));
var tabStrip = $("#tsProposal").data("kendoTabStrip");
if (errorCount == 0) {
$(tabStrip.items()[6]).attr("style", "display:none");
}
tabStrip.tabGroup.on('click', 'li', function (e) {
tabStrip.reload($(this));
});
})
</
script
>
@model PASS.ViewModels.Proposals.GeneralViewModel
@using (Ajax.BeginForm("_General", "Proposals", new AjaxOptions { UpdateTargetId = "generalReturnMsg", HttpMethod = "Post" }))
{
@Html.HiddenFor(model => model.Proposal_ID, Model.Proposal_ID)
<
div
class
=
"editor-container"
>
<
div
class
=
"editor-label"
>
@Html.Label("Title:")
</
div
>
<
div
class
=
"editor-field"
>
@Html.TextBoxFor(model => model.Title, new { style = "width: 350px;" })
@Html.ValidationMessageFor(model => model.Title)
</
div
>
<
br
class
=
"clear"
/>
<
br
/>
<
div
class
=
"editor-label"
>
@Html.Label("Total hours requested for LIFE of the proposal")
</
div
>
<
div
class
=
"editor-field"
>
@Html.TextBoxFor(model => model.Total_Hours_Requested)
@Html.ValidationMessageFor(model => model.Total_Hours_Requested)
</
div
>
<
br
class
=
"clear"
/>
<
br
/>
<
br
/>
<
p
><
input
type
=
"submit"
value
=
"Save"
/></
p
>
<
div
id
=
"generalReturnMsg"
></
div
>
</
div
>
}
I can't seem to find any examples of adding a menu item to a splitbutton in a toolbar.
Here is the code I have for the splitbutton:
$("#toolbar").kendoToolBar({
items: [
{
type: "splitButton",
text: "Select",
id: "selectButton",
click: selectButtonClickHandler,
menuButtons: [
{ text: "foo1" },
{ text: "foo2" }
]
}
]
});
I'm trying to do something like $("#selectButton").add(new menuButton("foo3"));
Is there a way to do this? How have I missed it in the documentation?
I'm trying to filter calendar MeetingAttendees which can have multiple users. I've built a filter and tested with various options, but it doesn't work. The basic example shows how to filter a calendar owner (which is a single value) and it works fine for me. But Attendees is an array and when I'm trying to filter that all my events disappear.
Here is my filter:
<
script
type
=
"text/javascript"
>
$(function () {
$("#teamMembers :checkbox").change(function (e) {
var checked = $.map($("#teamMembers :checked"), function (checkbox) {
return parseInt($(checkbox).val());
});
//alert(checked);
var filter = {
logic: "or",
filters: $.map(checked, function (value) {
return {
operator: "eq",
field: "Attendees",
value: value
};
})
};
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.dataSource.filter(filter);
});
})
</
script
>
}
Here is the code that loads calendar events:
public virtual IQueryable<
MeetingViewModel
> GetAll()
{
return db.Meetings.ToList().Select(meeting => new MeetingViewModel
{
MeetingID = meeting.MeetingID,
Title = meeting.Title,
Start = DateTime.SpecifyKind(meeting.Start, DateTimeKind.Utc),
End = DateTime.SpecifyKind(meeting.End, DateTimeKind.Utc),
StartTimezone = meeting.StartTimezone,
EndTimezone = meeting.EndTimezone,
Description = meeting.Description,
IsAllDay = meeting.IsAllDay,
SupportGroupId = meeting.SupportGroupId,
RecurrenceRule = meeting.RecurrenceRule,
RecurrenceException = meeting.RecurrenceException,
RecurrenceID = meeting.RecurrenceID,
Attendees = meeting.MeetingAttendees.Select(m => m.AttendeeID).ToArray(),
ActivityTypeId = meeting.ActivityTypeId
}).AsQueryable();
}
Here is my custom editor template:
@model Itsws.Models.MeetingViewModel
@{
//required in order to render validation attributes
ViewContext.FormContext =
new
FormContext();
}
@functions{
public
Dictionary<
string
,
object
> generateDatePickerAttributes(
string
elementId,
string
fieldName,
string
dataBindAttribute,
Dictionary<
string
,
object
> additionalAttributes =
null
)
{
Dictionary<
string
,
object
> datePickerAttributes = additionalAttributes !=
null
?
new
Dictionary<
string
,
object
>(additionalAttributes) :
new
Dictionary<
string
,
object
>();
datePickerAttributes[
"id"
] = elementId;
datePickerAttributes[
"name"
] = fieldName;
datePickerAttributes[
"data-bind"
] = dataBindAttribute;
datePickerAttributes[
"required"
] =
"required"
;
datePickerAttributes[
"style"
] =
"z-index: inherit;"
;
return
datePickerAttributes;
}
}
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.Title))
</div>
<div data-container-
for
=
"title"
class
=
"k-edit-field"
>
@(Html.TextBoxFor(model => model.Title,
new
{ @
class
=
"k-textbox"
, data_bind =
"value:title"
}))
</div>
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.Start))
</div>
<div data-container-
for
=
"start"
class
=
"k-edit-field"
>
@(Html.Kendo().DateTimePickerFor(model => model.Start)
.HtmlAttributes(generateDatePickerAttributes(
"startDateTime"
,
"start"
,
"value:start,invisible:isAllDay"
)))
@(Html.Kendo().DatePickerFor(model => model.Start)
.HtmlAttributes(generateDatePickerAttributes(
"startDate"
,
"start"
,
"value:start,visible:isAllDay"
)))
<span data-bind=
"text: startTimezone"
></span>
<span data-
for
=
"start"
class
=
"k-invalid-msg"
></span>
</div>
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.End))
</div>
<div data-container-
for
=
"end"
class
=
"k-edit-field"
>
@(Html.Kendo().DateTimePickerFor(model => model.End)
.HtmlAttributes(generateDatePickerAttributes(
"endDateTime"
,
"end"
,
"value:end,invisible:isAllDay"
,
new
Dictionary<
string
,
object
>() { {
"data-dateCompare-msg"
,
"End date should be greater than or equal to the start date"
} })))
@(Html.Kendo().DatePickerFor(model => model.End)
.HtmlAttributes(generateDatePickerAttributes(
"endDate"
,
"end"
,
"value:end,visible:isAllDay"
,
new
Dictionary<
string
,
object
>() { {
"data-dateCompare-msg"
,
"End date should be greater than or equal to the start date"
} })))
<span data-bind=
"text: endTimezone"
></span>
<span data-
for
=
"end"
class
=
"k-invalid-msg"
></span>
</div>
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.IsAllDay))
</div>
<div data-container-
for
=
"isAllDay"
class
=
"k-edit-field"
>
<input data-bind=
"checked: isAllDay"
data-val=
"true"
id=
"IsAllDay"
name=
"IsAllDay"
type=
"checkbox"
/>
</div>
@*<div
class
=
"endTimezoneRow"
>
<div
class
=
"k-edit-label"
></div>
<div
class
=
"k-edit-field"
>
<label
class
=
"k-check"
>
<input
checked
=
"checked"
class
=
"k-timezone-toggle"
type=
"checkbox"
value=
"true"
/>
Use separate start and end time zones
</label>
</div>
</div>*@
<script>
$(
".k-timezone-toggle"
).on(
"click"
, function () {
var isVisible = $(
this
).
is
(
":checked"
);
var container = $(
this
).closest(
".k-popup-edit-form"
);
var endTimezoneRow = container.find(
"label[for='EndTimezone']"
).parent().add(container.find(
"div[data-container-for='endTimezone']"
));
endTimezoneRow.toggle(isVisible);
if
(!isVisible) {
var uid = container.attr(
"data-uid"
);
var scheduler = $(
"\#scheduler"
).data(
"kendoScheduler"
);
var model = scheduler.dataSource.getByUid(uid);
model.
set
(
"endTimezone"
,
null
);
}
});
var endTimezone =
'${data.endTimezone}'
;
if
(!endTimezone || endTimezone ==
"null"
) {
$(
".k-timezone-toggle"
).trigger(
'click'
);
}
</script>
@*<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.StartTimezone))
</div>
<div data-container-
for
=
"startTimezone"
class
=
"k-edit-field"
>
@(Html.Kendo().TimezoneEditorFor(model => model.StartTimezone)
.HtmlAttributes(
new
{ data_bind =
"value:startTimezone"
}))
</div>
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.EndTimezone))
</div>
<div data-container-
for
=
"endTimezone"
class
=
"k-edit-field"
>
@(Html.Kendo().TimezoneEditorFor(model => model.EndTimezone)
.HtmlAttributes(
new
{ data_bind =
"value:endTimezone"
}))
</div>*@
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.RecurrenceRule))
</div>
<div data-container-
for
=
"recurrenceRule"
class
=
"k-edit-field"
>
@(Html.Kendo().RecurrenceEditorFor(model => model.RecurrenceRule)
.HtmlAttributes(
new
{ data_bind =
"value:recurrenceRule"
}))
</div>
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.Description))
</div>
<div data-container-
for
=
"description"
class
=
"k-edit-field"
>
@(Html.TextAreaFor(model => model.Description,
new
{ @
class
=
"k-textbox"
, data_bind =
"value:description"
}))
</div>
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.ActivityTypeId))
</div>
<div data-container-
for
=
"ActivityTypeId"
class
=
"k-edit-field"
>
@(Html.Kendo().DropDownListFor(model => model.ActivityTypeId)
.HtmlAttributes(
new
{ data_bind =
"value:ActivityTypeId"
, style =
"width: 280px"
})
.DataTextField(
"Text"
)
.DataValueField(
"Value"
)
.OptionLabel(
"None"
)
.ValuePrimitive(
true
)
.Template(
"<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#"
)
.BindTo(ViewBag.ActivityTypes).ToClientTemplate()
)
</div>
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.SupportGroupId))
</div>
<div data-container-
for
=
"ActivityTypeId"
class
=
"k-edit-field"
>
@(Html.Kendo().DropDownListFor(model => model.SupportGroupId)
.HtmlAttributes(
new
{ data_bind =
"value:SupportGroupId"
, style =
"width: 280px"
})
.DataTextField(
"Text"
)
.DataValueField(
"Value"
)
.OptionLabel(
"None"
)
.ValuePrimitive(
true
)
.Template(
"<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#"
)
.BindTo(ViewBag.SupportGroups).ToClientTemplate()
)
</div>
<div
class
=
"k-edit-label"
>
@(Html.LabelFor(model => model.Attendees))
</div>
<div data-container-
for
=
"Attendees"
class
=
"k-edit-field"
>
@(Html.Kendo().MultiSelectFor(model => model.Attendees)
.HtmlAttributes(
new
{ data_bind =
"value:Attendees"
})
.DataTextField(
"Text"
)
.DataValueField(
"Value"
)
.ValuePrimitive(
true
)
.TagTemplate(
"<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#"
)
.ItemTemplate(
"<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#"
)
.BindTo(ViewBag.TeamMembers).ToClientTemplate()
)
</div>
@{
ViewContext.FormContext =
null
;
}
Here is the sheduler code:
@(Html.Kendo().Scheduler<
Itsws.Models.MeetingViewModel
>()
.Name("scheduler")
.Date(DateTime.Today)
.Editable(editable =>
{
editable.TemplateName("CustomEditorTemplate");
})
.StartTime(new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 7, 00, 00))
.Height(600)
.Views(views =>
{
views.DayView();
views.WeekView(weekView => weekView.Selected(true));
views.MonthView();
views.AgendaView();
views.TimelineView();
})
.Timezone("Etc/UTC")
.DataSource(d => d
.Model(m =>
{
m.Id(f => f.MeetingID);
m.Field(f => f.Title).DefaultValue("No title");
m.RecurrenceId(f => f.RecurrenceID);
m.Field(f => f.Title).DefaultValue("No title");
})
.Read("Meetings_Read", "Scheduler")
.Create("Meetings_Create", "Scheduler")
.Destroy("Meetings_Destroy", "Scheduler")
.Update("Meetings_Update", "Scheduler")
)
)
Hello everyone,
I'm currently testing the Kendo Ui, especially the Grid, in an ASP.NET MVC - Environment and I'm a bit confused by the AJAX-Databinding.
The grid is constructed with the Kendo MVC GridBuilder in a razor-view.
There are multiple columns that are set to visible / invisible dynamically.
Everything was working like a charm until I've inspected the network-traffic that showed me, that the JSON-Result contains every column of the IEnumerable the grid is bound to, also the ones that are not even mentioned in the Columns-section.
Is there a way to turn this off and only download the data that is actually needed?
Thanks.
Kind regards,
Stefan
Hi,
I am trying to load the razor page/ form as acontent for TabStrip dynamically from Menu click event. The telerik team can help to with sample example.
Thanks,
Kiran