I'm using the ASP.NET MVC wrapper for Kendo UI and I'm trying to bind several dropdownlists within a custom template (x-kendo-template). I can't figure out how to do this using the ASP.NET MVC Wrapper (this is similar to this question: How do I bind a DropDownList to a DataSource within an editor template using the scheduler?).
There are some examples on using the Kendo Web version, but no complete examples out there that show using a custom pop-up editor with the scheduler that contains a dropdownlist pulling data from a URL (json data).
Is there an end-to-end example? I can load the scheduler with data. The issue is with the custom template and dropdownlist binding.
EDIT:
After searching extensively, I stumbled upon a "getting started" page from Telerik on using the Kendo UI Scheduler in ASP.NET MVC. They (Telerik) really need to do a better job cross-linking between Demos to Documentation to APIs and Examples (Here is the example)
I've also created a blog post that wraps everything for a Scheduler (from the database table to the Views), you can see that here.Kendo UI Scheduler with ASP.NET MVC and Peta Poco
The example shed some light which the demo and documentation do not do, like for instance, the ViewModel they use in their example online:
C# ViewModel
public class Projection : ISchedulerEvent
{
public string Title { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string Recurrence { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
// Custom Field
public int EventId { get; set; }
public int CustomerId { get; set; }
}
Your ViewModel that you use for the Scheduler must inherit from the ISchedulerEvent class or it will not work correctly.
Razor View
The Razor View is pretty straight-forward, although most of the demos you run across will show data getting passed via the server-side (from the controller). Here, I'm doing this via Ajax methods (Create, Read, Update, Destroy).
#(Html.Kendo().Scheduler<KendoUISchedulerDemo.Models.Projection>()
.Name("scheduler")
.Date(DateTime.Today)
.Height(600)
.DataSource(d => d
.Model(m =>
{
m.Id(f => f.EventId);
m.Field(f => f.Title);
m.Field(f => f.CustomerId);
m.Field(f => f.Description);
m.RecurrenceId(f => f.Recurrence);
})
.Read("Read", "Shared", new { Area = "Events" })
.Create("Create", "Shared", new { Area = "Events" })
.Destroy("Destroy", "Shared", new { Area = "Events" })
.Update("Update", "Shared", new { Area = "Events" })
)
.Events( events =>
{
events.Add("ABC.events.SchedulerAdd");
})
.Editable(edit =>
{
edit.TemplateId("schedulerTemplate");
})
)
The main point with using the datasource with ajax calls like above is that it allows us to put the methods in a separate controller so that we can keep the controller that is displaying the view clean.
Razor View - Kendo Template (for the pop-up editor of events)
This is the script block for the x-kendo-template that overwrites the default pop-up window when creating and editing events in the Kendo Scheduler. This script is pretty much the wild west and you can do whatever you want in it, and it is bound by default with the Kendo MVVM model. Take that with a grain of salt though because there is not a documented way to "extend" that ViewModel to properly put your datasources from custom drop down lists in the ASP.NET MVC wrapper (version) of the Scheduler. (This uses Twitter Bootstrap as well)
<script type="text/x-kendo-template" id="schedulerTemplate">
<div class="form-group">
<div class="col-md-5">
#Html.Label("title", "Title", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<input class="k-textbox" data-bind="value: title" />
</div>
</div>
</div>
<div class="form-group mTop10">
#Html.Label("CustomerId", "Customer", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<input id="CustomerId" class="w450" />
</div>
</div>
<div class="form-group mTop10">
<div class="left col-md-5">
#Html.Label("start", "Start", new { #class = "col-md-2 control-label left" })
<div class="col-md-10">
<input name="start" type="text" required data-type="date" data-role="datetimepicker" data-bind="value: start,invisible: isAllDay" />
<input name="start" type="text" required data-type="date" data-role="datepicker" data-bind="value: start,visible: isAllDay" />
</div>
</div>
<div class="left col-md-5">
#Html.Label("end", "End", new { #class = "col-md-2 control-label left" })
<div class="col-md-10">
<input name="end" type="text" required data-type="date" data-role="datetimepicker" data-bind="value: end ,invisible:isAllDay" />
<input name="end" type="text" required data-type="date" data-role="datepicker" data-bind="value: end ,visible:isAllDay" />
</div>
</div>
</div>
<div class="clear"></div>
<div class="form-group mTop10">
#Html.Label("isAllDay", "All Day", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<input type="checkbox" name="isAllDay" data-type="boolean" data-bind="checked:isAllDay">
</div>
</div>
</script>
JsonResults (in Controller)
Here are the CRUD Json Results. The Create, Update and Destroy JsonResults have been trimmed for the example.
public virtual JsonResult Read([DataSourceRequest] DataSourceRequest request)
{
var data = new List<Projection>();
data.Add(new Projection()
{
EventId = 1,
Start = DateTime.Now.AddDays(-2),
End = DateTime.Now.AddDays(-2).AddHours(2),
IsAllDay = false,
CustomerId = 1,
Description = "Booked for plumbing",
Title = "Manchester Residence"
});
return Json(data.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
public virtual JsonResult Create([DataSourceRequest] DataSourceRequest request, Projection evt)
{
if (ModelState.IsValid)
{
// Other code here
}
return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
}
public virtual JsonResult Update([DataSourceRequest] DataSourceRequest request, Projection evt)
{
if (ModelState.IsValid)
{
// Other code here
}
return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
}
public virtual JsonResult Destroy([DataSourceRequest] DataSourceRequest request, Projection evt)
{
if (ModelState.IsValid)
{
// Other code here
}
return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
}
JavaScript
Here is the JavaScript contained within a stand alone JS file that corresponds to my "Add" event for the Scheduler. I didn't show the "Edit" event as it is pretty much the same idea and you should be able to figure it out.
ABC.Events.SchedulerAdd = function (e) {
function GetCustomers(value) {
var url = "/Events/Shared/GetCustomers"
var success = function (result) {
if (result != null) {
$("#CustomerId").kendoDropDownList({
dataTextField: "FullName",
dataValueField: "CustomerId",
dataSource: new kendo.data.DataSource({ data: result })
});
}
};
$.ajax({ url: url, success: success });
}
GetCustomers();
};
One of the keys in this JavaScript function is that we are turning our field into a Kendo DropDownList and wiring our datasource up at the same time that we are receiving as a JsonResult (not shown, but it's a simple Json object). Another key is how we wire up the datasource as we are creating a new kendo.data.DataSource. If you try to simply wire up the JsonResult, it won't work.
Conclusion
This is a work around to fill dropdownlists in a Scheduler Template (pop-up) when using the ASP.NET MVC Wrapper version of the Kendo UI. I am open for a better way, in which I imagine it will be adding the Json list data to the Internal MVVM that the Kendo Scheduler uses, but without the documentation for ASP.NET MVC or examples of how to pull it off, this is a way it can work.
EDIT #2 - Telerik ASP.NET MVC Example
I finally heard back from Telerik Support on this issue and was directed to this link: http://www.telerik.com/support/code-library/custom-editor-9fd60fca3c02 There is a sample MVC project there that shows how to use a Custom Editor, Drop Down Lists with datasources, all within ASP.NET MVC. Why on Earth there is no link from the documentation to such projects that can obviously help is a mystery to me.
Did you manage to figure this out? I'm working on something similar and have managed to get some of this to work and I have a demo that might help. Mine is not 100% right now but I am getting there. I have a custom template linked to a resource. My issue is sometimes the model doesn't validate so I don't get a post back to the Jason method in the controller. Have you seen this example?
I am new to ColdFusion but I received a project to create a web app.
I am stuck at making multiple cfwindow's. I have a page that displays all upcoming training classes (called page A). It allows an admin to click on a link to open a window and view all students registered for that class (called page B). In page B, I would like to have a link under each students name. When the instructor clicks on it, he can open another cfwindow containing a form for entering payment information. ie Check number sent by the student.
Here is what I've got so far:
Page A:
<script type="text/javascript">
function viewList(id)
{
try {
ColdFusion.Window.destroy('view', true);
}catch(e) {}
ColdFusion.Window.create('view','Registration List', 'registration_list.cfm?id=' + id, {center:true, width:300, height:100, model:true});
}
</script>
<!---output trainingid with a given query name--->
<cfoutput query="myqueryname">
<tr>
<td colspan="3" align="center">View Registration List</td>
</tr>
</cfoutput>
<cfajaximport tags = "cfwindow">
<cfajaximport tags = "cfform">
Page B:
<script type="text/javascript">
function showDetail(detailid)
{
try {
ColdFusion.Window.destroy('viewFull', true);
}catch(e) {}
ColdFusion.Window.create('viewFull','Detail List', 'detail_form.cfm', {center:true, width:300, height:100, modal:false});
}
</script>
<cfoutput query="viewregistration">
First Name:#viewregistration.FirstName#<br />
Last Name: #viewregistration.LastName#<br />
Email: #viewregistration.Email# <br />
County: #viewregistration.Name#<br />
View
</cfoutput>
<cfajaximport tags = "cfwindow">
<cfajaximport tags = "cfform">
When I test my page and click on "View", nothing shows up. However, when I change onclick to display an alert(), it does work. Any idea how to solve this?
ItemCommand contains RepeaterCommandEventArgs which has two important fields:
CommandName
CommandArgument
how to get Button event,get asp:DropDownList select values
<asp:FormView runat="server" id="fwHotelDetails" DataKeyNames="id" OnDataBound="fwHotelDetails_DataBound" OnModeChanging="fwHotelDetails_ModeChanging" >
<ItemTemplate>
<asp:Repeater runat="server" id="repScore">
<ItemTemplate>
<asp:DropDownList ID="ddlnumber" runat="server">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
</asp:DropDownList>
<asp:LinkButton ID="saveButton" runat="server" CausesValidation="False" CommandName="Edit" CommandArgument='<%# Eval("id")%>' Text="Edit" />
</ItemTemplate>
</asp:Repeater>
<EditItemTemplate>
Test test, anything??
</EditItemTemplate>
</ItemTemplate>
</asp:FormView>
The RepeaterCommandEventArgs argument contains a property called Item. From this property you can access the method FindControl().
So your code would look like this:
void repScore_ItemCommand(Object sender, RepeaterCommandEventArgs e) {
DropDownList ddl = (DropDownList)e.Item.FindControl("ddlNumber");
string selectedValue = ddl.SelectedValue;
}
Also, don't forget to wire up your repeater to handle the event:
<asp:Repeater ... OnItemCommand="repScore_ItemCommand" .... >
I have some problems with nested repeaters. I have the following markup
<asp:UpdatePanel ID="upSupportDownloads" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div class="five-col">
<asp:Repeater ID="rep1" runat="server">
<ItemTemplate>
<asp:Repeater ID="rep2" runat="server">
<ItemTemplate></ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
...
It's not a working code, it's an example to understand my structure.
I can't access rep2 from my code behind. I can call rep1. But rep2 is invisible for me.
You need to find the nested repeater in the OnItemDataBound event of your main repeater. like this:
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView row = (DataRowView)e.Item.DataItem;
Repeater nestedRepeater = e.Item.FindControl("NestedRepeater") as Repeater;
nestedRepeater.DataSource = getMyData();
nestedRepeater.DataBind();
}
i am facing a problem regarding User control with the web service please help me
i have made an interface call IcustomeClass which have one method called GetHtml
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// Summary description for ICustomeClass
/// </summary>
public interface ICustomeClass
{
string GetHtml(string controlLocation);
}
i have a class called ControlBaseClass which inherit from UserControl and ICustomeClass
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.IO;
using System.Web.UI.HtmlControls;
/// <summary>
/// Summary description for ControlBaseClass
/// </summary>
public class ControlBaseClass : UserControl, ICustomeClass
{
public ControlBaseClass()
{
}
public string GetHtml(string controlLocation)
{
return GetControlHtml(controlLocation);
}
private string GetControlHtml(string control)
{
var controlMarkup = string.Empty;
Page page = new Page();
var customControl = page.LoadControl(control) as UserControl;
if (customControl != null)
{
var htmlForm = new HtmlForm();
var output = new StringWriter();
htmlForm.Controls.Add(customControl);
page.Controls.Add(htmlForm);
HttpContext.Current.Server.Execute(page, output, false);
controlMarkup = output.ToString();
}
return controlMarkup;
}
}
and i have a service called ControlService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
/// <summary>
/// Summary description for LoadControlService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class LoadControlService : System.Web.Services.WebService
{
public LoadControlService()
{
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public string GetControlHtml(string controlLocation)
{
ControlBaseClass controlBase = new ControlBaseClass();
return controlBase.GetHtml(controlLocation);
}
}
and i am using AJAX Script Manager on my Page
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/Services/LoadControlService.asmx" />
</Services>
<CompositeScript>
<Scripts>
<asp:ScriptReference Path="~/Scripts/ControlScript.js" />
</Scripts>
</CompositeScript>
</asp:ScriptManager>
<table>
<tr>
<td>
<input id="AddBrandButton" type="button" value="Brand" onclick="GetControl('~/UserControls/AddMovies.ascx')" />
</td>
<td>
<input id="AddConsoleButton" type="button" value="Console" onclick="GetControl('~/UserControls/AddLog.ascx')" />
</td>
</tr>
</table>
<div id="ResultDiv">
</div>
</div>
</form>
</body>
i have a java script code which use a web service for getting user control html
/// <reference path="../MainPage.aspx" />
/// <reference name="MicrosoftAjax.js"/>
function GetControl(control) {
LoadControlService.GetControlHtml(control, ControlSuccess, ControlFailure, "");
}
function ControlSuccess(result) {
var div = $get('ResultDiv');
div.innerHTML = result;
}
function ControlFailure(error) {
alert(error);
}
i have two button on my page called Add Movies and Add Log when i click the button the webservice return the html of user control and it display on the page its work fine now my problem is that when i click first button the user control appear and i add the data in the text boxes but when i click the second button another user control appear and the previous user control disappear.
i want to hold the data of the previous control tex boxes so that i can save all the data in the database in one click in other word i am making a tab controls which will save all of the data in one click.