Confirm form before submitting using Twitter Bootstrap in a Modal window [Snippet]
favourites patterns twitter-bootstrap - 📁 programmation
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('' + 'Continue');
/**
* 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($('' + fieldValue + ''));
// 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 = $("");
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
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