Idea
Have you ever wanted to create a way to confirm input before actually submitting the form. Automatically.
My snippet’s goal is exactly for that purpose. The idea is that it reads the form inputs and labels, and generates a modal window (like a lightbox) and asks confirmation. This project is a contribution I do to Twitter Bootstrap and jQuery-bootstrap-scripting (“dialog2”) to add on any form using Twitter Bootstrap form markup convention the capability to create a confirmation modal window.
The concept is that some forms needs to have some confirmation and requires more than “are you sure”, but also what you are submitting.
How it works
When the pages load, it executes in this order the following:
- Whether there is a form[data-behavior=confirm], and modify the form default submit button to replace it with a link (idea being that if there is no javascript enabled, you can still submit!)
- on a Click action on the newly created a.confirm-toggle, it fires up some html manipulation and creates a modal window using jQuery Bootstrap Scriptin’s Dialog2 plugin
Word of advice
I have to warn you though. The solution is not yet complete. It works well with input[type=text]
and some select
. But I need to add more field types as time goes. That’s why I created this Fiddle to give room for improvement. Feel free to collaborate. When the solution will be strong enough, i’ll contribute it to both projects in their respective syntax (dialog2
doesnt initialize the same way as Bootstrap’s modal()
Known limitations
- Works only with
select
andinput[type=text]
, and breaks bad withradio
andcheckbox
- Works only with ONE form in the page, for now.
¨
The code
You can play with this Fiddle in the meantime i make it ready-er
The javascript
/** * Use form's content into a confirmation modal * * Using: http://nikku.github.com/jquery-bootstrap-scripting/ * Requires: Twitter Bootstrap, dialog2 * * @author: Renoir Boulanger */ if ($('form[data-behavior=confirm]').length >= 1) { console.log('run.js: document ready : Applying confirmation, ' + $('form[data-behavior=confirm]').length + ' times'); $('form[data-behavior=confirm] select').click(function() { var dataValue = $(this).find(':selected').text(); $(this).attr('data-value', dataValue); // Debug console console.log('Adding data-value at: ' + dataValue); }); $('form[data-behavior=confirm] .confirm-toggle').replaceWith('<input id="confirm-submit" type="submit" class="is-hidden"/>' + '<a href="#" class="confirm-toggle btn btn-primary">Continue</a>'); /** * Since we know javascript is executed so far, lets handle it with the confirmation. * * That way, no javascript-enabled browsing user will be able to use the form. #progressiveEnhancement * * Do the work. */ $('form[data-behavior=confirm] .confirm-toggle').click(function(event) { event.preventDefault(); // Get form content var form = $('form[data-behavior=confirm]').clone().attr('id', 'cloned'); //.appendTo('body'); var i = 0; form.find(':input:not([type=hidden])').each(function() { var field = $(this); if (field.is('select')) { fieldValue = $(this).attr('data-value'); if (fieldValue === undefined) { fieldValue = field.find(':selected').html(); // Debug console console.log('fieldValue was undefined, setting to : ' + fieldValue); } // Debug console console.log('fieldValue is : ' + fieldValue); } else { fieldValue = field.val(); } // Remove undefined field (they are useless) if (fieldValue === '') { field.parent().parent().addClass('empty-field-resolved'); } // Debug console console.log('Field ' + i + ' :' + fieldValue + ' for #' + field.attr('id')); // Wrap fieldValue in a tag, Tested in IE7!! field.after($('<span class="value">' + fieldValue + '</span>')); // Remove the field itself, we only want to see the resulting field.remove(); i++; }); // Work stuff out for modal window, copying content, and building modal into the DOM var decorate = $("<div id=\"modal-placeholder\"><div class=\"modal-builder\"></div></div>"); var buildup = decorate.find(".modal-builder").html(form); buildup.appendTo('body'); // Debug console console.log('Appending #modal-placeholder in body, ready to call dialog2()'); // Remove not needed anymore stuff $('.modal-builder .help-block, .modal-builder .input-append, .modal-builder .form-actions').remove(); $('.modal-builder').dialog2({ title: "Are you sure?", id: "confirm-modal", modalClass: "modal-wide fade in", closeOnOverlayClick: false, closeOnEscape: false, initialLoadText: "Loading in progress...", buttons: { Confirm: { primary: true, click: function() { // Debug console.log('Inside dialog2() clicked Confirm'); $('#confirm-submit').click(); } }, "Forgot something": { click: function() { // Debug console.log('Inside dialog2() clicked cancel'); $(this).dialog2("close"); $('.modal').remove(); return false; } } } }); // Do my own cleanup. Remove potentially bogus nodes $('#modal-placeholder, .modal-header .close, .control-group.empty-field-resolved').remove(); }); } |
The CSS
Minimally…
.modal-wide { overflow:visible; width: 650px; } .modal-builder .control-label { padding:0 !important; font-weight:bold; } /* In case you use a span.required-star * with title="required field", I don't want to * have them in modal **/ .modal-builder .required-star { display:none; } .modal-builder .hide-in-confirm { display:none !important; } |
Tell me in the comments if you want the LESS block I created
The Form
Always using Twitter Bootstrap markup, A form minimally needs
What is really required here is
- Form tag has data-behavior="confirm" attribute
- Form submit button has at least the class name confirm-toggle
Just use any combination of Twitter Bootstrap Form patterns
<form class="form-horizontal" method="post"> <fieldset> <div class="control-group hidden-in-confirm"> <!-- This block will be hidden --> <label class="control-label" for="input01">Text input</label> <div class="controls"> <input id="input01" class="input-xlarge" type="text" /> In addition to freeform text, any HTML5 text-based input appears like so.</div> </div> <!-- ... the form ... --> <div class="form-actions"> <button class="btn">Cancel</button> <input class="btn btn-primary confirm-toggle" type="submit" value="Continue" /></div></fieldset> </form> |
Possible enhancements paths
My solution fit for what I needed. A two parameters to add confirm in a modal using the project’s markup. Sadly I read after doing it that there is some plugins I could have considered such as the Form plugin
.
End word
I am going to prepare this post and propose a pull request to the jQuery Bootstrap Scripting AND Bootstrap project in a day or two.
Ressources
- http://nikku.github.com/jquery-bootstrap-scripting/#
- http://twitter.github.com/bootstrap/base-css.html#forms
Comments
Daniel Gauthier
Salut Renoir,
Belle page, beaucoup d’ouverture et d’aide de ta part.
Prends-soin.
Daniel.