0

So I have this scenario with a screen like below:

enter image description here

I am trying to make the end date always 7 days greater than the start date. So when I change the start date to 2019-05-01,then end date should be 2019-05-08 and so on and so forth.

I am using datepicker library to make this work.

Code:

Start Date:&emsp;<input class="txtStartDate" style="font: 13px/1.231 Trebuchet MS;" type="text" id="txtStartDate" name="Start Date" value="<%=currentDate%>" readonly><br><br>


End Date: &emsp; <input class="txtEndDate" style="font: 13px/1.231 Trebuchet MS;" type="text" id="txtEndDate" name="txtEndDate" value="<%=defaultDate%>"  readonly required/><br><br>


<script>

$(function() {

  $(".txtEndDate").datepicker({
    changeMonth: true,
    changeYear: true,
    showOn: 'button',
    buttonImage: '../../../images/calendar.png',
    buttonImageOnly: true,
    title: 'Click to open calendar',
    alt: 'Click to open calendar'
  });
});

$(function() {

  $(".txtStartDate").datepicker({
    changeMonth: true,
    changeYear: true,
    showOn: 'button',
    buttonImage: '../../../images/calendar.png',
    buttonImageOnly: true,
    title: 'Click to open calendar',
    alt: 'Click to open calendar'
  });
});

$('#txtStartDate').datepicker();
$('#txtEndDate').datepicker();

$('#txtStartDate').change(function() {
  var interval = 7;

  function convertDateString(p) {
    return (p < 10) ? '0' + p : p;
  }

  var startDate = new Date($(this).val());
  startDate.setDate(startDate.getDate() + interval);
  $('#txtEndDate').val(startDate.getFullYear() + '/' + convertDateString(startDate.getMonth() + 1) + '/' + convertDateString(startDate.getDate()));
});

</script>

I implemented an onchange function to get it to work but there's no changes to it, is there anything I did wrong?

Screenshot of my datepicker:

enter image description here

halfer
  • 19,824
  • 17
  • 99
  • 186
