Prevent bootstrap-3 modal from closing when the form has changes - javascript

I'm trying to prevent the bootstrap-3 modal from closing without warning when there are changes made to the form inside the modal. However when I listen to the events fired by the modal and return false it will prevent the modal from closing ever. Here's my code:
$(function() {
$('body').live('shown.bs.modal', '#quickbutton-create', function () {
$(this).find('#quickbutton-create form').monitor();
});
$('body').live('hide.bs.modal', '#quickbutton-create', function () {
if ($(this).find('#quickbutton-create form').monitor('has_changed')) {
if (!confirm('Are you sure?')) {
return false;
}
}
});
});
So in short, in this case; how do I prevent the modal from closing just this once.

Ok so I figured it out, instead of return false I needed to event.preventDefault()
jsfiddle here: http://jsfiddle.net/ACYBv/1/
$(function() {
$('.modal').on('shown.bs.modal, loaded.bs.modal', function(e) {
// set form state
$(this).data('form-data', $(this).find('form').serialize());
});
$('.modal').on('hide.bs.modal', function(e) {
// check if the form data was changed since the modal was openened
if($(this).data('form-data') != $(this).find('form').serialize()) {
if(!confirm('you sure??')) {
e.preventDefault();
}
}
});
});

Related

Submit a form and stay on the same page?

I'm trying to make my form stay on the same page using jquery. I'm using a form named #clientUpdate-form that posts it's input to update.php. I have tried removing the window.location.href and tried changing it to window.location.href="edit_form.php?edit_id="+edit_id but the form always reverts back to index.php
Full Code:
/* Update Record */
$(document).on('submit', '#clientUpdate-form', function() {
$.post("update.php", $(this).serialize()).done(function(data) {
$("#dis").fadeOut();
$("#dis").fadeIn('slow', function() {
$("#dis").html('<div class="alert alert-info">' + data + '</div>');
$("#clientUpdate-form")[0].reset();
$("body").fadeOut('slow', function() {
$("body").fadeOut('slow');
window.location.href = "index.php";
});
});
});
return false;
});
/* Update Record */
you need to prevent the default event of form submit.
$(document).on('submit', '#clientUpdate-form', function(e) { // note the e, thats the event
e.preventDefault(); // this stops the default event of the form
// then your stuff goes here
});

off() not working in firefox but working in chrome

