I have worked mostly with Python so far, so I'm a newbie when it comes to JavaScript. Now I need the latter to implement a form. I have some ideas and requirements in mind and would like you to tell me how to start and which frameworks or tools to use.
My requirements are:
The server-side logic will be implemented in Python and Django.
The entire form is located on a single webpage.
The overall design of the webpage should be done with Twitter Bootstrap.
When the page has been loaded, only the first field of the form is displayed.
When this field has been filled and validates correctly, display the second field of the form below the first field
When a new field gets displayed, its webpage should scroll down automatically if necessary, so that the new field gets centered in the browser. The scrolling should occur with some nice animation.
My form also includes some fields of type ChoiceField. Each choice has its own set of additional settings which will be implemented as form fields as well. Once a particular choice has been made, only the respective set of settings should be displayed but not all settings for all choice fields at the same time. (Can I probably do this with a simple if-else structure?)
When all fields have been displayed, filled and validated and the form has been submitted, the server does some computations. The results of these computations should be displayed below the entire form, once they are ready. The webpage should again scroll down automatically to the results. The best would be to scroll down the webpage to an extent where the form is not visible anymore but only the results. So this is probably dependent on the size of the currently opened browser window.
I know that all of this is possible and I've also seen forms like that from time to time but don't have a concrete example at the moment. I also know that all of this is possible with JavaScript. Can I implement all of the above with JQuery or do I need additional tools? It would be great if a JavaScript expert guided me a bit through this mess inside my mind. Thank you in advance!
Make it work
Before doing anything with javascript make a normal form that works. I.e. generate a form using whatever server side language you want, and when you submit the form it should do what you want it to do. If you have a form that works without javascript you have the confidence that it'll always work if the js breaks.
Make it work better/ Progressive Enhancement
There look to be 2 or 3 requirements for your js - treat them all individually:
1. The form should show only one input at a time
E.g. with markup like this:
<form id="myForm" method="post">
<legend>My Awesome Form</legend>
<div class="question">
<label for="x">X</label>
<input name="x" id="x">
</div>
<div class="question">
<label for="y">Y</label>
<input name="y" id="y">
</div>
<div class="question">
<label for="z">Z</label>
<input name="z" id="z">
</div>
<div class="submit"><input type="submit" value="Submit"></div>
</form>
Use some js like this:
$('.question', '#myForm').not(':first-child').hide();
$('input', '#myForm').change() {
var div, next;
div = $(this).parent();
next = div.next();
if ($(this).val() && next.length) {
parent.hide();
next.show();
}
});
Which would show only one of the question divs at a time, and show the next one (if there is a next one) when the input is filled.
2. Validate user input
To validate the user input, create a function that does that for you, returning true/false as appropriate and hook that into your js so that it doesn't continue if the input value is deemed invalid:
validate(field, input) {
var valid = false;
// implement your logic here to validate input
if (valid) {
return true
}
return false;
}
$('input', '#myForm').change() {
var div, next;
if (!validate($('this').attr('name'), $(this).val()) {
return;
}
div = $(this).parent();
next = div.next();
if ($(this).val() && next.length) {
parent.hide();
next.show();
}
});
That will prevent the user from moving onto the next input, if the current one has an invalid value.
3. Submitting the form by ajax
Clicking submit should send the form data to the server, in (almost) the same ways as submitting the form normally. the only difference should be that it response with either a json response that you parse, or a snippet of html that you dump at the end of the page:
$('#myForm').submit(function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: $(this).attr('action'),
data: $(this).serialize(),
success: function(data, textStatus, jqXHR) {
// handle success response
},
error: function(jqXHR, textStatus, errorThrown)) {
// show the user an error
}
});
});
All of the js written here is untested, it should give you some ideas about how to tackle each aspect of what you want to do - of course, for more information of any particular method refer to the docs.
All of this can be done with jQuery, you shouldn't need any additional JS tools.
Since you have a lot of functionality to build out, I'm not going to go into details. However, I can provide some insight into how to go about each step of your process.
1.) Thats fine.
2.) Thats fine too, you just need one html page to accomplish this.
3.) I would recommend having all forms created in HTML with a CSS of display none. Then as the user progresses through, you can use .show() to "show" the hidden elements.
4.) Probably going to want to have a "next" button of some kind outside of your form. Use .click() To trigger a function that does whatever form validation you require on the value of the input form field. You can use .next() to cycle through your form inputs.
5.) If you want a browser scroll use scrollTop or the jQuery ScrollTo Plugin. If your just looking to move things on the screen and not truely scroll, use .animate()
6.) You will have to set the value on the fly as a user progresses. So use .change() to do the detection.
7.) Before submitting, run your validator on all the fields again to ensure you have all correct data. You'll want to use .ajax() to make the request to your service and prevent default on the actual form submit. Take the response you get back from the service and format the information accordingly.
That should give you insight on how to accomplish your project. Good Luck!
Related
I'm having trouble when I try to validate a form with the jQuery Validator plugin. So in this case, I have constructed a div table (not table elements, but divs styled as a table) where each row essentially is its own form complete w/ whatever form-controls.
Since this table could have potentially hundreds of rows however, I didn't want the overhead of wrapping each row element in its own separate form. So I came up with an idea where the save method just takes the row itself as an arg in order to create/validate/submit a form behind the scenes.
What I do is essentially clone the row and append the clone onto a new form I create like so
$("<form></form>").append(clonedRow);
Then I take the resulting variable (the form) and setup the validation. The validation options/setup look like this:
form.validate({
rules: {
Follow_Up_Code: { required: true, maxlength: 2 }
},
messages: {
Follow_Up_Code: { required: "...", maxlength: "..." }
},
submitHandler: function(){...}
});
Currently I only want to validate against one input in this row to test. Here is the input markup:
<input type="text" class="get set input" name="Follow_Up_Code" style="width: 100%;">
After the form runs .validate(), I immediately submit the form. However, for my test case the form passes validation and runs the SubmitHandler set up in the validator every time.
This leads me to think that any form I want to validate with this plugin needs to be attached to the DOM in order to validate properly. However I've found no documentation on this. I would like to know if there is a way I could fix this, or if I'm better off trying to find/create my own validation service for this purpose.
After testing, I've come to discover that. Yes, the form needs to be attached to the DOM in some way shape or form. However, you can get around this pretty easily and unobtrusively:
form.css({ position: "absolute", visibility: "hidden", left: "-5000px" });
$("body").append(frm);
frm.submit();
That way the user won't be able to see or interact with this form while it's on the DOM.
This will get the job done and validate the form. In this case however, if there were any validation errors that I would want to show on the original table. I would have to access the invalid controls from inside the validator's invalidHandler option on setup. From there I just need to insert the error message(s) at where my desired location happens to be.
After all is said and done, it would be a good idea to .destroy the validator and remove that form from the DOM. I believe doing this at the end of both the submit handler and invalid handler would be the best way to go about that.
I want to populate a city/state drop down list based on the postal code a user types into a textbox. So when the text changes, I'm going to make an ajax call to retrieve the data. However, I only want to perform that ajax request for valid postal codes. The field already validates using the DataAnnotations.RegularExpression attribute and jquery.validate.unobtrusive validation library. I'm unclear on what can and can't be used from jquery.validate when using unobtrusive. I've looked at the unobtrusive code, but haven't gotten an understanding of it yet. So two questions:
Using javascript,
is there a way to force validation on a specific field, not the whole form?
is there a way to check whether a specific field is valid?
After digging around in the source code, I've come to these conclusions. First, the purpose of unobtrusive is to wire up the rules and messages, defined as data- attributes on the form elements by MVC, to jQuery.validation. It's for configuring/wiring up validation, not a complete wrapper around it, so when it comes to performing validation that is already set up, you don't have to worry about "circumventing", or not involving, unobtrusive.
So to answer the questions:
Yes, there are two ways. The Validator.element(element) function and the $.fn.valid() extension method. .valid actually calls Validator.element internally. The difference is .valid works on a jQuery which allows you to perform the validation on one or more fields (or the form itself). Validator.element performs validation on only a single element and requires you to have an instance of the validator object. Although the documentation states .validate() "validates the selected form", it actually appears to initialize validation for the form, and if it has already been called, it simply returns the validator for the form. So here are examples of two ways to validate an input (below #2).
Yes, but not without also performing the validation. Both of the methods from #1 return a boolean so you can use them to determine whether a field is valid. Unfortunately there doesn't appear to be anything exposed by the library that allows you to check the validation without, in effect, showing or hiding the validation message. You would have to get at and run the rule(s) for the field from your code, which may be possible, but my need didn't justify spending the time on it.
Example:
<form>
<input id="txtDemo" type="text"></input>
</form>
...
<script type="text/javascript">
$("#txtDemo").valid();
//or
//Get the form however it makes sense (probably not like this)
var validator = $("form").validate();
//Note: while .element can accept a selector,
//it will only work on the first item matching the selector.
validator.element("#txtDemo");
</script>
you can find if a single field is valid and trigger this validation this way:
$("#myform").validate().element("#elem1");
details here http://docs.jquery.com/Plugins/Validation/Validator/element#element
Use like this:
$('#Create').on('click', function () {
var form = $('#test').closest('form');
$(form).validate();
if (!$(form).valid()) {
return
} else {
// Bide the data
}
});
Hope it works for you
I have a form where a user can chose the applications he has access to? and when he the applications he wants access to, he is presented with more options. One of them is notification email address. if the user choses two applications, he gets two notification email address fields to fill. But both of them are stored in the same column in the database.
There are multiple fields like user authorisation level, user branch etc which are uniform accross all applications.
i am trying to replicate the value of one field in the other with jquery. i tried the below which obviously fails. Can anyone suggest how to acheive the replication?
$("#email").val().change(function() {
$("#email1").val($("#email").val());
});
Edit: I have drop down fields as well as text boxes.
.val() returns a string which cannot have a change event. You need to use
$("#email").change(function() {
$("#email1").val($(this).val());
});
You will want to bind the change event using on or live depending on your version of jquery, if you haven't wrapped this piece of code in a ready block.:
$("#email").on("change",function() {
$("#email1").val($(this).val());
});
This fiddle shows setting a <select> tags value using .val() http://jsfiddle.net/8UG9x/
It is an often asked question:
Copy another textbox value in real time Jquery
depending on when you need this action to execute, but if live
$(document).ready(function() {
$('#proname').live('keyup',function() {
var pronameval = $(this).val();
$('#provarname').val(pronameval.replace(/ /g, '-').toLowerCase());
});
});
http://jsfiddle.net/KBanC/
another one, basically same:
JQUERY copy contents of a textbox to a field while typing
I'm trying to use the below search form and js to search my site. However, whenever you type a word in the form and click submit the form them takes the users browser to http://example.com/?s=searchterm , but I want it to take them instead to http://example.com/searchterm and totally leave out the characters ?s=
<script type="text/javascript">
function submitform()
{
document.forms["searchsite"].submit();
}
</script>
<form id="searchsite" action="/">
<input type='text' name='s' placeholder='search'>
Submit
</form>
Any positive advice? Btw, no, I don't believe I can use htaccess and mod_rewrite since I already have rules set.
You could set an onsubmit handler to intercept the form’s submission and replace the default action with setting the location href. This relies on JavaScript being enabled in the client side:
<form id="searchsite" action="/" onsubmit="javascript:location.href=this.action + encodeURIComponent(this.elements.namedItem('s').value); return false;">
This escapes the search term so that if the user enters something with ? or / in it, the server will interpret that as part of the path instead of thinking that the client is trying to send a querystring or access some subdirectory. The return false; states that the browser should stop its normal form submission procedure since the onsubmit handler has already updated location.href, which will cause the browser to start navigating as soon as the onsubmit handler returns.
However, you really should supplement this with server-side code. For something this simple, the JavaScript can be there to make your URIs pretty while skipping an HTTP redirect (so that the browser goes directly to the requested page slightly faster than otherwise). But you should really have a server-side redirect that gets triggered whenever the GET s parameter is sent.
Extra note: you should really replace your submission script with a <button/>, like:
<button type="submit">Submit</button>
and just drop your <a/> and <script/> tags completely. You get all of the functionality you need by overriding the form submission handler itself, no need to try to intercept button clicks, etc. With this change, your form should now work when the user presses ENTER instead of requiring the user to TAB to the <a/>. Use the intended HTML elements for their intended purposes and hook into the right events ;-).
I assume that your question is only about the client-side of the code and that you already have figured how to get your server-side code to read the value from the URI path. Figuring out how to read the value, if it is submitted this way, would take me some time to research and would require more information about your server-side setup.
Instead of submitting the form, build the URL and then set the location. You can add an ID to the search term (s in this case) and then simply build the URL:
var searchTerm = document.getElementById("s").value;
document.location = "http://example.com/" + searchTerm;
I have input field
<input type="text" name="vehicle_make[]" id="make1"/>
and i have help dropdown that updates this field if user choose to do so. I do it trough standard jquery code
$("#make1").val("value");
Problem is, since i use validate plugin to validate this field, if user click on validate before entering anything in that box, he will get notice that he needs to fill it, but then if he fills it trough dropdown, validate plugin will not detect it until user click on submit again.
I know i could call submit in function in which i process dropdown, but i think that it is not right solution, since i would need to check if validation is already done before doing that (since if it is not, it would start validation before i want it to start).
I also need to tie some other things to that field also, so i would like to know is there is a way in which i could write function so it always check if field is filled, even if user did not fill it directly.
Sorry if i didn't explain everything right, this is my first message here.
Try this
$("#make1").change(function(){
//do something there
});
I have found solution. First, i created js variable form_submitted, and added onclick event to submit button, to change value of variable form_submitted to yes. Then, i created function:
function update_validation(){
if(form_submitted == 'yes'){
$("#my_form").valid();
};
};
that i call when user do something that is not detected regularly with validate plugin. This function manually starts validation again, but only if it has been started before by clicking on submit.