Calculate date difference in jQuery - javascript

The question is; there are 2 fields in my application, one is date (Field1) and second is a label (Field2). So, I want that when user selects a date in field 1, then field 2 should be automatically populated (current date - date from field 1).
Can anyone help on how to implement it.
I'm using jQuery to display date:
// This displays the date dialog when user clicks on Field1
$('#Field1').click(function () {
$('#Field1').simpleDatepicker();
});
// Tried following code but it didn't worked
$('#Field1').click(function () {
$('#Field1').simpleDatepicker({
onSelect: function () {
$('#Field2').value(calculateDays($('#Field1').toString))
}
});
});
function calculateDays(dateString) {
var today = new Date();
var inputDate = new Date(dateString);
var days = today - inputDate;
return days;
};
This may look like pathetic code to some folks but I'm just a beginner, so any suggestions/comments are welcome.
Also please tell me if this can be done using html only and no need to go to jQuery. It is my understanding that the calculating days (difference between dates) code will go in jQuery since this needs to be fired after selecting date ('onSelect' event). Please correct if wrong.

I'm assuming that you're trying to use Karl Seguin's jquery.simpleDatePicker (it came top when searching for "simpledatepicker" on Google).
As Jimbo remarks in the comments, it's hard to advise on an MVC approach here — you say you want to do this purely with HTML, but HTML alone can't dictate behaviour (I'd say that's extremely un-MVC). HTML5 forms do allow some limited behavioural control (validation etc), and they also offer <input type="date"/>, but none of these help your situation.
So for this answer I'm just going to fix the mistakes in your code:
The plugin is initialised with the simpleDatePicker jQuery method — you forgot to capitalise the 'P';
The plugin itself caters for the click event. You should initialise it directly without waiting for user input;
There was no onSelect initialisation option in the source code: I chose to use a change event listener on the input to capture this;
You use the jQuery method value — that's native DOM Javascript — you should be using val instead;
toString won't work on DOM elements or jQuery objects — again, use the val method;
The native Date object can't parse dates in arbitrary formats — nor would your code produce a number of days if it did (it would just produce the difference in milliseconds). For this kind of functionality you should use a good date library: I've opted for Moment.
Resulting code (as demonstrated here):
$('#Field1')
.simpleDatePicker()
.on('change', function passValue(){
$('#Field2').val(calculateDaysFromNow($('#Field1').val()))
});
function calculateDaysFromNow(dateString){
return moment.duration(moment(dateString,'MMM DD YYYY').diff()).days();
}
A bit of elaboration on how I've used moment:
First of all, we want to parse #Field1's formatted date for an actual quantifiable date object:
moment(dateString,'MMM DD YYYY')
Next, we want to differentiate that from now. Like Date, moment assumes now if we pass no argument:
moment(dateString,'MMM DD YYYY').diff()
We don't want this as a date, but as a duration, so we'll pass it to moment's duration method:
moment.duration(moment(dateString,'MMM DD YYYY').diff())
…and finally, we want this expressed in days:
moment.duration(moment(dateString,'MMM DD YYYY').diff()).days()

I'm not sure but this:
$('#Field2').value(calculateDays($('#Field1').toString)) should be like this:
$('#Field2').value(calculateDays($('#Field1').val())) or $('#Field2').value(calculateDays($('#Field1').text()))

Here is solution for setting same date in second field.
Link:jquery: using two datepicker with two fields ( field 1 , field2 + 1 day ) like booking.com
Change the format according to your need.

Related

How to add 30 minutes to startdate in update/delete dialog in fullcalendar 3.10 javascript