I am using a beforeonload function but I want when the user submits the form beforeunload shouldn't work. Here is my code, which works fine in Chrome but not in Firefox.
window.form_submitted = '';
jQuery(document).ready(function() {
jQuery(window).on('beforeunload', function() {
if (form_submitted == '') {
return "Are you sure to leave that page";
}
});
});
jQuery('#form').on('submit', function (e) {
e.preventDefault();
jQuery(window).off('beforeunload');
form_submitted = 1;
site_redirect(resp.payment_url);
}
return false;
});
You have several syntax issues, and you have to place the submit block inside the DOMReady handler, otherwise JS will attempt to bind the event to an element which doesn't yet exist in the DOM. Also note you can remove the the global flag variable as you are unbinding the beforeunload event on form submission. Try this:
jQuery(document).ready(function($) {
$(window).on('beforeunload', function() {
return "Are you sure to leave that page";
});
$('#form').on('submit', function (e) {
e.preventDefault();
$(window).off('beforeunload');
site_redirect(resp.payment_url);
});
});
Also note that by doing a redirect when the form is submit (assuming that's what the site_redirect function is doing) then the content of the form will be lost.

Prevent click after focus event

When user clicks on input field, two consecutive events are being executed: focus and click.
focus always gets executed first and shows the notice. But click which runs immediately after focus hides the notice. I only have this problem when input field is not focused and both events get executed consecutively.
I'm looking for the clean solution which can help me to implement such functionality (without any timeouts or weird hacks).
HTML:
<label for="example">Example input: </label>
<input type="text" id="example" name="example" />
<p id="notice" class="hide">This text could show when focus, hide when blur and toggle show/hide when click.</p>
JavaScript:
$('#example').on('focus', _onFocus)
.on('blur', _onBlur)
.on('click', _onClick);
function _onFocus(e) {
console.log('focus');
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
$('#notice').removeClass('hide');
}
function _onClick(e) {
console.log('click');
$('#notice').toggleClass('hide');
}
function _onBlur(e) {
console.log('blur');
$('#notice').addClass('hide');
}
UPDATED Fiddle is here:
I think you jumbled up the toggles. No need to prevent propagation and all that. Just check if the notice is already visible when click fires.
Demo: http://jsfiddle.net/3Bev4/13/
Code:
var $notice = $('#notice'); // cache the notice
function _onFocus(e) {
console.log('focus');
$notice.removeClass('hide'); // on focus show it
}
function _onClick(e) {
console.log('click');
if ($notice.is('hidden')) { // on click check if already visible
$notice.removeClass('hide'); // if not then show it
}
}
function _onBlur(e) {
console.log('blur');
$notice.addClass('hide'); // on blur hide it
}
Hope that helps.
Update: based on OP's clarification on click toggling:
Just cache the focus event in a state variable and then based on the state either show the notice or toggle the class.
Demo 2: http://jsfiddle.net/3Bev4/19/
Updated code:
var $notice = $('#notice'), isfocus = false;
function _onFocus(e) {
isFocus = true; // cache the state of focus
$notice.removeClass('hide');
}
function _onClick(e) {
if (isFocus) { // if focus was fired, show/hide based on visibility
if ($notice.is('hidden')) { $notice.removeClass('hide'); }
isFocus = false; // reset the cached state for future
} else {
$notice.toggleClass('hide'); // toggle if there is only click while focussed
}
}
Update 2: based on OP's observation on first click after tab focus:
On second thought, can you just bind the mousedown or mouseup instead of click? That will not fire the focus.
Demo 3: http://jsfiddle.net/3Bev4/24/
Updated code:
$('#example').on('focus', _onFocus)
.on('blur', _onBlur)
.on('mousedown', _onClick);
var $notice = $('#notice');
function _onFocus(e) { $notice.removeClass('hide'); }
function _onClick(e) { $notice.toggleClass('hide'); }
function _onBlur(e) { $notice.addClass('hide'); }
Does that work for you?
Setting a variable for "focus" seems to do the trick : http://jsfiddle.net/3Bev4/9/
Javascript:
$('#example').on('focus', _onFocus)
.on('click', _onClick)
.on('blur', _onBlur);
focus = false;
function _onFocus(e) {
console.log('focus');
$('#notice').removeClass('hide');
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
focus = true;
}
function _onClick(e) {
console.log('click');
if (!focus) {
$('#notice').toggleClass('hide');
} else {
focus = false;
}
}
function _onBlur(e) {
console.log('blur');
$('#notice').addClass('hide');
}
If you want to hide the notice onBlur, surely it needs to be:
function _onBlur(e) {
console.log('blur');
$('#notice').addClass('hide'); // Add the hidden class, not remove it
}
When doing this in the fiddle, it seemed to fix it.
The code you have written is correct, except that you have to replae $('#notice').removeClass('hide'); with $('#notice').addClass('hide');
Because onBlur you want to hide so add hide class, instead you are removing the "hide" calss.
I hope this is what the mistake you have done.
Correct if I am wrong, Because I don't know JQuery much, I just know JavaScript.
you can use many jQuery methods rather than add or move class:
Update: add a params to deal with the click function
http://jsfiddle.net/3Bev4/23/
var showNotice = false;
$('#example').focus(function(){
$('#notice').show();
showNotice = true;
}).click(function(){
if(showNotice){
$('#notice').show();
showNotice = false;
}else{
showNotice = true;
$('#notice').hide();
}
}).blur(function(){
$('#notice').hide();
});

Unable to stop browser navigation using $("#tag").click()

I am trying to create a button called SignIn that accommodates browsers without javascript, but doesn't navigate when Javascript is enabled.
<script type="text/javascript">
$(function () {
$("#signIn").click(function () {
//
// Stop event bubbling
//
return false;
});
});
// Gets the div tag and its content for an identity provider
function GetIdentityProviderTag(idp, index)
{
return '<div class="identity-provider" id="button' + index + '"><button>' + idp.Name + ' </button></div>';
}
</script>
<div>
Sign In
</div>
What do I need to do to permit both javascript enabled, and javascript disabled browsers to work?
The next code snippet prevents the browser from following the link (mainly return false), you should remove it:
$(function () {
$("#signIn").click(function () {
//
// Stop event bubbling
//
return false;
});
});
If you just want to press the button automatically, use:
$(function () {
$("#signIn").click();
});
To stop the default action of a link click you need to add:
e.preventDefault();
To your script So it will look something like
$("#signIn").click(function (e) {
e.preventDefault();
//
// Code inserted here
//
});
The preventDefault() cancels the event if it is cancelable, without stopping further propagation of the event.
You could try
Sign In
<script type="text/javascript">
function signin() {
//Do sign in stuff
return false;
}
</script>

How can I refactor this jQuery code?

The code below is for a simple newsletter signup widget.
I'm sure there's a way to make it more concise, any ideas?
var email_form = $('.widget_subscribe form');
var email_submit = $('.widget_subscribe .submit');
var email_link = $('.widget_subscribe .email');
// Hide the email entry form when the page loads
email_form.hide();
// Show the form when the email link is clicked
$(email_link).click( function () {
$(this).toggle();
$(email_form).toggle();
return false;
});
// Hide the form when the form submit is clicked
$(email_submit).click( function () {
$(email_link).toggle();
$(email_form).toggle();
});
// Clear/reset the email input on focus
$('input[name="email"]').focus( function () {
$(this).val("");
}).blur( function () {
if ($(this).val() == "") {
$(this).val($(this)[0].defaultValue);
}
});
You have some similar code here.
// Show the form when the email link is clicked
$(email_link).click( function () {
$(this).toggle();
$(email_form).toggle();
return false;
});
// Hide the form when the form submit is clicked
$(email_submit).click( function () {
$(email_link).toggle();
$(email_form).toggle();
});
It could be refactored so the similarity is obvious.
// Show the form when the email link is clicked
$(email_link).click( function () {
$(email_link).toggle();
$(email_form).toggle();
return false;
});
// Hide the form when the form submit is clicked
$(email_submit).click( function () {
$(email_link).toggle();
$(email_form).toggle();
});
So you could wrap toggling the link and the form into a function.
var toggleEmailLinkAndForm = function () {
$(email_link).toggle();
$(email_form).toggle();
}
$(email_link).click(toggleEmailLinkAndForm);
$(email_submit).click(toggleEmailLinkAndForm);
And as others have pointed out, you can drop the redunant $()s.
var toggleEmailLinkAndForm = function () {
email_link.toggle();
email_form.toggle();
}
email_link.click(toggleEmailLinkAndForm);
email_submit.click(toggleEmailLinkAndForm);
It's already pretty concise, there's not much more you can do.
Anywhere you have $(email_submit) you can just have email_submit, because you've already wrapped it in $() (which makes it a jquery object).
Eg:
email_submit.click( function () {
email_link.toggle();
email_form.toggle();
});
I like Patrick McElhaney Code Best.
toggleEmailLinkAndForm() {
email_link.toggle();
email_form.toggle();
}
email_link.click(toggleEmailLinkAndForm);
email_submit.click(toggleEmailLinkAndForm);
Part of refactoring is not going overboard. I would not recommend creating an extra click event that calls the other click event. The point of refactoring is readability and flexibility. You can also use the jQuery method "add" to shrink the code but it will become even harder to read.
email_link.add(email_submit).click(function(){
email_link.add(email_form).toggle();
});
Like Patrick said (+1), and you can also skip the extra function:
email_submit.click(function () {
email_link.toggle();
email_form.toggle();
});
email_link.click(function () {
email_submit.click(); //calls the click function already subscribed
return false;
});

Categories