Daredevil
  • 1,672
  • 3
  • 18
  • 47
  • 2
    Which datepicker library are you using? This looks almost like jQuery UI Datepicker, but it doesn't have `title` and `alt`. – Barmar Apr 23 '19 at 03:50
  • It's redirects me to `jquery-ui-1.82.custom.min.js` , is that correct? – Daredevil Apr 23 '19 at 03:52
  • can you log `startDate` before set last line set value. – Kaushik Apr 23 '19 at 03:52
  • @Kaushik I don't follow what you're saying. – Daredevil Apr 23 '19 at 03:53
  • I edited my post to include a screenshot of the datepicker – Daredevil Apr 23 '19 at 03:55
  • Possible duplicate of [How to make sure end date is always 7 days more than start date?](https://stackoverflow.com/questions/55803646/how-to-make-sure-end-date-is-always-7-days-more-than-start-date) – halfer Apr 23 '19 at 07:46
  • This looks like a duplicate of your prior question. Four questions in two hours on the same theme is quite excessive anyway - it is worth being careful that your enthusiasm for asking questions does not turn into help vampirism. – halfer Apr 23 '19 at 07:47
  • But they are not duplicate, is that not allowed? Otherwise, i will delete it – Daredevil Apr 23 '19 at 08:03
  • It is technically OK if they are not duplicates (and since you now have some answers, it would be unfair on helpers to delete it). Nevertheless, I am still of the view that if you are asking four questions in two hours, you are not doing enough research on your own. – halfer Apr 23 '19 at 09:50

2 Answers2

2

Alternatively, rather than listening to $('#[start/end datepicker id]').change you can use the provided .on("change", function().

Fiddle or snippet below:

var interval = 7;
    $(function() {
      $("#sdatepicker").datepicker({
        minDate: 0,
        maxDate: interval
      });

      $("#edatepicker").datepicker({
        minDate: 0
      });

      var today = new Date();
      var target = new Date(today.getFullYear(), today.getMonth(), today.getDate() + interval);
      $("#sdatepicker").datepicker("setDate", today);
      $("#edatepicker").datepicker("setDate", target);

      $("#sdatepicker").datepicker({
        changeMonth: true,
        changeYear: true,
        showOn: 'button',
        buttonImage: '../../../images/calendar.png',
        buttonImageOnly: true,
        title: 'Click to open calendar',
        alt: 'Click to open calendar'
      }).on("change", function() {
        var start = $("#sdatepicker").datepicker("getDate");
        start.setDate(start.getDate() + interval);
        $("#edatepicker").datepicker("setDate", start);
        $("#edatepicker").datepicker("option", "minDate",
          $("#sdatepicker").datepicker("getDate"));
      });

      $("#edatepicker").datepicker({
        changeMonth: true,
        changeYear: true,
        showOn: 'button',
        buttonImage: '../../../images/calendar.png',
        buttonImageOnly: true,
        title: 'Click to open calendar',
        alt: 'Click to open calendar'
      }).on("change", function() {
        var start = $("#sdatepicker").datepicker("getDate");
        $("#sdatepicker").datepicker("setDate", start);
        $("#sdatepicker").datepicker("option", "maxDate",
          $("#edatepicker").datepicker("getDate"));
      });
    });
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<p>Start Date: <input type="text" id="sdatepicker"></p>
<p>End Date: <input type="text" id="edatepicker"></p>

Explanation:

minDate is used to prevent past date to be selected. 0 is today.

Using interval you can update the start/end date with a fixed interval when any of them was changed, and to limit end date cannot be less than the start date and start date cannot be greater than the end date you can combine maxDate and minDate:

$("#edatepicker").datepicker("option", "minDate", $("#sdatepicker").datepicker("getDate"));

and:

$("#sdatepicker").datepicker("option", "maxDate", $("#edatepicker").datepicker("getDate"));

Update

The following fiddle solved OP problem apparently as discussed. Snippet:

var interval = 7;
$(function() {
  var start;
  var today = new Date();
  var target = new Date(today.getFullYear(), today.getMonth(), today.getDate() + interval);
  $(".txtStartDate").datepicker("setDate", today);
  $(".txtEndDate").datepicker("setDate", target);

  $(".txtStartDate").datepicker({
    minDate: 0,
    changeMonth: true,
    changeYear: true,
    showOn: 'button',
    buttonImage: '../../../images/calendar.png',
    buttonImageOnly: true,
    title: 'Click to open calendar',
    alt: 'Click to open calendar',
    onSelect: function() {
      start = $(this).datepicker("getDate");
      start.setDate(start.getDate() + interval);
      $(".txtEndDate").datepicker("setDate", start);
      $(".txtEndDate").datepicker("option", "minDate",
        $(this).datepicker("getDate"));
      $(this).change();
    }
  }).on("change", function() {
    $(".txtEndDate").datepicker("setDate", start);
    $(".txtEndDate").datepicker("option", "minDate",
      $(this).datepicker("getDate"));
  });

  $(".txtEndDate").datepicker({
    minDate: 0,
    changeMonth: true,
    changeYear: true,
    showOn: 'button',
    buttonImage: '../../../images/calendar.png',
    buttonImageOnly: true,
    title: 'Click to open calendar',
    alt: 'Click to open calendar'
  });
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<p>Start Date: <input type="text" class="txtStartDate"></p>
<p>End Date: <input type="text" class="txtEndDate"></p>

$(".txtEndDate").datepicker("option","minDate", start.getDate())

won't work because

var start = $(".txtStartDate").datepicker("getDate"); is initialized, then updated into start.setDate(start.getDate() + interval);.

Which mean start.getDate() won't result in $(".txtStartDate").datepicker("getDate");

While $(".txtEndDate").datepicker("option", "minDate", $(".txtStartDate").datepicker("getDate")); work.

Also, apparently previous month won't trigger onchange or onselect setting the end date while calling them twice and early initializing of var start; would:

onSelect: function() {
      start = $(this).datepicker("getDate");
      start.setDate(start.getDate() + interval);
      $(".txtEndDate").datepicker("setDate", start);
      $(".txtEndDate").datepicker("option", "minDate",
        $(this).datepicker("getDate"));
      $(this).change();
    }
  }).on("change", function() {
    $(".txtEndDate").datepicker("setDate", start);
    $(".txtEndDate").datepicker("option", "minDate",
      $(this).datepicker("getDate"));
  });
Shinjo
  • 677
  • 6
  • 22
  • Is there a way to prevent people from choosing the end date < start date? because it doesn't make sense – Daredevil Apr 23 '19 at 04:38
  • There is, like in my example. The end date can't be picked less than today + interval. To prevent past date being picked you can modify the `minDate` value. – Shinjo Apr 23 '19 at 04:38
  • i followed the answer here: https://stackoverflow.com/questions/55804334/javascript-setting-mindate-to-prevent-from-choosing-date-before-current-date/55804372?noredirect=1#comment98276691_55804372 – Daredevil Apr 23 '19 at 04:39
  • Perhaps can that be changed to make sure end date cannot be chosen less than start date? – Daredevil Apr 23 '19 at 04:40
  • i tested your fiddle, it doesn't let me choose any date for end date after 30th – Daredevil Apr 23 '19 at 04:43
  • Do you mean before? Since `minDate` only restrict past date set not future date. – Shinjo Apr 23 '19 at 04:44
  • But for end date, i cannot choose 26th april, it's blurred out – Daredevil Apr 23 '19 at 04:45
  • That's because I set `minDate: interval` which is today+7. If you don't need it, it could be removed. See this: https://jsfiddle.net/3zy0den8/ – Shinjo Apr 23 '19 at 04:49
  • I get what you mean now, but i'm trying to prevent people from selecting end date end date – Daredevil Apr 23 '19 at 04:49
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/192245/discussion-between-shinjo-and-daredevil). – Shinjo Apr 23 '19 at 04:50
1

Don't use the change event of the input. Use the datepicker's onSelect option, it runs a callback when you select a date from it.

And you should use the setDate() method of the other datepicker to change its date.

  $(".txtStartDate").datepicker({
    changeMonth: true,
    changeYear: true,
    showOn: 'button',
    buttonImage: '../../../images/calendar.png',
    buttonImageOnly: true,
    title: 'Click to open calendar',
    alt: 'Click to open calendar',
    onSelect: function(value, dp) {
      var interval = 7;
      var start = dp.datepicker("getDate");
      start.setDate(start.getDate() + interval);
      $(".txtEndDate").datepicker("setDate", start);
    }
  });
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I don't follow, so how should the end date datepicker be? – Daredevil Apr 23 '19 at 04:00
  • I don't understand the question. `$(".txtEndDate").datepicker("setDate", start);` changes the end date datepicker. – Barmar Apr 23 '19 at 04:03
  • You don't need to make any changes to the end datepicker, just this change to the start datepicker. – Barmar Apr 23 '19 at 04:05
  • I see. I am not too familiar with this library, is there a way to prevent user to choose start date/end date that are before today? E.g 2019-03-01. I thought maybe i can add something to the function above. – Daredevil Apr 23 '19 at 04:08
  • 1
    Use the `minDate` option. Why don't you read the documentation? http://api.jqueryui.com/datepicker/ – Barmar Apr 23 '19 at 04:10