Foundation 6 Abide - How to implement formnovalidate - html

I have a form that is using Abide. The form has two buttons, both are type="submit" but one has the formnovalidate attribute set. This button is for "previous step" as it takes whatever the user has filled in and submits the form, taking the user to the previous step of the form.
The issue is that abide validation still kicks in when the user clicks cancel preventing the user to go back, until he has filled in all the fields on the current step. HTML5 validation has formnovalidate attribute exactly for this use case. Is there a way to "ignore/skip" the abide validation when the cancel button is clicked?
Issue link on github: https://github.com/zurb/foundation-sites/issues/11426#issuecomment-441956255

Resolved in the github issue. Currently there is no native support for this by Foundation. A workaround is to rewrite the submit handler in Foundation JS. I did it like this:
.on( "submit.zf.abide", function( e ){
var $btn = $(document.activeElement);
if (
/* there is an activeElement at all */
$btn.length &&
/* it's a child of the form */
t.$element.has($btn) &&
/* it's really a submit element */
$btn.is('[type="submit"]') &&
/* it has a "formnovalidate" attribute */
$btn.is('[formnovalidate]')
) {
return true;
}else{
return t.validateForm()
}
})

Related

Angular 4 : disable button as long as form not validated

I have a form with required fields and 2 buttons : first button submits the form and another button is to download the file.
On the one hand, as long as form is not valid, the submit button is disabled (and it enables when the form is valid) :
component.html :
<button type="submit" [disabled]="!formGroupTest.valid" >Valider</button>
=> It works
On the other hand, as long as form is not valid, the "download" button is disabled and it enables when : form valid AND button submit is clicked :
component.html :
<button [disabled]="!formGroupTest.valid || !buttonSubmitEnabled">Download</button>
For that, in component.ts, i initialize a boolean at false, and it becomes true when button submit clicked (method sendForm()) :
private buttonSubmitEnabled: boolean = false;
sendForm() {
this.buttonSubmitEnabled=true;
}
When I fill the form for the first time, it works perfectly => I click on the submit button and the download button becomes enable. However, after the first time, if I decide to change required fields and it returns the form as invalid, the 2 buttons are disabled (logically), but when I fill the fields correctly then the "download" button becomes enable. I understood the problem, because the 2 conditions to enable the button download are respected : Form valid AND button submit clicked once.
So, what if I want it to work every time, I think it's necessary to put the Boolean "buttonSubmitEnabled" at false each time the form is invalid, but I don't know how to do it.
FormGroup has a valueChanges property that you can subscribe to. Every form change will trigger this observable. You can use this to reset the submission boolean.
this.myForm.valueChanges.subscribe(x => this.buttonSubmitEnabled = false);
In keyup event of those input fields call a function disableDownload()
<input (keyup)="disableDownload()">
And inside disableDownload(), just make download buttonSubmitEnabled false
disableDownload() {
this.buttonSubmitEnabled = false;
}
Only make the buttonSubmitEnabled true once the form is submitted

Toggle switch to pass unchecked value

I'm using a checkbox to create a toggle switch as shown in this tutorial
The switch lives in a form where questions can be added dynamically. On submission the form posts as array of each answer back to the page to be processed however as the off switch doesn't pass a value back to the form the answers get out of sync with the answers for the other text fields. Is there any way to set a value for the off switch, i.e. when a check box is left unchecked?
I've tried to use the following to set my off checkboxes to off however it just seems to animate all the switches to on on form submission, anyone any ideas as to what I'm doing wrong?
$('form').submit(function(e){
var b = $("input:checkbox:not(:checked)");
$(b).each(function () {
$(this).val(0); //Set whatever value you need for 'not checked'
$(this).attr("checked", true);
});
return true;
});
You probably want to use Javascript to set a value for each checkbox "switch" in one of two ways:
Option 1: in the html of the switch elements/checkboxes, set the value attribute to zero by default. Then add a javascript click handler for the toggle to check its current value and toggle to the opposite state/value.
Option 2: add Javascript to the form's submit handler (on submit) that checks for any switch elements which have no values and set them to zero before processing form.
Either way should pass a value at all times, and your form should be able to keep track of all input states.
This snippet did the trick, as Anson suggested this finds all the checkboxes and sets them to either on or off on form submission:
$('form').submit(function () {
$(this).find('input[type="checkbox"]').each( function () {
var checkbox = $(this);
if( checkbox.is(':checked')) {
checkbox.attr('value','1');
} else {
checkbox.after().append(checkbox.clone().attr({type:'hidden', value:0}));
checkbox.prop('disabled', true);
}
})
});

How to make two checkboxes required out of three in HTML?

