Telerik Forums
UI for ASP.NET MVC Forum
3 answers
73 views
We have a combobox declared using the ASP.NET MVC wrapper (2013.2.716).
On IE (10 and earlier), giving it a value upon declaration causes the page to focus on the control and scroll down to it (if the combobox is past the current display area). So we end up with cases where a user would end up seeing the page scrolled down to the middle/bottom. We have confirmed that having ".Suggest(true)" triggers this behavior. Taking it off stops it from happening but we would prefer keeping it as it is helpful to aid users with its auto-completion.

Additionally, we have tested other browsers and they don't exhibit this behavior at all. Is this a known bug?

The declaration is quite simple and looks similar to this:

1.@Html.Kendo().ComboBox()
2.   .Suggest(true)
3.   .HighlightFirst(true)
4.   .BindTo(dataSource)
5.   .Value("someValue")
Georgi Krustev
Telerik team
 answered on 29 Oct 2013
3 answers
193 views
I use Kendo UI chart in scatter line mode to display data that was received from a sensor over time. I get the data from my server in JSON.
Sometimes I don't want the chart to display all the data that was received from the server, 
and sometimes I want to display a specific range of time (which the user had selected) even if there is no data at this time.
in order to accomplish this i figured i need to set up the graph's xAxis option like this:
xAxis: {
        min : fromSelectedTime,
        max : toSelectedTime,
        type: "date",    
    }

but when I add this option to the graph it stops displaying the graph correctly:
1) it only displays the min and max scales on the x axis and nothing in between.
2) more important: the values are not aligned correctly respectively to the x axis
(an item with the time of  1 pm on the 2nd of Oct for example is display before the 10/2 scale instead of after or not at all)
I've created a JSFiddle that shows the problem:
http://jsfiddle.net/ZZZF7/2/
It shows wrong display of the graph.
jsonData simulates the data that I  receive from the server. please not that in this case (but not always):
the first item is later than the min time (data.From = Tue, 01 Oct 2013 12:35:00 GMT)
and the last item is later than the max time (data.To = Wed, 02 Oct 2013 12:35:00 GMT).

if you would remove lines 41-45 the graph is displayed as expected.
Alexander Popov
Telerik team
 answered on 29 Oct 2013
1 answer
241 views
I am updating my kendo ui complete MVC package from version 2012.1.215 to 2013.2.918, but somehow there is file, kendo.custom.js in the javascript folder. (I am not the original creator of the project)

I am having problem to upgrade kendo to the newest version because of the file. I am stuck on this one and my project deadline is approaching, I don't have time to searching around Kendo site, so any helps are appreciated.
Vesko
Telerik team
 answered on 29 Oct 2013
4 answers
118 views
Hello Team,

I have implemented the scheduler in the ASP.Net MVC application and I am not able to get the start/stop dates from event creation popup to the controller's save method, below is the code please help me to resolve this issue.
The other issue is when I try to comment the dates and save the appointment in database and opens the appointment event creation again then it doesn't closes out.

Below is the code please help me to resolve this issue :
Controller Code :
using Kendo.Mvc.UI;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Kendo.Mvc.Extensions;
using VisionDB.Helper;
using VisionDB.Models;
using System.Globalization;
using System.IO;
using System.Collections.Specialized;
using System.Web.UI;
using System.Web.Security;

namespace VisionDB.Controllers
{
[Authorize]
public class CustomersController : Controller
{

#region Customers
public ActionResult Index()
{
return Search(null);
}

public ActionResult Search(string Search)
{
var db = new CustomersDataContext();
var results = from row in db.Customers
select row;

if (!string.IsNullOrWhiteSpace(Search))
{
results = results.Where(c => c.Number.ToLower().Contains(Search.ToLower())
|| c.Number.Replace(" ", "").ToLower().Contains(Search.Replace(" ", "").ToLower())
|| c.Firstnames.ToLower().Contains(Search.ToLower())
|| c.Surname.ToLower().Contains(Search.ToLower())
|| c.Address.ToLower().Contains(Search.ToLower())
|| c.Postcode.ToLower().Contains(Search.ToLower())
|| c.Postcode.Replace(" ", "").ToLower().Contains(Search.Replace(" ", "").ToLower())
|| c.Telephone.ToLower().Contains(Search.ToLower())
|| c.SMSNumber.ToLower().Contains(Search.ToLower())
|| c.SMSNumber.Replace(" ", "").ToLower().Contains(Search.Replace(" ", "").ToLower())
|| c.Email.ToLower().Contains(Search.ToLower()));
}
else
{
results = results.Where(c => false);
}

return View(results);
}

public ActionResult Customer(Guid Id,string message)
{
var db = new CustomersDataContext();
//get customers by id
var customer = db.Customers.Find(Id);
customer.EyeTests = new EyeTestsController().GetEyeTests(customer);
//get customer attachments
customer.GetAttachments = GetCustomerAttachments();
customer.Invoices = new InvoicesController().GetInvoices(customer);
foreach (Invoice invoice in customer.Invoices)
{
invoice.InvoiceDetails = GetInvoices(invoice);
}
if (message != null)
{
@ViewBag.Message = message;
}
return View(customer);
}

[HttpGet]
public ActionResult Edit(Guid Id)
{
var db = new CustomersDataContext();
var customer = db.Customers.Find(Id);
ViewBag.NHSPrivateLists = EnumHelper.ToSelectList(VisionDB.Models.Customer.NHSPrivateList.Unknown);
ViewBag.SmokerLists = EnumHelper.ToSelectList(VisionDB.Models.Customer.SmokerList.Unknown);

return View(customer);


}



[HttpPost]
public ActionResult Edit([Bind(Exclude = "Age,LastTestDate,NextTestDueDate")]Models.Customer customer)
{
if (string.IsNullOrWhiteSpace(customer.Telephone) && string.IsNullOrWhiteSpace(customer.SMSNumber))
{
ModelState.AddModelError("Telephone", "Either a telephone or SMS number must be supplied");
ModelState.AddModelError("SMSNumber", "Either a SMS or telephone number must be supplied");
}

if (ModelState.IsValid)
{
if (customer.Id == Guid.Empty)
{
customer.Id = Guid.NewGuid();
}

//Save to database
var db = new CustomersDataContext();

db.Entry(customer).State = EntityState.Modified;

db.SaveChanges();

return RedirectToAction("Customer", new { customer.Id });
}

return Edit(customer.Id);
}

[HttpGet]
public ActionResult Create()
{
//populate drop down lists
ViewBag.NHSPrivateLists = EnumHelper.ToSelectList(VisionDB.Models.Customer.NHSPrivateList.Unknown);
ViewBag.SmokerLists = EnumHelper.ToSelectList(VisionDB.Models.Customer.SmokerList.Unknown);
ViewBag.AppTypes = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.AppType.Eye_Test);
return View();
}

[HttpPost]
public ActionResult Create([Bind(Exclude = "Age,LastTestDate,NextTestDueDate")]Models.Customer customer)
{
if (string.IsNullOrWhiteSpace(customer.Telephone) && string.IsNullOrWhiteSpace(customer.SMSNumber))
{
ModelState.AddModelError("Telephone", "Either a telephone or SMS number must be supplied");
ModelState.AddModelError("SMSNumber", "Either a SMS or telephone number must be supplied");
}

if (ModelState.IsValid)
{
if (customer.Id == Guid.Empty)
{
customer.Id = Guid.NewGuid();
}

//Save to database
var db = new CustomersDataContext();
db.Customers.Add(customer);
db.SaveChanges();

return RedirectToAction("Customer", new { customer.Id });
}

return Create();
}
#endregion

#region Eyetest

public ActionResult EyeTest(Guid Id)
{
var db = new CustomersDataContext();

var eyeTest = db.EyeTests.Find(Id);
ViewBag.Customer = db.Customers.Find(eyeTest.CustomerId);

return View(eyeTest);
}

[HttpGet]
public ActionResult EditEyeTest(Guid Id)
{
var db = new CustomersDataContext();
var eyeTest = db.EyeTests.Find(Id);
ViewBag.Customer = db.Customers.Find(eyeTest.CustomerId);
ViewBag.Bases = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.Base.None);
ViewBag.AppTypes = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.AppType.Eye_Test);
ViewBag.AdviceAndRecallLists = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.AdviceAndRecallList.None);
ViewBag.AppRooms = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.AppRoom.One);
ViewBag.YesNos = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.YesNo.None);
ViewBag.LensTypes = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.LensType.Not_Assigned);
return View(eyeTest);
}

