Attach validation rule to form field programmatically - javascript

I am using VeeValidate to do some validation on a form made with Vue.js. I have it set up to display a span with the error message related to the input where the error occurred.
<div class="input-group">
<input type="date"
class="form-control"
name="panelData.AnalysisDate"
data-vv-as="Analysis Date"
v-model="panelData.AnalysisDate"
v-validate="'required|date_format:YYYY-MM-DD'">
</div>
<span v-show="errors.has('panelData.AnalysisDate')" class="redText">{{errors.first('panelData.AnalysisDate')}}</span>
All of the inputs are set up the same way and they are all working correctly.
The issue arises when I try to add a validation rule to the above input that requires a date-between rule that uses a year from today's date as the max value.
date_between:{min,max}
The v-validate attribute takes in a string of the validation rules delimted by a |. There is a way to dynamically add rules via the validator instance that gets automatically attached to the Vue instance.
$validator.attach({field}, {rules list}, {options})
I tried to do the code below in both the 'created' and 'mounted' life cycle hooks and neither yielded the results I am looking for.
var today = new Date();
var yearFromToday = new Date(today.getFullYear() + 1, today.getMonth(), today.getDate());
var yearFromTodayStr = yearFromToday.toISOString().substring(0, 10);
//'this' refers to the current view instance
//'panelData' is the name of an object in my component's data object
this.$validator.attach('panelData.AnalysisDate', 'date_between:2001-01-01,' + yearFromTodayStr, {
prettyName: 'Analysis Date'
});
The annoying thing is, the code works because if I use the console (chrome) to insert my code, it gives me the desired results once everything is rendered on the screen. I am not sure if I am using the correct lifecycle hooks.

The way I got around this feels hacky but I couldn't get it to work with my original approach.
For date fields that required a dynamic range I ended up using the directive style rules string and concatenated a computed property.
For example:
computed: {
ninetyNineYearsAgo() {
return new Date().getFullYear() - 99;
},
eighteenYearsAgoFormatted() {
let eighteenYearsAgo = new Date().getFullYear() - 18;
let todayISODate = new Date().toISOString().split('T')[0];
return eighteenYearsAgo + '-' + todayISODate.split('-')[1] + '-' + todayISODate.split('-')[2];
}
}
<div class="input-group">
<input type="date"
class="form-control"
name="panelData.AnalysisDate"
data-vv-as="Analysis Date"
v-model="panelData.AnalysisDate"
v-validate="'date_format:YYYY-MM-DD|date_between:' + ninetyNineYearsAgo +'-01-01,'+ eighteenYearsAgoFormatted + ',true'">
</div>

Related

Checking difference between two date and display custom message

Hello I have input on registration form and want to retrieve the value of input and compare it with the current date using JavaScript and display message after check age if age less than 18 year and display custom message on the bottom of input.
var dateControl = document.querySelector('input[type="date"]').getFullYear();
var startDate = new Date(document.getElementById('date1').value);
and this is the HTML
<input type="date" name="date" class="form-control" id="date1" value="{{ old('date', date('Y-m-d')) }} " onclick="checkDate()">
<div id="currentdate"></div>
but is give old value after each click.
and the message not displayed
Best regards
Not much code to go from but I think you may need this function anyway to compare the date you receive from the form with the current date and get the difference
function process() {
var today = new Date();
var date = new Date(document.getElementById("date1").value);
var diff = Number((today.getTime() - date.getTime()) / 31536000000).toFixed(0);
if (diff >= 18) {
// Your form submission goes here
console.log("success");
} else {
// your error handeling goes here
console.log("error");
}
}
PS: That this method won't give you the difference in an exact way,
it will just give you the difference between the years.

Bootstrap Datepicker With Daterange Not Saving Value as the Specified Format

I have a booking form that requires two dates, so I'm using the built in option that Bootstrap datepicker has (it consists on calling the datepicker function on the father element that contains the inputs), to show the daterange selected, this is my HTML:
<div class="grupo vip-fechas input-daterange">
<div class="barra verde"> <span>¿Cuándo llegas?</span></div>
<input type="text" class="input calendario" id="entrada_input" name="entrada_input" placeholder="Selecciona una fecha">
<input type="hidden" id="fecha_inicio" name="fecha_inicio">
<div class="barra verde"> <span>¿Cuándo te vas?</span></div>
<input type="text" class="input calendario" id="salida_input" name="salida_input" placeholder="Selecciona una fecha">
<input type="hidden" id="fecha_fin" name="fecha_fin">
</div>
This is my Javascript code:
$(document).ready(function(){
iniciarFechas();
});
function iniciarFechas(){
var date = new Date();
var today = new Date(date.getFullYear(), date.getMonth(), date.getDate());
var date_hidden;
$('.vip-fechas.input-daterange').datepicker({
weekStart: 1,
maxViewMode: 1,
language: "es",
startDate: today,
disableTouchKeyboard: true,
format: {
toDisplay: function(date, format, language) {
var fecha = moment(date).add(1,"day");
date_hidden = fecha;
return fecha.format("dddd DD [de] MMMM, YYYY");
},
toValue: function(date, format, language) {
var fecha = moment(date).add(1,"day");
return moment(fecha).format("DD/MM/YY");
//return moment(date, ["DD.MM.YYYY", "DDMMYYYY"]).toDate();
}
},
}).on("changeDate", function(e){
var fecha_formateada = moment(date_hidden).format("DD/MM/YY");
$(this).next().val(fecha_formateada);
});
}
The daterange works correctly but I want to store the formatted date inside the hidden inputs, as you can see, the format that I want is this: ...format("DD/MM/YY"); but what I get is the display format: format("dddd DD [de] MMMM, YYYY"), also I noticed that $(this) value within this line: $(this).next().val(fecha_formateada); refers to the container div, and not the input that has changed value, so how can I save the date as I want inside the hidden inputs?
I'm not sure what your problem is but by looking at your code I can only guess that you might be in the middle of a race condition.
You're setting the date_hidden variable in Datepicker.toDisplay and then reading from it in the changeDate custom event.
Put a debugger or a console log in both callbacks to make sure you're not in the middle of a race condition.
As for setting the formatted value in the input fields, well I can see in your HTML code that you have selectors that you can use, like the hidden field's ID for example.
Another thing I'd suggest is, instead of setting and reading the date_hidden field in those different callbacks, just call $('#elementID').datepicker('getDate') in the changeDate event handler and do all the transformations you need there, then extract that code and put it in a separate function.

How to have javascript presets today's date in HTML form

I am developing a project with Django.
I have an html webpage containing a form which has a date field.
I want javascript compile it with today's date as soon as my user lands on that webpage, so that he/she gets a kind of "default date".
I have in my html page (templates/aggiungi_terminologia.html), the date field:
<div class="form-group">
<label for="glossary_entry_input_21">Data di inserimento della terminologia</label>
<small id="inputHelp" class="form-text text-muted">Compilare solo se è nota la data di pubblicazione del documento fonte, altrimenti inserire la data di oggi.</small>
<input name="Data_inserimento_entry" type="date" value="01/01/1900" class="form-control" id="date_to_turn_into_today" placeholder="">
</div>
and then the javascript call at the end of the form:
{% load static %}
<script> src="{% static 'get_today_date.js' %}"</script>
And then, inside my javascript function (static/js/get_today_date.js):
var today = moment().format('DD/MM/YYYY');
document.getElementById("date_to_turn_into_today").value = today;
and since I am using moment.js, I added 'moment' in settings.py> INSTALLED_APPS ,
and to install moment I run on my console:
pip install django-staticfiles-moment
But when I run the server, all I get on that field is this:
My console is returning:
WARNINGS: app_glossario.glossary_entry.Data_inserimento_entry:
(fields.W161) Fixed default value provided.
HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to
have the current date as default, use django.utils.timezone.now
Why javascript is not replacing the date?
How can I make it work?
NOTE: the problem lies in the connection between js, html and django
Continue from comment about duplicated or not, take a look:
var now = new Date();
var day = ("0" + now.getDate()).slice(-2);
var month = ("0" + (now.getMonth() + 1)).slice(-2);
var today = now.getFullYear()+"-"+(month)+"-"+(day);
document.getElementById('inputDate').value = today;
<input type="date" id="inputDate" />
Please check this also.
I've seen similar behavior (where the input field shows a date placeholder instead of my desired date) when I provided a date string that was incorrectly formatted. The input element seems to need a format like yyyy-mm-dd.
Here's a pretty intuitive solution using vanilla JS. The default value of the input element will be the (locale-specific) date.
(And most of the further info you might want about JS Dates can be found here on MDN.)
const
// Selects input element
dateInput = document.getElementById("date"),
// Defines Date object
date = new Date(),
// Extracts component parts of Date object
year = date.getFullYear(),
month = date.getMonth(),
day = date.getDate(),
// Defines a function to add a leading zero if needed
pad = part => part < 10 ? "0" + part : part,
// Formats date to meet the `input` element's expectations -- like: `yyyy-mm-dd`
// (Adds +1 to month b/c `getMonth()` uses a zero-based array)
dateString = year + "-" + pad(month + 1) + "-" + pad(day);
// Inserts date string into input element
dateInput.defaultValue = dateString;
// Repeats this process for the "time" parts
/*
const
timeInput = document.getElementById("time"),
hours = date.getHours(),
minutes = date.getMinutes(),
seconds = date.getSeconds(),
timeString = pad(hours) + ":" + pad(minutes) + ":" + pad(seconds);
timeInput.defaultValue = timeString;
*/
<input id="date" type="date" />
<!--
// Optional input for time
<input id="time" type="time" />
-->
SOLVED
Here is what I did.
In a javascript file called
get_today_date.js
stored at path
static/js/get_today_date.js
I inserted
function get_today_date() {
var now = new Date();
var day = ("0" + now.getDate()).slice(-2);
var month = ("0" + (now.getMonth() + 1)).slice(-2);
var today = now.getFullYear()+"-"+(month)+"-"+(day);
document.getElementById('date_to_turn_into_today').value = today;
}
as suggested here https://stackoverflow.com/a/57953522/7658051 .
Then in the HTML page, before the closing </body> tag, I inserted
{% load static %}
<script type="text/javascript" src={% static "js/get_today_date.js" %}></script>
<script> get_today_date() </script>
and it works perfectly.
There was no neet to install the module moment, and even if my console returns
WARNINGS: app_glossario.glossary_entry.Data_inserimento_entry: (fields.W161) Fixed default value provided. HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to have the current date as default, use django.utils.timezone.now
my app works fine.
The previous code did not work just because I forgot to call the function in HTML, so I just had to add
get_today_date()
But in the end I am not sure if I correctly installed the moment module required for the previuos javascript script.

