Submit checkboxes with "Check All" button and clear validation error - twitter-bootstrap-3

Through much trial and error (mostly error), I have managed to incorporate jQuery Validate, Bootstrap 3 (using Popovers for validation messages), and DataTables to create I suspect a fairly common scenario:
A DataTable that contains a column of checkboxes, and offer a "check all" checkbox that selects all the checkboxes across pagination and filtering in a DataTable, and apply jQuery Validate to ensure a user doesn't submit without choosing at least one checkbox.
Here's a link to a live example of what I'm doing: http://live.datatables.net/lomelono/2/
It works (the script picks up all the checked checkboxes (either via the check all checkbox, or if manually chosen, and across pagination and filtering on the DataTable), and will validate if no checkbox is chosen.
What it doesn't do is:
Clear the validation error if the check all checkbox is chosen
Another odd side effect by using .appendTo() to ensure all checked checkboxes across pagination/filtering are chosen for submit is all the checkboxes (checked or unchecked) will appear at the bottom of the form before submit (the submit is disabled on the example so you can see the behavior).
Obviously I know just enough jQuery to be dangerous, but is there a better way to submit all the checked checkboxes, AND ensure client-side validation works correctly? Of course, I have a server-side catch, but ideally we want to inform the user BEFORE they submit.
I think I am really close to solving this, and hopefully someone can point me towards the finish line, that will hopefully benefit others who have this kind or similar sort of scenario.

SOLUTION
You may need to turn those <input type="checkbox"> that are checked and don't exist in DOM into <input type="hidden"> upon form submission.
For example:
$("#emailCompose").validate({
submitHandler: function(form) {
// Iterate over all checkboxes in the table
table.$('input[type="checkbox"]').each(function(){
// If checkbox doesn't exist in DOM
if(!$.contains(document, this)){
// If checkbox is checked
if(this.checked){
// Create a hidden element
$(form).append(
$('<input>')
.attr('type', 'hidden')
.attr('name', this.name)
.val(this.value)
);
}
}
});
//form.submit();
},
// ... skipped ...
});
DEMO
See jQuery DataTables: How to submit all pages form data for more details and demonstration.

Related

Quasar QSelect popup and input text persistent on click

I am trying to set up a QSelect driven by user input in order to achieve an "autocomplete" behavior. There are a few examples on the official documentation and they make use of the #filter callback.
I have currently two problems:
Whenever I click outside of the input field the input text is lost and the popup disappears.
If I click on the input the current text remains, but the pop is hidden until I click on it again.
For the latter issue, one workaround is to force the popup to show upon click:
<q-select
ref="input"
...
#click.native.prevent="onClick"
>
...
onClick(){
if( this.searchFilter.length > 0){
this.$refs.input.showPopup()
}
}
However, the inconvenience is that the popup still shortly disappears for a short while before showing again. I've also tried using #click.native.stop instead of #click.native.prevent to no avail.
As for issue number 1 I haven't even found a workaround yet.
Here is a related issue, though the popup disappearing was a wanted behavior in his case.
I set up a basic Pen to illustrate the issue. Try clicking on the input or outside the input at the same height.
The trick was to use #click.capture.native and then conditionally stop the propagation inside the callback function via event.stopImmediatePropagation() See it working here

Access to a function\$refs in another component not in the same level as current one

I've a Vue 2 application, with different components nested.
Their structure is kinda (I'm skipping the not-relevant ones for my question):
<root>
<app>
<component1/>
...
<component3>
<billingAddress>
<customForm/>
</billingAddress>
<shippingAddress>
<customForm/>
</shippingAddress>
</component3>
...
<lastComponent/>
</app>
</root>
The customForm1 and 2 contain a form, validated via vee-validate - so there' a ValidationObserver component.
Those two forms are validated at the relative submit - the submit action is custom, when they are successfully validated, they are hidden - and there is no redirect.
On the "lastComponent" there's a "submit" button whichis disabled until both form are correctly submitted and which does some other logic.
Today I've been asked to change the behaviour of that button: now it may launch the validation and the submit of those two form, skipping so the "manual" submission of the users.
I'm not sure how can handle this, as the ValidationObserver and the custom actions are in components unrelated to the "lastComponent".
For now, I've managed traversing the tree of $refs starting from $root, but I don't really like an approach so fragile.
This is what I'm doing in my "submit" action:
let shippingAddressValid = await this.$root.$children[0].$refs.addresses.$refs.shippingAddress.$refs.addressForm.$refs.shippingAddressForm.validate();
if (shippingAddressValid) {
await this.$root.$children[0].$refs.addresses.$refs.shippingAddress.$refs.addressForm.updateAddress();
}
I'd like to know if there's a better approach.
I've found this anweser that is interesting. However, I haven't found a way to set up a custom event via "global bus" that returns me a value, asynchronously.
I mean, it's mandatory, to get the "valid" state of the form, before calling the submit method.
I can't just call the validation in the method, because I have to do some logic if the form is invalid.

How to disable the button if some input field is not filled?

IBM web experience factory uses dojo library, I am wondering if the I set <input type="text" name="usrname" required> in the consumer model, does the button still work if the input is not filled?
Well, HTMLFormElement has a method called checkValidity() which you can use.
So, in your case, you could use the :input selector with dojo/query to query all input elements inside a form (includes buttons, checkboxes, textfields, text areas and select boxes) and then use the onChange event to check if the form is valid and change the buttons disabled attribute.
For example:
query("[name=myForm] :input").on("change", function(evt) {
var isInvalid = !evt.target.form.checkValidity();
query("button[type=submit]").attr("disabled", isInvalid);
});
Now all you need to do is to make sure that your button is initially disabled/enabled depending on the initial state of the form.
A full example can be found on JSFiddle: http://jsfiddle.net/j8L6j77g/

Reconnecting multiple Ajax.BeginForms when dynamically loading the forms

I have a long form made up of multiple sections, each with its own questions. Each section can be saved independently with an <input type="submit" value="Save" /> button.
Each section is loaded dynamically into the page (and there are a variable number of sections).
Each form is authored separately as an Ajax.Begin() ajax form, but with dynamic loading of the forms it appears UnobstrusiveJavaScript will not bind the submit buttons and they perform a standard postback.
What is the simplest way to reconnect the ajax functionality of the submit buttons?
After checking the source of UnobstrusiveJavaScript (which is quite small) it leaves permanent event handlers using .on('submit') so it should just work with dynamically loaded pages.
Turns out the master form was missing the inclusion of UnobstrusiveJavaScript:
#Scripts.Render("~/bundles/jqueryval")
Worth checking fiddler when this sort of thing occurs :)

disabling a submit button till validation

Is there a way using dojo/dijit to disable the submit button till all the fields in a form are valid. Kind of like having a dojo > method > onChange inside the form? So the submit button only becomes enabled when all the form elements have meet their criteria?
Are you using a dijit.form.Form widget as your form? If you are, I would suggest connecting to the Form's onValidStateChange event. The docs for this event specifically state your use case:
onValidStateChange
Defined by dijit.form._FormMixin
Stub function to connect to if you want to do something (like disable/enable a submit button) when the valid state changes on the form as a whole. Deprecated. Will be removed in 2.0. Use watch("state", ...) instead.
The best way to see what events are available for a given widget is to look at the API Documentation for the widget you are interested in under the "Event Summary" heading. The dojocampus reference documentation often leaves out examples for references to some of the more obscure features of the widgets.
I would suggest to have a hidden button which will submit the form. When you click visbile button run a javascript function that validates all the input and then clicks on the hidden button to submit the form. Please find the pseudo code below
<form action="register">
<input dojoType="dijit.validation.TextBox"/>
<button onClick="validateall()">submit</button>
<button id="submitForm" type="submit" hidden="true"/>
</form>
function validateAll(){
if(AllOk){
clearErrorMessage();
dojo.byId('submitForm').click();
}else{
showErrorMessage();
}