How to show confirmation pop up when changing page in DataTable - javascript

I am landing on the first page of DataTable, make some changes.
Then I move to the second page.
Actually, confirmation popup is shown but it navigate to the second page.
Expected: confirm pop is shown but it still landing on the first.
Here is my code:
$('#dataTable-id').on( 'page.dt', function (event) {
if( change ){
bootbox.dialog({
title: "Confirmation",
message : "Discard changes?",
buttons :{
main: {
label : "Leave",
className : "btn-primary",
callback: function (){
// To avoid broking page/length controller
// move to other pages
return true; // cancel draw
}
},
cancel: {
label : "Stay",
className : "btn-default",
callback : function() {
// stay at current page.
return true;
}
}
},onEscape: function () {return true;}
});
}
});
How to show confirmation popup before page change?

The page.dt event is only informational, it can not be canceled.
You can workaround that restriction by writing a custom preDrawCallback like discussed here: https://datatables.net/forums/discussion/25507
EDIT: You have to cancel the redraw generally and do the paging manually in the bootbox callback (as it does not work as a real modal dialog like the native javascript confirm()). I modified the above example to incorporate a bootbox confirm dialog on paging: https://jsfiddle.net/bk4nvds5/
$(document).ready(function () {
var pageLen = 10;
var originalPage = 0;
var originalPageLen = pageLen;
var gotoPage = 0;
var gotoPageLen = originalPageLen;
var fromBootbox = false;
var table = $('#example').DataTable({
"pageLength": pageLen,
"preDrawCallback": function (settings) {
if(table){ // ignore first draw
if (!fromBootbox) {
// To avoid broking page/length controller, we have to reset the paging information
gotoPage = settings._iDisplayStart;
gotoPageLen = settings._iDisplayLength;
bootbox.confirm("Are you sure?", function(result) {
console.log("goto page" + gotoPage + " (result: " + result + ")");
if (result) {
fromBootbox = true;
table.page.len(gotoPageLen);
table.page(gotoPage / gotoPageLen).draw(false);
fromBootbox = false;
}
});
settings._iDisplayStart = originalPage;
settings._iDisplayLength = originalPageLen;
$('[name="example_length"]').val(originalPageLen);
return false; // cancel draw
}else{
originalPage = settings._iDisplayStart;
originalPageLen = settings._iDisplayLength;
}
}
}
});
});

Related

How to achieve recursive call - jquery

I have a custom created dialog module.
I am passing a mvc view called Cart to this module.
The cart view has a link called 'Create New Contat' clicking on which the view(Cart) will be replaced with another view(Contact) using an ajax call. The contact view has a button called cancel. When the user clicks on Cancel the old view(Cart) will replace the existing view(contact).
The problem I am facing is after replacing the view none of the links or buttons work on the view.
Can some body pls directed me towards a better way of doing this.
Pasted below is the code.
$(document).on('click', '.ddlCart li', function(e) {
var ddlselectedVal = $(this).attr('id');
var selectedListinsCount = selected_Listings.length;
var SelectedMlsnums = selected_Listings.join();
var agentId = $("#AgentId").val();
var Action;
var EnvironmentURL = $("#EnvironmentURL").val();
var postData = { AgentId: agentId, Mlsnums: SelectedMlsnums, ActionTypeValue: “PreAddToCart” };
var close = function (event, ui) {
$('#dvModalDialog').dialog("close");
}
var open = function (event, ui) {
var url = EnvironmentURL + "MLSReports/Stats/SearchContacts";
$("#btncart_cancel").on("click", function () {
$('#dvModalDialog').dialog("close");
});
$("#btncart_submit").on("click", function () {
var url = EnvironmentURL + "MLSReports/Stats/Cart";
//Send the data using post and put the results in a div
$.post(url, {
AgentId: agentId, Mlsnums: SelectedMlsnums, ActionTypeValue: "AddToCart"
},
function (data) {
// Replace current data with data from the ajax call to the div.
$("#dvModalDialog").empty().append(data);
});
});
$("#lnkCreateNewcart").on("click", function () {
var url = EnvironmentURL + "MLSReports/Stats/Cart";
//Send the data using post and put the results in a div
$.post(url, {
ActionTypeValue: "preAddorEditContact"
},
function (data) {
//debugger;
// Replace current data with data from the ajax call to the div.
$("#dvModalDialog").empty().append(data);
$("#btnCancelContact").on("click", function () {
////********** replace the view (Contact) with the view (Cart).
// In the cancel event I am loading the previous page.I am having problem here. after post none of the controls work.
$.post(url, {
ActionTypeValue: "PreAddToCart"
},
function (data) {
//debugger;
// Replace current data with data from the ajax call to the div.
$("#dvModalDialog").empty().append(data);
})
});
});
});
};
if (ddlselectedVal == "AddtoCart") {
var rd = Mod.ReportsDialog({ title: 'Add To Cart', close: close, open: open });
rd.url = EnvironmentURL + "/MLSReports/Stats/Cart";
rd.targetElement = '#dvModalDialog'// '#dvSendEmail'
rd.formName = '#frmCart'
rd.postData = postData
rd.open();
}
});

