Validate form with Javascript - javascript

I am trying to get a validation process to work using Javascript, my form has four radio buttons and one submit button, and I wanted to make it so if the user clicks submit and no radio buttons are selected then it pops up an alert and doesn't submit the form. Here's what my form looks like:
<form method="post" name="inform">
If you checked off <span style="text-decoration:underline">any</span> problems, how <span style="text-decoration:underline">difficult</span> have these problems made it for you to do your work take care of things at home or get along with other people?
<table id="lastquestion">
<tr>
<td>Not difficult at all</td>
<td>Somewhat difficult</td>
<td>Very difficult</td>
<td>Extremely Difficult</td>
</tr><tr>
<td style="text-align:center"><input type="radio" value="not difficult at all" name="finalquestion" /></td>
<td style="text-align:center"><input type="radio" value="somewhat difficult" name="finalquestion" /></td>
<td style="text-align:center"><input type="radio" value="very difficult" name="finalquestion" /></td>
<td style="text-align:center"><input type="radio" value="extremely difficult" name="finalquestion" /></td>
</tr>
</table>
<input type="hidden" value="<?php echo $totalScore; ?>" name="totalScore" />
<input type="submit" value="Submit Final Answer" name="submit" onclick="return validate(inform)" />
</form>
And here's what the script looks like:
function validate(formCheck)
{
if(formCheck.finalquestion == "")
{
alert("Please Choose an option");
return false;
}
else
{
return true;
}
}
But for some reason my button is submitting no matter what, Any advice here would help, thank you!
UPDATE: I have tried selecting a radio and then alerting in the validate function and formCheck.finalquestion prints: [object NodeList], so I don't think the value of which button is selected is going through properly.

You are relying on naming behaviour that works only in IE: Only that browser provides a global Javascript variable xyz (or, to be more exact, window.xyz) for each element with that name.
To specify the form, use submit button's form attribute. It is always a reference to the form object:
return validate(this.form);
To get the element of a radio button, you need to specify the value attribute. Use
if(formCheck.elements.finalquestion.value == "")

Related

Html form submitting previous choice when I refresh page of Flask web app

