I am using jquery validation plugin. and designing the webpage using various elements (e.g,div ,li etc) .
There are tabs(tab1,tab2,tab3 ect) and through internal link these tabs contain several nos of fields(field1,,field2,....filed n).
Actually I want to mark the bg-color of the tab(e.g,tab2) as 'red' if there is any 'required' field missed .
For that I have tried the following code...
if(!(jQuery('#admissionForm').valid())) {
var n = $("label.error").parents("div.tab-body").index();
console.info(n);
var sel = "li.ui-state-default:nth-child(" + n + ")";
console.info(sel);
jQuery('label.error').each(function(n) {
$("label.error").parents("div#form-wizard").children("ul.ui-tabs-nav").children(sel).children("a").css("background-color","red");
});
}
The problems are
This code works for only one tab.
The .each() function takes the highest index.For example if there are error in all tabs then it marks only the 'tab3' tab not all the tabs.
So I want code which can mark the tabs. as respective error occurred as well doesn't mark the tabs which does contain any error.
Plz.. somebody help me out.
Thanx.. in advance...
This could be a little tricky to help you with. I'm not sure how familiar you are with the validate plugin.
You can't really do it the way you want it to, because you need to check all panels' inputs and see if they were valid or not.
The only way to differentiate that, without using the internal validation, is by using label.error:visible and label.error:hidden to see if they were valid or not. That is where your first problem lie. Since you have tabs, they are hidden even though they might be errored.
Which is why your example can only mark one tab or all tabs.
To solve this, you need to replace the current validation handler and unhighlight, so that you can do some highlighting and checking on your own.
I've arranged this JSFiddle that you can "fiddle" around with, hopefully the comments are enough to help you.
The idea is that at validation, you check which inputs were invalid, then get the parent panel and add an error class to the corresponding tab. When the user has corrected the error, or there is no error, the unhighlight will remove the error class from the tab.
And here's the code. Using JQuery, JQuery UI and JQuery validation plugin.
Javascript
$("#tabs").tabs();
$("#submitForm").button();
$("#validatetabs").validate({
submitHandler: function(form) {
alert("Done!");
},
invalidHandler: function(form, validator) {
//Check if there are any invalid fields
var errors = validator.numberOfInvalids();
if (errors) {
//Get all panels with errors
var errorpanels = $(validator.invalidElements()).closest(".ui-tabs-panel", form);
//Get ui tab sibling for every panel and add error
errorpanels.each(function(){
$(this).siblings(".ui-tabs-nav").children("li").addClass("ui-state-error");
});
}
},
unhighlight: function(element, errorClass, validClass) {
$(element).removeClass(errorClass);
//Get panel
var panel = $(element).closest(".ui-tabs-panel", element.form);
if (panel.size() > 0) {
//Check to see if there are any more errors on this panel
if (panel.find("." + errorClass + ":visible").size() == 0) {
//Find matching tab for this elements panel id
panel.siblings(".ui-tabs-nav")
.find("a[href='#" + panel[0].id + "']")
.parent().removeClass("ui-state-error");
}
}
}
});
HTML
<form id="validatetabs" method="get" action="">
<div id="tabs">
<ul>
<li>Tab1</li>
<li>Tab2</li>
<li>Tab3</li>
</ul>
<div id="tabs-1">
A required field: <input id="inp1" name="inp1" class="required" type="text"/>
<br/>
Another required field: <input id="inp1a" name="inp1a" class="required" type="text"/>
</div>
<div id="tabs-2">
A required field: <input id="inp2" name="inp2" class="required" type="text"/>
<br/>
Another required field: <input id="inp2a" name="inp2a" class="required" type="text"/>
</div>
<div id="tabs-3">
A required field: <input id="inp3" name="inp3" class="required" type="text"/>
<br/>
Another required field: <input id="inp3a" name="inp3a" class="required" type="text"/>
</div>
</div>
<p>
<input id="submitForm" class="submit" type="submit" value="Submit"/>
</p>
</form>
CSS
label, input{
display: block;
width: 100px;
}
label.error{
position: absolute;
background: white;
width: auto;
margin-left: 125px;
margin-top: -26px;
padding: 2px;
color: red;
font-style: italic;
}
Related
I have to make a page, where there are 3 forms within it, but only one should be displayed. Also, these forms shouldn't be connected. For example if I would put in some kind of validation within all 3 of the forms, only the one I use should respond to the validation code, the other ones should stay idle untill I switch the form and use it. I have to make this without frameworks, plain, JS or PHP, HTML and CSS.
I have a page where I can switch forms, 1 is displayed, 2 are hidden. However, I made a validation class, and it is validating all 3 forms, since the 2 i'm not using are just hidden, not disabled so this is not working.
Any one know how I sould make these forms, so they would be independent from each other? I mean, how would they go about making this code, not making mine into account. I want to redo it and just add my other stuff on top of it.
if my deductions are correct on the little information given, here is probably what you are looking for
const
Bt_SwitchForm = document.getElementById("Switch-Form"),
FormX_Count = 3;
var
formActiv = 0,
formX = {};
function formX_Submit(e) {
e.preventDefault()
console.log('formX_Submit on =', this.id )
}
document.querySelectorAll('form').forEach( (elm, Item)=>
{
formX[elm.id] = { 'f' : elm, 'ref': Item }
elm.onsubmit = formX_Submit;
});
Bt_SwitchForm.onclick=()=>{
formActiv = ++formActiv % FormX_Count;
for(let elm in formX) {
formX[elm].f.className = formX[elm].ref===formActiv ? '': 'form_Off'
};
}
form {
display: block;
padding: 20px;
border: 1px solid grey;
width : 200px;
}
form.form_Off { display : none }
button { margin: 10px}
<form id="form1" class="">
<input type="text" id="inputTxt1" value="" placeholder="input form 1" >
<button type="submit">submit</button>
<button type="rest">reset</button>
</form>
<form id="form2" class="form_Off">
<input type="text" id="inputTxt1" value="" placeholder="input form 2" >
<button type="submit">submit</button>
<button type="rest">reset</button>
</form>
<form id="form3" class="form_Off">
<input type="text" id="inputTxt3" value="" placeholder="input form 3" >
<button type="submit">submit</button>
<button type="rest">reset</button>
</form>
<button id="Switch-Form">Switch Form</button>
I think it is useless for me to explain this code since you seem to live with a strong power of deduction. ;)
I'm completely new to Backbone.js and jQuery and I'm trying to set an input field of a form to "disabled" when I check a checkbox. I'm not sure if I have to do it the way I show in the code below, if so what should I do in the disableInput function?
JS
events: {
'change #myCheckbox': 'disableInput',
},
disableInput : function(){
...
}
HTML
<div class="x">
<input type="text" id="myInput">
<input type="checkbox" id="myCheckbox">
<div>
EDIT: This may seem like dupplicate of other posts, but those questions are about vanilla JS I'm using Backbone here so it's not the same.
If you want to go the pure CSS route, you can place the checkbox above the text and switch the order to your liking using flexbox. Then, you can write CSS that changes the opacity and pointer-events for the checkbox sibling.
.x {
display: flex;
}
.x #myCheckbox {
order: 2;
}
.x #myCheckbox:checked + #myInput {
pointer-events: none;
opacity: 0.6;
}
<div class="x">
<input type="checkbox" id="myCheckbox">
<input type="text" tabindex="-1" id="myInput">
</div>
Tab Issue
In order to stop someone from tabbing into the input, you can add tabindex="-1" to the input.
Here is a simple one liner
Granted I am not familiar with backbone.js but you should be able to figure out how to incorporate this.
function disableInput(){
document.getElementById("myInput").disabled=document.getElementById('myCheckbox').checked
}
<div class="x">
<input type="text" id="myInput">
<input type="checkbox" onchange="disableInput();" id="myCheckbox">
<div>
I think Backbone way would be the following
events: {
"change #myCheckbox": function() {this.disableInput.apply(this, arguments);}
},
disableInput: function(args) {
var checked = $(args.target).is(":checked");
this.$el.find("#myInput").disabled = checked;
}
Relatively new to html coding, and very new with javascript. On this page, I don't want the option to email an editor to become visible until a tripID is filled in (but form not submitted yet). Here is the form so far without that option added yet:
TripID:
<input type='text' id='atripid' name='atripid' size='6' maxlength='6' /><br><br>
Port:
<input type='text' id='aport' name='aport' size='6' maxlength='6' /><br><br>
<div id=acheckbox><br> E-mail editor? </b>
<input type='checkbox' name='acheck' onchange='copyTextValue(this);'/><br>
<div id='div' style='display:none'>
<br> <b>Subject:</b> <input type='text' id='asubject' name='asubject' size='70' maxlength='75'/><br><br>
<textarea name='aemailbody' cols='85' rows = '10'>Explain any packaging or labeling mistakes here...</textarea>
</div>
</div>
<script>
function copyTextValue(bf) {
if(bf.checked){
document.getElementById('div').style.display = 'block';
var atext = 'Frozen Sample Error Notice: '+ document.getElementById('atripid').value;
}else{
document.getElementById('div').style.display = 'none';
var atext = '';
}
document.getElementById('asubject').value = atext
}
</script>
</div>
Now to hide the email editor option until tripid is filled in, I got something like this to work on jfiddle:
<form action="">
tripid:<input type="atripid" id="atripid" value="">
port:<input type="aport" id="aport" value="">
</form>
<div id="acheckbox" style="display:none">
<br><br><br>
This is where the email options (subject and textbox) would appear.
</div>
<script>
$("#atripid").keyup(function(){
if($(this).val()) {
$("#acheckbox").show();
} else {
$("#acheckbox").hide();
}
});
</script>
But for some weird reason, it won't work anywhere else, so I can't figure out how to incorporate it into what I already have. Does anyone have any ideas that could help me? Thanks!
You can do something like this with pure javascript:
<input type="atripid" id="atripid" value="" onkeyup="keyupFunction()">
And define your keyupFunction().
See jsfiddle
The code you attempted on jsfiddle requires that you import jquery.js files. An alternate way of doung what you intend to do is
<input type='text' id='atripid' name='atripid' size='6' maxlength='6' onkeyup="toggleCheckBox(this)" />
<input type='checkbox' name='acheck' id="acheckbox" style="display:none;" onchange='copyTextValue(this);'/>
with js
function toggleCheckBox(element) {
if(element.value=='') {
document.getElementById('acheckbox').style.display = 'none';
}
else {
document.getElementById('acheckbox').style.display = 'block';
}
}
The issue is the .keyup() method, which is not consistent across browsers and does not account for other means of user input. You would rather, use an Immediately Invoked Function Expression (IIFE) that will detect the propertychange of the input field in question and then to fire the desired event if the condition is met. But for the purposes of simplicity, and the fact that I'm not as well versed enough in IIFE syntax, simply bind some events to the input field, like so:
$("#atripid").on("keyup change propertychange input paste", (function(e) {
if ($(this).val() === "") {
$("#acheckbox").hide();
} else {
$("#acheckbox").show();
}
}));
#acheckbox {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<form action="">
tripid:
<input type="atripid" id="atripid" value="">port:
<input type="aport" id="aport" value="">
</form>
<div id="acheckbox">
<br>
<br>
<br>This is where the email options (subject and textbox) would appear.
</div>
I'm new to jQuery and the .Validate jQuery Validation Plugin. I'm trying to integrate it into a multi-step form. Basically, I've set up a switch based on which next button the user presses and want to validate only that specific part of the form based on that.
When I successfully validate the first part of the form and move onto the second fieldset, the next set of fields come up already throwing validation errors. I've tried disabling the fields (which prevents the slider logic I'm using from working for some reason), specifically telling it to ignore that fieldset by class and directly declaring ignore: ":hidden" even though it's the default behavior.
I've placed the code I'm having trouble with in a jsFiddle here: http://jsfiddle.net/13x7Lbk7/4/ (updated)
Here is the specific part of my code that calls validation for the first step of the form:
$(".next").click(function(){
// Initialize form
var form = $("#frmSignup");
// Determine which step of the form we're on
switch($(this).attr("value")) {
case "step1":
$("#frmSignup").validate({
rules: {
txtZipCode: {
required: true,
number: true,
minlength: 5,
maxlength: 5,
},
txtSchoolName: {
required: true,
minlength: 5,
},
},
messages: {
txtZipCode: {
required: "Zip Code Required",
number: "Enter a valid 5 digit zip code",
minlength: "Enter a valid 5 digit zip code",
},
txtSchoolName: {
required: "School Name Required",
},
},
});
break;
// --- SNIP ---
} // End step switch
if ($("#frmSignup").valid() == true){
// Fieldset logic is here, see jsFiddle if you're curious
} // End isValid if
}); // End click function
And here is the relevant HTML for the first two fieldsets:
<fieldset class="fsStep1">
<h2>Step 1</h2>
<h3>Information</h3>
<label for="txtZipCode">Zip Code</label>
<input type="text" name="txtZipCode" value="" pattern="\d*" id="txtZipCode" required />
<label for="txtExample">Example Field</label>
<input type="text" name="txtExample" value="" id="txtExample" required />
<hr />
<button name="next" value="step1" class="next action-button">Next</button>
</fieldset>
<fieldset class="fsStep2">
<h2>Step 2</h2>
<h3>Example</h3>
<label for="txtInfo">Info</label>
<input type="text" name="txtInfo" id="txtInfo" value="" pattern="[a-zA-Z -]+" required />
<label for="txtOther">Other</label>
<input type="text" name="txtOther" id="txtOther" value="" pattern="[a-zA-Z -]+" required />
<hr />
<input type="button" name="previous" class="previous action-button" value="Previous" />
<button name="next" value="step2" class="next action-button">Next</button>
</fieldset>
I'm sure I'm missing something boneheaded here, but I keep going through the code, reviewing documentation, searching the web and I've been coming up against a blank wall all day. Please put me out of my mysery and tell me exactly why I'm stupid. :) Thank you!
Ok, if it does not like hidden fields, use this trick to hide them:
/*Hide all except first fieldset*/
#frmSignup fieldset:not(.shown) {
height:0;
overflow:hidden;
position: absolute;
top: -9999px;
}
Add the .shown class to your first fieldset.
You have no .next elements, but buttons named next.
So replace $(".next").click with $("button[name='next']").click.
Instead of if ($("#frmSignup").valid() == true), you can do if ($("#frmSignup").valid()).
And you'll need to remove the required attributes in your HTML, as hidden elements are not filled yet, so they prevent you from going to the next step. Let $.validate() do the job.
JS Fiddle Demo
I have a form with a bunch of checkboxes and input fields. I'm using jquery(1.10.1) to manipulate a number of things about the form based on user input from another form on the page. This was all working a few weeks ago but suddenly I've found that none of the checkboxes are submitting after they are changed by jquery.
The checkboxes are of the form:
<input type="checkbox" id="prod_70" name="prod[70]" class="product style_1 color_1 lens_3 status_1 " value="1" checked />
My Jquery code looks the other form to decide which boxes the user is interested in and then creates a selector based on that and the classes assigned to the checkboxes checking the boxes requested by the user:
$(curSel).prop('checked',true);
I was using:
$(curSel).attr('checked','checked').prop('checked',true);
But simplified since that shouldn't be necessary. I also tried adding a .change() for good measure but that didn't solve the problem so I took it back out.
When I submit the form none of the checked checkboxes show up and $_POST['prod'] (PHP on the backend) isn't there. $_REQUEST['prod'] is also not there. The other fields on the form are submitting. And if I submit the form without letting jquery update anything then the checkboxes do submit and $_POST['prod'] is as expected.
I've used the console in chrome and firebug in firefox to inspect the checkboxes while interacting with the page and 'checked' is being added and removed and the checkboxes are displaying correctly even when they're not submitting.
I've checked the HTML on the page to make sure everything is valid and there aren't any missing close tags or nested tags and the only other JS on the page are for FB's like button and twitters follow button.
I'm at a loss as to what could be causing this and my searches aren't turning up anything similar anymore.
EDITING TO ADD MORE:
After more debugging it appears that the problem isn't with changing the checkboxes. It's happening when the <li> that the checkboxes are in is hidden with .hide() and then reshown with .show(). After doing that the checkboxes in the <li> are never submitting even though other form elements inside the <li> are. Here's a full <li>:
<li class="prod style_1 color_1 lens_7 status_1 bulk-list-item" id="prod_55">
<div class="bulk-prod-name">
<input type="checkbox" id="prod_55" name="prod[55]" class="product style_1 color_1 lens_7 status_1 " value="1" />
<label for="prod_55">
<span class="style-name">Player</span>
<span class="color-name">Matte Black</span> |
<span class="lens-name">Rose Hi-Def LTD 17/35</span>
<span class="part-number">PLMBHD03</span>
<div style="margin-top:10px;">
<span class="bulk-prod-status">Status: <b>In Stock</b></span>
</div>
</label>
</div>
<div class="bulk-prod-image">
<div style="position:absolute; top:0;"><img style="width:100%;" src="/art/products/11/1/frame/thumb/1.png"></div>
<div style="position:absolute; top:0;"><img style="width:100%;" src="/art/products/11/1/lens/thumb/7.png"></div>
<div style="clear:both;"></div>
</div>
<div class="bulk-prod-price">
MSRP: $ <input type="text" id="prod_msrp_55" name="prod_msrp[55]" class="msrp inputbox" value="179.00" prod_id="55">
<input type="hidden" id="prod_msrp_orig_55" class="orig_price" value="179.00" orig_id="prod_msrp_55">
Dealer Price: $ <input type="text" id="prod_dprice_55" name="prod_dprice[55]" class="dprice inputbox" value="90.00" prod_id="55">
<input type="hidden" id="prod_dprice_orig_55" class="orig_price" value="90.00" orig_id="prod_dprice_55">
</div>
<div class="bulk-prod-edit">
Edit this product.
<div style="display:none" id="files_55">
<table width=100%>
<tr>
<td width=50% valign=top><small>Fullsize:<br>
<span style="color:#009900"> /art/products/11/1/frame/full/1.png</span><br>
<span style="color:#009900"> /art/products/11/1/lens/full/7.png</span><br>
</small>
</td>
<td width=50% valign=top><small>Thumbnais:<br>
<span style="color:#009900"> /art/products/11/1/frame/thumb/1.png</span><br>
<span style="color:#009900"> /art/products/11/1/lens/thumb/7.png</span><br>
</small>
</td>
</tr>
</table>
</div>
</div>
</li>
And here's the full jQuery that's hiding/showing/checking/unchecking things:
$(document).on('change', '.prod_selector', function(e) {
// console.log('Selection changed:');
e.preventDefault();
$('.prod').hide();
$('.product').prop('checked', false);
var lens = $('#lens_selector').val();
var color = $('#color_selector').val();
var style = $('#style_selector').val();
var pstatus = $('#status_selector').val();
var curSel = '';
if (lens>0) {
curSel += '.lens_' + lens;
}
if (color>0) {
curSel += '.color_' + color;
}
if (style>0) {
curSel += '.style_' + style;
}
if (pstatus>0) {
curSel += '.status_' + pstatus;
}
if ((lens==0) && (color==0) && (style==0) && (pstatus==0)) {
curSel = '.prod';
$('.product').prop('checked',true);
}
// console.log('curSel: ' + curSel);
$(curSel).show()
$(curSel).prop('checked',true);
$('#prod_count').text($('.prod:visible').length);
});
After messing with things I've determined that if I don't .hide() anything then it all work as expected (other than not hiding things that need to be hidden) but if any <li>'s are hidden then even once their shown again checkboxes inside of them don't get included in the form submission even though other input fields do.
I see a semi-colon missing:
$(curSel).show()
$(curSel).prop('checked',true);
The missing semicolon can stop the second statement from setting any checkbox as checked.
Problem solved. Turns out I was asking the wrong question. After more testing I finally determined that it wasn't jquery causing the problem after all.
The problem was more items were added to the database that this page manages which added more fields to the form and we were hitting the max_input_vars limit in the php config. Which I realized could be causing the issue after finding this: Limit of POST arguments in html or php
I raised the max_input_vars for this site and now the form is working again.