Prompt popup in bootbox is not closing

The prompt popup that occurs when I click the button with class 'alert3' does not close.
CLICKMEMEMEMEMEME
and this is the function that I am invoking:
<script>
$(document).on("click", ".alert3", function(e) {
bootbox.prompt("What is your name?", function(result) {
if (result === null) {
Example.show("Prompt dismissed");
} else {
Example.show("Hi <b>"+result+"</b>");
}
});
});
</script>
The popup does not close because you have an error in the callback function, so it crashes before bootbox can make the popup disappear.
The best guess is that Example is not defined in your code. Maybe you took it on the Bootbox website, they are using a javascript object called Example.
If you want to show the result with your callback function, you can add this to your html:
CLICKMEMEMEMEMEME<br/>
<p id='result'></p>
And then change your javascript:
<script>
$(document).on("click", ".alert3", function(e) {
bootbox.prompt("What is your name?", function(result) {
if (result === null) {
$('#result').html("Prompt dismissed");
} else {
$('#result').html("Hi <b>"+result+"</b>");
}
});
});
</script>
Prompt popup in bootbox.js
That is not working because Example function is not defined there.We need to first defined them that using current selector value and text associated with them.here $("#result") is used to show error message in particular div.
html code:
<p>Click here-><a class="alert" href=#>Alert!</a></p><p id='result'</p>
code:
var Example = (
function()
{
"use strict";
var elem,
hideHandler,
that = {};
that.init = function(options) {
elem = $(options.selector);
};
that.show = function(text) {
clearTimeout(hideHandler);
$("#result").html(text);
$("#result").fadeIn();
hideHandler = setTimeout(function() {
that.hide();
}, 4000);
};
that.hide = function() {
$("#result").fadeOut();
};
return that;
}());

Enabling History API with datatables

I have a dataTable object on a page representing a list of releases I need to keep track of with the url /releases I want to add the following functionality
if /releases?query=<query>, the dataTable will initialized with the provided query
The query parameter is updated if the user changes the search term
The back and forward buttons in the browser go the appropriate query
So far I am able to do the first 2, but when I listen for the popstate event, redrawing the table triggers a pushState which I can't figure out how to prevent. Here's my code so far:
$(document).ready(function(){
var prevSearch;
var table = $('#releases').dataTable({
"bJQueryUI" : true,
"sPaginationType" : "full_numbers",
"iDisplayLength" : 50,
"oSearch": {"sSearch": '#{params[:query]}'},
"fnDrawCallback": function(oSettings) {
var curSearch = oSettings.oPreviousSearch.sSearch;
if (!prevSearch) {
prevSearch = curSearch;
} else if (curSearch != prevSearch) {
console.log("changed to: " + curSearch);
history.pushState({query: curSearch}, "title", "releases?query=" + curSearch);
prevSearch = curSearch;
}
}
});
window.addEventListener("popstate", function(e) {
if (e.state) {
table.fnFilter(e.state.query);
}
});
});
Note, I am using a rails backend and this is inlined javascript being served in the page.
you have only 2 options here:
move pushState code out of drawCallback. There must be some other code that causes the datatables to draw when user enters something. put your pushState code there. This is the ideal solution
add a hack like this
$(document).ready(function () {
var prevSearch;
var saveState = true;
var table = $('#releases').dataTable({
"bJQueryUI":true,
"sPaginationType":"full_numbers",
"iDisplayLength":50,
"oSearch":{"sSearch":'#{params[:query]}'},
"fnDrawCallback":function (oSettings) {
var curSearch = oSettings.oPreviousSearch.sSearch;
if (!prevSearch) {
prevSearch = curSearch;
} else if (curSearch != prevSearch) {
console.log("changed to: " + curSearch);
if (saveState) {
history.pushState({query:curSearch}, "title", "releases?query=" + curSearch);
}
prevSearch = curSearch;
}
}
});
window.addEventListener("popstate", function (e) {
if (e.state) {
saveState = false;
table.fnFilter(e.state.query);
saveState = true;
}
});
});

How do I create my own confirm Dialog?

