Bootbox dialog.modal('hide') doesn't hide modal - javascript

I have a problem with bootbox.js modals. I wanted to use bootbox.dialog for pausing UI while Ajax is being executed and waiting for response. Everything works cool if I use dialog.modal('hide'); inside bootbox.alert with confirm (after clicking OK it hides dialog.modal), but I'd not like to confirm it every time. When I'm using dialog.modal('hide'); outside the bootbox.alert with confirm it doesn't hide dialog.modal... Where is the problem? Working code (hiding modal) is inside success and not working is inside error
var dialog = bootbox.dialog({
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we do something...</p>',
closeButton: false
});
var checkboxId = "#" + $(this).attr('id');
var checked = $(this).is(":checked");
if (checked) {
$.ajax({
url: url,
type: "POST",
data: { estimatedCostId: #Model.EstimatedCostID },
success: function (data) {
if (!data.Success)
{
bootbox.alert(data.ErrorMessage, function () {
dialog.modal('hide');
});
$(checkboxId).prop('checked', !checked);
}
},
error: function (request, status, error) {
dialog.modal('hide');
bootbox.alert("Błąd serwera");
$(checkboxId).prop('checked', !checked);
}
});
}

Most likely, this is a timing issue. If your AJAX call is "too quick", the success/fail callbacks are being called before the bootbox.dialog function has resolved. So, this:
dialog.modal('hide');
winds up being called on an undefined object. I was running into a similar issue on a recent project, and solved it by putting the AJAX call into the shown.bs.modal event, like so:
var checkboxId = "#" + $(this).attr('id');
var checked = $(this).is(":checked");
var dialog = bootbox.dialog({
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we do something...</p>',
closeButton: false
})
// this is the change
.on('shown.bs.modal', function(){
if (checked) {
$.ajax({
url: url,
type: "POST",
data: { estimatedCostId: #Model.EstimatedCostID },
success: function (data) {
if (!data.Success)
{
bootbox.alert(data.ErrorMessage, function () {
dialog.modal('hide');
});
$(checkboxId).prop('checked', !checked);
}
},
error: function (request, status, error) {
dialog.modal('hide');
bootbox.alert("Błąd serwera");
$(checkboxId).prop('checked', !checked);
}
});
}
});

You can use this also in a simple way
bootbox.hideAll();

Related

Ajax post not working in window beforeunload

i have multiple identical forms (one for each month) that sit on multiple sections using this script :
http://www.jquery-steps.com/Examples
no problems there.
When i hit the next or previous buttons, i post the data on the form with this :
var tsf = $('.tsf-wizard-1').tsfWizard({
stepEffect: 'basic',
stepStyle: 'style1',
validation: false,
navPosition: 'top',
manySteps: true,
stepTransition: true,
showButtons: true,
showStepNum: true,
height: '500px',
prevBtn: '<i class="fa fa-chevron-left"></i> Vorige Maand',
nextBtn: 'Volgende Maand <i class="fa fa-chevron-right"></i>',
finishBtn: '<i class="fa fa-table"></i> Overzicht',
onNextClick: function (e, from, to, validation) {
var stap = from+1;
var formstep = '#'+stap.toString()+'_form';
var pathname = window.location.pathname; // Returns path only
var url = window.location.href;
$.ajax({
type: 'post',
url: 'user_settings/add_data',
data: $(formstep).serialize(),
success: function () {
console.log($(formstep).serialize());
},
error: function (){
$( "#remarks").html("<span class=\"label label-danger\">ERROR !</span> Problem saving..");
}
});
},
onPrevClick: function (e, from, to, validation) {
var stap = from+1;
var formstep = '#'+stap.toString()+'_form';
$.ajax({
type: 'post',
url: 'user_settings/add_data',
data: $(formstep).serialize(),
success: function () {
console.log($(formstep).serialize());
},
error: function (){
$( "#remarks").html("<span class=\"label label-danger\">ERROR !</span> Problem saving..");
}
});
}
});
But, when the user leaves the page i want to have all of the forms posted with an ajax call. So i tried this (The hold.open and .close is busy indicator)
$(window).on('beforeunload', function ()
{
//this will work only for Chrome
pageSave();
});
$(window).on("unload", function ()
{
//this will work for other browsers
pageSave();
});
function pageSave()
{
if (!_wasPageSaved)
{
HoldOn.open({
theme:'sk-cube-grid',
message:"<h4>Savig data..</h4>"
});
var goodsaves=0;
for (i = 1; i <= 12; i++) {
var formstep = '#'+i.toString()+'_form';
$.ajax({
type: 'post',
url: '<?php echo base_url();?>user_settings/add_data',
data: $(formstep).serialize(),
success: function () {
goodsaves=goodsaves+1;
},
error: function (){
console.log('error saving data :');
}
});
}
HoldOn.close();
if (goodsaves=>11) {
_wasPageSaved = true;
console.log('all forms saved');
}
}
}
Problem is that sometimes the data is saved, sometimes not. I can't put my finger on it why it doesn't always work . I see the busy indicator, i don't get any alerts in my console and the next page is loaded. But my data isn't saved...
hope anyone can clear this out , thanks allot in advance.

How to get a value from Ajax call to be used in a Bootbox button's function?

I am using Bootbox for my modals and I am having trouble in showing the form validation errors from an Ajax call to the modal. The callback function for the submit button on my modal calls the add_college function to submit the form via Ajax.
When there are validation errors, the modal is populated with validation errors. The problem is that the modal closes regardless if there are validation errors or not. I want the modal to not close only when there are no validation errors.
I know I can just return false in the callback function on my button when there are validation errors to not close it but I have no way of knowing if there are validation errors since I cannot return a value in the Ajax call since it is asynchronous. What is the proper way of doing it?
Here is my code:
$('#new-college-btn').click(function () {
bootbox.dialog({
title: "New College",
message:
''// <Insert long HTML form here>
,
buttons: {
add: {
label: "Add",
className: "btn btn-primary",
callback: function () {
var form_data = {
college_name: $('#college-name').val(),
college_initials: $('#college-initials').val(),
username: $('#username').val(),
password: $('#password').val(),
confirmation_password: $('#confirmation-password').val()
};
add_college(form_data);
}
},
cancel: {
label: "Cancel",
className: "btn btn-default"
}
}
}); // end bootbox dialog
});
function add_college(form_data) {
console.log(form_data);
$.ajax({
url: 'admin/add_new_college',
type: 'POST',
data: form_data,
dataType: 'JSON',
success: function (response)
{
if (response.error) { // there are form validation errors
// populate modal with validation errors here
} else {
// other data processing here
Result.success('College Successfully Added!');
}
},
error: function () {
console.log("fail");
}
});
}
If you want to control when the dialog closes, make sure the callback for your "submit" button always returns false. Then, in the done() (and probably fail()) callbacks for the ajax function, call bootbox.hideAll() to close the dialog (along with any other dialogs you may have opened).
If you want to only close the current dialog, do something along this line:
var dialog = bootbox.dialog({
/* rest of your options... */,
buttons: {
submit: {
label: "Submit",
callback: function() {
var data = [];
$.post('/url', data)
.done(function(result, status, jqxhr){
// if everything went well...
dialog.modal('hide');
})
.fail(function(jqxhr, status, error){
// etc.
});
return false;
}
}
}
});
Basically, create a reference to the dialog, which you can then use inside of the ajax callback.

Trouble getting JQuery AJAX's success event to show a thank you page

I have this code and, if everything is okay, the result should be a thank you page.
Here is the code:
<a class="large red button round" onclick="$.ajax({ type: 'POST', data:$('#newsletter').serialize(), url: 'http://www.stress-free-life.co.il/lists/?p=subscribe& amp;id=1', success: function (msg) { openWin(); $('#Name').val(''); $('#email').val(''); }, failure: function (msg) { alert('Sorry, we were unable to process your subscription.'); } }); return false;" href="javascript; return false;">לחץ כאן</a>
I have tried several options but can't get the thank you page to display.
Um... let's clean this up, onclick handlers are really hard to read and are generally considered bad practice
Your HTML:
<a class="large red button round my-button" href='#'>לחץ כאן</a>
And in a separate JS file you should have:
$(function(){
$('.my-button').on('click', function(e){
e.preventDefault();
$.ajax({
type: 'POST',
data: $('#newsletter').serialize(),
url: 'http://www.stress-free-life.co.il/lists/?p=subscribe&id=1',
success: function(msg){
window.location = "/my-thank-you-page.html";
//openWin(); // No idea what this function is...
//$('#Name').val('');
//$('#email').val('');
},
failure: function(msg){
alert('Sorry, we were unable to process your subscription.');
}
});
});
});
Perhaps something like this...
<a id="ajaxpost" class="large red button round" href="javascript:void(0)">לחץ כאן<a>
<script>
$("#ajaxpost").click(function () {
$.ajax({
type: 'POST',
data: $('#newsletter').serialize(),
url: 'http://www.stress-free-life.co.il/lists/?p=subscribe&id=1',
success: function (msg) {
openWin();
$('#Name').val('');
$('#email').val('');
window.location = "url of thank-you page";
},
failure: function (msg) {
alert('Sorry, we were unable to process your subscription.');
}
});
});
</script>

Insert HTML using jQuery

I have two pieces of code, first of all I have my code which toggles open a div with an included close button:
http://jsfiddle.net/spadez/uhEgG/27/
$(document).ready(function () {
$('#country').click(function () {
$("#country_slide").slideToggle();
});
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
});
Then I also have my Ajax code which is designed to fire when the div has been opened:
$(function () {
$('#country_link').on('click', function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend: function () {
$('.loader').show();
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
// $("#country_slide").hide('fast');
// alert('request failed');
},
complete: function () {
$('.loader').hide();
},
});
return false;
});
});
What I am stuck with now is, how do I make the ajax only execute when the div is being opened? Because I am working with a toggle and close button it seems difficult to work out what the click is doing, whether it is opening it or closing it.
I guess my options are to have some kind of flag or alternatively have some "if" code, so if class is equal to .hidden then do not execute. I haven't been able to integrate either of these solutions and I am unsure if either of them is the proper way to achieve this.
Include the check as part of your slide function:
$("#country_slide").slideToggle(function() {
if ($(this).is(":visible")) {
alert("im visible!");
}
});
Demo: http://jsfiddle.net/tymeJV/uhEgG/28/
if($("#country_slide").is(":visible"))
//call ajax
This code adds data to the element, to check if it's already loaded next time you click on it.
Currently I am not able to test it, so it may contain errors.
$(function () {
$('#country_link').on('click', function (e) {
// Prevent from following the link, if there is some sort of error in
// the code before 'return false' it would still follow the link.
e.preventDefault();
// Get $link because 'this' is something else in the ajax request.
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true)
return false;
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend: function () {
$('.loader').show();
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
// $("#country_slide").hide('fast');
// alert('request failed');
},
complete: function () {
$('.loader').hide();
},
});
});
});

