I have a simple datetime attribute to pick a date like this on the views
= f.date_select :period_end_at, default: { day: 31 }
It defaults to last day of the month as the example. The problem is that if month selected is "June" that has 30 days, since there is no '31' day for June, it will save the object as day 1 instead of day 30.
Is there an easy way to always save to the highest day of the month if the value provided is above all available for that moonth?
Not sure if it could be shortened, but this should work (if I understood your question correctly):
= f.date_select :period_end_at, default: { day: Time.days_in_month(Time.now.month) }
Take a look at this js snippet, it works well for me with Rails 4.2.0
<script>
$(function(){
railsMonthDates();
$("select[id*=_2i], select[id*=_1i]").change( railsMonthDates );
});
function railsMonthDates() {
$("select[id*=_2i]").each(function(){
$monthSelect = $(this);
$daySelect = $(this).siblings("select[id*=_3i]");
$yearSelect = $(this).siblings("select[id*=_1i]");
var year = parseInt($yearSelect.val());
var month = parseInt($monthSelect.val());
var days = new Date(year, month, 0).getDate();
var selectedDay = $daySelect.val()
$daySelect.html('');
for(var i=1; i<=days; i++) {
$daySelect.append('<option value="'+i+'">'+i+'</option>');
}
$daySelect.val(selectedDay);
});
}
</script>
Simply paste it into the partial which has the form.
Pay attention, it match every element which has id*=_1i, id*=_2i or id*=_3i, so if you have more f.date_select you need to specify a better matcher.
Related
I want to show human readable date time in my frontend. My data comes from rails backend. When I use {{ item.created_at }} it shows the time like rails way 2016-10-10T10:29:47.993Z. But How can I show this like 5 days ago, 3 hours ago in angular js?
To format dates in angular you can use date filter like this:
{{ item.created_at | date:'yyyy-MM-dd HH:mm' }}
You are looking for a very particular format so I think you need to build a custom filter to show exactly that. You can use this filter scaffolding:
.filter('customDate', function() {
return function(date) {
// 1. Get current date
// 2. Get diff from expression date to current
// 3. Apply your format and return result;
};
});
Lastly there is a library called momentjs to manipulate dates and times and there is an angular version of that:
Check the am-time-ago directive of the library:
<span am-time-ago="item.created_at"></span>
Try this, Create a filter for that, for reusability of code
var jimApp = angular.module("mainApp", []);
jimApp.controller('mainCtrl', function($scope){
$scope.date = "1992-05-07T22:00:00.000Z";
});
jimApp.filter('dateFilter', function() {
function calculateDate(date) {
date = new Date(date);
var year = date.getFullYear();
var month = date.getMonth()+1;
var day = date.getDate();
return day+'-'+month+'-'+year;
}
return function(date) {
return calculateDate(date);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="mainApp" ng-controller="mainCtrl">
<div>{{date | dateFilter}}</div>
</div>
I have a ASP.NET MVC 4 project with EF. In my (create) view I want to display beside an EditorFor for a date the week number of the current year.
I have a helper:
#model Helios.Models.tablename
#helper Week(DateTime dt)
{
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
#weekNum
}
...
<div class="editor-field">
#Html.TextBoxFor(model => model.date_birth, new {onchange="?"}) #Week(date_birth?)
</div>
I'm not sure if this can be acomplished in Razor, but I need to update the week number if I change the date
Q : How can I display the week no. beside the datepicker and update it if the date is changed ?
Here is a post on that deals with calculating the week number.
How can I calculate/find the week-number of a given date?
But it all depends on if you plan to set it on the server or if the client is to be able to change date. If the client can change the date then you would need javascript instead.
function(d) {
var day = d.getDay();
if(day == 0) day = 7;
d.setDate(d.getDate() + (4 - day));
var year = d.getFullYear();
var ZBDoCY = Math.floor((d.getTime() - new Date(year, 0, 1, -6)) / 86400000);
return 1 + Math.floor(ZBDoCY / 7);
}
From: http://jquery142.blogspot.se/2010/04/how-to-get-week-number-for-date-in.html
I need a way to find these in grails:
1) I have two dates say start and end.
2) User selects two dates in the browser say them userStartDate and userEndDate.
I have all these values, but I need to write a query that do find that both start and end falls between userStartDate and userEndDate.
For example, March 2nd and March 3rd falls between March 1st and March 4th. Given that :
March 2nd and March 3rd are userStartDate and userEndDate dates respectively
March 1st and March 4th are start and end respectively. (they are domain objects).
I have this code which works for between cases i.e start is in between userStartDate and userEndDate like so :
test = Holiday.createCriteria().list {
and {
user {
eq('username',username)
}
or {
between('start',userStartDate,userEndDate)
between('end',userStartDate,userEndDate)
}
}
}
As according to my question, how can attach that part into my code?
Thanks in advance.
Assuming that you already do a check that userStartDate is before userEndDate (validated when the user selects) and that start is before end in the database (validated when inserting), the criteria query should look something like this:
test = Holiday.createCriteria().list {
user { eq('username',username) }
lt('start', userStartDate)
gt('end', userEndDate)
}
This checks that start is less than (i.e. before) userStartDate and that end is greater than (i.e. after) userEndDate. There is also no need to wrap in an and block since all clauses are implicitly and-ed.
Date provides before and after methods (http://docs.oracle.com/javase/6/docs/api/)
if(start.after(userStartDate) && start.before(userEndDate))
{
//start is between userStartDate && userEndDate
}
The simplest way to figure out if one date is between two others is using a Range object
def start = new Date()
def end = new Date() + 10
// make a date range
def dateRange = start..end
// test if some dates are within the range
def inRange = new Date() + 5
def outsideRange = new Date() + 50
assert inRange in dateRange
assert !(outsideRange in dateRange)
However, you mentioned that you want to compare dates in a query, so a Groovy solution may not be optimal. Here's an example for checking if someone's birthday is between 2 dates using a criteria query
def start = new Date()
def end = new Date() + 10
def results = User.withCriteria {
between('birthday', start, end)
}
To the question started, my code (I'll try to only include relevant portions to start), starting with my script:
function RaceDate_onChange() {
var pickedDate = $(this).data('tDatePicker').value();
var month = pickedDate.getMonth() + 1;
$.get("/RaceCard/Details?year=" + pickedDate.getFullYear() + "&month=" + month + "&day=" + pickedDate.getDate());
}
Then my markup:
#Html.Telerik().DatePickerFor(model => model.RaceDate).ClientEvents(events => events.OnChange("RaceDate_onChange"))
And finally a bit of the receiving action:
[HttpGet]
public ActionResult Details(int year, int month, int day)
{
var viewModel = new RaceCardModel {Metadata = DetailModelMetadata.Display, RaceDate = new DateTime(year, month, day)};
I'm trying to get the selection of a new date to trigger a GET, to refresh the page without submitting a form. This works fine, except for this problem:
In GET requests to the Details action, the day value is always one day behind the DatePicker. E.g. The first value is set from a view model property, when the view is rendered, say 3. I then click on 14 and hit my breakpoint in the action method. The day value is 3. When I click on 29 and hit the breakpoint, the day value is 14.
Besides asking what is wrong, I'll take a liberty and ask if there is a better way that is no more complicated. I am fairly novice and would rather deliver working code that needs revision than get bogged down in tangents and details.
Try using e.value instead as shown in the client-side events example. You are probably using an older version where the value() method returned the previous value during the OnChange event.
UPDATE:
"e.value" means the value field of the OnChange arguments:
function onChange(e) {
var date = e.value; // instead of datePicker.value()
}
As far as the 1 month difference you are getting, that's normal, and it is how the getMonth() method works in javascript on a Date instance:
The value returned by getMonth is an
integer between 0 and 11. 0
corresponds to January, 1 to February,
and so on.
So adding +1 is the correct way to cope with the situation, exactly as you did.
Just a little remark about your AJAX call: never hardcode urls. Always use url helpers when dealing with urls:
var year = pickedDate.getFullYear();
var month = pickedDate.getMonth() + 1;
var day = pickedDate.getDate();
var url = '#Url.Action("Details", "RaceCard")';
$.get(url, { year: year, month: month, day: day }, function(result) {
// process the results of the AJAX call
});
what does navigationAsDateFormat do?
also, I have changeMonth and changeYear enabled, how can I make it so that when you change the month and year using those dropdowns, the input field is automatically updated (e.g., updates without having to click on a new day)
added this parameter, does what I need it to, but would still like to get the day in the easiest way possible:
onChangeMonthYear: function(year, month, inst) { $(this).val(month + '/01/' + year); }
Here's the docs for navigationAsDateFormat
When true the formatDate function is
applied to the prevText, nextText, and
currentText values before display,
allowing them to display the target
month names for example.
You could write a function to change the value in the input when the onChangeMonthYear event is raised
Here's a Working Demo
Something like
$('#picker').datepicker({
onChangeMonthYear: function(year, month, inst) {
var now = new Date(this.value);
if (now) {
var max = new Date(year, month, 0).getDate();
var day = now.getDate() > max?
max : now.getDate();
var newDate = new Date(year, month -1, day);
inst.input.datepicker('setDate', newDate);
}
},
changeMonth: true,
changeYear: true
});