[HttpPost]
public ActionResult EditEyeTest([Bind]Models.EyeTest eyeTest)
{
if (eyeTest.TestDateAndTime == null)
{
ModelState.AddModelError("Test date", "A test date is required");
}

if (ModelState.IsValid)
{
if (eyeTest.Id == Guid.Empty)
{
eyeTest.Id = Guid.NewGuid();
}

string signatureJson = Request.Form["output"];

//Save to database
var db = new CustomersDataContext();

db.Entry(eyeTest).State = EntityState.Modified;

db.SaveChanges();

return RedirectToAction("EyeTest", new { eyeTest.Id });
}

return EditEyeTest(eyeTest.Id);
}

[HttpGet]
public ActionResult CreateEyeTest(Customer customer)
{
var db = new CustomersDataContext();
var Customer = db.Customers.Find(customer.Id);
ViewBag.Bases = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.Base.None);
ViewBag.AppTypes = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.AppType.Eye_Test);
ViewBag.AdviceAndRecallLists = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.AdviceAndRecallList.None);
ViewBag.AppRooms = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.AppRoom.One);
ViewBag.YesNos = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.YesNo.None);
ViewBag.LensTypes = EnumHelper.ToSelectList(VisionDB.Models.EyeTest.LensType.Not_Assigned);
ViewBag.Customer = Customer;

return View();

}

[HttpPost]
public ActionResult CreateEyeTest([Bind]Models.EyeTest eyeTest)
{
eyeTest.CustomerId = eyeTest.Id;

if (eyeTest.Id == Guid.Empty)
{
eyeTest.Id = Guid.NewGuid();
}

//Save to database
var db = new CustomersDataContext();
var Customer = db.Customers.Find(eyeTest.CustomerId);

eyeTest.Title = Customer.ToString() + " eye test";
db.EyeTests.Add(eyeTest);
db.SaveChanges();

return RedirectToAction("EyeTest", new { eyeTest.Id });

}
#endregion

#region Invoice
public ActionResult Invoice(Guid Id)
{
var db = new CustomersDataContext();

var invoice = db.Invoices.Find(Id);
ViewBag.Customer = db.Customers.Find(invoice.CustomerId);
invoice.InvoiceDetails = GetInvoices(invoice);
return View(invoice);
}

private ICollection<InvoiceDetail> GetInvoices(Invoice invoice)
{
var db = new CustomersDataContext();

var results = from row in db.InvoiceDetails
select row;

if (invoice != null)
{
results = results.Where(c => c.InvoiceId == invoice.Id && c.UnitPrice >= 0);
}
else
{
results = results.Where(c => false);
}

var payments = from row in db.InvoiceDetails
select row;

if (invoice != null)
{
payments = payments.Where(c => c.InvoiceId == invoice.Id && c.UnitPrice < 0);
}
else
{
payments = payments.Where(c => false);
}

return results.Union(payments).ToList();
}
[HttpGet]
public ActionResult CreateInvoice(Guid Id)
{
var db = new CustomersDataContext();
Invoice Invoice = new Invoice();
Invoice.CustomerId = Id;
ViewBag.Customer = db.Customers.Find(Id);
return View(Invoice);
}
[HttpPost]
public ActionResult CreateInvoice(string List, Invoice invoice)
{
List<InvoiceDetail> InvoiceDetailList = null;
if (!string.IsNullOrEmpty(List) && invoice.InvoiceDate != null)
{
InvoiceDetailList = (List<InvoiceDetail>)Newtonsoft.Json.JsonConvert.DeserializeObject(List, typeof(List<InvoiceDetail>));
}
else
{
ModelState.AddModelError("Invoice", "No invoice detail lines");
}
if (ModelState.IsValid)
{
using (CustomersDataContext db = new CustomersDataContext())
{
ViewBag.Customer = db.Customers.Find(invoice.CustomerId);

if (invoice.Id == Guid.Empty)
{
invoice.Id = Guid.NewGuid();
invoice.UserId = 1;
}

//Save to database
invoice.CreatedTimestamp = DateTime.Now;
db.Entry(invoice).State = EntityState.Modified;
db.Invoices.Add(invoice);
int result = db.SaveChanges();

if (result == 1)
{
foreach (var Detaillst in InvoiceDetailList)
{
Detaillst.InvoiceId = invoice.Id;
if (Detaillst.Id == Guid.Empty)
{
Detaillst.Id = Guid.NewGuid();
}
db.Entry(Detaillst).State = EntityState.Modified;
db.InvoiceDetails.Add(Detaillst);
db.SaveChanges();
}
}
return Json(new { HasError = false, Message = "Success" });
}
}

return Json(new { HasError = true, Message = "Invoice not created! please add invoice detail lines" });
}

