I have been trying to figure this out for two days, but I really do need some help on this problem.
I have a html form that has a submit button with a conditional js confirmation pop up that is working but I want to change the conditional js confirmation pop up with a bootstrap modal to fit in with the rest of my project.
When the form is submitted and the value of a html select list on the form has changed, then the conditional js confirmation pop up will display. The user must click the OK button on the js confirmation pop up for the form submission to proceed.
Or else if the html select list has not changed the js confirmation pop up will not display and the form will submit.
Here is my working form code:
<form id="language_view_form" class="form-horizontal" action="{% url language_view %}" method="post">
Here is my working button code inside the form:
<input id="submit_button" onclick="if(confirmChangeLanguage())showProgressAnimation();else return false;" type="submit" value="Update" />
Here is the working js code:
function confirmChangeLanguage() {
if ($('#id_language_code').val() != '{{ user.get_profile.language_preference }}') {
return confirm("Are you sure you want to change the language?");
} else {
return true;
}
}
The above code is working, but I am trying to replace the js confirmation pop up code with a bootstrap modal to fit in with the rest of my project and I have encountered some issues that has really confused me.
Here is the bootstrap modal code that displays the modal confirmation:
$('a[update-confirm]').click(function(ev) {
var href = $(this).attr('href');
if (!$('#updateConfirmModal').length) {
$('body').append('<div id="updateConfirmModal" class="modal modal-confirm-max-width modal-vertical-centered" role="dialog" aria-labelledby="updateConfirmLabel" aria-hidden="true"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button><h4 class="modal-title" id="updateConfirmLabel">{% trans "Confirm Language Change" %}</h4></div><div class="modal-body"></div><div class="modal-footer"><button class="btn" data-dismiss="modal" aria-hidden="true">{% trans "Cancel" %}</button> <a class="btn-u btn-u-blue" id="updateConfirmOK" onclick="showProgressAnimation();">{% trans "Update Langauge View" %}</a></div></div>');
}
$('#updateConfirmModal').find('.modal-body').text($(this).attr('update-confirm'));
$('#updateConfirmOK').attr('href', href);
$('#updateConfirmModal').modal({show:true});
return false;
});
Here is the button code to submit the form but no modal is displayed:
<input update-confirm="Are you sure you want to change the language of the website?" class="btn btn-danger" type="submit" value="Submit but NO modal" />
Here is the button code that displays the modal but does not submit the form:
<a class="btn btn-warning" href="#" update-confirm="Are you sure you want to change the language of the website?">Modal but NO submit</a>
I am obviously missing some understanding of what exactly is happening here. The use of an < input for the form submission over a < a hyperlink has me confused.
How do I add in the conditional if statement to the modal code AND submit the form when the user clicks on the OK modal button?
I have been trying to figure this out for two days, but I really do need some help on this problem.
I have a html form that has a submit button with a conditional js confirmation pop up that is working but I want to change the conditional js confirmation pop up with a bootstrap modal to fit in with the rest of my project.
When the form is submitted and the value of a html select list on the form has changed, then the conditional js confirmation pop up will display. The user must click the OK button on the js confirmation pop up for the form submission to proceed.
Or else if the html select list has not changed the js confirmation pop up will not display and the form will submit.
Here is my working form code:
<form id="language_view_form" class="form-horizontal" action="{% url language_view %}" method="post">
Here is my working button code inside the form:
<input id="submit_button" onclick="if(confirmChangeLanguage())showProgressAnimation();else return false;" type="submit" value="Update" />
Here is the working js code:
function confirmChangeLanguage() {
if ($('#id_language_code').val() != '{{ user.get_profile.language_preference }}') {
return confirm("Are you sure you want to change the language?");
} else {
return true;
}
}
The above code is working, but I am trying to replace the js confirmation pop up code with a bootstrap modal to fit in with the rest of my project and I have encountered some issues that has really confused me.
Here is the bootstrap modal code that displays the modal confirmation:
$('a[update-confirm]').click(function(ev) {
var href = $(this).attr('href');
if (!$('#updateConfirmModal').length) {
$('body').append('<div id="updateConfirmModal" class="modal modal-confirm-max-width modal-vertical-centered" role="dialog" aria-labelledby="updateConfirmLabel" aria-hidden="true"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button><h4 class="modal-title" id="updateConfirmLabel">{% trans "Confirm Language Change" %}</h4></div><div class="modal-body"></div><div class="modal-footer"><button class="btn" data-dismiss="modal" aria-hidden="true">{% trans "Cancel" %}</button> <a class="btn-u btn-u-blue" id="updateConfirmOK" onclick="showProgressAnimation();">{% trans "Update Langauge View" %}</a></div></div>');
}
$('#updateConfirmModal').find('.modal-body').text($(this).attr('update-confirm'));
$('#updateConfirmOK').attr('href', href);
$('#updateConfirmModal').modal({show:true});
return false;
});
Here is the button code to submit the form but no modal is displayed:
<input update-confirm="Are you sure you want to change the language of the website?" class="btn btn-danger" type="submit" value="Submit but NO modal" />
Here is the button code that displays the modal but does not submit the form:
<a class="btn btn-warning" href="#" update-confirm="Are you sure you want to change the language of the website?">Modal but NO submit</a>
I am obviously missing some understanding of what exactly is happening here. The use of an < input for the form submission over a < a hyperlink has me confused.
How do I add in the conditional if statement to the modal code AND submit the form when the user clicks on the OK modal button?
Share Improve this question asked Jul 18, 2014 at 6:52 user1261774user1261774 3,69510 gold badges58 silver badges104 bronze badges 3- can you please add a sample on jsfiddle – Dhiraj Commented Jul 20, 2014 at 18:17
- 1 @user1261774, your problem arises from the fact that bootstrap's modal is async, while javascript's confirm() is not. The answers below provide a way to overe this problem. Basically you have to cancel the submit immediately, and use form.submit() on the callback from bootstrap's modal. I suggest reading up how callbacks work on javascript recurial./programming/… – Andrei Dvoynos Commented Jul 21, 2014 at 6:22
- I have attempted to write a callback to solve this but I am not getting the result. If some can show me how to execute the callback function, this would earn the bonus points. – user1261774 Commented Jul 22, 2014 at 6:37
7 Answers
Reset to default 4First of all, never add events in markup, especially when using jquery
the solution, would be simple, you just add your event on submit form (use button, for submitting) and just add click action to the OKbutton
JS
$('#language_view_form').on('submit',function(ev) {
var $form=this;
ev.preventDefault();
var href = $(this).attr('href');
var modal=$('<div class="modal modal-confirm-max-width modal-vertical-centered" role="dialog" aria-labelledby="updateConfirmLabel" aria-hidden="true">');
modal.append($('<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button><h4 class="modal-title" id="updateConfirmLabel">{% trans "Confirm Language Change" %}</h4></div>'));
modal.append($('<div class="modal-body"></div>'));
var modalFooter=$('<div class="modal-footer"><button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button></div>');
var okButton=$('<button class="btn btn-u btn-u-blue">Update Langauge View</button>');
modalFooter.append(okButton);
modal.append(modalFooter);
$('body').append(modal);
modal.modal({show:true});
modal.on('hidden.bs.modal',function(e) {
modal.remove();
});
okButton.click(function() {
$form.submit(); //or ajax submit here = you choose, in case of ajax use modal.modal('hide'); to hide modal.
})
});
});
HTML
<form id="language_view_form" class="form-horizontal" action="/" method="post">
<input type="text"/>
<button class="btn btn-warning" href="#" update-confirm="Are you sure you want to change the language of the website?">Submit</button>
</form>
DEMO
you can use this normal modal html template from bootstrap
<form id="test" action="jsfiddle" method="POST">
<select id="slct" data-original-value="0">
<option value="0">Select</option>
<option value="1">Option 1</option>
</select>
<button data-condition="test" data-toggle="modal-confirm" data-message="Are you sure?" data-title="Woooooo dude!" data-target="#submit-confirm" type="submit">Submit</button>
</form>
notice that you now can set a data-condition
function name which must return true
or false
to show the modal
function test(){
return true;
};
you can define your title
and message
body from the modal through the button element too
data-message
and data-title
modal toggle now bees data-toggle="modal-confirm"
and this js does the trick
$(document).ready(function(){
//modal condition confirm
$('button[data-toggle="modal-confirm"]').click(function(event) {
event.preventDefault();
var self = $(this);
var message = self.data('message');
var title = self.data('title');
var target = $(self.data('target'));
var condition = self.data('condition');
if( target.length == 1) {
target.find('.modal-title').html(title);
target.find('.modal-body').html(message);
var showModal = true;
var fn = window[condition];
if(typeof fn === 'function') {
showModal = fn(condition);
}
if( showModal ) {
target.on('shown.bs.modal', function(e) {
target.find('button[data-confirm="modal"]').click(function(e){
e.preventDefault();
var parentForm = self.closest('form');
console.log(parentForm.html());
if( parentForm.length == 1 ) {
parentForm.submit();
}
});
});
target.modal({ show: true });
};
};
});
});
i made a small example on jsfiddle
http://jsfiddle/ZwAsL/2/
<form id="language_form">
<select name="language" id="language">
<option value="en" selected="selected">English</option>
<option value="sp">Spanish</option>
<option value="hi">Hindi</option>
</select>
<input type="submit" value="Submit">
</form>
<!-- Modal markup -->
<div class="modal fade" id="language-confirmation">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
<p>Do you really want to change the website language?</p>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn btn-default" id="accept-language-change">Yes</button>
<button type="button" data-dismiss="modal" class="btn btn-primary" id="reject-language-change">No</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
var current_language = 'en'; // {{ user.get_profile.language_preference }}
var languageChangeAccepted = false;
$('#language_form').on('submit', function(e) {
var selected_lang = $('#language option:selected').val();
if(current_language != selected_lang && !languageChangeAccepted){
e.preventDefault();
// ask for confirmation
$('#language-confirmation').modal({'show': true});
}
});
$('#language').change(function(){
languageChangeAccepted = false;
})
$('#accept-language-change').click(function(){
languageChangeAccepted = true;
$('#language_form').submit();
});
$('#reject-language-change').click(function(){
languageChangeAccepted = false;
});
</script>
FIDDLE
Change your form button to look like this
<input id="submit_button" type="submit" value="Update" />
Make Change to your confirmChangeLanguage();
javascript function like this
$("#submit_button").click(function(){
if ($('#id_language_code').val() != '{{ user.get_profile.language_preference }}') {
//assuming that your main modal div have ID = updateConfirmModal
//and modal OK Button Anchor Tag
$('#updateConfirmModal').modal('show');
return false;
}
return true;
});
Now Change OK anchor tag in Modal to
<a class="btn btn-warning" id="modalOK" >Modal OK</a>
Now Call javascript function on onclick of anchor tag
$("#modalOK").click(function(){
//as form will submit
//there is no need to remove modal as new page will be reloaded
$("#language_view_form").submit();
});
Your modal HTML will look like
<div id="updateConfirmModal" Class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false" data-keyboard="true" data-backdrop="static">
<div class="modal-header alert-error text-center">
<h5>
Modal Header
</h5>
</div>
<div class="modal-body">
Are you sure you want to change the language of the website?
</div>
<div class="modal-footer">
<a class="btn btn-warning" id="modalOK" >Modal OK</a>
</div>
</div>
I've a working example with bare minimum functionality (and not the prettiest) but it does what you're asking for. http://jsfiddle/zMr56/13/
<form id="test" action="jsfiddle" method="POST">
<select id="slct" data-original-value="0">
<option value="0">Select</option>
<option value="1">Option 1</option>
</select>
<button type="button">Submit</button>
</form>
<div class="modal fade" id="modal-dialog" style="display:none">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" id="okay-button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
$(function(){
$('#okay-button').on('click', function(){
$('#test').trigger('confirmation.button.clicked', true);
});
$('#test button').on('click', function(e, selector, data){
if(!data){
var $slct = $('#slct');
if($slct.val() != $slct.data("original-value")){
$('#modal-dialog').modal('show');
}
else{
$('#test').trigger('submit', true);
}
}
});
$('#test').on('confirmation.button.clicked', function(){
var $slct = $('#slct');
if($slct.val() != $slct.data("original-value")){
$('#test').trigger('submit', true);
}
});
});
You are assuming that an input will wait for the modal to finish (by the user clicking one of the buttons), however it cannot know to do that, it is a basic HTML control and the modal is created by Bootstrap, a Javascript framework.
Firstly, you are targeting the wrong element when using <input>, with the result that the <input> does not show the modal, but instead submits. This is because you are specifying the following query in your "click" event handler:
$('a[update-confirm]').click(...)
Your button, however, is an <input> not an <a>. To match both (and all elements with the "update-confirm" attribute), you can query with
$('[update-confirm]').click(...)
To instead match just the two elements (a, input), use
$('a[update-confirm], input[update-confirm]').click(...)
As for <a>: The reason <a> does not submit the form is because hyperlinks do not submit forms. You can however submit the form within the click handler of a hyperlink using
$('form#some-form').submit();
...from within your "$('a[update-confirm]').click()" handler.
The <input> tag that you specified is a submit button (type="submit"), which has as it's builtin action submission of the form. However you are not firing an event upon submission of the form, so it simply submits.
Making the modal actually show confirmation and submit
To handle both, simply submit the form dynamically.
Replace:
$('#updateConfirmOK').attr('href', href);
With:
$('#updateConfirmOK').click(function() {
$('form#my-form-id').submit();
return false;
});
And simply use the <a> approach you already have for the markup.
Please refer the JSFiddle: http://jsfiddle/VfkJ6/3/
Your HTML will be:
<form id="language-view">
<!-- Some control to select the language goes here -->
<select id="language">
<option value="EN">English</option>
<option value="ESP">Spanish</option>
<option value="GER">German</option>
</select>
<!-- This is the submit button, no need ofr any decoration, only 1 submit button per form -->
<input type="submit" />
</form>
<!-- The modal div goes here, just some div for an example, you build your own bootstrap modal -->
<div class="modal fade" id="language-change-confirm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">Confirm Language Change</h4>
</div>
<div class="modal-body">
You seem to have changed the language, and this is a major change. Are you sure?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save Changes</button>
</div>
</div>
</div>
</div>
And your JS will be:
// Have a global variable to for previous value, if you don't have a model for the form like in BackboneJS
var previousLanguage = 'EN',
languageChanged = false;
// Helper functions, just to make you understand
// Show Modal
function toggleModal() {
$('#language-change-confirm.modal').modal('toggle');
}
function submitForm() {
alert('Form submitted');
$('#language-view').submit();
}
// Override the Submit event
$('form#language-view').submit(function (event) {
// If language has not changed, submit the form
if (!languageChanged) return;
else
// Show the modal here if the language has indeed been changed
toggleModal();
// Prevent the actual submit event
event.preventDefault();
});
// If language is changed, set or reset languageChanged variable
$('#language').change(function () {
if ($(this).val() != previousLanguage) languageChanged = true;
else languageChanged = false;
});
// Write the OK button's click event handler
$('#language-change-confirm .btn-primary').click(function (event) {
// Stop click event from trying to load a page with the URL in href
event.preventDefault();
// Optionally, close the modal
toggleModal();
// Submit the form
submitForm();
});
// Write the Cancel button's click event handler
$('#language-change-confirm .btn-default,#language-change-confirm .close').click(function (event) {
// Stop click event from trying to load a page with the URL in href
event.preventDefault();
// Optionally, reset the language
$('#language').val(previousLanguage);
$('#language').change();
// Close the modal
toggleModal();
});
I think it will be self explanatory. Please ask for clarifications if necessary. I have used Bootstrap and jQuery.