I've got this Kendo Scheduler that is displayed in the View but without any data.
The Scheduler on the View:
#(Html.Kendo().Scheduler<ProjName.Models.ScheduleInspectionModel>()
.Name("scheduler")
.Views(views =>
{
views.DayView();
views.WorkWeekView();
views.WeekView();
views.MonthView(mv => mv.Selected(true));
views.AgendaView();
})
.Timezone("Etc/UTC")
.DataSource(d => d
.Read("ControllerName", "GetScheduleInspections")
)
)
The datasource invokes the controller method below:
public ActionResult GetScheduleInspections([DataSourceRequest]DataSourceRequest request)
{
ScheduleInspectionModel sim = new ScheduleInspectionModel();
var gsio = sim.getScheduleInspections();
List<ScheduleInspectionModel> list = new List<ScheduleInspectionModel>();
if (gsio.scheduleinspections != null)
{
foreach (wsScheduleInspection.scheduleInspectionOutput scheduleInspection in gsio.scheduleinspections)
{
ScheduleInspectionModel sim2 = new ScheduleInspectionModel
{
GlobalEquipConditionId = scheduleInspection.globalEquipmentCondition.id,
Description = scheduleInspection.globalEquipmentCondition.code,
Start = DateTime.Now,
End = DateTime.Now.AddHours(2),
Title = scheduleInspection.globalEquipmentCondition.code,
IsAllDay = true
};
list.Add(sim2);
}
}
return Json(list.ToDataSourceResult(request));
}
But this method is never run, despite being on the Scheduler Datasource property. It should run that method and return a list of inspections. I don't know why isn't the method being hit. With a Kendo Grid, for example, the method on the Datasource Read is hit as soon as the page is loaded.
Try making sure your definition has these two items as I think they are required.
.Date(new DateTime(2013, 6, 13))
.StartTime(new DateTime(2013, 6, 13, 7, 00, 00))
EDIT
I was able to get the following code to work:
Model
// NOTE: It's important that your model class implements ISchedulerEvent
public class TaskViewModel : ISchedulerEvent
{
public string Title { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string StartTimezone { get; set; }
public string EndTimezone { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
}
SchedulerController.cs
public class SchedulerController : Controller
{
// GET: Scheduler
public ActionResult Index()
{
var model = new SchedulerViewModel();
// In this case, it doesn't matter what this model is really since we're using AJAX binding
return View(model);
}
// I usually have my binding methods for Kendo use HttpPost
[HttpPost]
public ActionResult GetData([DataSourceRequest] DataSourceRequest request)
{
var data = new List<TaskViewModel>
{
new TaskViewModel
{
Start = new DateTime(2014, 12, 1, 8, 0, 0),
End = new DateTime(2014, 12, 1, 17, 0, 0),
Title = "Task 1"
}
};
return Json(data.ToDataSourceResult(request));
}
}
Index.cshtml (view)
#(Html.Kendo().Scheduler<TaskViewModel>()
.Name("scheduler")
.Views(views =>
{
views.DayView();
views.WorkWeekView();
views.WeekView();
views.MonthView(mv => mv.Selected(true));
views.AgendaView();
})
.Timezone("Etc/UTC")
.DataSource(d => d
.Read("GetData", "Scheduler")
))
If this doesn't work for you, I would make sure your versions (for Kendo, jQuery, etc) are correct. Hope this helps.
Yes, Scheduler read is called as soon as it is loeded. But it may not be getting data in proper format as it expects. So it is not able to bind the data. If you can check for these modification:
1) Define the "Model" in "DataSource" of scheduler as defined in this example.
2) Also the action method should return object of "MyModel" class(model on which scheduler is defined)
not "ScheduleInspectionModel" class.
Related
I am having issue of using Kendo UI scheduler,
When I schedule task ,
Kendo UI start and end date not returning on server side.
Start and end date always return default date.
Here a Razor Code :
#model IEnumerable<Web.Models.PlantColor>
#{
ViewBag.Title = "Schedule View";
}
<h2>Schedule View</h2>
#(Html.Kendo().Scheduler<WorkScheduler.Web.Models.KendoSchedular>()
.Name("scheduler")
.Date(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day))
.StartTime(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 08, 00, 00))
.Height(600)
.Views(views =>
{
views.DayView();
views.WorkWeekView();
views.WeekView();
views.MonthView();
views.AgendaView();
})
.Resources(resource =>
{
resource.Add(m => m.PlantId)
.Title("Owner")
.DataTextField("Text")
.DataValueField("Value")
.DataColorField("Color")
.BindTo(Model);
})
.DataSource(d => d
.Model(m =>
{
m.Id(f => f.id);
})
.Read("ReadSchedule", "ScheduleView")
.Create("CreateSchedule", "ScheduleView")
.Destroy("Destroy", "ScheduleView")
.Update("Update", "ScheduleView")
)
)
Make sure that you have the start and end fields defined in your Model that you are posting back (and model inherits from ISchedulerEvent):
public class CalendarAppointmentViewModel : ISchedulerEvent
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Recurrence { get; set; }
public string StartTimezone { get; set; }
public string EndTimezone { get; set; }
private DateTime start;
public DateTime Start
{
get
{
return start;
}
set
{
start = value.ToUniversalTime();
}
}
private DateTime end;
public DateTime End
{
get
{
return end;
}
set
{
end = value.ToUniversalTime();
}
}
public string RecurrenceRule { get; set; }
public int? RecurrenceID { get; set; }
public string RecurrenceException { get; set; }
public bool IsAllDay { get; set; }
I can see this question is already accepted as best answer. Perhaps following might be helpful also for someone struggling to return Start/End dates from Editor of Kendo Scheduler.
I had same issue, and followed the solutions provided here, still no success. In my case defining the culture and creating a Model inherited from "ISchedulerEvent" was still returning default date to the server side in Create & Update events handler methods of the Controller.
For me problem was a missing .js file.
kendo.timezones.min.js
So for anyone who is in the same shoes like me, kindly look at your Scripts folder in the project, and if that .js file is missing.
And please follow these steps in setting up the project.
I am trying to implement the scheduler control to show live calculation of material usage on daily bases (in a week by week view).
I am unable to have the Usage data displayed in the cells although I managed to have to Materials displayed on the left hand side. I wonder if any one could help or give me some hints on what I am doing wrong. Here is my code so far:
I can be sure that data is being return to the view but the view is not showing the usage data, which is simply numeric values corresponding to a material on a specific day of the week. I have also attached a screenshot of how it looks like:
the Controller method to read the data:
public JsonResult Read([DataSourceRequest] DataSourceRequest request)
{
try
{
var usageList = new List<ReportUsageViewModel>();
var imports = _importRespository.GetImports();
foreach (var usageReportStoredProcedure in imports)
{
var usageViewModel = new ReportUsageViewModel();
usageViewModel.MaterialID = usageReportStoredProcedure.MaterialID;
usageViewModel.Start = usageReportStoredProcedure.ScanDate;
usageViewModel.End = usageReportStoredProcedure.ScanDate;
usageViewModel.DailyUsage = usageReportStoredProcedure.UsageQuantity;
usageViewModel.Title = usageReportStoredProcedure.UsageQuantity.ToString();
usageList.Add(usageViewModel);
}
return Json(usageList.ToDataSourceResult(request));
}
catch (Exception exc)
{
ErrorHelper.WriteToEventLog(exc);
return null;
}
}
The actual control
<div id="StockViewer">
#(Html.Kendo().Scheduler<WorcesterMarble.ViewModels.ReportUsageViewModel>()
.Name("StockViewer")
.Timezone("Europe/London")
.Resources(resource => resource.Add(m => m.MaterialID)
.Title("Materials")
.Name("Materials")
.DataTextField("Name")
.DataValueField("MaterialID")
.BindTo(Model.MaertiaList))
.MajorTick(270)
.MinorTickCount(1)
.StartTime(DateTime.Now.Date.AddHours(8))
.EndTime(DateTime.Now.Date.AddHours(17))
.AllDaySlot(false)
.Date(DateTime.Now.Date)
.Editable(false)
.Views(x => x.WeekView(v =>
{
v.Footer(false);
v.Selected(true);
v.DateHeaderTemplate("<span class='k-link k-nav-day'>#=kendo.toString(date, 'ddd dd/M')#</span>");
}))
.Group(group => group.Resources("Materials").Orientation(SchedulerGroupOrientation.Vertical))
.DataSource(d => d
.Model(m => {
m.Id(f => f.MaterialID);
m.Field(f => f.Title).DefaultValue("No title");
})
.Read("Read", "ReportUsage")
)
)
Update: This is the ViewModel implementing the ISchedulerEvent
public class ReportUsageViewModel : ISchedulerEvent
{
public int MaterialID { get; set; }
public string MaterialName { get; set; }
public int? DailyUsage { get; set; }
public List<MaterialViewModel> MaertiaList { get; set; }
public string Description { get; set; }
public System.DateTime End { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceException { get; set; }
public string RecurrenceRule { get; set; }
public System.DateTime Start { get; set; }
public string Title { get; set; }
}
The issue was in these two lines:
.StartTime(DateTime.Now.Date.AddHours(8))
.EndTime(DateTime.Now.Date.AddHours(17))
The data was there but these two lines were hiding it. The data was being logged at times outside the time range of 8 to 17 so I removed these two lines and then set the Major ticks to 1440, which is the total number of ticks in 24 hrs, which helped me hiding the time column as I didn't need it..
I'm having hard time understanding how to convert an Enum value to it's corresponding name. My model is as follows:
public class CatalogRule
{
public int ID { get; set; }
[Display(Name = "Catalog"), Required]
public int CatalogID { get; set; }
[Display(Name = "Item Rule"), Required]
public ItemType ItemRule { get; set; }
public string Items { get; set; }
[Display(Name = "Price Rule"), Required]
public PriceType PriceRule { get; set; }
[Display(Name = "Value"), Column(TypeName = "MONEY")]
public decimal PriceValue { get; set; }
[Display(Name = "Exclusive?")]
public bool Exclude { get; set; }
}
public enum ItemType
{
Catalog,
Category,
Group,
Item
}
public enum PriceType
{
Catalog,
Price_A,
Price_B,
Price_C
}
A sample result from .net API:
[
{
$id: "1",
$type: "XYZ.CMgr.Models.CatalogRule, XYZ.CMgr",
ID: 1,
CatalogID: 501981,
ItemRule: 0,
Items: "198",
PriceRule: 1,
PriceValue: 0.5,
Exclude: false
},
{
$id: "2",
$type: "XYZ.CMgr.Models.CatalogRule, XYZ.CMgr",
ID: 2,
CatalogID: 501981,
ItemRule: 2,
Items: "9899",
PriceRule: 2,
PriceValue: 10.45,
Exclude: false
}
]
So in this example, I need to get Catalog for results[0].ItemRule & Price A for results[0].PriceRule. How can I accomplish this in BreezeJS??
This is easy to do in ASP.NET Web API, because it is an out-of-box feature in the default JSON serializer (Json.NET).
To see strings instead of enum numbers in JSON, just add an instance of StringEnumConverter to JSON serializer settings during app init:
var jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
jsonFormatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
UPDATE: Yep, you right, this is not help with Breeze.js. Ok, you can anyway do a little magic to make enums work like strings (while new version with fix is not released).
Create a custom ContextProvider which updates all integer enum values in metadata to strings. Here it is:
public class StringEnumEFContextProvider<T> : EFContextProvider<T>
where T : class, new()
{
protected override string BuildJsonMetadata()
{
XDocument xDoc;
if (Context is DbContext)
{
xDoc = GetCsdlFromDbContext(Context);
}
else
{
xDoc = GetCsdlFromObjectContext(Context);
}
var schemaNs = "http://schemas.microsoft.com/ado/2009/11/edm";
foreach (var enumType in xDoc.Descendants(XName.Get("EnumType", schemaNs)))
{
foreach (var member in enumType.Elements(XName.Get("Member", schemaNs)))
{
member.Attribute("Value").Value = member.Attribute("Name").Value;
}
}
return CsdlToJson(xDoc);
}
}
And use it instead of EFContextProvider in your Web API controllers:
private EFContextProvider<BreezeSampleContext> _contextProvider =
new StringEnumEFContextProvider<BreezeSampleContext>();
This works well for me with current Breeze.js version (1.1.3), although I haven't checked other scenarios, like validation...
UPDATE: To fix validation, change data type for enums in breeze.[min|debug].js, manually (DataType.fromEdmDataType function, dt = DataType.String; for enum) or replace default function during app init:
breeze.DataType.fromEdmDataType = function (typeName) {
var dt = null;
var parts = typeName.split(".");
if (parts.length > 1) {
var simpleName = parts[1];
if (simpleName === "image") {
// hack
dt = DataType.Byte;
} else if (parts.length == 2) {
dt = DataType.fromName(simpleName);
if (!dt) {
if (simpleName === "DateTimeOffset") {
dt = DataType.DateTime;
} else {
dt = DataType.Undefined;
}
}
} else {
// enum
dt = DataType.String; // THIS IS A FIX!
}
}
return dt;
};
Dirty, dirty hacks, I know... But that's the solution I found
There will be a new release out in the next few days where we "change" breeze's enum behavior ( i.e. break existing code with regards to enums). In the new release enums are serialized and queried by their .NET names instead of as integers. I will post back here when the new release is out.
I have been struggling with this for several days. I need to populate a dropdownlistfor with genres.
My MovieRepository to grab the genres:
public IQueryable<Movies> MoviesAndGenres
{
get { return db.Movies.Include(m => m.parentGenre); }
}
My movie model
public virtual Genres parentGenre { get; set; }
Genre Model:
public class Genres
{
public Genres()
{
this.movies = new HashSet<Movies>();
}
[Key]
public int genreId { get; set; }
[Required(ErrorMessage = "A genre name is required")]
[StringLength(25)]
public String genreName { get; set; }
public ICollection<Movies> movies { get; set; }
}
I am trying to pass in the genres with a select list, but I am getting a LINQ to Entities does not recognize the System.String To String() Method, and this method cannot be translated to a stored expression.
Movies Controller, addMovie action:
ViewBag.Genres = movieRepository.MoviesAndGenres.Select(m => new SelectListItem
{
Text = m.parentGenre.genreName,
Value = m.parentGenre.genreId.ToString()
}).ToList();
return View();
View:
#Html.DropDownListFor(m => m.parentGenre, (SelectList)ViewBag.Genres)
Any help would be greatly appreciated!
Update:
Repository:
public IQueryable<Genres> MoviesAndGenres
{
get { return db.Genres; }
}
Controller:
var x = movieRepository.MoviesAndGenres.Select(m => new
{
Text = m.genreName,
Value = m.genreId
});
ViewBag.Genres = new SelectList(x);
return View();
View:
#Html.DropDownListFor(m => m.parentGenre, (SelectList)ViewBag.Genres)
Since you're retrieving all of the records anyways, you can just do this.
ViewBag.Genres = movieRepository.MoviesAndGenres.AsEnumerable()
.Select(m => new SelectListItem
{
Text = m.parentGenre.genreName,
Value = m.parentGenre.genreId.ToString()
});
You would also need to change your view to:
#Html.DropDownListFor(m => m.parentGenre, new SelectList(ViewBag.Genres))
Actually, a better approach would probably be this, since then it only retrieves the specific columns you need:
var x = movieRepository.MoviesAndGenres.Select(m => new
{
Text = m.parentGenre.genreName,
Value = m.parentGenre.genreId
});
ViewBag.Genres = new SelectList(x)
Also, the ToList() is no longer required because it's already in a an immediate state.
I am trying to render a Partial from within a System.Web.Helpers.WebGrid
my model class looks like this:
class GameInfo
{
public List<AppUser> Team1 { get; set; }
public List<AppUser> Team2 { get; set; }
// and more properties
}
class AppUser
{
public string PictureUrl { get; set; }
public string ProfileUrl { get; set; }
public long GamesWon { get; set; }
public long GamesLost { get; set; }
public int Points { get; set; }
// and more properties
}
I want my GridView to show a list of GameInfo's in my grid view.
What is turning out be to be tougher than expected is rendering the Teams (List).
To stay DRY I created a partial view to render a Team (_Team.cstml).
This is my razor code:
#if (Model != null)
{
var webgrid = new WebGrid(source: Model.Games,
rowsPerPage: 10);
<div id="grid">
#webgrid.GetHtml(
columns: webgrid.Columns(
webgrid.Column(header: "Score", format: #<text>#item.Score1/#item.Score1</text>),
webgrid.Column(header: "Team 1", format: (item) =>
{
return "hello sb"; // this line works!
//return Html.Partial("_Team", item.Team1); // this gives an error
})
)
)
</div>
}
Any idea how I can get this to work?
Thank you!
In case someone else runs into this, I managed to solve it this morning.
This works:
webgrid.Column(header: "Team 1", format: (item) =>
{
List<Cuarenta.Web.Models.AppUser> team = ((Cards.Cloud.WebRole.Admin.GameInfo)item.Value).Team1;
return Html.Partial("_Team", team);
})