[HttpGet]
public ActionResult EditInvoice(Guid Id)
{
var db = new CustomersDataContext();
var invoice = db.Invoices.Find(Id);
ViewBag.Customer = db.Customers.Find(invoice.CustomerId);
Session["InvoiceId"] = Id;
invoice.InvoiceDetails = GetInvoices(invoice);
return View(invoice);
}

[HttpPost]
public ActionResult EditInvoice([Bind]Models.Invoice invoice)
{
//if (invoice.InvoiceDetails.Count == 0)
//{
// ModelState.AddModelError("Invoice", "No invoice detail lines");
//}

if (ModelState.IsValid)
{
if (invoice.Id == Guid.Empty)
{
invoice.Id = Guid.NewGuid();
}

//Save to database
var db = new CustomersDataContext();
invoice.CreatedTimestamp = DateTime.Now;
db.Entry(invoice).State = EntityState.Modified;

db.SaveChanges();

return RedirectToAction("Invoice", new { invoice.Id });
}

return EditInvoice(invoice.Id);
}

public ActionResult EditingInline_Read([DataSourceRequest] DataSourceRequest request, Guid Id)
{
if (Id != Guid.Empty)
{
return Json(SessionInvoiceRepository.All().Where(x => x.InvoiceId == Id).ToDataSourceResult(request));
}
return Json(null);
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditingInline_Create([DataSourceRequest] DataSourceRequest request, InvoiceDetail invoiceDetail, string Mode)
{
if (Mode != "Create")
{
if (invoiceDetail != null)
{
invoiceDetail.InvoiceId = (Guid)Session["InvoiceId"];
SessionInvoiceRepository.Insert(invoiceDetail, Mode);
}
}
else
{
if (invoiceDetail != null)
{
SessionInvoiceRepository.Insert(invoiceDetail, Mode);
}
}

return Json(new[] { invoiceDetail }.ToDataSourceResult(request));
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditingInline_Update([DataSourceRequest] DataSourceRequest request, InvoiceDetail invoiceDetail)
{
if (invoiceDetail != null && ModelState.IsValid)
{
var target = SessionInvoiceRepository.One(p => p.Id == invoiceDetail.Id);
if (target != null)
{
target.Description = invoiceDetail.Description;
target.UnitPrice = invoiceDetail.UnitPrice;
target.Quantity = invoiceDetail.Quantity;
target.ProductTypeId = invoiceDetail.ProductTypeId;
SessionInvoiceRepository.Update(target);
}
}
return Json(new[] { invoiceDetail }.ToDataSourceResult(request, ModelState));
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditingInline_Destroy([DataSourceRequest] DataSourceRequest request, InvoiceDetail invoiceDetail)
{
if (invoiceDetail != null)
{
SessionInvoiceRepository.Delete(invoiceDetail);
}

//return RedirectToAction("EditInvoice", "Customers", new { Id = invoiceDetail.InvoiceId });
return Json(new[] { invoiceDetail }.ToDataSourceResult(request, ModelState));
}
#endregion

#region Calendar

public ActionResult Calendar()
{
using (CustomersDataContext db = new CustomersDataContext())
{
List<Schedule> getSchedules = (from b in db.EyeTests
select new Schedule
{
id = b.Id,
customerid = b.CustomerId,
Title = b.Title,
testdateandtime = b.TestDateAndTime,
Start = b.Start.HasValue ? b.Start.Value : b.TestDateAndTime,
End = b.Start.HasValue ? b.End.Value : b.TestDateAndTime,
Description=b.Notes
}).ToList();

return View(getSchedules);
}
}
public virtual JsonResult ReadSchedule([DataSourceRequest] DataSourceRequest request)
{
using (CustomersDataContext db = new CustomersDataContext())
{
List<Schedule> getSchedules = (from b in db.EyeTests
select new Schedule
{
id = b.Id,
customerid = b.CustomerId,
Title = b.Title,
testdateandtime = b.TestDateAndTime,
Start = b.Start.HasValue?b.Start.Value:b.TestDateAndTime,
End = b.Start.HasValue ? b.End.Value : b.TestDateAndTime
}).ToList();

return Json(getSchedules.ToDataSourceResult(request));
}
}
[HttpPost]
public JsonResult SearchCustomer(string SearchData)
{
using (CustomersDataContext db = new CustomersDataContext())
{
List<Customer> GetCustomers = (from Customers in db.Customers
where Customers.Firstnames.Contains(SearchData) || Customers.Surname.Contains(SearchData) ||
Customers.Address.Contains(SearchData) || Customers.Telephone.Contains(SearchData)
select Customers ).ToList();

String json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(GetCustomers);
return Json(json, JsonRequestBehavior.AllowGet);

}
}

public virtual ActionResult DestroySchedule([DataSourceRequest] DataSourceRequest request, Schedule schedule)
{
if (schedule != null)
{
if (schedule.id != Guid.Empty)
{
using (CustomersDataContext dbContext = new CustomersDataContext())
{
EyeTest eyetest = dbContext.EyeTests.Where(x => x.Id == schedule.id).FirstOrDefault();
dbContext.Entry(eyetest).State = EntityState.Modified;
dbContext.EyeTests.Remove(eyetest);
dbContext.SaveChanges();
}
}
}

return RedirectToAction("Calendar", "Customers");
//return Json(new[] { schedule }.ToDataSourceResult(request, ModelState));
}
[HttpPost]
public JsonResult SetCustomerId(string CustomerId)
{
Session["SelectedCustomerId"] = CustomerId;
return Json("Success");
}
public virtual ActionResult CreateSchedule([DataSourceRequest] DataSourceRequest request, Schedule schedule)
{
if (schedule != null)
{
using (CustomersDataContext dbContext = new CustomersDataContext())
{
EyeTest eyetest = new EyeTest();
if (schedule.id == Guid.Empty)
{
//Guid CustomerId = Guid.Parse(Session["SelectedCustomerId"].ToString());
eyetest.Id = Guid.NewGuid();
eyetest.TestDateAndTime = System.DateTime.Now;
// Here time frames become unavailable - Comment By Reishabh
//eyetest.Start = ConvertDateFormat(schedule.Start.ToString());
//eyetest.End = ConvertDateFormat(schedule.End.ToString());
eyetest.Title = schedule.Title;
eyetest.Notes = schedule.Description;
// Replace below customerId from selected CustomerId
eyetest.CustomerId = Guid.Parse("057982f7-5aa1-4850-9de8-10aa264ede76");
//eyetest.CustomerId = CustomerId;
//eyetest.CustomerId = schedule.CustomerId;
//eyetest.AppointmentType = new VisionDB.Models.EyeTest.AppType();
eyetest.UserId = 1;
dbContext.EyeTests.Add(eyetest);
dbContext.SaveChanges();
}
}
}
return RedirectToAction("Calendar", "Customers");
//return Json(new[] { schedule }.ToDataSourceResult(request));
}

public virtual ActionResult UpdateSchedule([DataSourceRequest] DataSourceRequest request, Schedule schedule)
{
if (ModelState.IsValid)
{
if (schedule != null)
{
using (CustomersDataContext dbContext = new CustomersDataContext())
{
if (schedule.id != Guid.Empty)
{
EyeTest target = dbContext.EyeTests.Where(p => p.Id == schedule.id).FirstOrDefault();
target.TestDateAndTime = ConvertDateFormat(schedule.testdateandtime.ToString());
target.Start = ConvertDateFormat(schedule.Start.ToString());
target.End = ConvertDateFormat(schedule.End.ToString());
target.Notes = schedule.Description;
target.Title = schedule.Title;
dbContext.Entry(target).State = EntityState.Modified;
}
dbContext.SaveChanges();
}
}
}

return RedirectToAction("Calendar", "Customers");
//return Json(new[] { schedule }.ToDataSourceResult(request, ModelState));
}

public DateTime ConvertDateFormat(string date)
{
DateTimeFormatInfo dateTimeFormatterProvider = DateTimeFormatInfo.CurrentInfo.Clone() as DateTimeFormatInfo;
dateTimeFormatterProvider.ShortDatePattern = "MM/dd/yyyy HH:mm:ss"; //source date format
DateTime dateTime = DateTime.Parse(date, dateTimeFormatterProvider);
string formatted = dateTime.ToString("dd/MM/yyyy HH:mm:ss");
return Convert.ToDateTime(formatted);
}
#endregion

#region Attachments
public ActionResult UploadAttachments(IEnumerable<HttpPostedFileBase> files, string Comments, Guid Id, int AttachmentId = 0)
{
string fileName = string.Empty;
if (files != null)
{
foreach (var file in files)
{
if (file.ContentLength > 0)
{
fileName = Path.GetFileName(file.FileName);
string urlPath = string.Format("{0}{1}", Server.MapPath("~/content/uploads/"), Id);
var path = Path.Combine(urlPath, fileName);
// Create directory as necessary and save image
if (!Directory.Exists(urlPath) && !System.IO.File.Exists(path))
{
Directory.CreateDirectory(urlPath);
file.SaveAs(path);
}
}
}
}
if (AttachmentId == 0)
{
using (var entities = new CustomersDataContext())
{
Attachments attachments = new Attachments();
attachments.FileName = fileName;
attachments.FileComments = Comments;
attachments.CustomerId = Id;
//check file already exist and if not save the attachments
bool Isfilealreadyexists = entities.Attachments.Where(m => m.FileName == attachments.FileName).Any();
if (!Isfilealreadyexists)
{
entities.Attachments.Add(attachments);
int i = entities.SaveChanges();
}
else
{
ViewBag.Message = "File already exist! please delete the existing one and upload again";
}

}
}
else
{
EditAttachments(AttachmentId, Comments, Id);
}
return RedirectToAction("Customer", new { Id = Id, message = ViewBag.Message });
}

public ActionResult EditAttachments(int id, string Comments, Guid customerId)
{
using (var entities = new CustomersDataContext())
{
//get and edit the attachments
Attachments data = entities.Attachments.Where(m => m.Id == id).FirstOrDefault();
data.FileComments = Comments;
entities.SaveChanges();
}
return RedirectToAction("Customer", new { id });
}
public IEnumerable<Attachments> GetCustomerAttachments()
{
using (var entities = new CustomersDataContext())
{
//get customers by id
return entities.Attachments.ToList();
}
}

public ActionResult Delete(int Id)
{
Attachments data = null;
using (var entities = new CustomersDataContext())
{
//delete the customer
data = entities.Attachments.Where(m => m.Id == Id).FirstOrDefault();
entities.Attachments.Remove(data);
entities.SaveChanges();
}
//to delete the file from the folder
string urlPath = string.Format("{0}{1}", Server.MapPath("~/content/uploads/"), data.CustomerId);
var path = Path.Combine(urlPath, data.FileName);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
return RedirectToAction("Customer", new { Id = data.CustomerId });
}
#endregion

public ActionResult Recalls(string DueDateDays, string LastRecallDays)
{

if (DueDateDays == null || DueDateDays.Length == 0)
{
DueDateDays = "30";
}

if (LastRecallDays == null || LastRecallDays.Length == 0)
{
LastRecallDays = "5";
}
DateTime dueDateCutOff = DateTime.Now.Date.AddDays(Convert.ToInt32(DueDateDays));

var db = new CustomersDataContext();
var results = from row in db.Customers
select row;

results = results.Where(c => c.NextTestDueDate.HasValue == false
|| (c.NextTestDueDate.Value < dueDateCutOff
&& c.LastRecallDate == null));

return View(results);
}

public ActionResult SendRecalls(Customer customer, FormCollection form)
{
string[] rawselectedids = form.Get("SelectedIds").Split(',');
int recallMethod = Convert.ToInt32(Request.Form["Filter"]);
List<Guid> selectedIds = new List<Guid>();

foreach (string id in rawselectedids)
{
if (id.Length > 1)
{
selectedIds.Add(new Guid(id.Replace("chkbox", "")));
}
}

SendRecallMessages(selectedIds, recallMethod);

TempData["OutboxMessage"] = string.Format("{0} recalls sent", selectedIds.Count);

return RedirectToAction("Outbox");
}

private void SendRecallMessages(List<Guid> selectedIds, int recallMethod)
{
var db = new CustomersDataContext();
var results = from row in db.Customers
select row;

results = results.Where(model => selectedIds.Contains(model.Id));

var templates = from row in db.MessageTemplates
select row;

templates = templates.Where(t => recallMethod == t.MessageTypeId
&& ((UserProfile)HttpContext.Session["user"]).customer.Id == t.CustomerId);
string template = templates.First().Template;


foreach (Customer customer in results)
{
if (customer.SMSNumber != null && customer.SMSNumber.Length > 5)
{

Message message = new Message();
message.Id = Guid.NewGuid();
message.RecipientId = customer.Id;
message.MessageTypeId = recallMethod;
message.SenderUserId = ((UserProfile)HttpContext.Session["user"]).UserId;
message.ToAddressNumber = customer.SMSNumber;
message.MessageText = string.Format(template,
customer.TitleAndName(), customer.NextTestDueDate.Value.ToShortDateString(), customer.SMSNumber); //todo: get number for practice
message.AddedToQueue = DateTime.Now;
message.Cancelled = null;
message.CancelledByUserId = null;
message.Sent = null;

db.Messages.Add(message);
}
else
{
//handle where sms doesn't exist or too short
}
}

db.SaveChanges();
}

public ActionResult Outbox()
{
var db = new CustomersDataContext();

var results = from row in db.Messages
select row;

results = results.Where(m => m.Sent == null && m.Cancelled == null);


return View(results);
}
}
}


View Code :

@model IEnumerable<VisionDB.Models.Schedule>
@{
ViewBag.Title = "Calendar";
}

@(Html.Kendo().Scheduler<VisionDB.Models.Schedule>()
//.Events(e =>
//{
// e.Edit("EditEvent");

//})
.Name("scheduler")
.Editable(true)
.Date(@DateTime.Today.Date)
.StartTime(new DateTime(2013, 6, 13, 10, 00, 00))
.EndTime(new DateTime(2013, 6, 13, 23, 00, 00))

.Height(600)
.Views(views =>
{
views.DayView();
views.WeekView(weekView => weekView.Selected(true));
views.MonthView();
views.AgendaView();
})

//.Resources(resource =>
//{
// resource.Add(m => m.CustomerId)
// .Title("Owner")
// .DataTextField("Text")
// .DataValueField("Value")
// .DataColorField("Color")
// .BindTo(new[] {
// new { Text = "Alex", Value = 1, Color = "#f8a398" } ,
// new { Text = "Bob", Value = 2, Color = "#51a0ed" } ,
// new { Text = "Charlie", Value = 3, Color = "#56ca85" }
// });
//})

.Selectable(true)
.Editable(true)
.MajorTick(60)
//.BindTo(Model)
.DataSource(d => d
.Model(m =>
{
//m.Id(f => f.CustomerId);
// m.Field(f => f.CustomerId).DefaultValue(1);

})

.Read("ReadSchedule", "Customers")
.Create("CreateSchedule", "Customers")
.Destroy("DestroySchedule", "Customers")
.Update("UpdateSchedule", "Customers")

)
)


<script>

//function EditEvent(e) {
// $('.k-popup-edit-form.k-scheduler-edit-form.k-window-content.k-content').hide();
// $('.k-widget.k-window').append('<div id="DivSelectCustomerInner">' + $('#DivSelectCustomer').html() + '</div>');
// //$('#DivSelectCustomer').remove();
//}

function CustomerSelected() {

$('#DivSelectCustomerInner').hide();
$('.k-popup-edit-form.k-scheduler-edit-form.k-window-content.k-content').show();
//ICustomerId

// $('#DivSelectCustomerInner').hide();
}
function SearchCustomer() {
var sPath = '@Url.Action("SearchCustomer", "Customers")';
var SearchData = $("#DivSelectCustomerInner #TxtFName").val();
//var SurName = $("#DivSelectCustomerInner #TxtSName").val();

$.ajax({
type: 'POST',
url: sPath,
data: "{'SearchData': '" + SearchData + "'}",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
WriteToCustomers(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
function SelectCustomer(CustomerId,CustomerName) {
var sPath = '@Url.Action("SetCustomerId", "Customers")';
$.ajax({
type: 'POST',
url: sPath,
data: "{'CustomerId': '" + CustomerId + "'}",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
$('#DivSelectCustomerInner #BtnNext').show(500);
$('.k-edit-form-container').append('<input type="hidden" id="HdnCustomerId" name="CustomerId" data-bind="value:CustomerId" value="' + CustomerId + '">');
$('.k-window-title').html('Event - Selected Customer : ' + CustomerName);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}

function WriteToCustomers(data)
{
//alert(data);
if (data) {
if (data!=null) {
var isdata = 0;
var CustomerHTML = '<table>';
if(data.length>0)
{
//alert("passed length");
CustomerHTML += '<tr>';
CustomerHTML += '<td>Select </td>';
CustomerHTML += '<td>First Name </td>';
CustomerHTML += '<td>Surname </td>';
CustomerHTML += '<td>Address</td>';
CustomerHTML += '</tr>';
$.each($.parseJSON(data), function (key, value) {
isdata = 1;
CustomerHTML += '<tr>';
CustomerHTML += '<td><input type="button" value="Select" onclick="SelectCustomer(\'' + value.Id + '\',\'' + value.Firstnames + ' ' + value.Surname + '\' )" /> </td>';
CustomerHTML += '<td>' + value.Firstnames + '</td>';
CustomerHTML += '<td>' + value.Surname + '</td>';//
CustomerHTML += '<td>' + value.Address + '</td>';
CustomerHTML += '</tr>';
});
CustomerHTML += '</table>';

}
//alert(CustomerHTML);
if (isdata == 0) {
$('#SearchResultDiv').html('<p> No Customers Found</p>');
} else {
// alert(CustomerHTML);
$('#DivSelectCustomerInner #SearchResultDiv').html(CustomerHTML);
}

}else{
LoadAppointment(ScheduleId);
}
}

//return false;
}



</script>
<div id="DivSelectCustomer" style="display:none;">
<h3 style="margin-left:15px;">Search Customer</h3>
@*<div class="k-edit-label"> <label for="title">Search</label></div>*@
<input type="text" class="k-input k-textbox" id="TxtFName" style="width:200px;margin-left:15px;margin-right:10px;"/><input type="button" class="k-button" value="Search" onclick="SearchCustomer()" />
<br /><br />
<div style="text-align:right"></div>
<br />
<div id="SearchResultDiv"></div>
<br />
<div class="k-edit-buttons k-state-default" style="text-align:right">
<input type="button" id="BtnNext" class="k-button" style="display:none;" value="Next" onclick="CustomerSelected()" />
</div>

</div>
<div id="tempdiv"></div>




Model Code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Kendo.Mvc.UI;
using Kendo.Mvc.Extensions;

namespace VisionDB.Models
{
public class Schedule : ISchedulerEvent
{
public Guid id { get; set; }
public Guid customerid { get; set; }
public string Description { get; set; }
public DateTime testdateandtime { get; set; }
public string Title { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public bool IsAllDay { get; set; }
public string recurrence { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
// public int ICustomerId { get; set; }


}
}
Vladimir Iliev
Telerik team
 answered on 29 Oct 2013
1 answer
199 views
I am new to Kendo. I am working with the Ajax tutorial.  In my view I place the line:
@(Html.Kendo().Grid<KendoGridAjaxEditing.Models.RoleViewModel>()

When I run and access my page with the Kendo Grid, I get the following error message:

Compiler Error Message: CS0246: The type or namespace name 'KendoGridAjaxEditing' could not be found (are you missing a using directive or an assembly reference?)

I have searched the documentation and cannot find the namespace to resolve error message.  I appreciate the assistance in resolving this error.

Atanas Korchev
Telerik team
 answered on 29 Oct 2013
5 answers
179 views
Hello,

I have a problem with Kendo UI for ASP.NET MVC, below my soure code : 
<%= Html.Kendo().Chart(Of MyNamespace.DateIntPair) _
    .Name("chart") _
    .Legend(False) _
    .DataSource(Function(ds) ds.Read(Function(read) read.Action("GetStatsUniqueViews", "Home", New With {.id = RouteData.Values("id")}))) _
    .Series(Function(series) series.Area(Function(model) model.IntValue)) _
    .CategoryAxis( _
        Function(axis) axis.Categories(Function(model) model.DateValue).Date().BaseUnit(ChartAxisBaseUnit.Days)))
     
    %>

When i start the web page, i have this error :

Object reference not set to an instance of an object


When I remove .Date().BaseUnit(ChartAxisBaseUnit.Days, it's works.

Any ideas ?

Thank you in advance.
Daniel
Telerik team
 answered on 28 Oct 2013
2 answers
138 views
So, I started off with my grid being selectable like so:

(Html.Kendo().Grid(Model.TPOrderDetails)
       .Name("Grid")
       //.HtmlAttributes(new { style = "height: 750px; width: 1000px; "})
 
       .ToolBar(toolBar => toolBar.Template(
 
           @<text>
               <label>Plant Personnel:</label>
               @Html.DropDownList("PersonnelID", (SelectList)ViewData["PersonnelList"])
        
               @item.CustomCommandToolBarButton("assignWork", "Assign", "AssignOrders", "Production", null, new { id = "assignButton", @class="btn-success" })
               @item.CustomCommandToolBarButton("unassignWork", "Clear Assignment", "UnassignOrders", "Production", null, new { id = "unassignButton", @class = "btn-error"})
               @item.CustomCommandToolBarButton("clearSelections", "Clear Selections", "ClearSelections", "Production", null, new { id = "clearSelections", @class="btn-warning"})
               @item.CustomCommandToolBarButton("refreshGrid", "Refresh", "RefreshGrid", "Production", null, new { id = "refreshGrid", @class = "btn-success"})
 
           </text>
           )
 
       )
 
 
       .Columns(columns =>
           {
               columns.Bound(p => p.RequestedShipDate).Format("{0:d}").Hidden(true);
               columns.Bound(p => p.ContainerSize);
               columns.Bound(p => p.SystemNumber);
               columns.Bound(p => p.CustomerName);
               columns.Bound(p => p.Order_ID).Groupable(false).Visible(false);
                
               columns.Bound(p => p.CreditApproval)
                   .Template(@<text>
                           @Html.CheckBox("test", false);
                       </text>)
                    
                   .ClientTemplate("<input type='checkbox' #= CreditApproval ? checked='checked':'' # class='input-checkbox' disabled='disabled' />")
                   .Title("Approved");
                    
                
                
               columns.Bound(p => p.AssignedPersonnel).Title("Assigned");
 
           })
       .Groupable()
            
           .Pageable(pager =>
               pager.Refresh(true))
           .Sortable()
           .Filterable()
           .Selectable(selectable => {
               selectable.Mode(GridSelectionMode.Multiple);               
           })
           .DataSource(dataSource => dataSource
                   .Ajax()
                   .PageSize(100)
                   
                   .Read(read => read.Action("Orders_Read", "Production"))
                  
                    
                   .Sort(sort =>
                   {
                       sort.Add("ContainerSize");
                       sort.Add("SystemNumber");
                   })
                   .Group(group =>
                   {
                       group.Add("RequestedShipDate", typeof(DateTime?));
                   })
           )
This lets me select items and then my custom toolbar buttons work fine when they send the selected rows off to the ajax handlers.  But, I want to be able to toggle them and not use the default behavior, which deselects other rows when you select an individual row.  

After hunting around for a while on the forums and through the support docs, it seems you can't do this through Selectable and have to turn that off to use some other jquery to handle the selection.    This is easy enough to accomplish, so I do it this way:

$("#Grid").delegate('tbody >tr', 'click', function () {
     $(this).toggleClass('k-state-selected');
});
This also works fine.  Until I start trying to handle my CustomToolbarButtons via javascript.  These are my javascript functions, which work(ed) when Selectable was configured in the razor syntax, but do not work with the javascript selection:
function assignProductionWork()
    {
        var selection = getGridSelectedItems('#Grid');
        var personnelID = $('#PersonnelID').val();
 
        $.ajax({
            type: "POST",
            url: "/Production/AssignOrders",
            data: JSON.stringify({ personnelID: personnelID, items: selection }),
            dataType: "html",
            contentType: "application/json; charset=utf-8",
            success: function (data) {
 
                refreshGrid();
            },
            error: function () {
                alert('Unable to assign production!');
            }
 
        });
    }
 
    function unassignProductionWork()
    {
        var selection = getGridSelectedItems('#Grid');
 
        $.ajax({
            type: "POST",
            url: "Production/UnassignOrders",
            data: JSON.stringify({ items: selection }),
            dataType: "html",
            contentType: "application/json; charset=utf-8",
            success: function (data) {
                refreshGrid();
            },
            error: function() {
                alert('Unable to clear work assignments.');
            }
        });
    }
 
    function getGridSelectedItems(gridid)
    {
        var grid = $(gridid).data("kendoGrid");
        var selection = [];
 
        grid.select().each(
            function () {
                var dataItem = grid.dataItem($(this));
                selection.push(dataItem);
            }
        );
 
        return selection;
    }

When these run now, I get: Uncaught TypeError: Cannot call method 'value' of undefined , which is being through by the "var dataItem = grid.dataItem($(this));" line.  

If I flip back to selectable, it works just fine - does anyone have any thoughts?  I've been banging my head against this for quite awhile now...
Adam
Top achievements
Rank 1
 answered on 28 Oct 2013
2 answers
445 views
Hello,
i've implemented a custom comand delete-button for inline-editing. if clicked, a popup fades in and i have the choice to click "yes" or "no" for delete confirmation.
but on controller the delete-event is triggered twice and throws errors. what is wrong with my code? hope you can help me.

Grid:
@(Html.Kendo().Grid(Model)
    .Name("Adressen")
     
    // Datasource
    .DataSource(dataSource => dataSource
        .Ajax()
        .AutoSync(true)
        .PageSize(250)
        .Model(model =>
        {
            model.Id(p => p.Eadr);
            model.Field(p => p.Eadr).Editable(false);
            model.Field(p => p.BaLand).DefaultValue(new LiCPSAdmin2.Models.BaLand());
        })
        .Events(events => events.Error("adressen_error_handler"))
        .Create(create => create.Action("Create", "Adressen"))
        .Read(read => read.Action("Read", "Adressen"))
        .Update(update => update.Action("Edit", "Adressen"))
        .Destroy(destroy => destroy.Action("Delete", "Adressen"))
    )
     
    //Columns
    .Columns(columns =>
    {
        columns.Command(command =>
        {
            command.Edit().Text(" ");
            command.Custom(" ").Click("adressen_delete_handler").HtmlAttributes(new { name = "btn_delete"});
        }).Width(90).HtmlAttributes(new { style = "background-color: rgb(238, 238, 238)" });
        columns.Bound(p => p.Eadr).Width(90).HtmlAttributes(new { style = "text-align:center;" });
        columns.Bound(p => p.Nama);
        columns.Bound(p => p.Namb);
        columns.Bound(p => p.Namc);
        columns.Bound(p => p.Namd);
        columns.Bound(p => p.Name);
        columns.Bound(p => p.Namf);
        columns.Bound(p => p.Pstc).Width(90).HtmlAttributes(new { style = "text-align:center;" });
        columns.Bound(p => p.Ccty).Width(90).HtmlAttributes(new { style = "text-align:center;" });
        columns.Bound(p => p.BaLand.Dsca)
            .Width(200)
            .ClientTemplate(" #= BaLand ? BaLand.Dsca : '' # ")
            .Filterable(f => f.UI("statesFilter"));
    })
     
    // Events
    .Events(events => events.Edit("adressen_edit_handler")
        .DataBound("adressen_bound_handler"))
         
    // Options
    .ToolBar(toolbar => toolbar.Create().HtmlAttributes(new { enabled = "false" }))
    .Editable(editable => editable.Mode(GridEditMode.InLine).DisplayDeleteConfirmation(false))
    .Pageable()
    .Sortable()
    .Filterable(filter => filter.Extra(false))
    .Scrollable(scrollable => scrollable.Virtual(true))
    .HtmlAttributes(new { style = "height:100%;" })
    .Resizable(resize => resize.Columns(true))
    .ColumnResizeHandleWidth(5)
    .Reorderable(reordering => reordering.Columns(false))
)
Javascript:
function adressen_delete_handler(e) {
    e.preventDefault();
 
    var grid = this;
    var row = $(e.currentTarget).closest("tr");
     
    $("#delete_confirmation_popup").css({'top': ($(row).position().top + 157 + ($(row).height() / 2)), 'margin-left': (86)}).fadeIn();
 
    $("#btn_yes").off().on('click',function () {
        grid.removeRow(row);
        $("#delete_confirmation_popup").fadeOut();
    });
 
    $("#btn_no").off().on('click',function () {
        grid.cancelChanges();
        $("#delete_confirmation_popup").fadeOut();
    });
};
Thanks for help! :)
Helga
Top achievements
Rank 1
 answered on 28 Oct 2013
14 answers
689 views
I'm not sure if this is an issue my grid configuration or just a general MVC issue I am having but I've got a grid in a partial view and when I try to delete an item it is posting to the parent view controller method instead of the method I have configured in the grid.  I believe I have the views configured correctly but I must be missing something.

View:
@model PASS.ViewModels.Proposals.RequiredViewModel
 
@using (Ajax.BeginForm("Required", "Proposals", new AjaxOptions { UpdateTargetId = "requiredReturnMsg", HttpMethod = "Post" }))
{
  
@Html.HiddenFor(model => model.Proposal_ID, Model.Proposal_ID)
 
<div class="editor-container">
 
    <div class="editor-label">
        @Html.Label("Funding Source")
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => model.Funding_Source_ID,  new SelectList(Model.FundingSources, "Value",  "Text"), "(Select One)")
        @Html.ValidationMessageFor(model => model.Funding_Source_ID)
    </div>   
    <br class="clear" />
    <div class="editor-label">
        @Html.Label("Specify (only if requested)")
    </div>
    <div class="editor-field">
        @Html.TextBoxFor(model => model.Funding_Specify, new { style = "width: 350px;" })
        @Html.ValidationMessageFor(model => model.Funding_Specify)
    </div>
    <br class="clear" />
    <br />
    <br />
    <p><input type="submit" value="Add Funding Source" /></p>
    <br />
    <br />
    @Html.Action("FundingSources", "Proposals", new { proposalID = Model.Proposal_ID })
    <br />
    <br />
 
    <div id="requiredReturnMsg"></div>
 
</div>
     
}
The partial view is called by the @Html.Action

Partial View:
@model IEnumerable<PASS.ViewModels.Proposals.FundingSourcesViewModel>
    
@using (Ajax.BeginForm("FundingSources", "Proposals", new AjaxOptions { }))
{
 
<div style="width:95%;">
@(Html.Kendo().Grid(Model)
    .Name("gvFundingSources") 
    .Columns(columns =>
    {
        columns.Bound(o => o.FundingSourceDescription).Title("Funding Source");
        columns.Bound(o => o.Funding_Specify).Title("Specifics");
        columns.Command(command => { command.Destroy(); }).Width(50);
    })
    .Sortable()
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model => model.Id(o => o.ID))
        .Read(read => read.Action("FundingSources", "Proposals"))
        .Destroy(destroy => destroy.Action("DeleteFundingSource", "Proposals"))
    )
)
</div>
     
}

Controller Methods:
public ActionResult Required(int proposalID)
{
    var context = new PASSEntities();
 
    RequiredViewModel model = new RequiredViewModel
    {
        Proposal_ID = proposalID,
        FundingSources = context.Funding_Sources.ToList().Select(m => new SelectListItem { Value = m.ID.ToString(), Text = m.Description }).ToList()
    };
 
    return PartialView(model);
}
 
[HttpPost]
public ActionResult Required(RequiredViewModel model)
{
    try
    {
        var context = new PASSEntities();
        var fundingsource = context.Proposal_Funding_Sources.Find(model.ID);
        bool bAdd = false;
 
        if (fundingsource == null) {
            fundingsource = new Proposal_Funding_Sources();
            bAdd = true;
        }
 
        fundingsource.Funding_Source_ID = model.Funding_Source_ID;
        fundingsource.Proposal_ID = model.Proposal_ID;
        fundingsource.Funding_Specify = model.Funding_Specify;
 
        if (bAdd) context.Proposal_Funding_Sources.Add(fundingsource);
        else context.Entry(fundingsource).State = System.Data.EntityState.Modified;
        context.SaveChanges();
 
        var message = new SystemMessage(Models.eMessageType.SUCCESS);
        message.Message = "Your data has been saved!";
        return PartialView("_SystemMessage", message);
    }
    catch
    {
        var message = new SystemMessage(Models.eMessageType.ERROR);
        message.Message = "Save Failed!";
        return PartialView("_SystemMessage", message);
    }
 
}
 
[ChildActionOnly]
public ActionResult FundingSources(int proposalID)
{
    var context = new PASSEntities();
 
    var model = (from a in context.Proposal_Funding_Sources
                 join b in context.Funding_Sources on a.Funding_Source_ID equals b.ID
                 where a.Proposal_ID == proposalID
                 select new FundingSourcesViewModel()
                 {
                     ID = a.ID,
                     Proposal_ID = a.Proposal_ID,
                     Funding_Source_ID = a.Funding_Source_ID,
                     Funding_Specify = a.Funding_Specify,
                     FundingSourceDescription = b.Description
                 });
 
    return PartialView(model);
}
 
[HttpPost]
[ChildActionOnly]
public ActionResult DeleteFundingSource(int id)
{
    try
    {
        using (PASSEntities context = new PASSEntities())
        {
            var fundingsource = context.Proposal_Funding_Sources.Find(id);
            context.Entry(fundingsource).State = System.Data.EntityState.Deleted;
            context.SaveChanges();
        }
 
        var message = new SystemMessage(Models.eMessageType.SUCCESS);
        message.Message = "Your data has been saved!";
        return PartialView("_SystemMessage", message);
    }
    catch
    {
        var message = new SystemMessage(Models.eMessageType.ERROR);
        message.Message = "Save Failed!";
        return PartialView("_SystemMessage", message);
    }
}

When I try to debug, the DeleteFindingSource Post method is not reached but instead the Required Post method (which is the parent view) is called.

Thanks.
Stephen
Top achievements
Rank 1
 answered on 25 Oct 2013
3 answers
344 views
Hi,

I am facing the format issues in the DateTime Picker control in the scenario if it behaves as a individual control / when it is placed inside the grid.

Please find the attached document for detailed explanation.

Regards,
Sreejesh
Alexander Popov
Telerik team
 answered on 25 Oct 2013
Narrow your results
Selected tags
Tags
+? more
Top users last month
Rob
Top achievements
Rank 3
Iron
Iron
Iron
Atul
Top achievements
Rank 1
Iron
Iron
Alexander
Top achievements
Rank 1
Veteran
Iron
Serkan
Top achievements
Rank 1
Iron
Shawn
Top achievements
Rank 1
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Rob
Top achievements
Rank 3
Iron
Iron
Iron
Atul
Top achievements
Rank 1
Iron
Iron
Alexander
Top achievements
Rank 1
Veteran
Iron
Serkan
Top achievements
Rank 1
Iron
Shawn
Top achievements
Rank 1
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?