In my Flask application, I have a simple form of type POST and 4 radio-buttons options with the same name. When I choose an option and press "next" (a submit-type input), a new page loads with different content but a form of the same type.
The issue is, if I refresh the newly loaded page, the form is submitted with the option having the same value as the previously chosen option.
Form:
<form id="myForm" name="myForm" method="post" >
<table align="center" cellpadding="10" border="0" style="background-color: antiquewhite;">
<tr>
<td rowspan="2"><h3>Is this an <i>origin</i> for the <i>claim?</i></h3></td>
<td><input type="radio" name="op" id="op1" value="1" >Yes</td>
<td><input type="radio" name="op" id="op2" value="2" >No</td>
<td rowspan="2"><input type="submit" value=Next></td>
</tr>
<tr>
<td><input type="radio" name="op" id="op3" value="3" >Invalid Input</td>
<td><input type="radio" name="op" id="op4" value="4" >Don't Know</td>
</tr>
</table>
</form>
Snippet of Python code dealing with form:
if request.method == 'POST':
op = request.form.get('op')
if op:
if op in ['1', '2', '3', '4']:
save_annotation(session.get('claim'),session.get('origin'), op, name)
c_url, o_url = get_least_annotated_page(name, session['claim'])
else:
c_url = session['claim']
o_url = session['origin']
else:
print("NOT POST AND LOGGED IN")
c_url, o_url = get_least_annotated_page(name)
.
.
.
.
.
return render_template('index.html',t1=c_url, t2=o_url)
I just want to be able to refresh the page without the form being POSTed.
I already tried using
document.getElementById("myForm").reset();
as well as
<body onload="document.myForm.reset();">
and
autocomplete="off"
Full code available here(annotator.py, app/templates/index.html, and app/templates/base.html):
https://github.com/MohamedMoustafaNUIG/AnnotatorVM.git
EDIT:session is just a global variable that I use to store stuff. name is initialised in the beginning of the python code, and save_annotation() and get_least_annotated_page() are functions.
EDIT2: When a new page is loaded, the buttons are all unchecked. Yet when I refresh, an option is submitted. I only noticed by looking through the command line output.
When you refresh the page the browser will perform the last action, in your case a POST.
The way to avoid this would be to change the return to a redirect instead of render:
if request.method == 'POST':
...
return redirect(url_for('this_view'))
...
Source
You can try:
document.getElementById("op1").prop('checked', false)
this will uncheck the radio button. This can be done to each one.
I found a working solution. It might need more testing before I am sure, but for now it is working fine.
Basically, Ill keep a variable that will be incremented when the user chooses an option. Ill then compare the value stored in session (server-side) with the version sent in the form by the POST request. If they are the same, then this is a refresh, otherwise it is a normal submit.
Code:
Client-side (index.html)::
<form method="post">
<table align="center" cellpadding="10" border="0" style="background-color: antiquewhite;">
<tr>
<td rowspan="2"><h3>Is this an <i>origin</i> for the <i>claim?</i></h3></td>
<td><input type="radio" name="op" id="op1" onchange="incAlpha();" value="1" >Yes</td>
<td><input type="radio" name="op" id="op2" onchange="incAlpha();" value="2" >No</td>
<td rowspan="2"><input type="submit" value=Next></td>
</tr>
<tr>
<td><input type="radio" name="op" id="op3" onchange="incAlpha();" value="3" >Invalid Input</td>
<td><input type="radio" name="op" id="op4" onchange="incAlpha();" value="4" >Don't Know</td>
</tr>
</table>
<input type="hidden" id="alpha" name="alpha" value={{alpha}}>
</form>
<script type="text/javascript">
var globFlag=true; // use so that the incrementation is only triggered once every page load
function incAlpha()
{
if(globFlag)
{
let value= document.getElementById("alpha").value;
document.getElementById("alpha").value = (parseInt(value)+1)%10;
globFlag=false;
}
}
</script>
Python (Flask) Code:
name = session.get('username')
alphaFromSession = session.get('alpha')
if request.method == 'POST':
op = request.form.get('op')
alphaFromClient = request.form.get('alpha')
if op and not (alphaFromSession == alphaFromClient):
if op in ['1', '2', '3', '4']:
save_annotation(session.get('claim'),session.get('origin'), op, name)
session['alpha']=alphaFromClient
c_url, o_url, src_lst, donePg, totalPg, done, total = get_least_annotated_page(name, session.get('claim'))
.
.
.
.
return render_template('index.html',t1=c_url, t2=o_url,alpha=session.get('alpha'))

Radio input not working with localStorage

