I'm using the jQuery validation plugin and I'm looking to add some custom logic. I have a series of checkboxes which have children checkboxes associated with them. For certain (not all) of these parent checkboxes, I want to require that one of the children checkboxes is checked. I have no issue hardcoding for this so I was adding a field like this to my DOM:
<input type="hidden" id="child_required_1" class="child_required_1" />
And then adding a custom validator like this:
jQuery.validator.addMethod('child_required_1', function(val, element) {
if($('#product_responses_1').length > 0) {
if($('#product_responses_1').is(':checked')) {
var count = $("input:checkbox:checked[id^='children_tags_1_']").length;
if(count == 0) {
return false;
}
}
}
return true;
}, 'You must select at least one child.');
This works perfectly fine. But when I duplicate all of this and add "_2", only one of the validators seems to fire. So from what I can gather, custom validators are unique per form? If that's the case, how am I supposed to handle a situation like this where I may need 15-20 of these all showing in different places? I don't want to just show one error.
I could also create a class rule but that doesn't solve my problem of creating multiple error labels and placing them in the relevant positions.
Apparently having it on a hidden field didn't work, but when I removed the hidden fields and applied that class to the actual checkboxes themselves, it worked fine. Not entirely sure why.
Related
I am looking for some help on how to validate radio buttons generically across multiple screens and make the script reusable. I have manage to get it working by using a single class $('.radio_validate'). However, if I want to reuse the script for any other pages I would have to duplicate the script which is not ideal.(I'm not super familiar with JS so appreciate any support on this.)
Here's the code specifically on the radio button validation. Basically adding the error class if not checked and remove the error class if checked. Ideally, I would like to make $('.radio_validate') into something that is reusable if possible.
if( $('.radio_validate').is(':visible') && !$('.radio_validate').is(':checked') ){
$('.radio_validate')
.closest('.form__item')
.addClass('error');
shakeCurrentCard( $('.radio_validate').closest('.step') );
//return false;
}
else {
$('.radio_validate')
.closest('.form__item')
.removeClass('error');
}
If you plan on having every single radio button validated no matter the page, then use:
$("input[type='radio']")
However, if you don't want all of the radio buttons to be validated, then adding a class or data-attribute, to the radios you want validated is the best option.
loops through the radio instead of doing them all at once:
$("input[type='radio']").each(function() {
if ($(this).is(':visible') && !$(this).is(':checked')) {
$(this)
.closest('.form__item')
.addClass('error');
shakeCurrentCard($(this).closest('.step'));
//return false;
} else {
$(this)
.closest('.form__item')
.removeClass('error');
}
});
I have an HTML input field where certain characters shouldn't be allowed. The functional part is solved, but I would like to display a tooltip/message next to the input field while it contains illegal characters.
I have a boolean which keeps track of this, but I've been unable to make a satisfactory tooltip/message.
I've tried tweaking uib-tooltip, but It requires the user to hover over the input area. I've tried making a span/div/label that's hidden/displayed based on the boolean, but my CSS skills aren't strong enough.
The app uses Angularjs and Bootstrap 3.
The input field is not part of a form.
where you catch that boolean just say to display the div next to input like
myDiv.visible = true;
Without knowing your exact Javascript, I can't really answer it directly.
I would do something like
function invalid() {
if (invalid = true) {
document.getElementById("alert").style.visibility = 'visible'
}
}
make sure the error message is set to hidden,
then have the checker function run on focus..
<input type="text" onfocus="invalid()">
https://jsfiddle.net/we67geke/1/
This comment by user Lex solved the problem.
You can manually set the visibility of the uib-tooltip using the
tooltip-is-open attribute. Simply use the same boolean you are using
to keep track of the invalid characters.
As you mentioned
The app uses Angularjs and Bootstrap 3.
I suggest that you should use Boostrap tooltip. Use $('#element').tooltip('show') and $('#element').tooltip('hide') with your flag to handle status of Tooltip.
I don't know how your codes work, my idea seems like:
HTML:
<input type=text (keypress)="eventHandler()"> // angular >= 2
<input type=text ng-keypress="eventHandler()"> // angular 1
Angular code:
eventHandler() {
if (isIllegal) {
$('#element').tooltip('show');
} else {
$('#element').tooltip('hide');
}
}
Something like that.
Bootstrap Tooltip: https://getbootstrap.com/docs/3.3/javascript/#tooltips
I need to validate the selection of at least one check box on a table. I am not using an alert because I already have a class on CSS that highlights in red the inputs, selects and other elements if they are not filled out.
This is my JS:
var btnRegister= document.querySelector('#btnRegisterRegObr');
btnRegister.addEventListener('click', function () {
var bError= false;
//I am initializing this boolean variable so that it also shows an error
//message on the screen if the user has not selected any option at all...
var elementCheckRegObr = document.querySelector('#checkRegObr');
if (elementCheckRegObr.checked==false){
bError=true;
elementCheckRegObr.classList.add('error');
//This part of the code brings the error I have
//previously created on CSs if the checkbox is not checked
}
else{
elementCheckRegObr.classList.remove('error');
}
});
The button on HTML has the right id on the HTML: id="btnRegisterRegObr.
I was looking at some codes here and people were validating using the .checked==false
However this does not seem to work for mine.
As a matter of fact, I first thought I needed to use the syntax of if (elementCheckRegObr.checked=="") but that one does not seem to work either.
I dont have problems validating inputs, selects nor radio buttons, but I am not sure if I am doing it on the right way with the check boxes. Any help or advice would be greatly apprecciate it :)
I suggest that you use getElementById to get your elements, and test if the checkbox is checked this way:
if(document.getElementById('idOfTheCheckBox').checked){
alert('hey, im checked!');
}
I am using Dojo labels and checkboxes in one of my app inside smarty file. I want to add a certain behavior to uncheck a checkbox, if any other checkbox is checked. I also check if that checkbox is originally checked, it will uncheck the same. (I do not want to use radio button)
Here is my code for one CheckBox:
<input id="form.cs"
data-dojo-type='dijit.form.CheckBox'
type="checkbox"
data-dojo-props="value:'true', type:'checkbox', name:'cs', style:'vertical-align: top'"
onChange="if(dijit.byId('form.cs"').checked)
dijit.byId('form.cs"').set('checked', false);
else
dijit.byId(' form.nl"').set('checked', false);"
/>
The problem with code is when i add curly braces, this is not rendered by smarty engine and throws error.
For example :
onChange="if(dijit.byId('form.cs"').checked) {
dijit.byId('form.cs"').set('checked', false); }
else {
dijit.byId(' form.nl"').set('checked', false);"}
The above code snippet will create a breakdown in the smarty.
I recommend writing your event handler in JavaScript. If you're going to write all your event handlers as attributes you're going to have a lot of problems like code validation, ... .
You could write a loop that actually loops over all checkboxes, setting the value to the opposite of the changed value (so if one checkbox becomes true, the other ones must become false).
To do this you could write a simple function like this:
var toggleCheckboxes = function(myNode, value) {
query("input[type=checkbox]").forEach(function(node) {
if (node !== myNode) {
registry.getEnclosingWidget(node).set("value", !value, false);
}
});
};
The dojo/query module allows you to get a list of all nodes matching the given selector. With the dijit/registry module you can retrieve the actual widget behind the DOM node and then you just set the value using:
registry.getEnclosingWidget(node).set("value", !value, false);
The third parameter (set to false) is actually very important. This parameter will prevent further event invocations. If you don't put that parameter there it will actually trigger another onChange, causing an infinite loop.
Now the only thing you need to do is bind an onChange event handler to each checkbox that calls this function, you can also to that with the dojo/query and dijit/registry module, for example:
query("input[type=checkbox]").forEach(function(node) {
registry.getEnclosingWidget(node).on("change", function(value) {
toggleCheckboxes(node, value);
});
});
A complete example can be found on JSFiddle.
But I still recommend using a radiobutton. I think you can actually say this is a bad UI design, a checkbox and a radiobutton have different goals, use them for what they're meant to.
I've got a form with a bunch of textboxes that are disabled by default, then enabled by use of a checkbox next to each one.
When enabled, the values in these textboxes are required to be a valid number, but when disabled they don't need a value (obviously). I'm using the jQuery Validation plugin to do this validation, but it doesn't seem to be doing what I expect.
When I click the checkbox and disable the textbox, I still get the invalid field error despite the depends clause I've added to the rules (see code below). Oddly, what actually happens is that the error message shows for a split second then goes away.
Here is a sample of the list of checkboxes & textboxes:
<ul id="ItemList">
<li>
<label for="OneSelected">One</label><input id="OneSelected" name="OneSelected" type="checkbox" value="true" />
<input name="OneSelected" type="hidden" value="false" />
<input disabled="disabled" id="OneValue" name="OneValue" type="text" />
</li>
<li>
<label for="TwoSelected">Two</label><input id="TwoSelected" name="TwoSelected" type="checkbox" value="true" />
<input name="TwoSelected" type="hidden" value="false" />
<input disabled="disabled" id="TwoValue" name="TwoValue" type="text" />
</li>
</ul>
And here is the jQuery code I'm using
//Wire up the click event on the checkbox
jQuery('#ItemList :checkbox').click(function(event) {
var textBox = jQuery(this).siblings(':text');
textBox.valid();
if (!jQuery(this).attr("checked")) {
textBox.attr('disabled', 'disabled');
textBox.val('');
} else {
textBox.removeAttr('disabled');
textBox[0].focus();
}
});
//Add the rules to each textbox
jQuery('#ItemList :text').each(function(e) {
jQuery(this).rules('add', {
required: {
depends: function(element) {
return jQuery(element).siblings(':checkbox').attr('checked');
}
},
number: {
depends: function(element) {
return jQuery(element).siblings(':checkbox').attr('checked');
}
}
});
});
Ignore the hidden field in each li it's there because I'm using asp.net MVC's Html.Checkbox method.
Using the "ignore" option (http://docs.jquery.com/Plugins/Validation/validate#toptions) might be the easiest way for you to deal with this. Depends on what else you have on the form. For i.e. you wouldn't filter on disabled items if you had other controls that were disabled but you still needed to validate for some reason. However, if that route doesn't work, using an additional class to filter on (adding and removing with your checkboxes) should get you to where you want to go, but easier.
I.e.
$('form').validate({
ignore: ":disabled",
...
});
Usually when doing this, I skip 'depends' and just use the required jQuery Validate rule and let it handle the checking based on the given selector, as opposed to splitting the logic between the validate rules and the checkbox click handler. I put together a quick demo of how I accomplish this, using your markup.
Really, it boils down to required:'#OneSelected:checked'. This makes the field in question required only if the expression is true. In the demo, if you submit the page right away, it works, but as you check boxes, the form is unable to submit until the checked fields are filled with some input. You could still put a .valid() call in the checkbox click handler if you want the entire form to validate upon click.
(Also, I shortened up your checkbox toggling a bit, making use of jQuery's wonderful chaining feature, though your "caching" to textBox is just as effective.)
Depends parameter is not working correctly, I suppose documentation is out of date.
I managed to get this working like this:
required : function(){ return $("#register").hasClass("open")}
Following #Collin Allen answer:
The problem is that if you uncheck a checkbox when it's error message is visible, the error message doesn't go away.
I have solved it by removing the error message when disabling the field.
Take Collin's demo and make the following changes to the enable/disable process:
jQuery('#ItemList :checkbox').click(function()
{
var jqTxb = $(this).siblings(':text')
if ($(this).attr('checked'))
{
jqTxb.removeAttr('disabled').focus();
}
else
{
jqTxb.attr('disabled', 'disabled').val('');
var obj = getErrorMsgObj(jqTxb, "");
jqTxb.closest("form").validate().showErrors(obj);
}
});
function getErrorMsgObj(jqField, msg)
{
var obj = {};
var nameOfField = jqField.attr("name");
obj[nameOfField] = msg;
return obj;
}
You can see I guts remove the error message from the field when disabling it
And if you are worrying about $("form").validate(), Don't!
It doesn't revalidate the form it just returns the API object of the jQuery validation.
I don't know if this is what you were going for... but wouldn't changing .required to .wasReq (as a placeholder to differentiate this from one which maybe wouldn't be required) on checking the box do the same thing? If it's not checked, the field isn't required--you could also removeClass(number) to eliminate the error there.
To the best of my knowledge, even if a field is disabled, rules applied to it are still, well, applied. Alternatively, you could always try this...
// Removes all values from disabled fields upon submit
$(form).submit(function() {
$(input[type=text][disabled=disabled]).val();
});
I havent tried the validator plugin, but the fact that the message shows for a splitsecond sounds to me like a double bind, how do you call your binders? If you bind in a function try unbinding just before you start, like so:
$('#ItemList :checkbox').unbind("click");
...Rest of code here...
Shouldn't validate the field after disabling/enabling?
jQuery('#ItemList :checkbox').click(function(event) {
var textBox = jQuery(this).siblings(':text');
if (!jQuery(this).attr("checked")) {
textBox.attr('disabled', 'disabled');
textBox.val('');
} else {
textBox.removeAttr('disabled');
textBox[0].focus();
}
textBox.valid();
});
I had the exact same problem.
I solved this by having the radio-button change event handler call valid() on the entire form.
Worked perfect. The other solutions above didn't work for me.