<input type="checkbox" name="Package1" value="packagename">
<input type="checkbox" name="Package2" value="packagename">
<input type="checkbox" name="Package3" value="packagename">
How to make any two checkboxes required for the user to submit the form. The user should not be able to submit the form unless he has checked atleast two checkboxes?
How to achieve that?
Rename checkboxes to name=package[] and values 1, 2, 3.
Then in PHP you'll have o condition (if you send form with GET method, just change POST to GET):
if (isset($_POST['package']) && count($_POST['package']) >= 2) {/* continue */}
If you want to validate it in browser (JS), than:
<script>
var i = 0;
$('[type="checkbox"]').each(function() {
if ($(this).is(':checked')) {
i++;
}
});
if (i <= 1) {
return false; // disable sending form when you've checked 1 checkbox in maximum
}
</script>
Add a class that refers only these checkboxes and then count how many are checked.
A quick and dirty way to validate the checkboxes using JavaScript:
JavaScript
checkCheckboxes = function() {
var numberOfCheckedCheckboxes = 0;
var checkbox1 = document.getElementsByName("Package1")[0];
var checkbox2 = document.getElementsByName("Package2")[0];
var checkbox3 = document.getElementsByName("Package3")[0];
if (checkbox1.checked)
{
numberOfCheckedCheckboxes++;
}
if (checkbox2.checked)
{
numberOfCheckedCheckboxes++;
}
if (checkbox3.checked)
{
numberOfCheckedCheckboxes++;
}
alert(numberOfCheckedCheckboxes >= 2);
}
DEMO: JSFiddle
This code isn't the cleanest block of code, however it does get the job done, and will return true if there are at least 2 checkboxes checked, and will return false otherwise. To make it cleaner, you can change the name value of each checkbox to the same name, such as "packages", and then use document.getElementByName("packages"), then use a for-each loop to loop through each element and check its checked state (I would provide a demo in JSFiddle or JSBin, however it seems that Google Chrome is blocking the script in that case). Using the for-each implementation would allow you to use the same amount of code, regardless of the number of checkboxes.
In HTML, you cannot.
You can impose restrictions in client-side JavaScript or in server-side processing of form data, or both. As usual, client-side restrictions are inherently unreliable and should be regarded as convenience to the user, not a reliable method of doing anything. Server-side processing depends on the server-side technology used.

<button> with form attribute does not work on IE

my question is why something like that:
<form id="aaa" action"xxx">
</form>
<button form="aaa" type="submit">Button</button>
does work in Firefox,Opera,Chrome and does NOT work in IE 11 and mobile devices with Windows system? Example above does nothing, button seems not to belongs to form.
thank You in advance.
As already mentioned, the button should ideally be within the form. However, one way to proceed, with the button outside of the form, is to have the button trigger the form submit via JavaScript.
A quick and dirty jQuery example to illustrate:
$('button[form="aaa"]').click(function()
{
$('#aaa').submit();
});
You can replace this with an in-line onclick="" attribute on the button element if preferred.
This question is old but I thought I'd share how I got this working with a React app. I needed the onSubmit callbacks to be run when a form was submitted, and that wasn't happening when calling submit directly on the form. Here was my quick solution to the problem. It only accounts for buttons outside of the form:
/**
* Is the [form] attribute supported?
*/
const isSupported = (() => {
const TEST_FORM_NAME = 'form-attribute-polyfill-test';
const testForm = document.createElement('form');
testForm.setAttribute('id', TEST_FORM_NAME);
testForm.setAttribute('type', 'hidden');
const testInput = document.createElement('input');
testInput.setAttribute('type', 'hidden');
testInput.setAttribute('form', TEST_FORM_NAME);
testForm.appendChild(testInput);
document.body.appendChild(testInput);
document.body.appendChild(testForm);
const sampleElementFound = testForm.elements.length === 1;
document.body.removeChild(testInput);
document.body.removeChild(testForm);
return sampleElementFound;
})();
/**
* If it's not, listen for clicks on buttons with a form attribute.
* In order to submit the form and have all the callbacks run, we insert
* a button, click it and then remove it to simulate a submission from
* inside the form.
*/
if (!isSupported) {
window.addEventListener('click', e => {
const {target} = e;
const formId = target.getAttribute('form');
if (target.nodeName.toLowerCase() === 'button' && formId) {
e.preventDefault();
const form = document.getElementById(formId);
const button = document.createElement('button');
form.appendChild(button);
button.click();
form.removeChild(button);
}
});
}
A submit button is generally used to submit data from a form to the server (JavaScript not taken into account). As the button in your example is not part of the form, it has no associated data to submit.
EDIT: After noticing the form attribute, the user JayC's answer is correct. Internet Explorer does not support that attribute on buttons, whereas the other browsers do. Its a part of the HTML 5 standards which has not been implemented yet.

Rails: Disabling an image_submit_tag

I have a button on my signup form, like such:
<%= image_submit_tag('/assets/atmosphere_forward.png', :class => "signup_submit_button")%>
When the user clicks it, there's a delay of a few seconds while the form is being processed. How can I change the image of submit button while this is occurring (similar to using :disable_with with other tags)?
Or, alternatively, how can I add a field to my form that only appears when the form is processing (which could contain "Please Wait" or something similar)?
I don't think that the Rails UJS tools are enough to change the state of an input field, add/remove a class or show and hide properties. You will have to use JavaScript.
form = $('#your_form');
form.submit(function(event) {
//change the button
var btn = form.find('input[type="submit"]');
btn.image = '...';
//setup the please wait message
var message = $('<div class="please-wait">Please Wait...</div>');
form.append(message);
});
I do suggest for the form button you use CSS and then just change the class within your submit event.