Django Form, check validate before submit. (HTML) - html

For a regular html form, I could use java script to validate input onsubmit, which means the submit button is work only for a valid input, hence no http response required.
However, I am unable to do the same thing for a django form.
A Django form in html is simply as {{form}}.
for example {{form.title}} is the form for title.
So I am looking for a way to validate the Django form at front end (in HTML). only the valid input would be post

Not Django specific. Its a frontend Javascript framework Job. Or if you are certain that your webapps's target audience is all latest browser oriented, supporting HTML5, then go for HTML form validations (source) .
If you do not want to go for client side validation and re-use your Django's validation code, then I would suggest serialize and submit the form using ajax. You could get a JSON reply and parse it using javascript, or get the whole updated form back(using Django's template engine) and update the DOM. In case you need a sample, let me know which method you are opting for. Hope this helps.

Include jquery validator
<script type="text/javascript" src="{% static 'js/jquery.validate.min.js' %}"></script>
In contact.html
Loader .gif while you send form
<div id="loadingDiv" class="hiddenClass">
<p><img src="{% static "images/ajax-loader.gif" %}" alt="loader" ><br/>Please wait... while we...<p>
</div>
your form code in contact.html
<form method="post" action="/contact/send/" id="contact_wrap">
<div class="name">
<label class="label">Name <span class="required">*</span></label>
<input name= "firstname" id="firstname" class="inputtext" type="text" maxlength="20" size="12" placeholder="First Name"/>
</span>
</div>
<-- your code -->
</form>
submit button in contact.html
<div class="button">
<input id="submitform" class="submitform" type="submit" name="submitform" value="Send" />
</div>
script to validate form in contact.html
<script>
$(function() {
$( "#contact_wrap" ).validate({
errorClass: "my-error-class", //apply a css class for error if you have style for valid
validClass: "my-valid-class", //apply a css class for error if you have style for error
rules: {
firstname: {
required: true
},
},
messages: {
firstname: {
required: "Please enter your First Name."
},
},
});
});
</script>
To check validation before submit in contact.html
show ajax-loader.gif from loading div
<script>
$( "#submitform" ).click(function() {
if ($('#contact_wrap').valid()) $( "#loadingDiv" ).removeClass( "hiddenClass" ).addClass( "showClass" );
});
</script>

Related

Angular, validate form when submitting from outside form [duplicate]

Given this code:
<div ng-controller="MyCtrl">
<form ng-submit="onSubmitted()">
Header inputs:
<input type="name" ng-model="sample" required/>
<input type="name" ng-model="sampleX" required/>
<input type="submit" value="This submit triggers validation. But I wanted to put this button at the end of the page"/>
</form>
<hr/>
Some other form here. Think line items
<hr />
<a class="btn" ng-click="/* what could should be put here, so this can trigger the firt form's validation, then submit? */">Wanted this submit button to trigger the validation+submit on the form in which this button doesn't belong</a>
</div>
var app = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.onSubmitted = function() {
alert('submitted!');
};
}
I want the last button to trigger the validation(then submit when things are valid) on first form. As of now, only the button inside the form can trigger that form's validation and submission. Is there any possible way for a button outside the form to do that?
Live test: http://jsfiddle.net/dzjV4/1/
You can create directive which you can then attach to <a class="btn".... Check this jsfiddle
http://jsfiddle.net/dzjV4/2/
Note that I added to <input type='submit' id='clickMe'... and linked it with link at the bottom <a class='btn' linked="clickMe"...
for (control of $scope.[form name].$$controls) {
control.$setDirty();
control.$validate();
}
You can try the above codes. Make it running before submit.
Ideally there'd be a programmatic way to cause validation to re-run across a form. I have not investigated that completely but had a situation that required multiple controls to be re-validated based on different data in the scope -- without the user interacting with the individual controls. This arose because the form had two action buttons which each required different validation rules be in play when they were clicked.
The UI requirement changed before I fully implemented forcing re-validation but before it did I got most of what I needed by copying and then re-setting the form's data. This forced re-validation across the form within the current scope. Basically, it's along the lines of the following (not tested, but taken from the code that was working). In this case the form's data was bound to the properties in one object.
var formData = $parse(<form's model>);
var dataCopy = angular.copy( formData($scope) );
formData.assign( $scope, dataCopy );
This may or may not be acceptable, but if you can get away with the SUBMIT button being disabled until the form is completed, you can do this:
<form name="formName">
<input ng-required="true" />
</form>
<button ng-click="someFunction()" ng-disabled="formName.$invalid" />
It's also worth noting that this works in IE9 (if you're worried about that).
Give your form a name:
<div ng-controller="MyCtrl">
<form name="myForm">
<input name="myInput" />
</form>
</div>
So you can access your form validation status on your scope.
app.controller('MyCtrl', function($scope) {
$scope.myForm.$valid // form valid or not
$scope.myForm.myInput // input valid or not
// do something with myForm, e.g. display a message manually
})
angular doc
There is no way to trigger browser form behavior outside of a form. You have to do this manually.
Since my form fields only show validation messages if a field is invalid, and has been touched by the user:
<!-- form field -->
<div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }">
<!-- field label -->
<label class="control-label">Suffix</label>
<!-- end field label -->
<!-- field input -->
<select name="Parent_Suffix__c" class="form-control"
ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes"
ng-model="rfi.contact.Parent_Suffix__c" />
<!-- end field input -->
<!-- field help -->
<span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched">
<span ng-message="required">this field is required</span>
</span>
<!-- end field help -->
</div>
<!-- end form field -->
I was able to use this code triggered by a button to show my invalid fields:
// Show/trigger any validation errors for this step
angular.forEach(vm.rfiForm.stepTwo.$error, function(error) {
angular.forEach(error, function(field) {
field.$setTouched();
});
});
// Prevent user from going to next step if current step is invalid
if (!vm.rfiForm.stepTwo.$valid) {
isValid = false;
}

Id duplicates when using templates in parse / backbone / js / html

I get duplicate ids when I set the views like so in my render function
var template = _.template($("#user-login-template").html(), {});
this.$el.html(template);
The html looks like this after running the render function, before runing the render function. Beforehand, the <div class ="app"> is empty (as it should be). It copy pasted the code from template and therefore the ids into the div.
<div class="app">
<input type="text" id="signup-username" placeholder="Username"/>
<input type="password" id="signup-password" placeholder="Create a Password"/>
<button id="signUpBtn">Sign Up</button>
<button id="logInBtn">Login</button>
</div>
<!-- Templates -->
<!-- Login Template -->
<script type="text/template" id="user-login-template">
<input type="text" id="signup-username" placeholder="Username"/>
<input type="password" id="signup-password" placeholder="Create a Password"/>
<button id="signUpBtn">Sign Up</button>
<button id="logInBtn">Login</button>
</script>
For reference, this is what my whole view looks like
var LogInView = Parse.View.extend({
el: '.app',
events: {
"click .signUpBtn": "signUp",
"click .logInBtn": "logIn"
},
initialize: function (){
this.render()
},
logIn: function () {
//To Do
},
render: function () {
var template = _.template($("#user-login-template").html(), {});
this.$el.html(template);
}
});
If Webstorm is complaining about the ids inside the <script> then it is wrong and you have three options:
Get a new IDE that has a better understanding of HTML.
Figure out how to reconfigure Webstorm to know what HTML really is. There must be a way to beat some sense into Webstorm, this sort of thing is very common these days.
Ignore the warnings (yuck).
Things inside <script> are not HTML and are not part of the DOM. Ask the browser what $('input[type=text]').length is after your template is rendered and you'll get 1 since the
<input type="text" id="signup-username" placeholder="Username"/>
inside the <script> isn't HTML, it is just text. You can even check the HTML specification of <script>:
Permitted contents
Non-replaceable character data
Non-replaceable character data is not HTML, it is just text.

Making 'file' input element mandatory (required)

I want to make (an HTML) 'file' input element mandatory: something like
<input type='file' required = 'required' .../>
But it is not working.
I saw this WW3 manual which states 'required' attribute is new to HTML 5. But I am not using HTML 5 in the project I am working which doesn't support the new feature.
Any idea?
Thanks to HTML5, it is as easy as this:
<input type='file' required />
Example:
<form>
<input type='file' required />
<button type="submit"> Submit </button>
</form>
You can do it using Jquery like this:-
<script type="text/javascript">
$(document).ready(function() {
$('#upload').bind("click",function()
{
var imgVal = $('#uploadfile').val();
if(imgVal=='')
{
alert("empty input file");
return false;
}
});
});
</script>
<input type="file" name="image" id="uploadfile" size="30" />
<input type="submit" name="upload" id="upload" class="send_upload" value="upload" />
As of now in 2017, I am able to do this-
<input type='file' required />
and when you submit the form, it asks for file.
You could create a polyfill that executes on the form submit. For example:
/* Attach the form event when jQuery loads. */
$(document).ready(function(e){
/* Handle any form's submit event. */
$("form").submit(function(e){
e.preventDefault(); /* Stop the form from submitting immediately. */
var continueInvoke = true; /* Variable used to avoid $(this) scope confusion with .each() function. */
/* Loop through each form element that has the required="" attribute. */
$("form input[required]").each(function(){
/* If the element has no value. */
if($(this).val() == ""){
continueInvoke = false; /* Set the variable to false, to indicate that the form should not be submited. */
}
});
/* Read the variable. Detect any items with no value. */
if(continueInvoke == true){
$(this).submit(); /* Submit the form. */
}
});
});
This script waits for the form to be submitted, then loops though each form element that has the required attribute has a value entered. If everything has a value, it submits the form.
An example element to be checked could be:
<input type="file" name="file_input" required="true" />
(You can remove the comments & minify this code when using it on your website)
var imgVal = $('[type=file]').val();
Similar to Vivek's suggestion, but now you have a more generic selector of the input file and you don't rely on specific ID or class.
See this demo.
Some times the input field is not bound with the form.
I might seem within the <form> and </form> tags but it is outside these tags.
You can try applying the form attribute to the input field to make sure it is related to your form.
<input type="file" name="" required="" form="YOUR-FORM-ID-HERE" />
I hope it helps.
All statements above are entirely correct. However, it is possible for a malicious user to send a POST request without using your form in order to generate errors. Thus, HTML and JS, while offering a user-friendly approach, will not prevent these sorts of attacks. To do so, make sure that your server double checks request data to make sure nothing is empty.
https://www.geeksforgeeks.org/form-required-attribute-with-a-custom-validation-message-in-html5/
<button onclick="myFunction()">Try it</button>
<p id="geeks"></p>
<script>
function myFunction() {
var inpObj = document.getElementById("gfg");
if (!inpObj.checkValidity()) {
document.getElementById("geeks")
.innerHTML = inpObj.validationMessage;
} else {
document.getElementById("geeks")
.innerHTML = "Input is ALL RIGHT";
}
}
</script>

show JSON in new window

I have a problem with json. I'd like to display the result of my form in the new browser window in JSON. (When user fills all fields in the form, button becomes enabled and shows JSON in specified format (I did it)). I translated it in JSON but dunno how to output it...I'm thinking of create new html page and do window.open on button on 1st page, but then it doesn't read data from 1st page which user entered. Or should I save it somehow in JSON file and then read it from other page?
For example:
<form name="form" ng-controller="MyCtrl">
<label> <b> * Date: </b> </label> <input type="datetime-local" ng-model="date" name="date" onkeyup="changeButtonStatus()" onchange="changeButtonStatus()" required> </input>
<button type="submit" id="btn" class="btn" disabled="disabled">Submit</button>
</form>
I have some form with date field and button:
I can easily get JSON of date field by {{date | json}} on the same page, but I just want to output it in new browser window. How can I do this? Please help me with some tips. Thanks.
If it's not too big you can send the information to the new window as a data URL.
The frame will be reused once it is open.
This might be a start, showing how to plug in the JSON data and break it up over multiple lines for display.
window.open('data:application/json,'
+JSON.stringify(location).replace(/([[{,])/g, "$1%0a"),
'jsonFrame',
'resizeable,top=100, left=100, height=200, width=300,status=1')
See MDN for all the details.
You should be able to get at the window.opener from the new window and parse values out of it. The following plunker shows storing data from the current scope in an accessible area when the controller's submit is clicked. From the new window it then parses the content from the opener into the window's scope for further processing.
http://plnkr.co/edit/OkKX5zxYVSoZ7w81WV8J?p=preview
You'll notice here too how to get an angular friendly way of calling the submission and the disabling of the button until ready.
Hope this helps.
How about to save your input data into a cookie on one page and then get it via JavaScript when you will open a new window?
I could prepare the code in jsFiddle, but seems like it does not import external resources at this moment. So I'll post it here:
page 1:
...
<form name="form" ng-controller="MyCtrl">
<label> <b> * Date: </b> </label> <input id="date" type="datetime-local" ng-model="date" name="date" onkeyup="changeButtonStatus()" onchange="changeButtonStatus()" required> </input>
<button id="btn" class="btn" >Submit</button>
</form>
<script type="text/javascript" src="https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js"></script>
<script type="text/javascript">
$('#btn').click( function() {
var cookie_value = $('#inut_test').val();
/*cookie_value should be your json string*/
$.cookie("json_cookie", cookie_value, { path: '/' });
window.open("http://localhost/page2");
return false;
});
</script>
...
page 2:
...
<a id="see-cookie" href="#">
click me!!!
</a>
<script type="text/javascript" src="https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js"></script>
<script type="text/javascript">
$('#see-cookie').live('click', function() {
alert($.cookie('json_cookie'));
return false;
});
</script>
...
Do not forget about { path: '/' } cookie property to set it for all site and about including jQuery cookie library into your page.

Html placeholder text in a textarea form

On one of my websites I have created a form that collects the persons name, email and a description of their idea.
I limited the characters of the description to 500 characters as I don't want to read a ton and I figured out how to have the text appear in the textarea before the user inputs what they want.
Currently the user has to delete "Description of your idea" themselves but I want to add the placeholder class where it deletes what I have written in the textarea when they click the textarea
I have looked on a few sites and couldn't figure out how to use it I placed it in my code, but usually the class just appeared as text inside my textarea.
Any help on using this class would be great thank you
Here is what I have written
Inside the head tags
<script language="javascript" type="text/javascript">
function limitText(limitField, limitCount, limitNum) {
if (limitField.value.length > limitNum) {
limitField.value = limitField.value.substring(0, limitNum);
} else {
limitCount.value = limitNum - limitField.value.length;
}
}
</script>
Inside the body tags
<form name="form1" method="post" action="ideas.php">
Your Name: <input type="text" name="name"><br>
Your Email: <input type="text" name="email"<br>
<textarea name="desc" cols=50 rows=10 onKeyDown="limitText(this.form.desc,this.form.countdown,500);"
onKeyUp="limitText(this.form.desc,this.form.countdown,500);">Description of your idea</textarea><br>
<font size="1">(Maximum characters: 500)<br>
You have <input readonly type="text" name="countdown" size="3" value="500"> characters left.</font>
<br>
<input type="submit" name="Submit" value="Submit!"> </form>
There is a feature in HTML5 called 'placeholders', which produces exactly this feature without you having to do any coding at all.
All you need to do is add a placeholder attribute to your form field, like so:
<input type='text' name='name' placeholder='Enter your name'>
Sadly, of course, only a few browsers currently support it, but give it a go in Safari or Chrome to see it in action. The good news is that it is being added to virtually all browsers in the near future.
Of course, you still need to cater for users with older browsers, but you may as well make use of the feature in browsers that can use it.
A good way to deal with it is to use the placeholder attribute, and only fall back to the Javascript solution if the browser doesn't support the feature. The Javascript solution can take the text from the placeholder attribute, so you only need to specify it in one place.
See this page for how to detect whether the placeholder feature is supported: http://diveintohtml5.ep.io/detect.html
(or, as it says on that page, just use Modernizr)
The Javascript fall-back code is fairly simple to implement. Exactly how you do it would depend on whether you want to use JQuery or not, but here are links to a few examples:
http://www.morethannothing.co.uk/2010/01/placeholder-text-in-html5-a-js-fallback/
http://www.hagenburger.net/BLOG/HTML5-Input-Placeholder-Fix-With-jQuery.html
And of course Google will give you loads more if you search for html5 placeholder fallback or something similar.
Hope that helps.
Check out http://www.ajaxblender.com/howto-add-hints-form-auto-focus-using-javascript.html I think it has what you are looking for.
Here is a simple page that has an email field on it that I quickly put together (pulled mostly from the tutorial).
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
// Focus auto-focus fields
$('.auto-focus:first').focus();
// Initialize auto-hint fields
$('INPUT.auto-hint, TEXTAREA.auto-hint').focus(function(){
if($(this).val() == $(this).attr('title')){
$(this).val('');
$(this).removeClass('auto-hint');
}
});
$('INPUT.auto-hint, TEXTAREA.auto-hint').blur(function(){
if($(this).val() == '' && $(this).attr('title') != ''){
$(this).val($(this).attr('title'));
$(this).addClass('auto-hint');
}
});
$('INPUT.auto-hint, TEXTAREA.auto-hint').each(function(){
if($(this).attr('title') == ''){ return; }
if($(this).val() == ''){ $(this).val($(this).attr('title')); }
else { $(this).removeClass('auto-hint'); }
});
});
</script>
</head>
<body>
<form>
Email: <input type="text" name="email" id="email" title="i.e. me#example.com" class="auto-hint" />
</form>
</body>
</html>
The title text is put in the field if it's empty, and removed once the user starts typing.