There is no readonly attribute associated to an input element when the ui:inputdata renders, so there is no question of making the ui:date readonly. I was going to recommend lightning:input but you do not get the nice date picker option with lightning:input component
This is what I did,
Downloaded momentJS from here: https://momentjs.com/ and load it into the static resource( do not go for CDN option locker service will not support CDN)
Though this JS library is not officially published as locker supported third party library , i looked this forum and saw @mohith answer this question: Is there a version of moment.js that works with the current Locker Service?
The only close answer I found to validate mm/dd/yyyy format was by using momentJS, all other options will fail you somewhere down the line.
Not to the code
Component:
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction" access="global">
<ltng:require scripts="{!$Resource.momentjs}"
afterScriptsLoaded="{!c.validatedate}" />
<ui:inputDate aura:id="dateField" label="Birthday" value="2014-01-30" displayDatePicker="true" format="MM/dd/yyyy" change="{!c.validatedate}"/>
</aura:component>
controller:
({
validatedate : function(component, event, helper) {
var date_val = component.find("dateField").get("v.value");
var date_formatter = new Date(date_val);
if(date_val.includes('//') || !moment(date_formatter, 'MM/DD/YYYY', true).isValid()){
alert("invalid date please enter in MM/DD/YYYY format");
component.find("dateField").set("v.value","2014-01-30");
}
}
})
output: