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.
Related
I'm making a patient system with calculating the age of patient base on their birthday, but i'm getting error when I add it
Javascript:
<script>
var dob = new Date("06/24/2008"); <!-- I wanted to add {{ patient.birth }} into the date part-->
//calculate month difference from current date in time
var month_diff = Date.now() - dob.getTime();
//convert the calculated difference in date format
var age_dt = new Date(month_diff);
//extract year from date
var year = age_dt.getUTCFullYear();
//now calculate the age of the user
var age = Math.abs(year - 1970);
//display the calculated age
document.write("Age of the date entered: " + age + " years");
</script>
And {{ patient.birth }} is the sql query that I wanted to add into the script.
var birthdate = $("#birth").val();
or
var birthdate = "{{ birth }}"
Depending on how the value is being implemented in the jinja.
Let me know which one works for you situation if you could.
I've done this in the past using both of these methods.
note: it's not by accident I'm leaving the "patient." out. This is intentional.
If they are changing the birthdate value on this screen.
Then you need to make an onchange event.
For example:
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.7.1.min.js"></script>
<style>
function makeChange() {
var birthdate = $("birth").val();
}
</style>
</head>
<form method="POST" action="">
<div onchange="makeChange()">
{{ patient.birth }}
</div>
</form>
Argument passed to Date constructor should be in correct format.
In your case patient.birth should be string just like in your example: "06/24/2008".
You can not say like so:
const date = new Date("3 1930");
It prints
Invalid Date
https://www.tutorialspoint.com/javascript/javascript_date_object.htm
I'm hoping someone can help me figure out how to code an app that allows you to select a mailing date with jquery datepicker, select Standard or First-class shipping from a dropdown, and calculate an estimated delivery date window (7-12 Days for Standard, 3-5 Days for First-class).
I had it working when the "Mailing in" [number] "Days" accepted a string input but then it broke when I added code for the datepicker.
I also need to keep weekends & holidays excluded from the shipping calculation.
Here's a link to the full pen: https://codepen.io/allyjfuller/pen/oNXvwJL
$('#calculateShippingEstimate').click(function( event ) {
//Prevent button from 'submitting' and reloading the page
event.preventDefault();
//Capture the mailing date
var $mailingDate = $("#mailingDate").val();
var $postageType = $("#postageType").val();
var $shipStateShippingDuration = eval('data.shipTimes.' + $postageType);
var $totalShippingTime = parseInt($mailingDate) + parseInt($shipStateShippingDuration);
//Create the date
var date = new Date();
var month = date.getMonth()+1;
var day = date.getDate() + parseInt($totalShippingTime);
var year = date.getFullYear();
<form>
<section>
<label>Mailing on</label>
<input id="mailingDate" placeholder="number"></input>
</section>
<section>
<label>Postage:</label>
<select id="postageType">
<option value="Standard">Standard</option>
<option value="FirstClass">First-Class</option>
</select>
</section>
<input class="button" id="calculateShippingEstimate" type="submit" value="Get Estimated Delivery Date"></input>
<div class="results"></div>
</form>
Looking through your code snippet it seems like you're trying to hand roll a lot of features that already exist within the JS Date framework.
Once you get the starting date and the number of days for shipping, you can add those days together to create a final shipping date. From there and within a loop, you may go day by day and check whether the current date index is a weekday or not (using Date.getDay()).
With that you may check for Saturday [6] and Sunday [0] and then add days needed on top of the final date.
I've included my version of the code below with some console debugging but have not added code holidays. Holidays may be checked for using an array or map. Get all the holiday dates for a year and then have the current index check the holiday array/map to see if there are any matches. If there are, add another day to the final date.
The function for addDays is pulled from here. It adds some explanation which I think you'll find helpful.
function addDays(date, days) {
const copy = new Date(Number(date))
copy.setDate(date.getDate() + days)
return copy
}
// FINAL SHIPPING ESTIMATE
$('#calculateShippingEstimate').click(function( event ) {
event.preventDefault();
let mailingDateVal = $("#mailingDate").val();
let shippingDuration = data.shipTimes[$("#postageType").val()];
let mailingDate = new Date(mailingDateVal);
console.log("final Date: " + addDays(mailingDate, shippingDuration));
let finalDate = addDays(mailingDate, shippingDuration)
let mailingDateIndex = new Date(mailingDate);
while(mailingDateIndex <= finalDate) {
console.log("current mailDateIndex: " + mailingDateIndex)
if (mailingDateIndex === finalDate) {
break;
}
// Weekend
console.log(mailingDateIndex.getDay());
if (mailingDateIndex.getDay() == 0 || mailingDateIndex.getDay() == 6) {
console.log("weekend day hit! Adding day to final...")
finalDate = addDays(finalDate, 1);
}
mailingDateIndex = addDays(mailingDateIndex, 1);
}
});
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>
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
This is my html code with a snippet of just the code I am trying to use to invalidate/validate date entries with hopefully all of the corresponding and necessary variables declared.
<html>
<head>
<title> Booking Page </title>
<script>
function Booking(){
var departuredate = document.getElementById("departdate").value; //departure date selected by user
var arrivaldate = document.getElementById("arrivedate").value; //arrival date selected by user
departuredate = new Date(departuredate);
arrivaldate = new Date(arrivaldate);
CurrentDate = new Date(); //todays date
month = '' + (arrivaldate.getMonth() + 1),
day = '' + arrivaldate.getDate(),
year = arrivaldate.getFullYear();
var adate = [day, month, year].join('/');
alert(adate);
the adate is for the arrival date only. I plan to just copy and adjust the code across once it is correct for the departure date. Currently the code seems to invalidate all entries, not allowing completely valid entries to be validated.
var re = /[0-9]{2}\/[0-9]{2}\/[0-9]{4}/;
if (!adate.match(re))
{
document.getElementById("temp").innerHTML = "Incorrect format"
document.MyForm.arrivedate.focus();
document.getElementById("arrivedate").style.border='1px solid red';
return false;
}
else
{
// if none of the above situaton's occur then the input is true and validated
alert('Dates are validated');
return true;
}
}
</script>
</head>
<body>
<H1> Booking Form </H1>
<Form action="testpage.py" method="POST" name="MyForm" onsubmit="return Booking()">
<p>Departure Date:</p>
<input type=date name="departdate" id="departdate" >
<p>Arrival Date:</p>
<input type=date name="arrivedate" id="arrivedate">
<input type=submit value="Find flights">
</Form>
</body>
</html>
You have multiple problems here. First is that the date type for inputs is non-standard, so it won't work in most browsers (IIRC chrome, edge, and iOS safari are the exceptions).
I recommend that you either use a third-party library like jquery-ui-datepicker or use a text input with the validation logic using the html pattern attribute or a js event handler if you have to support desktop safari (which doesn't support the pattern attribute).
Something like <input type="text" pattern="/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/"...
Or if pattern won't work:
var myDateInput = document.getElementById('date-input');
myDateInput.addEventListener('change', function(e) {
if (!(e.target.value.match(dateRegex)) {
//let user know somehow
}
});
You can throttle the handler so that it doesn't fire on successive keystrokes. Also note that even in browsers with the date input type they expect "yyyy-mm-dd" format, so make your regex:
/[0-9]{4}-[0-9]{2}-[0-9]{2}/.