The confirm box only has two options: ok and cancel.
I'd like to make one myself, so I can add a third button: save and continue. But the issue I currently don't know how to solve, is that: once the custom confirm dialog is up, how do I block the previously running script (or navigation) from running? and then how do I make the buttons return values for the confirmation?
my understanding of the confirm dialog box is this:
it's a visual boolean, that has the power to block navigation and scripts on a page. So, how do I emulate that?
If you want a reliable proven solution... Use jQuery... it'll work on every browser without worrying about crappy IE etc. http://jqueryui.com/demos/dialog/
In javascript, you don't stop while you're waiting for a user action : you set a callback (a function) that your dialog will call on close.
Here's an example of a small dialog library, where you can see how callbacks can be passed.
dialog = {};
dialog.close = function() {
if (dialog.$div) dialog.$div.remove();
dialog.$div = null;
};
// args.title
// args.text
// args.style : "", "error" (optionnel)
// args.buttons : optional : map[label]->function the callback is called just after dialog closing
// args.doAfter : optional : a callback called after dialog closing
dialog.open = function(args) {
args = args || {};
if (this.$div) {
console.log("one dialog at a time");
return;
}
var html = '';
html += '<div id=dialog';
if (args.style) html += ' '+args.style;
html += '><div id=dialog-title>';
html += '</div>';
html += '<div id=dialog-content>';
html += '</div>';
html += '<div id=dialog-buttons>';
html += '</div>';
html += '</div>';
this.$div=$(html);
this.$div.prependTo('body');
$('#dialog-title').html(args.title);
$('#dialog-content').html(args.text);
var buttons = args.buttons || {'Close': function(){return true}};
for (var n in buttons) {
var $btn = $('<input type=button value="'+n+'">');
$btn.data('fun', buttons[n]);
$btn.click(function(){
if ($(this).data('fun')()) {
dialog.close();
if (args.doAfter) args.doAfter();
}
});
$btn.appendTo($('#dialog-buttons'));
}
this.$div.show('fast');
shortcuts.on('dialog', {
27: function(){ // 27 : escape
dialog.close();
}
});
}
Two call samples :
dialog.open({
title: 'ccccc Protection Error',
text: 'There was an error related to cccc Protection. Please consult <a href=../cccc.jsp>this page</a>.',
style: 'error'
});
var ok = false;
dialog.open({
title: sometitle,
text: someHtmlWithInputs,
buttons: {
'OK': function() {
if (// inputs are valid) ok = true;
return true;
},
'Cancel': function() {
return true;
}
},
doAfter: function() {
if (ok) {
if (newvg) {
cccmanager.add(vg);
} else {
cccmanager.store();
}
if (doAfter) doAfter();
}
}
});
As specified by others, you may not need your own library if you just want to make a dialog.

Push function to front of object literal

I have some html to popup a jQuery UI modal:
Click me
With this javascript code:
$('.popup').click(function() {
var a = this;
var dialog = $('<div>').load($(a).attr('href'), function() {
var form = dialog.find('form');
dialog.dialog({
modal: true,
title: $(a).attr('title'),
buttons: {
Add : function () {
$.post($(form).attr('action'), $(form).serialize());
dialog.dialog('close');
},
Cancel: function () {
dialog.dialog('close');
}
}
});
if ($(a).attr('data-third')) {
// Add here a button
}
});
return false;
});
The idea is the resource in the modal contains a form, on submit of the modal the form is submitted. Now when Click me exists, it means a third button is placed in the modal in this order: Cancel | Add | Add & new.
I tried this code:
if($(a).attr('data-third')) {
var buttons = dialog.dialog('option', 'buttons');
buttons[$(a).attr('data-third')] = function(){
// Callback here
}
dialog.dialog('option', 'buttons', buttons);
}
I got a new button, but the order is Add & new | Cancel | Add. How can I make sure the order is Cancel | Add | Add & new?
With this code you should always get Cancel | Add | Add & new? (from left to right.
$('.popup').click(function() {
var a = this;
var dialog = $('<div>').load($(a).attr('href'), function() {
var form = dialog.find('form');
dialog.dialog({
modal: true,
title: $(a).attr('title'),
buttons: {
Cancel: function() {
dialog.dialog('close');
},
Add: function() {
$.post($(form).attr('action'), $(form).serialize());
dialog.dialog('close');
}
}
});
if ($(a).data('third')) {
var buttons = dialog.dialog('option', 'buttons');
console.log(buttons);
buttons[$(a).data('third')] = function() {
// Callback here
}
dialog.dialog('option', 'buttons', buttons);
}
});
return false;
});
Fiddle here: http://jsfiddle.net/rqq2p/1/
Remember to use data() and not attrib() to get the attribute from the link!
EDIT - basically "buttons" is an object, and each property is one of the buttons. I think that the order in which the buttons appear is the order in which the properties are added. In my example Cancel is the leftmost button because it was the first added property and add & new it's the rightmost because it was the latest. If you need to fiddle with the order you could create a new object and add the properties in the order you want:
if ($(a).data('third')) {
var buttons = dialog.dialog('option', 'buttons');
var newButtons = {};
newButtons[$(a).data('third')] = function() {
// Callback here
}
newButtons['Cancel'] = buttons['Cancel'];
newButtons['Add'] = buttons['Add'];
dialog.dialog('option', 'buttons', newButtons);//now add & new should be the leftmost
}
Untested, but I would imagine the array key should be buttons.length like this
if($(a).attr('data-third')) {
var buttons = dialog.dialog('option', 'buttons');
buttons[buttons.length] = function(){
// Callback here
}
dialog.dialog('option', 'buttons', buttons);
}

Categories

Resources