Jquery Ajax - Not loading text

I am new to jquery and coding in general. This is what I am trying to do:
When a link is clicked, expand the #country_slide div
Show "loading" text
If ajax is successful, put the contents of an html file into the div
Otherwise alert an error and close the div
This is the code I now have:
http://jsfiddle.net/spadez/n9nVs/5/
window.onload = function () {
var a = document.getElementById("country_link");
a.onclick = function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend : function() {
$("#country_slide").show();
$("#country_slide").val('<p>Loading</p>')
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
$("#country_slide").hide();
},
complete : function() {
$('.loader').hide();
},
});
return false;
}
}
When the link is clicked, I never see the loading text in the box. Please can someone tell me where I have gone wrong here? Also if anyone can offer any words of advice about my first jquery script I would really appreciate it.
Your anchor's id is country, not country_link. So:
var a = document.getElementById("country");
or just use jQuery's id selector:
var a = $("#country");
or even better directly chain:
$(function() {
$('#country').click(function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend : function() {
$("#country_slide").show();
$("#country_slide").html('<p>Loading</p>')
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
$("#country_slide").hide();
},
complete : function() {
$('.loader').hide();
},
});
return false;
}
});
Notice that I have used the $(document).ready function instead of window.onload. Also I have replaced the onclick event subscription with jQuery's click function. If you are using jQuery it would be better to take full advantage of it.
Working jsFiddle Demo
You don't have any country_link element in your page.
Instead of using window.onload you can use DOM ready.
Attach click handler by jQuery with .on() method.
The .val() method is for <input />. For other elements, use .html() instead.
// DOM ready instead of window.onload
$(function () {
// attach click handler by jQuery instead of onclick
$('#country').on('click', function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend : function() {
$("#country_slide").show();
// val() method is for <input />
// use html() instead
$("#country_slide").html('<p>Loading</p>')
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
$("#country_slide").hide();
},
complete : function() {
$('.loader').hide();
},
});
return false;
});
});
References:
.html() - jQuery API Documentation
.on() - jQuery API Documentation
.val() - jQuery API Documentation
jQuery( callback ) - jQuery API Documentation
On the fiddle you have
<a href="#" id="country">
Where it should be:
<a href="#" id="country_link">
or change the JS to be
var a = document.getElementById("country");
Because there is no element with an ID country_link
document.getElementById() returns null if the element isn't found
document.getElementById('country').onclick = ...; //should work
In JavaScript, null is a special primitive and you cannot add properties to primitive types.
You have to add an element with id=country_link and the this code will work as NOX said. I have tried that in jsfiddle. try it using
$("#country").click(function(){
// your code goes here
})
that will works.
document.getElementById("country_link"); shall be replaced by document.getElementById("country"); as "country_link" is not the id of any <a> tag in the mark up.
If you are using jQuery library you may handle event like-
$(document).on("click","a",function(){
//ajax stuff
});
Updated Your jsfiddle Code. Just check. its going to failure method. In your workspace you should have the test.html returning the actual data. Thanks.
Don't use plain JS if you already have jQuery (it will be easier for you):
;$(document).ready(function(){
$(country_link).click(function () {
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend : function() {
$(country_slide).show();
$(country_slide).val('<p>Loading</p>');
},
success: function (data, textStatus) {
$(country_slide).html(data);
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
$(country_slide).hide();
},
complete : function() {
$('.loader').hide();
},
});
return false;
});
});

Categories