I want the user to be able to type a date in the format of YYYY-MM-DD but not type anything that doesn’t match that…
This is a usability question. Felgall gave a good answer but I wanted to elaborate on it.
Make sure you are using a <label> that very clearly tells people what kind of date format you are looking for. Sure, someone somewhere may still mix the day and month numbers (and if they use numbers under “13” your back-end check will never catch that), and someone will still just start filling stuff in however they do on most other forms (because lots of people don’t bother to read), but at least you’ve stated in plain-text what you need.
Second possibility (along with the label) is to set up multiple inputs to make what you are looking for clearer to the user.
For example, you could have three text inputs, using “size” and “maxlength” attributes to give users more feedback on what you are looking for. Or three select drop-down controls, which make it clear what’s possible by only offering one type of input. We do this (even though drop-downs are somewhat less user-friendly than text inputs) and use names of months in the month dropdown to make it absolutely clear which is months and which is days. On the back end, PHP changes each month to the desired format (two numbers).
You could use Javascript to correct-as-they-go (Javascript can check simple things like, are they typing numbers? are they typing 4 numbers, then a -, then two numbers, then a -, then 2 more numbers, and nothing more?) as a feedback device. Users such as myself don’t enable Javascript, which is why you’d never rely on this to check your data (you do that with PHP), but most people have it on and it’s just to help them along.
and secondary to that, is there a way to make it so the user can only type in a date if the previous checkbox is selected?
Again, your back end will ensure this, but your front-end needs to encourage it, which is the best it can do.
You can use Javascript to set the date input(s) to “disabled” unless the checkbox is checked (or, you can have Javascript pull the date input offscreen so it’s not seen until the user checks the checkbox… out of sight, out of mind). Not everyone has Javascript on, so of course you’re also going to make it clear with labels and other text that the date makes sense ONLY when the checkbox is checked. Using text like “if so, enter the date” helps.
Since users without Javascript will be able to fill in the date, your back-end script will throw away the date data (without bothering to check if the date was inputted in the correct format, because it doesn’t matter) if the checkbox was not checked. This means the user wasted some of their time entering the date, but does not return an error. The user never knows they were “wrong” and that’s fine.
While you’ll rely on your back end logic to test the input, making the front-end as clear as possible will reduce the number of “bad” versions you get. Which means, fewer error messages for the users, and they get their form submitted correctly as soon as possible, in as few tries as possible.