Simple Flask jQuery AJAX - html

I am trying to get the logic of using jQuery AJAX and Flask, however I am not coming right. I have been following tutorials here and here, but no resolution. To get the logic - I simply want to input dates in two separate fields, and return those dates to the same page in a normal <p> tag. My suspicion is a problem in the server receiving the dates. Submitting the relative form does not return anything to #result
HTML FORM
<form>
<input name="StartDate" id="StartDate" type="date" class="form-control"></div>
<input name="EndDate" id="EndDate" type="date" class="form-control"></div>
<button class='btn btn-info'>Generate</button>
</form>
<p id=result></p>
jQuery - located at the bottom of the <body> tag, after importing jQuery itself.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('a#generate').bind('click', function () {
$.getJSON($SCRIPT_ROOT + '/generate_report', {
StartDate: $('input[name="StartDate"]').val(),
EndDate: $('input[name="EndDate"]').val()
}, function (data) {
$("#result").text(data.result);
});
return false;
});
});
</script>
Flask Server - I have imported relevant dependencies
#app.route('/generate_report', methods=['GET', 'POST'])
def generate_report():
start_date = request.args.get('StartDate', 0, type=str)
end_date = request.args.get('EndDate', 0, type=str)
return jsonify(result=start_date + "-" + end_date)

Please use the button to send the form, an anchor within the form does not make sense.
I would advise you to use the "submit" event
of the form, although the "click" event of the button would also work. The preventDefault function bypasses the standard behavior of the form, so that you can send the form yourself using getJSON. To serialize the form data, I use the serialize
function which converts all form data into a conforming string. Thus the data is sent as "application/x-www-form-urlencoded".
The variable $SCRIPT_ROOT is not used by me in this example because it is
basically empty under localhost and is not absolutely necessary.
<form name="my-form">
<div class="form-group">
<label for="start-date">Start</label>
<input type="date" name="start-date" id="start-date" class="form-control">
</div>
<div class="form-group">
<label for="end-date">End</label>
<input type="date" name="end-date" id="end-date" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Generate</button>
</form>
<p id=result></p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("form[name='my-form']").submit(function(event) {
event.preventDefault();
const formData = $(this).serialize();
$.getJSON("/generate_report", formData, function(data) {
$("#result").text(data.result);
});
});
});
</script>
The result of request.args.get is by default of type str.
If the form field is empty, get always returns None. A possible KeyError due to a missing value is bypassed.
#app.route('/generate_report')
def generate_report():
start_date = request.args.get('start-date')
end_date = request.args.get('end-date')
return jsonify(result=f'{start_date} - {end_date}')

Related

HTML FORM- validate one field against another field value at browser (client) level

I have two DATE fields in a standard HTML form (startdate) and (enddate)
<form method="POST" action="processform.php" target="_top">
<span>▶</span><select class="selectdate" name="startdate" required>
<option value='2019-12-31'>Tue, 31-Dec-19</option><option value='2019-12-30'>Mon, 30-Dec-19</option><option value='2019-12-27'>Fri, 27-Dec-19</option><option value='2019-12-26'>Thu, 26-Dec-19</option><option value='2019-12-24'>Tue, 24-Dec-19</option><option value='2019-12-23'>Mon, 23-Dec-19</option><option value='2019-12-20'>Fri, 20-Dec-19</option><option value='2019-12-19'>Thu, 19-Dec-19</option><option value='2019-12-18'>Wed, 18-Dec-19</option><option value='2019-12-17'>Tue, 17-Dec-19</option><option value='2019-12-16'>Mon, 16-Dec-19</option><option value='2019-12-13'>Fri, 13-Dec-19</option><option value='2019-12-12'>Thu, 12-Dec-19</option><option value='2019-12-11'>Wed, 11-Dec-19</option><option value='2019-12-10'>Tue, 10-Dec-19</option><option value='2019-12-09'>Mon, 09-Dec-19</option><option value='2019-12-06'>Fri, 06-Dec-19</option><option value='2019-12-05'>Thu, 05-Dec-19</option><option value='2019-12-04'>Wed, 04-Dec-19</option><option value='2019-12-03'>Tue, 03-Dec-19</option><option value='2019-12-02'>Mon, 02-Dec-19</option><option value='2019-11-29'>Fri, 29-Nov-19</option> </select>
<span>▶</span><select name="enddate" required>
<option value='2020-01-03'>Fri, 03Jan20</option><option value='2020-01-10'>Fri, 10Jan20</option><option value='2020-01-17'>Fri, 17Jan20</option><option value='2020-01-24'>Fri, 24Jan20</option><option value='2020-01-31'>Fri, 31Jan20</option><option value='2020-02-07'>Fri, 07Feb20</option><option value='2020-03-13'>Fri, 13Mar20</option><option value='2020-03-20'>Fri, 20Mar20</option><option value='2020-03-27'>Fri, 27Mar20</option><option value='2020-04-03'>Fri, 03Apr20</option><option value='2020-04-09'>Thu, 09Apr20</option><option value='2020-06-12'>Fri, 12Jun20</option><option value='2020-06-19'>Fri, 19Jun20</option><option value='2020-06-26'>Fri, 26Jun20</option><option value='2020-07-02'>Thu, 02Jul20</option><option value='2020-07-09'>Thu, 09Jul20</option><option value='2020-12-11'>Fri, 11Dec20</option><option value='2020-12-18'>Fri, 18Dec20</option><option value='2020-12-24'>Thu, 24Dec20</option><option value='2020-12-30'>Wed, 30Dec20</option><option value='2021-01-07'>Thu, 07Jan21</option> </select>
<input type="submit" value="Submit">
</form>
All I wish is to check if the user selected startdate must be less than the selected enddate at the BROWSER level (not at the server).
If selected startdate is greater than or equal to the selected enddate, it should show an error without actually submitting the form. The form should be submitted only if the startdate is less than the enddate.
While I was able to get it working on the server side using PHP, I am unable to make it work at the browser level (possibly javascript which I am not very conversant with).
Any inputs on how this can be achieved?
This is the code I am trying but it is showing "valid date range" for all cases:
const first = document.getElementsByName('startdate')[0];
first.addEventListener('change', function() {
console.log(first.value);
});
const second = document.getElementsByName('enddate')[0];
second.addEventListener('change', function() {
console.log(second.value);
});
if (first.valueOf() > second.valueOf()) {
alert("date is not in valid range");
}else{
alert("date is in valid range");
return true;
}
Thanks
You'll have to use JavaScript for any client-side validations. You can make the PHP call from the JavaScript side.
You can validate date in JavaScript like:
(from here)
function validation(form) {
var v2 = document.getElementById('v2'),
date = new Date(v2.value),
d1 = date.getTime(),
d2 = new Date('12/12/2012').getTime(),
d3 = new Date('1/1/2013').getTime();
if (d1 > d2 || d1 < d3) {
return true;
}else{
alert("date is not in valid range")
}
}
It might seem like a complicated task, but you can actually divide it into more manageable chunks:
Listen to changes in the form fields' values.
Validate the new values, then either allow them or do something else (i.e. show an error message).
For (1) I'd suggest you use JS. For example:
const first = document.getElementsByName('startdate')[0];
first.addEventListener('change', function() {
console.log(first.value);
});
const second = document.getElementsByName('enddate')[0];
second.addEventListener('change', function() {
console.log(second.value);
});
<form method="POST" action="processform.php" target="_top">
<span>▶</span>
<select class="selectdate" name="startdate" required>
<option value='2019-12-31'>Tue, 31-Dec-19</option>
<option value='2019-12-30'>Mon, 30-Dec-19</option>
</select>
<span>▶</span>
<select name="enddate" required>
<option value='2020-01-03'>Fri, 03Jan20</option>
<option value='2020-01-10'>Fri, 10Jan20</option>
</select>
<input type="submit" value="Submit">
</form>
And then you can take it further and use the listeners' functions to actually compare the two dates.
As a side note, I also encourage you to use JS in order to produce those (too) similar <option> tags. Something like this:
const startDateElement = document.getElementsByName('startdate')[0];
const startDates = ['2019-12-31', '2019-12-30', '2019-12-27']; // etc.
startDates.forEach((date) => {
const newOption = document.createElement('option');
newOption.setAttribute('value', date);
newOption.innerHTML = date;
startDateElement.appendChild(newOption);
});
// And the same for end date
<form method="POST" action="processform.php" target="_top">
<span>▶</span>
<select class="selectdate" name="startdate" required>
</select>
</form>
Then your code will be much more generic, hence easier to read, maintain and update in the future.
The functionality helps to track the user selection from start date and time to the end date and time on the client side. PHP will evaluate on the server side (Not preferable)
The user may not be able to select the end date previous of the start date.
Here is the link given below with example
DEMO - https://jsfiddle.net/ssuryar/vr1zd8ep/
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/build/css/bootstrap-datetimepicker.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment-with-locales.js"></script>
<script src="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/src/js/bootstrap-datetimepicker.js"></script>
</head>
<div class="container">
<div class='col-md-5'>
<div class="form-group">
<div class='input-group date' id='datetimepicker6'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-md-5'>
<div class="form-group">
<div class='input-group date' id='datetimepicker7'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker6').datetimepicker();
$('#datetimepicker7').datetimepicker({
useCurrent: false //Important! See issue #1075
});
$("#datetimepicker6").on("dp.change", function (e) {
$('#datetimepicker7').data("DateTimePicker").minDate(e.date);
});
$("#datetimepicker7").on("dp.change", function (e) {
$('#datetimepicker6').data("DateTimePicker").maxDate(e.date);
});
});
</script>
</html>

How can we send and receive data in same HTML form using angularjs with JSON schema?

Suppose this is the form:
<form name="inputForm">
<input type="text" name="ipname" ng-model="formData.name">
<input type="text" name="ipage" ng-model="formData.age">
<button ng-submit="formSubmit(formData)"></button>
</form>
How do we need to write JSON schema with name or ng-model to store it in db?
You can do something as follows. The only issue in your version was you were using ng-submit with button which should be used at form level.
var app = angular.module('test',[]);
app.controller('testController',function($scope){
$scope.formData = {}
$scope.formSubmit = function() {
// Form validations
console.log($scope.formData)
// Use formData JSON Object to send it to API using $http/$resource
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<body ng-app="test" ng-controller="testController">
<form name="inputForm">
<input type="text" name="ipname" ng-model="formData.name">
<input type="text" name="ipage" ng-model="formData.age">
<button ng-click="formSubmit()">Submit</button>
</form>
</body>

Angular JS HTML 5 date input value get in YYYY-MM-DD format

I would like to know how to get HTML 5 date input value get to script. This date format should be in YYYY-MM-DD. This value should be store in date1 variable after click the submit button.
HTML Code:
<form ng-controller="validateCtrl" name="myaForm" novalidate>
<input class="datepicker validate" type="date" id="birthday" ng-model="birthday" placeholder="yyyy-MM-dd" required>
<button type="submit" ng-submit="submitfun()">Submit</button>
</form>
Script Code:
<script>
var app = angular.module('myApp', []);
app.controller('validateCtrl', function($scope) {
$scope.submitfun= function () {
birthday = $filter('date')(birthday, 'yyyy/MM/dd');
}
});
</script>
This code not working for me how to solve this problem.
You missed to declare scope variable. Write $scope.birthday.
There is no way possible to change the format of html5 input date type, look at possible solution in the below answer:
How can I load value on input date with angular?
I'll add to that if you would like to get the formatted string value of the date, then you either use $moment library like this:
<form ng-controller="validateCtrl" name="myaForm" novalidate>
<input class="datepicker validate" type="date" id="birthday" ng-model="birthdayModel" placeholder="yyyy-MM-dd" required>
<button type="submit" ng-submit="submitfun()">Submit</button>
</form>
$scope.submitfun= function () {
$scope.birthday = $moment($scope.birthdayModel).format('YYYY-MM-DD');
console.log($scope.birthday.toString());
}
or parse the date manually like this:
$scope.submitfun= function () {
var days = $scope.birthdayModel.getDate();
var months = $scope.birthdayModel.getMonth()+1;
var years = $scope.birthdayModel.getFullYear();
//Now you have them separate you can put them in whatever format you want
//like this for example:
$scope.birthday = days+'-'+months +'-'+years ;
console.log($scope.birthday);
}

HTML5 form is not getting submitted

I have the following code to submit a form. If I use the event listener function name as submit, the form does not get submitted. If I use any other name, it will. Should not I use any HTML5 keyword like submit in JavaScript as function name? In this case submit is a HTML5 keyword which can be used as a type of any INPUT element.
<form onsubmit="submit()">
<input type="email" name="email" />
<input type="submit"/>
</form>
function submit() {
var f = $('form').serialize();
alert(f);
}
You're already using jQuery here so a more elegant solution to the whole problem would be:
// HTML
<form name="my-form">
<input type="email" name="email" />
<input type="submit"/>
</form>
Then have a separate JS file:
//Js
$(document).ready(function(){
$('form[name="my-form"]').submit(function(e){
var f=$(this).serialize();
alert(f);
});
});
This also gives you extra options to prevent the form from submitting cleanly; add this at the end of the submit(){ } function.
e.preventDefault();
Update
As the OP pointed out the original question was whether the function name submit() can be used as the onsubmit attribute in a form.
This answer suggests that it cannot, as carrying out the following:
document.form['my-form'].submit();
Would be a valid way to trigger submission of the form; thus that method name can't then be included in the HTML. I am searching now for a better source to confirm this for sure I have found a similar source on Mozilla Developer Network which confirms the code above but doesn't explicitly define that the keyword submit cannot be used.
You know, there is another way to do this. You could separate your html from javascript enritelly.
<form id="form">
<input type="email" name="email" />
<input type="submit"/>
</form>
//Rest of your code
<script>
$(function() {
$('#form').submit(function() {
var f = $('#form').serialize();
// do your stuff
return true; // return false to cancel form action
});
});
</script>

Handling a form purely from Javascript

I have the following form in a website of mine.
<form action="" method="GET">
<input type="text" name="query" value="" />
<input type="button" name="talk" value="talk" onClick="askCow(this.form)" />
</form>
Clicking the button does fire an AJAX request that updates the page. Using return does not, however; it simply submits the form using GET, which is not the desired behavior. Using onsumit="return false;" or similar disables submission, but this is not the desired behavior.
How can I execute the askCow function on an enter press ("form submission") while making sure the form is NOT submitted? Am I a bad person for doing this? The reason I use AJAX is that it lets me omit templating logic on the server side entirely.
Thanks!
Edit: here is the complete page
<html>
<head><title>Psycowlogist</title></head>
<body>
<div id="history">
Previous discussion
</div>
<div id="cow">
<pre>
_______________________
< What is your problem? >
-----------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
</pre>
</div>
<div id="talk">
<form id="talkForm" action="" method="GET" onsubmit="askCow(this)">
<input type="text" name="query" value="" />
<input type="button" name="talk" value="talk" onClick="askCow(this.form)" />
</form>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js" type="text/javascript" charset="utf-8"></script>
<script type="text/coffeescript">
$j = jQuery
window.askCow = (form) ->
$j.get "/cowanswer",
{q: form.query.value},
(data) -> $j("#cow pre").html(data["cow-answer"])
return false
</script>
</html>
Just use onsubmit event of form
<form action="" method="GET" onsubmit="return askCow(this);">
<input type="text" name="query" value="" />
<input type="button" name="talk" value="talk"/>
</form>
askCow function should look something like this
function askCow()
{
//do ajax stuff
return false;
}
You can use jQuery Form Plugin .
And within the call, you can call askCow() .
var options = {
target: '#output', // target element(s) to be updated with server response
beforeSubmit: showRequest, // pre-submit callback
success: showResponse // post-submit callback
};
$('#theForm').submit(function() {
askCow(this);
$(this).ajaxSubmit(options);
return false;
});