In the update window I would like to automatically add 30 minutes to the event start date:
$('#updatedialog').dialog({
autoOpen: false,
width: 680,
buttons: {
"update": function () {
var eventToUpdate = {
id: currentUpdateEvent.id,
title: $("#eventName").val(),
description: $("#eventDesc").val(),
color: $("#colorPicker").val(),
start: new Date($("#eventStart").val()),
end: new Date($("#eventEnd").val()),
//end: new Date($("#eventEnd").val(moment(event.start).add(30, "m").format("YYYY-MM-DD[T]HH:mm"))),
//end: new Date($("#eventEnd")).setMinutes($("#eventStart").val() +30),
note: $("#EditEventNote").val(),
/*start: moment($("#eventStart").val(), "DD/MM/YYYY HH:mm"),*/
};
PageMethods.UpdateEvent(eventToUpdate, updateSuccess);
$(this).dialog("close");
currentUpdateEvent.title = $("#eventName").val();
currentUpdateEvent.description = $("#eventDesc").val();
currentUpdateEvent.color = $("#colorPicker").val();
currentUpdateEvent.note = $("#EditEventNote").val();
currentUpdateEvent.start = new Date($("#eventStart").val());
currentUpdateEvent.start.setMinutes(currentUpdateEvent.start.getMinutes() + 30);
$('#calendar').fullCalendar('updateEvent', currentUpdateEvent);
$('#calendar').fullCalendar('refetchEvents');
},
But this code doesn't work.
Firstly this is largely a momentJS issue, not a fullCalendar one.
You need to clone the start date, mutate it by 30 minutes, and then format it for output.
N.B. event.start doesn't actually appear anywhere in your code, so I'm assuming you actually wanted to use the value from the "eventStart" textbox instead. And I've gone back to setting the date format the way we agreed in your earlier question about this code. It's unclear why you've stopped doing it that way, because you already made clear it didn't work to set the start/end dates using new Date(...).
Therefore your code would look this like:
"update": function () {
var start = moment($("#eventStart").val()); //parse the start date
var end = moment(start); //clone the start date to make the end date
end.add(30, "m"); //add 30 minutes to the end date
//create the event object with formatted dates
var eventToUpdate = {
start: start.format("YYYY-MM-DD HH:mm"),
end: end.format("YYYY-MM-DD HH:mm")
//...etc
};
$("#eventEnd").val(end.format("YYYY-MM-DD[T]HH:mm")); //only include this line if you actually want to set the value of the eventEnd textbox.
//...etc
Minimal demo: https://codepen.io/ADyson82/pen/PojKGXY
Relevant documentation:
https://momentjs.com/docs/#/parsing/moment-clone/
https://momentjs.com/docs/#/manipulating/add/
P.S. I want to make a more general point about your approach to programming, based on what you've shown here, and your various previous questions where I've intervened.
This attempt:
//end: new Date($("#eventEnd").val(moment(event.start).add(30, "m").format("YYYY-MM-DD[T]HH:mm")))
contains a jumble of code all packed together in what appears to be a giant piece of guesswork, or possibly a "throw everything at it until something sticks" approach. Neither of those techniques are going to make you a good programmer. Programming is a science / engineering discipline, not an art form or a hit-and-hope game. You need to be methodical and precise. If the best you can say about it is that it "doesn't work", then it's clear you haven't analysed it at all. To solve problems in your code, you need to analyse it and debug it piece by piece.
So what you need to do with that code, to see why it's not working, is take it all apart, read the documentation properly for each of the many functions you've used there, and work out what they output and whether that's relevant to your situation - and/or whether each one gives suitable input to the thing you've included it within.
When testing JavaScript / jQuery code you should also be checking in your browser's Console (in the Developer Tools) for errors, and using the built-in debugger to step through the code line by line to see the values of your variables, and spot where the code and the values don't do what you expected them to. (If you don't know what you expect a particular part of the code to do, then you should either scrap that part and write something you can understand, or go and read documentation and try examples using that code until you do understand it. Otherwise you're just back to guessing again, and that's pointless.)
You can test each part of the code individually to verify your understanding. Putting large numbers of function calls together in one line like in the example above makes it very difficult to debug - for testing, you should split it into invidiual lines and see what each one produces, before deciding whether it's useful to put into the next step. For example if we break down that code into separate steps, we'd end up with:
var moment1 = moment(event.start);
moment1.add("30", "m");
var formattedDate = moment1.format("YYYY-MM-DD[T]HH:mm");
var x = $("eventEnd").val(formattedDate);
var dt = new Date(x);
var eventToUpdate = {
//...
end: dt
}
Now let's pick apart the logical flaws, one by one:
event.start doesn't appear to exist in the context you've shown (unless you've omitted some outer code). So you're probably starting with a blank to begin with. As I mentioned above, I'm guessing you actually meant to use the value from the eventStart textbox instead.
If event.start does exist in this context, then it looks like it probably came from fullCalendar, and fullCalendar v3 (as per its documentation) already gives you dates as momentJS objects - so you don't need to wrap them in the moment() constructor all over again. Whilst it does no harm, it's also inefficient and clutters up your code for no reason.
$("eventEnd").val() will set the value of a field on the page. It's not clear whether this was intentional or not, since your stated objective was to add 30 minutes to the event's start date (presumably to form an end date ready to send to the server, although your wording could be interpreted to mean you actually want to modify the start date itself, not use it as an end date).
.val() doesn't return a value (it only sets a value when used the way you've done it). Therefore x will always be empty.
Because x is empty, new Date(x) won't do anything useful.
You don't want new Date anyway, because you need to send a pre-formatted Date as a string to your server - we already discussed this in one of your previous questions so it's not clear why you've tried this again now - apart from, as I've assumed above - that you still don't really understand any of these individual pieces of code and are still guessing randomly without testing them properly or reading anything about what they do. I will speak candidly and say that you will never achieve anything as a programmer until you learn to do both of those things. Once you start doing them, your tasks will suddenly start to seem a lot easier.
As you can see, once we break this down one by one, it's a lot easier to find the problems on their own than when it's all together in one line and you can't tell which part is doing what. Once you've got something that works, then it's fine to reduce it down into less lines if you think it saves space or makes the code neater. But don't do that until you're sure it's going to do what you want.

show certain date in date picker

I'm using pickmeup datePicker in my Angular project, and it works good and stable but I faced a problem. When I'm trying to set a particular date, picker breaks and/or disappears. I used the method set_date from the documentation but I think I'm missing something.
I use the following code
showDate(timestamp: number) {
const timeString = timestamp.toString();
this.pickerInstance.set_date(new Date(timeString));
}
I have a stackblitz code template here.
So the idea is, I want to have a button when I'm pressing on it, it passes timestamp value to showDate function and after that datePicker shows my date.
I don't want to use jquery here, I believe this could be done without it. But maybe I'm wrong.
Any ideas, comments, help is welcome? thank you.
The constructor of Date needs a number not a a string.
You need to call this.pickerInstance.update() after the update
public showDate(timestamp: number) {
this.pickerInstance.set_date(new Date(timestamp));
this.pickerInstance.update();
}

Change jquery datetimepicker format on event

After much too much googling and searching stackoverflow for my answer, I have been unsuccessful. So I am sorry if this is a duplicate.
I have a datepicker that displays only time. I wish to toggle between military and standard time on a dropdown onchange event.
My attempts have been something of this:
function militarytoggle(element)
{
timetype = $("#military").val();
if(timetype == "military")
{
$('.time').datetimepicker({
timeOnly: true,
timeFormat: 'HH:mm'
});
}
else if(timetype == "standard"){
$('.time').datetimepicker({
timeOnly: true,
timeFormat: 'hh:mm TT'
});
}
}
EDIT: The datetime method I am using (that is currently working) is rendered on document ready:
$('.time').datetimepicker({
timeOnly: true,
dateFormat: '',
timeFormat: 'hh:mm TT'
});
I only wish to change timeFormat on an event.
One would think this would work, redundancy aside. What on Earth am I doing wrong??
Thanks in advance everyone!
One of your if statements is written as
if($(timetype == "military")
the other as
else if(timetype == "standard")
First of all, the former of those has unclosed parenthesis. But also, one uses $ and the other doesn't. Only one of these can be the correct syntax (I'm thinking the later).
Similarly, you use
$('.time').datepicker
in one place and
$('.time').datetimepicker
in the other. Again, only one of these is probably the right method to use.
Edit: added from comments below:
If the datetimepicker method is a constructor, calling it again after the page has been created may not actually change the format of an existing control.
Further:
You should check the documentation (or the source code if there is no good documentation) of the datetime picker widget to see if there is a method for changing the display format of an existing control (or if the format is a public property you might be able to assign it directly). If there is not, then having two versions initialized and hiding one is probably the best way to do it, although you could also do a post back to the server, and have some server side code that uses a passed parameter to render a page with the datetimepicker set to the desired format.
I have solved this problem by adding a military and standard time field for each form. I then toggle the disabled property as well as the display CSS instead of trying to change the datetimepicker.
Then I just bind datetime picker to all fields on document ready.
function militarytoggle(element)
{
timetype = $("#military").val();
if(timetype == "military")
{
$(".standard").prop("disabled",true).css("display","none");
$(".military").prop("disabled",false).css("display","block");
}else if(timetype == "standard"){
$(".standard").prop("disabled",false).css("display","block");
$(".military").prop("disabled",true).css("display","none");
}
}
This seems hacky, if anyone else has a cleaner solution I will accept it as an answer.

Changing date entered in textbox to another format using javascript asp.net

I've been looking at forums and tutorials all day, and I can't seem to figure this out. I'm 100% new to asp.net and web design (html, etc); I have been using winforms and vb.net for a few months now.
I have a textbox (ID=DOBTextbox) on a page, and I'm trying to implement javascript code that, when the textbox text length is at least 6 chars (or better yet, can be evaluated as a date), the text changes to a specific date format (preferably MMM dd, yyyy, but I'd be willing to use a built-in javascript date converter function that gets it close). I want to use javascript because I want it to be client-driven.
Following many of the examples along these lines, I understand that I need to create a function in my source file, and I can add an attribute to my code-behind file.
<script type="text/javascript">
function reformatDate(inputDate) {
var outputDate = inputDate.toString();
return outputDate;
}
</script>
And in my code-behind:
DOBTextBox.Attributes.Add("onblur", "reformatDate('" & DOBTextBox.Text & "')")
However, nothing happens when I leave the textbox.
Note: I used "onblur" because I kept trying things out. My first preference is an event that fires when the user changes the text of the textbox. Also, I used ".tostring()" in my function because I got an error saying that todatestring() wasn't recognized (I think todatestring() output is closer to the format I'd like).
Thanks in advance for any help!!!
You probably want this:
DOBTextBox.Attributes.Add("onblur", "reformatDate(this.value);")
With your code, you're trying to combine ASP.NET code and javascript. ASP.NET is static when sent to the browser, javascript is dynamic. When you use your code, you're hardcoding the value of the textbox at the time your ASP.NET code is run into the attribute. So the HTML will probably render as something like:
<input type="text" id="whatever" name="whatever" value="10/24/2001" onblur="reformatDate('10/24/2001')" />
With my change, it will make javascript grab the textbox's value at the time it is blurred and pass it to the reformatDate function. So it will be rendered as something like:
<input type="text" id="whatever" name="whatever" value="10/24/2001" onblur="reformatDate(this.value)" />
Something you may want is to use onchange, not onblur, so that the function only fires when the textbox's value changes, not just if the textbox is blurred.
UPDATE:
The ASP.NET code needs changed to:
DOBTextBox.Attributes.Add("onblur", "this.value = reformatDate(this.value);")
so that the value of the textbox is re-set to the converted value.
UPDATE2:
Try changing your function to:
function reformatDate(inputDate) {
if (inputDate.length > 5) { // Least amount of characters for possible date
var outputDate = new Date(inputDate); // Convert input to date object
if (!isNaN(outputDate.getTime())) { // Makes sure the date is valid
return outputDate.toDateString(); // Return formatted date only if valid
}
}
return inputDate; // Return original value if invalid date
}

Parse ONLY a time string with DateJS

I'm using the excellent (but large) DateJS library to handle dates and times in my webapp. I just came across something that I'm not sure how to handle.
I want my users to be able to enter Time strings only, without a date, but they should be able to enter it in any manner they please. For instance:
5:00 pm
17:00
5:00pm
5:00p
5p
etc.
Using Date.parse(value) converts these strings into a full date, which is exactly what I want. However, it also allows the user to enter any other part of a date string, such as:
sat 5pm
1/1/2010 5pm
etc.
I'm trying to use DateJS to validate an input field for a time value. Something like:
function validateTime(value) {
return Date.parse(value) !== null;
}
Is there a way to use DateJS features to solve this? There are other SO questions that provide solutions, but if DateJS has a way to do this, I don't really want to add more custom code to my app to do this.
Shortly after asking my question, I discovered that Date.parseExact() can take an array of format strings. Somehow I'm missed that. I managed to get something working with the following code:
function validateTime(input) {
return Date.parseExact(input, [
"H:m",
"h:mt",
"h:m t",
"ht","h t"]) != null ||
Date.parseExact(input, [
"h:mtt",
"h:m tt",
"htt","h tt"]) != null;
};
Note that some formats don't seem to be able to be included together at the same time, which is why I split them into two separate parseExact() calls. In this case, I couldn't include any string that contained a single t in it with format strings that contained a double tt in it.
The additive approach seems cumbersome. Takes away the beauty of DateJS in my opinion. I needed the same solution and decided to just sneakily append the date in front of my input string before parsing with DateJS:
var parsed = Date.parse(Date.today().toString('M/d/yyyy') + ' ' + this.value);
if (parsed) {
alert(parsed.toString('h:mm tt'));
}
Now DateJS will not be sniffing around for any of its date-part parsing patterns, as you have already subbed it in.
Hope this helps someone!

Categories