I have MVC 5 application. I have the following workflow:
Select a time from kendo time picker control -> On server converts that time into UTC -> Store UTC time in the database -> Retrieve UTC time from DB -> Bind it back to time picker control
Server’s time zone is Central Standard Time (UTC -6:00)
I have the following steps:
1> User selects a time from the Kendo Time picker control and submits it to the server. For example assume user picks “6:00 PM”
2> On server when I check the posted date value, the Kind property is unspecified. That means if I convert this time to UTC time its going to use server’s time zone to offset the time. However i think we want client’s timezone to offset.
3>So I thought of using Kendo time picker’s value() method which returns the value in string format as Wed May 18 2016 18:00:00 GMT-0500 (Central Daylight Time). This value has time zone info including day light saving.
4>So I added hidden field and on client side I assign string value to hidden field.
5> On server I use the hidden field value to convert into UTC and store it into database. So the above value is stored as 23:00:00 UTC time. ( offset is -5)
So far so good
6> On some other screen now I want to show this value to client.
7> Now when i bind this UTC time back to time picker control, it shows 5:00 PM instead of 6:00 PM ( that is 17:00:00 instead of 18:00:00). That means its offsetting by -6 (that’s Central Standard Time).
Question:
1> When getting the value from time picker it knows the day light time zone. ( as we see in the string value). However when we set the value its not considering day light time zone. Why?
Model
public class Mymodel
{
[DataType(DataType.Time)]
public DateTime OrderTime { get; set; }
public string OrderTimeHidden { get; set; }
}
View: That captures time
#model MyNameSpace.Mymodel
<div>
#(Html.Kendo().TimePickerFor(x => x.OrderTime)
.Format("hh:mm tt")
.Value("08:00 PM")
.HtmlAttributes(new { onkeydown = "javascript:return false;" })
)
#Html.HiddenFor(x=>x.OrderTimeHidden)
</div>
Javascript: That post the model to server
submit.click(function () {
$('#OrderTimeHidden').val($("#OrderTime").getKendoTimePicker().value());
// do post here
$.ajax({...})
})
Controller: That converts and saves time into database
[HttpPost]
public ActionResult Save(MyModel model)
{
var dt = DateTime.ParseExact(model.OrderTimeHidden.Substring(0, 33), "ddd MMM d yyyy HH:mm:ss 'GMT'K", CultureInfo.InvariantCulture);
var entity = new MyEntity();
//OrderTime on entity is of type TimeSpan
entity.OrderTime = dt.ToUniversalTime().TimeOfDay;
SaveToDataBase(entity)
return View("SomeView");
}
Controller: That shows the time on UI
[HttpGet]
public ActionResult ViewTime()
{
var entity = GetEntityFromDataBase();
var model = new MyModel();
model.OrderTime = new DateTime(entity.OrderTime.Ticks, DateTimeKind.Utc)
return View();
}
View: That shows the time on UI
<div>
#Html.Kendo().TimePickerFor(x => x.OrderTime)
.Format("hh:mm tt");
</div>
Related
How to do some date validation here so that when user enter end date less than start date it will prompt error to user? Is there any built in function made by AppMaker? Thanks for sharing!
If you want to limit the input to a data model, you can use the Advanced section of the data model.
You can also achieve data validation through Event section or Data Validation section. Use the the first one to implement small scripts and the second one to hardcode rules into the app.
// date is not a previous date
var date = new Date();
if (widget.value < date) {
alert('Invalid date');
}
// date is not a future date
var date = new Date();
if (widget.value > date) {
alert('Invalid date');
}
// second date is not higher than first date
if (widget.value > widget.parent.descendants.firstDate.value) {
alert('Invalid date');
}
I have a requirement to calculate a record and record total age with the use of enhanced SLA. Is it possible?
Age : A record has a StartDate field and the value of StartDate is 1st March 2016 and there is another field named as EndDate and the value of EndDate is 31st March 2016, and the service getting hold for 3 days in this period, so the Age will be : 31 - 3 = 28
Total Age : Same as per above example but the difference is we does not need to include the hold days, So the Total Age will be : 31.
Thanks,
I found this interesting blog post by Aileen Gusni here
Intercept Column/Field Value in CRM View using RetrieveMultiple Plugin C#
Basically she creates a new field (in the example below it is pa_age), but she doesn't add it to the form or anything
Instead she catches the Retrieve and RetrieveMultiple messages in a Plugin and calculates this field as required.
I've pasted her code below
Note this is not my code, it was written by Aileen
public void Execute(IServiceProvider serviceProvider)
{
#region must to have
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
// Create service with context of current user
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
//create tracing service
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
#endregion
//this is to modify the Age column
if (context.OutputParameters.Contains("BusinessEntityCollection"))
{
var retrievedResult = (EntityCollection)context.OutputParameters["BusinessEntityCollection"];
foreach (Entity entity in retrievedResult.Entities)
{
if (entity.Contains("birthdate"))
{
var birthday = entity.GetAttributeValue<DateTime>("birthdate");
int age = CalculateAgeYear(birthday);
//modify the Age field
entity.Attributes["pa_age"] = age;
}
}
}
}
There are a few things to consider with this approach:
The pa_age field's value never gets set. It is added to the entity only so that it can be included in the view
this means that the pa_age field can't be included on the form or in reports because it will always be null
you can't use the pa_age field in advanced finds (filter), but of course you can add it to the advanced find results. The reason for this is the same as before: the value isn't actually saved in the database
Her blog post has much more information and screenshots of how it all works. I haven't tried this approach but it might be useful for you
I have a website that is written in asp.net using C#. grdStatus is an instance of System.Windows.Forms.DataGridView. It displays 2 columns -- StatusDate and Status. StatusDate contains DateTime values. Status contains strings. The problem is that when the grid is sorted on StatusDate, it does not sort the values as DateTimes. Honestly, I'm not quite sure how it's sorting them. When I click on the Status Date column header, it sorts the dates like this:
Status Date
9/24/2014 10:01:06 AM
9/24/2014 10:00:58 AM
9/23/2014 7:27:23 PM
9/1/2015 4:48:35 PM
10/22/2014 12:15:38 PM
10/22/2014 12:15:29 PM
10/22/2014 12:12:52 PM
10/22/2014 12:12:27 PM
It's certainly not sorting them by DateTime, but it doesn't seem to be sorting them alphabetically, either. Here's the method that refreshes the grid. I added the two lines indicated by ---> in an attempt to force it to sort the rows by DateTime, but they seem to have no effect.
private void RefreshGrid()
{
IEnumerable<OrderService.OrderDetailStatus> statusItems = services.OrderSvc.GetStatusHistoryForOrderDetail(OrderDetailId);
IEnumerable<ViewModels.StatusHistoryGridViewModel> gridItems = AutoMapper.Mapper.Map<IEnumerable<ViewModels.StatusHistoryGridViewModel>>(statusItems);
grdStatus.AutoGenerateColumns = false;
grdStatus.DataSource = gridItems.ToDataTable<ViewModels.StatusHistoryGridViewModel>();
--->grdStatus.Columns[0].ValueType = typeof(DateTime);
--->grdStatus.Sort(grdStatus.Columns[0], ListSortDirection.Ascending);
}
Here's the view model that's being used as the data source for the grid. As you can see, CreatedDate (which is mapped to StatusDate) is a DateTime member.
namespace IVGOffice.ViewModels
{
public class StatusHistoryGridViewModel
{
public string StatusName { get; set; }
public DateTime CreatedDate { get; set; }
}
}
I've looked at some other posting related to this, but I haven't found anything that helps. Can anyone explain to me how to get this to sort correctly?
Part of the problem was that I was overlooking that fact that one of the dates had a different year from the others. After I noticed that, I was able to get the control to sort the column by the date; however, I still wasn't able to get it to sort by both date and time. I think this may be a bug in the DateGridView control. I replaced it with an UltraGrid control from Infragistics and that worked correctly.
I use the following jQuery function to format my datepicker
$(".datepicker").datepicker({
dateFormat : "MM yy"
}).attr('readonly', true);
Upon selection I can see the text field is set correctly to November 2013. Before form is submitted I am using Spring validation to validate the date with
public class LocalMonthEditor extends PropertyEditorSupport {
#Override
public void setAsText(final String text) throws IllegalArgumentException {
if (!StringUtils.hasText(text)) {
// Treat empty String as null value.
setValue(null);
} else {
LocalDateTime localDateTime = LocalDateTime.parse(text,
DateTimeFormat.forPattern("MMMM yyyy"));
setValue(localDateTime);
}
}
#Override
public void setValue(final Object value) {
super.setValue(value == null || value instanceof LocalDateTime ? value
: new LocalDateTime(value));
}
#Override
public LocalDateTime getValue() {
return (LocalDateTime) super.getValue();
}
#Override
public String getAsText() {
return getValue() != null ? getValue().toString() : "";
}
}
However after form being submitted the text field is changed to 2013-11-01T00:00:00.000. How can I maintain the field to November 2013 ?
First of all, if the data you need is simply a month and a year, why are you using Joda-Time at all? That's like getting in your car to drive to your mailbox at the end of the driveway: extra effort and complexity for no benefit.
Instead, I suggest you choose between:
Track a pair of variables (month, year)
Define your own class with a pair of members (month, year), and track an instance.
Use a String as seems to be your intention: "November 2013" as you seem to be thinking, or a simpler schemes such as "2013-11".
Secondly, because you created an instance of LocalDatetime, at some point toString seems to be called. The default output of toString on a LocalDateTime is output in the standard ISO 8601 format you saw: 2013-11-01T00:00:00.000. A LocalDateTime has a date value and a time value (hence the name), even if the time value may be set to zeros (meaning start of day). So this is a feature, not a bug.
I don't know Spring Validatation nor the rest of your class structure. I'm guessing you are storing a LocalDateTime instance where instead you meant to be (or should be) storing a String instance. You may need to read up on the subject of "model" versus "view". Often we track data behind the scenes differently than we present data to the user. In this case, you probably should be holding a pair of ints or Integers (one for month, one for year) in your model with a String in your view ("November 2013").
You are setting your local time object directly to text field, thats why your getting full date string.convert your date object by using parse() method and set it. Do not create new object for date set your value directly.
I have passed DIctionary to my view using a viewbag item.
In my view I am them converting back to Dictionary:
var date = veiwbag.Dictionary as Dictionary;
My dcitionary is set up as:
Key = string of date ("MMM yyyy") eg - SEP 2012
value = int - which is a count of entries in database where the date matches the key.
I am abel to output these Key value pairs. I need to know ho wwhen suer sleects an entry I can return the string Key to an aciton method to retrieve all dates for that string.
I'm new to MVC3 so am a bit lost.
My initial thinking was along the lines of:
(this syntax may be slightly wring as doing from memory)
#date.key (#date.value)
my controller has action:
public ActionResult Previous(string date)
{
..work on data
return View(..my results);
}
the code in the ActionResult is fine . The link takes me to my ActionResult but the string is null. How do I pass the
date.key
into the ActionResult as a string variable? Am I going about this all the wring way?
You could use a HTML helper to generate a proper link to this controller action:
#Html.ActionLink(
string.Format("{0} ({1})", date.key, date.value),
"Previous",
new { date = date.Key }
)
And if you need to specify the controller name as well you could use the following overload:
#Html.ActionLink(
string.Format("{0} ({1})", date.key, date.value),
"Previous",
"Posts",
new { date = date.Key },
null
)
Assuming default routes have been setup this will generate the following markup:
SEP 2012 (9)
and when the Previous controller action is invoked it will successfully be passed the date parameter of SEP 2012.
If you use default routes, then use:
public ActionResult Previous(string id)
or your link must look like:
/Posts/Previous?date=sometext
but better solution is use #Html.ActionLink:
#Html.ActionLink(String.Format("{0} ({1})", date.key, date.value), "Previous", "Posts", new { data = date.Key }, null)