Unable to access input date values with javascript

I've been using forms which upon submit call a function which makes use of the inputted data. So far this has worked fine with text, but switching to date inputs is causing me trouble.
I'm using the following code, but the "startDate", "endDate" values are empty.
<form onsubmit="myFunction()">
Start Date:
<input type="date" name="startDate" id="startDate">
End Date:
<input type="date" name="endDate" id="endDate">
<input type="submit">
</form>
<!-- Form to process above date submit -->
<script>
function myFunction() {
var locationID = "1";
var startDate = document.getElementById("startDate").value;
var endDate = document.getElementById("endDate").value;
var apiURL = "APIUrl" + locationID + "_" + startDate + "_" + endDate;
alert("The form was submitted" + apiURL);
$.get(apiURL, function( data ) {
$( ".result" ).html( data );
});
}
</script>
The alert gives me back the APIUrl, plus the location ID, but blank values for the dates.
Any ideas?
Thanks for your help.
You didn't specify what browser you are using.
Since you're already using jQuery, I recommend using it to retrieve the field values, i.e.
var startDate = $("#startDate").val();
var endDate = $("#endDate").val();
That would resolve browser inconsistencies that could play a part in your issue.
Your code work as expected in Chrome because it supports input date but this is not the case for IE, Firefox and Safari as you can see here : http://caniuse.com/#search=input%20date
It would probably be better if you use a library like JQuery-UI for the datepicker so it can be supported by all browsers

Javascript - loop through datepickers and set date

I don't know Javascript at all. I have a form where there can be any number of datepicker textboxes. When the user selects a date in the first datepicker textbox, then I want all the remaining datepicker textboxes to have that same date.
Does this require a function?
Edit: I tried to create a function, but I don't know javascript at all!
function UpdateValuationDates(event) {
$valuationDatePicker = $(event.target);
var valuationDate = $valuationDatePicker.datepicker("getDate");
if (valuationDate != null) {
//loop through all items
document.getElementById("dateValuationDate").Text
$valuationDatePicker.datepicker("setDate", valuationDate);
$valuationDatePicker.trigger('change');
}
}
So I think this can be ignored. I have also read that there is a datepicker on selected event:
$(".date").datepicker({
onSelect: function(dateText) {
display("Selected date: " + dateText + "; input's current value: " + this.value);
}
});
So I guess I need to edit this code to populate the rest of the textboxes, but how to find out at runtime how many there are?
The HMTL has a repeater with the datepicker repeated x number of times:
<abc:DatePicker runat="server" ID="dateValuationDate"
With the help of html's input type=date and some basic classes' knowledge, you can do that.. Considering you have following Date pickers:
<input type="date" class="dateTime">
<input type="date" class="dateTime">
<input type="date" class="dateTime">
Now you simply need to listen to a change in any one of there values:
$(".dateTime").on("change", function(){
and when the change occurs, get the changed value and set all other date pickers to that new value:
$(".dateTime").val($(this).val());
So it'll be something like this:
$(document).ready(function(){
$(".dateTime").on("change", function(){
$(".dateTime").val($(this).val());
});
});
See the DEMO here
EDIT: Considering you're new to JavaScript, here's how i'm getting the reference to all those elements, through .className, as they all have same class name so for each event (change, update value) they all will be referenced.

Categories

Resources