Radio input not working with localStorage
I used localStorage for many examples and work with me good except starRating.
Here is example example
I tried many codes , but does not work
Please give me example. Sorry I'm newbie.
<table>
<thead>
<tr>
<th STYLE="width:200px">link</th>
<th STYLE="width:200px">rating</th>
<th STYLE="width:200px">Options</th>
</tr>
</thead>
<tr>
<td>
<A CLASS="flink" HREF="https://www.google.com" TARGET="_blank">site a</A>
</td>
<td>
<span class="starRating">
<input CLASS="inputrating" CHECKED id="rating_9_5" type="radio" name="rating_9" value="5">
<label for="rating_9_5">5</label>
<input CLASS="inputrating" id="rating_9_4" type="radio" name="rating_9" value="4">
<label for="rating_9_4">4</label>
<input CLASS="inputrating" id="rating_9_3" type="radio" name="rating_9" value="3">
<label for="rating_9_3">3</label>
<input CLASS="inputrating" id="rating_9_2" type="radio" name="rating_9" value="2">
<label for="rating_9_2">2</label>
<input CLASS="inputrating" id="rating_9_1" type="radio" name="rating_9" value="1">
<label for="rating_9_1">1</label></span>
</td>
<td>
add
</td>
</tr>
<tr>
<td>
<A CLASS="flink" HREF="https://www.google.com" TARGET="_blank">site b</A>
</td>
<td>
<span class="starRating">
5
4
3
2
1
add
$(".starRating").on("click", function(){
selected_rating = $('input', this).data("inputrating");
selected_id = $('input', this).data("rating-id");
console.log(selected_rating)
});
You need to change your event binding to the Radio Buttons, not the spans that contain them.
Next, you need to access the values of the radio buttons, rather than using the jQuery .data() method, which I'm not sure what you are doing with.
this.value
In the event handler is all you need for that.
Next, you need to actually store the values, which you didn't have any code for:
if(window.localStorage){
localStorage.setItem("Site A Rating", this.value);
} else {
console.log("localStorage not supported.");
}
Here is a working Fiddle: https://jsfiddle.net/6jfey3cj/4/
And a screen shot showing the different site's ratings in localStorage.
The key issue you are struggling with is how to decide which element is best to trigger your function on. You are currently triggering on .starRating which is a span. It is possible to use that as the trigger but makes much more sense to simply fire the function whenever someone chooses a value on .inputrating which is a class that is unique to all your star rating radio buttons.
Try this code out:
$(".inputrating").on("change", function(){
checked_rating = $(this).val();
checked_id = $(this).attr('id');
console.log(checked_rating);
console.log(checked_id);
});
If you notice I changed click to change. This will make it so that your code only fires once on rating select. That way if you end up running an ajax function to update a database it won't keep getting called over and over if the user decides to spam click the same radio button over and over.
Here is a working fiddle demonstrating the solution: JSFiddle
You can change your javascript function as below
$(".inputrating").on("click", function(){
selected_rating = $(this).val();
selected_id = this.id;
console.log(selected_rating);
console.log(selected_id);
});
updated fiddle -
https://jsfiddle.net/tfhg15xw/2/

group all radio buttons with different names

I am trying to find a way to validate all of my radio buttons to make sure atleast one of them is checked. The problem is doing it with the names and id's have to remain in the format that they are in.
So basically I want to have a way to group all of my radio buttons even with different names and id's.
I understad how to loop for all checked buttons in the table but some are outside of the table, the code is just an example of what I need to do.
<table id="table" width="100%" border="0" cellpadding="5">
<tr>
<td><input type="radio" name="blue" id="blue" value="blue1" /></td>
<td><input type="radio" name="blue" id="blue" value="blue2" /></td>
<td><input type="radio" name="red" id="red" value="red1" /></td>
<td><input type="radio" name="red" id="red" value="red2" /></td>
<td><input type="radio" name="blue" id="green" value="green1" /></td>
<td><input type="radio" name="green" id="green" value="green2" /></td>
</tr>
</table>
Something like this:
if($('input[type="radio"]:checked').length > 0){
//at least one radio on your page is checked
}
Assuming you are going for the HTML5 validation, just make one of them required, and then change it as they go:
<input required type="radio" name="blue" id="blue" value="blue1" />
JS:
$radios = $('input[type="radio"]');
$radios.on('change', function() {
if ($(this).is(':checked')) {
$radios.prop('required', false);
$(this).prop('required', true);
}
});
$('form').on('submit', function(e) {
if ($('input[type="radio"]:checked').length === 0) {
e.preventDefault();
alert("Must check at least one radio");
return false;
}
});
Given your posted html I'd suggest changing the name of all those posted <input /> elements to colour (or color, according to language preference) to clearly associate them together.
However, if that can't be done, and you're able to add a class-name as a means of associating the group:
var allInputs = $('input.colour'),
checked = allInputs.filter(':checked'),
choiceMade = checked.length > 0;
Incidentally:
…I think by adding the class if I checked one, it would check the rest in that class.
No, that behaviour - unchecking one element should another be checked - is entirely dependent on the <input /> sharing a name attribute and being semantically grouped. It doesn't matter how else you create an association, so long as you don't yourself create that functionality.
To make sure at least one radio button within table is checked and the one at the top of the page:
if ($('#top-radio').is(':checked') && $('#table :radio:checked').length) {
// valid, something is checked
}

