0

For an order form I've created I've been asked to change it a bit so that if a certain shop is chosen they will not be able to select Sundays for a delivery date. My thinking was to have a script running that if a user selected that an alert would appear saying that it's not an option and the date field would be reset.

I have tried the following script but it does not work but no errors appear so I'm not sure where I have gone wrong:

const validation = dateString => {
var value = document.getElementById("collect").value;
const day = (new Date(dateString)).getDay();

if (value == "Auld Toon" && day == 0) {
    return false;
}
return true;
}

// Sets the value to '' in case of an invalid date
document.querySelector('.date').onchange = evt => {
    var value = document.getElementById("collect").value;
  if (!validation(evt.target.value)) {
    evt.target.value = '';
    alert("Unfortunately " + value + " is shut on this day. Please select another");

  }
}

This is the html for selecting a shop and choosing a date:

 <select id="collect" name="collect">
     <option value="" selected="selected" disabled>Select One</option>
     <option value="Alford">Alford</option>
     <option value="Auld Toon">Auld Toon</option>
     <option value="Banff">Banff</option>
     <option value="Emmas">Emmas</option>
     <option value="Insch">Insch</option>
     <option value="Kemnay">Kemnay</option>
     <option value="Market Place">Market Place</option>
     <option value="Mastrick"> Mastrick</option>
     <option value="Meldrum Bakery">Meldrum Bakery</option>
     <option value="North Street">North Street</option>
     <option value="Rousay">Rousay</option>
     <option value="Seafield Street">Seafield Street </option>
     <option value="St Machar">St Machar </option>
     <option value="St Swithin">St Swithin Street </option>
     <option value="Stonehaven">Stonehaven</option>
     <option value="Torry">Torry</option>
     <option value="Keystore Old Aberdeen">Keystore Old Aberdeen</option>
     <option value="Keystore Old Meldrum">Keystore Old Meldrum </option>
     <option value="Highclere">Highclere</option>
 </select>

 <p>What date is this required for?</p>
 <input id="datefield" class="date" name="date" type='date' onkeydown="return false" min='2019-05-10'></input>

Would appreciate any help as to where I have gone wrong and how I can go about fixing it. Thanks

Edit: Okay so it's because of this similar script running that stops my script working:

const validate = dateString => {
  const day = (new Date(dateString)).getDay();
  const month = (new Date(dateString)).getMonth()+1;
  const number = (new Date(dateString)).getDate();
  if (value == "Auld Toon" && day == 0 || number == 25 && month == 12 || number == 24 && month == 12 || number == 26 && month == 12 || number == 27 && month == 12 || number == 1 && month == 1 || number == 2 && month == 1) {
    return false;
  }
  return true;
}


// Sets the value to '' in case of an invalid date
document.querySelector('.date').onchange = evt => {
  if (!validate(evt.target.value)) {
    evt.target.value = '';
    alert("We cannot deliver butteries on this day. Please select another");
  }
}

So is it possible to have these 2 scripts separate or would I just need to join them together and add an if statement for showing the appropriate alert?

Lewis Ross
  • 153
  • 2
  • 13
  • can you please show how you are loading the script. I think you are loading it in the 'head' tag, so the script is being run before the dropdown is rendered. – PR7 Aug 15 '19 at 10:52
  • It's not in the head tag, comes after the end of the form tag – Lewis Ross Aug 15 '19 at 11:01
  • The above code is showing the alert. Is there something i am missing ? See JSFiddle : https://jsfiddle.net/rzotp9nf/ – PR7 Aug 15 '19 at 11:08
  • Okay, so turns out that the script is correct, but because I have a similar script already running it stops this one from working, I've updated my question – Lewis Ross Aug 15 '19 at 11:14
  • Please read the answers to [Why does Date.parse give incorrect results?](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results); `new Date(dateString)` does essentially the same thing as `Date.parse(dateString)`. – Heretic Monkey Aug 15 '19 at 12:55

2 Answers2

1

The 'script' tags are executed sequentially and the Javascript code will be combined hence the second 'onchange' event listener is overriding the first one. You can implement it like this by using one 'onchange' listener:

const validateDate = dateString => {
  const month = new Date(dateString).getMonth() + 1;
  const number = new Date(dateString).getDate();

  // Invalid Dates (24, 25, 26 December and 1, 2 January)
  if (
    (number === 25 && month === 12) ||
    (number === 24 && month === 12) ||
    (number === 26 && month === 12) ||
    (number === 27 && month === 12) ||
    (number === 1 && month === 1) ||
    (number === 2 && month === 1)
  ) {
    return false;
  }
  return true;
};

const validateShop = (value, dateString) => {
  const day = new Date(dateString).getDay();

  if (value === "Auld Toon" && day === 0) {
    return false;
  }

  return true;
};

document.querySelector(".date").onchange = evt => {
  var shop = document.getElementById("collect").value;
  var date = evt.target.value;

  // First Check if date is valid
  if (!validateDate(date)) {
    date = "";
    alert("We cannot deliver butteries on this day. Please select another");
    return; // Return from function if invalid date
  }

  // Shop Validation
  if (!validateShop(shop, date)) {
    alert("Unfortunately " + shop + " is shut on this day. Please select another");
    date = "";
  }
};
<select id="collect" name="collect">
     <option value="" selected="selected" disabled>Select One</option>
     <option value="Alford">Alford</option>
     <option value="Auld Toon">Auld Toon</option>
     <option value="Banff">Banff</option>
     <option value="Emmas">Emmas</option>
     <option value="Insch">Insch</option>
     <option value="Kemnay">Kemnay</option>
     <option value="Market Place">Market Place</option>
     <option value="Mastrick"> Mastrick</option>
     <option value="Meldrum Bakery">Meldrum Bakery</option>
     <option value="North Street">North Street</option>
     <option value="Rousay">Rousay</option>
     <option value="Seafield Street">Seafield Street </option>
     <option value="St Machar">St Machar </option>
     <option value="St Swithin">St Swithin Street </option>
     <option value="Stonehaven">Stonehaven</option>
     <option value="Torry">Torry</option>
     <option value="Keystore Old Aberdeen">Keystore Old Aberdeen</option>
     <option value="Keystore Old Meldrum">Keystore Old Meldrum </option>
     <option value="Highclere">Highclere</option>
 </select>

 <p>What date is this required for?</p>
 <input id="datefield" class="date" name="date" type='date' onkeydown="return false" min='2019-05-10'></input>
PR7
  • 1,524
  • 1
  • 13
  • 24
  • Thanks for the answer I tried it on jsfiddle here: https://jsfiddle.net/pa173fsh/ but it's only the first validation that is getting used? Even if Auld Toon and Sunday is selected it still gives the alert: We cannot deliver butteries on this day. Please select another – Lewis Ross Aug 15 '19 at 12:01
  • @LewisRoss can you please explain the logic for the long if statement ? I would suggest that you should extract that logic in a function. if (value == "Auld Toon" && day == 0 || number == 25 && month == 12 || number == 24 && month == 12 || number == 26 && month == 12 || number == 27 && month == 12 || number == 1 && month == 1 || number == 2 && month == 1) { return false; } – PR7 Aug 15 '19 at 12:11
  • Was just the way I had learned how to do it. How could I change it so that the appropriate alert shows, so that if Auld toon is selected for a Sunday the second valuation into play rather than the first one? – Lewis Ross Aug 15 '19 at 12:24
  • @LewisRoss i have updated my answer according to my understanding of your requirements. I hope this helps. – PR7 Aug 15 '19 at 12:46
  • @LewisRoss JSFiddle for the above code : https://jsfiddle.net/h4o2tcs1/ – PR7 Aug 15 '19 at 13:02
0

Instead of evt.target.value = ''; try document.getElementById("collect").value = '';

Also you access the DOM twice for the Collect element. I would pass the value variable into the validation function, saves you the double look up

Liam Kenneth
  • 982
  • 1
  • 11
  • 21
  • I used your fiddle and did what I suggested and it works. https://jsfiddle.net/tu3e4fs2/ based on the logic you have, when I select "Auld Toon" and set the date to 25th I get an alert and the drop down resets – Liam Kenneth Aug 15 '19 at 12:17
  • Hi thanks. But it gives the first alert rather than the second one if that makes sense? – Lewis Ross Aug 15 '19 at 12:25
  • With how you have your logic set up this works https://jsfiddle.net/sza24p6h/ But with what you have you don't distinguish between nondelivery days and closed days. – Liam Kenneth Aug 15 '19 at 13:25