Validate a text field only if display:block

I have 2 text fields that need to be validated.
Merge/Reason field needs to be validated
Barcode needs to be validated only if it is displayed, i.e. if checkbox is checked.
What I am trying to do is pop-up an alert box for merge-reason (regardless) and add a validation message for barcode in alert if not hidden
Here is the code:
<tr><td>
<input type="checkbox" name="createCharge" id="createCharge" onClick="checkBox('Barcode', 'CreateCharge');" value="1"/>
<lable>Charge</label>
</td></tr>
<tr id="Barcode" style="display:none;">
<td>
<label>Barcode</label>
<input type="text" name="Barcode" id="Barcode"/>
</td>
</tr>
<tr>
<td>
<label>Merge:</label>
<input type="text" name="Reason" id="Reason"/>
</td>
</tr>
You can simply check like this:-
if($(x).is(":visible"))
{
//your element is visible
}
JAVASCRIPT
var display= document.getElementById('x').style.display;
if(display=='block')
{
//do validation here.
}
if( $('#Barcode').is(':visible') ){
// Perform code here
}
How do I check if an element is hidden in jQuery?
if( $('#Barcode').is(':visible') && $('#Reason').val().length!==0 ){
// Barcode is visible and reason has a value more then 0 chars long
}

check to see if a particular checkbox is checked in a td using jquery

I am trying to make textbox readonly or not depending on the value of a checkbox of personalLoan. If personalLoan checkbox is checked I want the text to be not readonly. If it is unchecked then I want the text box to be readonly. Here is one of the rows
<tr id="mytableRows">
<td class="even"><input type="checkbox" value="true" name="homeLoan" ></td>
<td class="odd"><input type="checkbox" value="true" name="autoLoan" ></td>
<td class="even"><input type="checkbox" value="true" name="personalLoan" ></td>
<td class="odd"><input type="checkbox" value="true" name="noLoan" ></td>
<td class="odd"><input type="text" name="peronalAmount" value="1" readonly></td>
</tr>
I so far has this code
$(document).ready(function(){
$('.test tr').click(function (event) {
$(this).find(':checkbox').each(function(p){
if($(this).attr('name') == 'personalLoan'){
if ($(this).is(':checked')) {
alert("checked");
}else{
alert("unchecked");
}
}
});
});
});
This tells me the current status of the checkbox but what I really need is to know onchange of the personalLoan checkbox so I can make the textbox readonly or not in that row (td)
thanks
For my own sanity, here is what I understand the solution to be.
$('input[type=checkbox]', '.test').on('change', function(e) {
if (this.name === 'personalLoan') {
$(this).parents('tr').find('input[type=text]').prop('readonly', !this.checked);
}
});
Assuming a table with class test, this allows input when personalLoan is checked, and toggles to readonly when unchecked.
Demo on jsFiddle. (I've highlighted the checkbox in red.)
If this isn't it, then I really have no idea what you're trying to do.
It seems to me that you really want radio buttons, not checkboxes, and that the amount field should be set to disabled rather than readonly if the user selects "no loan".
Anyhow, here's an approach you can take. I've put the code in–line for convenience, it can re-implemented in jQuery or whatever you want, it's just an example of how to do what you seem to be trying to do.
The timeout is used so that the one click event can be used for any element in the form, including the reset button.
<form onclick="
var form = this;
setTimeout(function() {
form.personalAmount.readOnly = form.loanType[3].checked;
},0);
">
<table>
<tr>
<td><input type="radio" value="homeLoan" name="loanType">Home</td>
<td><input type="radio" value="autoLoan" name="loanType">Auto</td>
<td><input type="radio" value="personalLoan" name="loanType">Personal</td>
<td><input type="radio" value="true" name="loanType">None</td>
<td><input type="text" name="personalAmount" readonly></td>
<tr>
<td colspan="4">
<input type="reset">
</table>
</form>

Categories

Resources