JavaScript dialog pop up event wait for OK to be pressed - javascript

I got a delete (input submit) button which pops up a dialog (Alloy UI dialog, html) when clicked:
A.all("#RFB input.ConfirmDelete").each(function(node){
node.on('click', function(event) {
if(confirmed) {
showUserWaitDialog();
return true;
}
else {
deactivateKeyboardNav();
deleteConfirm(node, confirmDeleteMessage, function () { //Runs the function rendering the pop up
confirmed = true;
event.target.click();
showUserWaitDialog();
});
}
});
});
The problem is that the event is running async and thus performs the deletion, and not waiting for the user to click OK (calling the callback).
The deleteConfirm takes the following arguments
function deleteConfirm(link, pText, callback) {
The content in the pop up consists of:
var bodyContent = '<div class="vl-info vl-message"><h2>'+titleText+'</h2>'+
'<p>'+pText+'</p>' +
'<p class="more button-area">'+confirmButtonText+''+discardButtonText+'</p></div>';
And the button functions:
A.one('.deleteOK').on('click', function(e){
(jQuery.isFunction(callback)) && callback.apply();
confirmDialog.close();
confirmDialogOpen = false;
});
A.one('.deleteNotOK').on('click', function(e){
confirmDialog.close();
confirmDialogOpen = false;
return false;
});
How should I approach this?

Alloy UI provides a nice Dialog box API. It may be worth to see this example and apply for your requirement.
var dialog = new A.Dialog({
title : '<your dialog box title here>',
centered: true,
modal: false,
width: 600,
height: 250,
bodyContent: <You can keep the message to display here>,
buttons: [
{
label: 'Delete',
id: 'deleteBtn',
handler: function() {
//Place code to delete here. It get executed when user click on Delete button.
}
},
{
label: 'Cancel',
id: 'cancelActionItemBtn',
handler: function() {
this.close();
}
}
]
}).render();

Related

ExtJs (v 6.0.0, classic) Message box with custom text and forms

I want to have a workflow in ExtJs where I display a modal dialog in which someone needs to enter some data into a form and then presses the 'OK' to move on.
As far as I have seen the basic Ext.MessageBox could be a good fit in the first place.
But the documentation just describes a 'message' property. This one seems to be very restricted to me.
What I need is a custom form to be displayed as main body.
A custom form with three toggle buttons and a textarea.
Not some prefigured single and simple textfields or textareas.
How can that be done? - Is the Ext.MessageBox not the right item to use?
Building a modal window does not feel correct as well since there are a lot of configurations which need to be done on top.
Did I miss something? Is the problem understandable?
What I have so far:
Ext.Msg.show({
title:'Title',
message: 'Here we should see another form with 3 togglable buttons and a textarea...',
buttons: Ext.Msg.OK,
icon: Ext.Msg.QUESTION,
fn: function(btn) {
console.log('button: '+ btn)
if ( btn !== 'ok' ) { return; }
},
});
And this is somewhat what it should look like...
Of course it would be nice to react on the user's input after OK is pressed. Any hints are welcome as well.
I added showDialog function to window class by overriding it.
You can call showDialog by passing parentWindow and only parentWindow will be masked
showDialog: function(parentWindow) {
var me = this;
me.parentWindow = parentWindow;
parentWindow.disableByMask();
parentWindow.on({
show: me.onParentShown,
destroy: me.onParentDestroyed,
hide: me.onParentHid,
maskclick: me.onParentMaskClicked,
scope: me
});
me.show();
},
disableByMask: function() {
var me = this;
me.setLoading("");
me.loadMask.msgWrapEl.hide();
var el = me.loadMask.getEl();
el.setStyle({ opacity: 0 });
el.on({
mousedown: function () {
el.setStyle({ backgroundColor: "#CCCCCC", opacity: .5 });
me.fireEvent("maskclick", me, el);
},
mouseup: function () {
el.setStyle({ backgroundColor: "#FFF", opacity: 0 });
}
});
},
hideDisabledMask: function() {
var me = this,
el = me.loadMask.getEl();
me.setLoading(false);
el.setStyle({ backgroundColor: "rgba(204, 204, 204, .5)", opacity: 1 });
me.loadMask.msgWrapEl.show();
me.loadMask.msgEl.show();
me.loadMask.msgTextEl.show();
},
onParentShown: function() {
var me = this;
me.show();
},
onParentDestroyed: function() {
var me = this;
me.close();
},
onParentHid: function() {
var me = this;
me.hide();
},
onParentMaskClicked: function() {
var me = this;
me.zIndexManager.bringToFront(me);
},
onDestroy: function() {
var me = this;
if (me.parentWindow) {
me.parentWindow.hideDisabledMask();
me.parentWindow.un("show", me.onParentShowed, me);
me.parentWindow.un("destroy", me.onParentDestroyed, me);
me.parentWindow.un("hide", me.onParentHid, me);
me.parentWindow.un("maskclick", me.onParentMaskClicked, me);
}
me.callParent();
}
Instead of using Ext.MessageBox, you have to create a customized pop up window with 3 buttons and a text area as items and a tbar button with text OK. For that button you have to use handler for your necessary actions i.e..,
tbar =[
{
text: 'Ok',
handler: function() {
var textAreaValue = Ext.getCmp('text-area-id').getValue();
}
}
];

Form in Bootbox Dialog

I want to display a Bootbox dialog that includes an "OK" button. When the user clicks the "OK" button, it should POST back, with the ID of the message to confirm that the user has viewed the message. The Bootbox dialog is the form. I don't see a way to make the dialog buttons a submit form with hidden fields, which is what I assume is the right way to accomplish my goals.
Thanks to the helpful comments from Isabel Inc and Mistalis, I have a working solution.
Notes specific to my implementation:
The messages contain images that need to be responsive, so I add the appropriate Bootstrap classes to each image
The messages may have links. Clicking a link is equivalent to clicking "OK" on the dialog
And the JavaScript that makes it happen...
jQuery(function($, window, bootbox, undefined) {
var accept = function(callback) {
$.ajax({
type: 'POST',
data: {message_id: 244826},
success: callback()
});
};
var $message = $('<p><img src="https://www.gravatar.com/avatar/80fa81938a6d1df92cd101d7fe997a71" alt></p><p>Here is a message from Sonny.</p>');
$message.find('img').addClass('img-responsive center-block');
$message.find('a').on('click', function(e) {
var href = $(this).attr('href');
if (0 === href.length) {
return;
}
e.preventDefault();
accept(function() { window.location.href = href; });
});
bootbox.dialog({
message: $message,
closeButton: false,
buttons: {
accept: {
label: 'OK',
callback: function() {
accept(function() { window.location.reload(); });
}
}
}
});
}(jQuery, window, bootbox));

js override confirm

I want to try to override window.confirm function with modal dialog.
<a href="http://example.com" onClick="return confirm('you want to go?')">
<script>
window.confirm = function(message){
$("#confirm-dialog").modal('show');
$("#confirm-dialog .modal-body p").html(message);
$("#confirmYes").on("click", function () {
return true;
});
}
</script>
When I click in modal window on the #confirmYes element it returns true, but the redirect by href link will not work...Why?
Can somebody tell me how I can do this thing without changing my link?
Thanks
UPD
Yii framework generates that code for CGridView widget and i want to override it. I can't change this code, because its in framework. Instead this confirm standard i want to use my modal window
$(document).on('click','#product-grid a.delete',function() {
if(!confirm('Are you sure you want to delete this item?')) return false;
var th=this;
var afterDelete=function(){};
$.fn.yiiGridView.update('product-grid', {
type:'POST',
url:$(this).attr('href'),
success:function(data) {
$.fn.yiiGridView.update('product-grid');
afterDelete(th,true,data);
},
error:function(XHR) {
return afterDelete(th,false,XHR);
}
});
return false;
});
Here is a practice that we used in my company in a UI conversion project.
It is ugly though, but it works just fine.
var clickState={};
var justClicked=null;
window.confirm = function(message) {
var e = window.event || window.confirm.caller.arguments[0];
var el = e.target || e.srcElement; // the element's click that triggers confirm dialog
if(justClicked && clickState[justClicked]===true){
clickState[justClicked]=false;
return true;
}else{
// your async style confirmation dialog (e.g. jQuery's dialog)
showConfirmBox(message, function() {
justClicked=el;
clickState[el]=true;
$(justClicked).click(); // in the call back function , click the target again.
});
}
return false;
};
Js default confirm dialog work synchronously, it means that code will wait for the user to make his choice to continue. When you override confirm dialog this way what happens is that your new stylish confirm dialog is shown but method end immediately and returns undefined.
You can work with callbacks;
<a href="http://example.com" onClick="confirm('you want to go?', function(result){
if(result)
//code to redirect, like window.location(this.href);
}); return false;">
then:
<script>
window.confirm = function(message, cb){
$("#confirm-dialog").modal('show');
$("#confirm-dialog .modal-body p").html(message);
$("#confirmYes").on("click", function (userChoice) {
cb(userChoice); //true or false - your jquery plugin will supply this value
});
}
</script>
EDIT: Its important to keep the link url on href (instead of just leaving "/#") for SEO reasons - for the link not be triggered you should also return false after calling your new confirm dialog.
If you need Overriding the window.alert() dialog box you can find it here
after that I have create my own Overriding the window.confirm() dialog box you can find it here
Overriding the window.confirm() dialog box.
It is pretty simple just like:
window.confirm = function(message, title, doYes) {
$(document.createElement('div'))
.attr({title: title, class: 'confirm'})
.html(message)
.dialog({
buttons: {
"Confirm": function() {
$(this).dialog("close");
if (doYes && (typeof doYes === "function")) {
doYes();
}
},
"Cancel": function() {
$(this).dialog("close");
}
}
,
close: function() {
$(this).remove();
},
draggable: true,
modal: true,
resizable: false,
width: 'auto'
});
};
// New confirm
//confirm('This is a <strong>new</strong> alert!','Confirm', function(){alert('Yes')},function(){alert('No')});
I know it is an old post but I want to share my solution, I know this changes the yii default behaviour but I replaced their function for one custom working the same way, I am gonna ask yii gurus about a better way or if in the future this can be done easily.
In framework/yii/zii/widgets/grid/CButtonColumn.php modify the initDefaultButtons:
/**
* Initializes the default buttons (view, update and delete).
*/
protected function initDefaultButtons()
{
if($this->viewButtonLabel===null)
$this->viewButtonLabel=Yii::t('zii','View');
if($this->updateButtonLabel===null)
$this->updateButtonLabel=Yii::t('zii','Update');
if($this->deleteButtonLabel===null)
$this->deleteButtonLabel=Yii::t('zii','Delete');
if($this->viewButtonImageUrl===null)
$this->viewButtonImageUrl=$this->grid->baseScriptUrl.'/view.png';
if($this->updateButtonImageUrl===null)
$this->updateButtonImageUrl=$this->grid->baseScriptUrl.'/update.png';
if($this->deleteButtonImageUrl===null)
$this->deleteButtonImageUrl=$this->grid->baseScriptUrl.'/delete.png';
if($this->deleteConfirmation===null)
$this->deleteConfirmation=Yii::t('zii','Are you sure you want to delete this item?');
foreach(array('view','update','delete') as $id)
{
$button=array(
'label'=>$this->{$id.'ButtonLabel'},
'url'=>$this->{$id.'ButtonUrl'},
'imageUrl'=>$this->{$id.'ButtonImageUrl'},
'options'=>$this->{$id.'ButtonOptions'},
);
if(isset($this->buttons[$id]))
$this->buttons[$id]=array_merge($button,$this->buttons[$id]);
else
$this->buttons[$id]=$button;
}
if(!isset($this->buttons['delete']['click']))
{
if(is_string($this->deleteConfirmation))
$confirmation="if(!confirm(".CJavaScript::encode($this->deleteConfirmation).")) return false;";
else
$confirmation='';
if(Yii::app()->request->enableCsrfValidation)
{
$csrfTokenName = Yii::app()->request->csrfTokenName;
$csrfToken = Yii::app()->request->csrfToken;
$csrf = "\n\t\tdata:{ '$csrfTokenName':'$csrfToken' },";
}
else
$csrf = '';
if($this->afterDelete===null)
$this->afterDelete='function(){}';
$withConfirmation = strlen($confirmation) == 0 ? 0 : 1;
$confirmationMessage = CJavaScript::encode($this->deleteConfirmation);
$this->buttons['delete']['click']=<<<EOD
`function(event) {
event.preventDefault();
if ($withConfirmation){
var th=this;
var afterDelete=$this->afterDelete;
var deleteUrl=$(this).attr('href');
console.log(deleteUrl);
$(document.createElement('div')).attr({
title:'AtenciĆ³n',
'class': 'dialog'
}).html($confirmationMessage).dialog({
buttons: {
"OK": function () {
$(this).dialog('close');
$.fn.yiiGridView.update('{$this->grid->id}', {
type:'POST',
url:deleteUrl,$csrf
success:function(data) {
$.fn.yiiGridView.update('{$this->grid->id}');
afterDelete(th,true,data);
},
error:function(XHR) {
return afterDelete(th,false,XHR);
}
});
return true;
},
"Cancel": function () {
$(this).dialog('close');
return false;
}
},
close: function () {
$(this).remove();
},
draggable: false,
modal: true,
resizable: false,
width: 'auto'
}).position({
my: "center",
at: "center",
of: window
});
}
}
EOD;
}
}
`
EDIT:
I also learned how to do it without modify core yii:
In you widget grid you a file for the buttons like this:
array
(
'class'=>'CButtonColumn',
'deleteConfirmation'=>'Atencion',
'buttons'=>array
(
'update'=>array
(
'imageUrl'=>FALSE,
'label'=>'update',
'options'=>array('title'=>'update'),
'visible'=>'$row > 0'
),
'delete'=>array
(
'imageUrl'=>FALSE,
'label'=>'delete',
'options'=>array('title'=>'delete'),
'click'=>'function(){$("#mydialog").dialog("open"); return false;}',
),
),
'template'=>'{update} | {delete}'
),
Try adding a return to the onclick:
a href="http://example.com" onclick="return confirm("you want to go?")">

jQuery UI Dialog with Confirmation

I have a jQuery UI dialog that gets a line of text. If this text is not contained in a localStorage dictionary, I insert it into the dictionary. If it is present, I want to give the user the option not to overwrite the existing entry in the "ok" handler.
Because jQuery UI dialogs are stateful and persist across multiple calls unless explicitly removed (AFAICT), I'm not seeing a clear path to presenting the "are you sure you want to nuke your previous entry?" alert without resorting to ... uh ... alert.
The question, succinctly stated: Can you create a confirmation box from inside a jQuery UI Dialog?
Thanks.
I have not used jQuery UI Dialog, but you can always create your own html elements and do whatever you wish with them, including layering them on top of the jQuery dialog.
I guess you could have googled something to find these links:
Anyways have it and make fun:
JQuery Dialogs
Jquery Confirmation
Cheers!!!
Ok, it turned out the best way I found to handle this was using closures. Like this (pseudo-code):
getThingieName: handler(function() {
var $dialog;
$dialog = $('<div id="thingie-name-dialog" class="ui-widget"></div>').html("<p>Enter a name for this thingie</p>\n<input type=\"text\" id=\"dlg-thingie-name\" style=\"width: 80%\" />").dialog({
autoOpen: false
}, {
title: 'enter a name',
modal: true,
buttons: {
Add: function() {
var value = $('#dlg-thingie-name').val();
$(this).dialog('close');
$('#thingie-name-dialog').remove();
return handler(value); // <= closure to handle the onAdd
},
Cancel: function() {
$(this).dialog('close');
return $('#thingie-name-dialog').remove();
}
}
});
return $dialog.dialog('open');
}),
getConfirmation: function(message, handler) {
var $dialog;
$dialog = $('<div id="confirmation-dialog" class="ui-widget"></div>').html("<p>" + message + "</p>").dialog({
autoOpen: false
}, {
title: 'confirm overwrite',
modal: true,
buttons: {
Ok: function() {
$(this).dialog('close');
$('#confirmatio-dialog').remove();
return handler(true); // <= closure to handle onOk
},
Cancel: function() {
$(this).dialog('close');
$('#Thingie-name-dialog').remove();
return handler(false); // <= closure to handle onCancel
}
}
});
return $dialog.dialog('open');
}
// Calling sequence
Snippets.getSnippetName(function(value) {
if (value == null) return false;
if (localStorage.getItem(value)) {
getConfirmation("This thingie, " + value + ", already exists. Overwrite?", function(response) {
if (response) return localStorage.setItem(value, snippet);
});
} else {
localStorage.setItem(value, snippet);
}
}
This may not be the optimal code, but it does make the triggering of the dialogs dependent on the button push by embedding them in the handlers.

How do I get a JQuery statement to wait until it's completed before continuing?>

Firstly, I'm new at Javascript / Jquery so it might be a stupid question...
I'm using the dialog box that is in the JQuery UI collection. I have a button that when clicked, it either shows a confirm box or an alert box. My code is like below...
function checkfn() {
if (document.getElementById('<%=HomeInstSelected.ClientID%>').value == 'False') {
var dialogResult = false;
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
Continue: function () {
dialogResult = true;
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close").slideUp();
}
}
});
// alert just debug code!
alert(dialogResult);
return dialogResult;
}
else {
$("#dialog-HomeInstitutionPrompt").dialog({
height: 140,
modal: true
});
}
}
My problem is in the confirm part, it seems the confirm box is not waiting for me to hit Continue or Cancel - it's just going straight to the alert part and returning dialogResult = false.
Is it possible to halt execution of until after I've run the $('#dialog-confirm') command?
Alternatively, is it possible to return true for the checkfn() function, in the Continue function? That way, I will not need a dialogResult var at all?
I haven't used the .dialog in jQuery UI before, but, in general with jQuery, functions are run asynchronously. What this means is that you need to put the code that you want run in the Continue function.
One possibility is to send a success/cancel function to checkfn that you would call from the Continue and Cancel functions.
function checkfn(success, cancel) {
if (document.getElementById('<%=HomeInstSelected.ClientID%>').value == 'False') {
var dialogResult = false;
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
Continue: function () {
if(success) success();
$(this).dialog("close");
},
Cancel: function () {
if(cancel) cancel();
$(this).dialog("close").slideUp();
}
}
});
}
You can call the function like this:
checkfn(function () {
alert('success!');
}, function () {
alert('failure!');
});
Just put everything you want to do inside "Continue" and "Cancel" button definitions. So, you will not need a dialogResult and alert will hit when it is needed.
if (document.getElementById('<%=HomeInstSelected.ClientID%>').value == 'False') {
var dialogResult = false;
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
Continue: function () {
alert('Dialog result is true. I can do whatever I want here');
$(this).dialog("close");
},
Cancel: function () {
alert('Cancel is clicked. I should go on my life');
$(this).dialog("close").slideUp();
}
}
});
}
else {
$("#dialog-HomeInstitutionPrompt").dialog({
height: 140,
modal: true
});
}
-- You can't return a value for your function, because after initialization of the function, the code goes on. You need to fill Continue button definition.
This is something I struggled with when I started too, The code doesn't run as it reads on the page. When you call the dialog function it executes asynchronously. The continue and cancel functions are bound to the click actions on the buttons, meanwhile the code below the dialog function runs without waiting for the events.
Long story short the result needs to happen in the cancel and continue callbacks.
Problem is you're trying to return a boolean value when you should really pass the resulting functions in instead. Alot of things in jquery and javascript in general work that way. Thankfully the language provides the ability to program in this way.
function checkfn( resultfn(boolval) ) {
if (document.getElementById('<%=HomeInstSelected.ClientID%>').value == 'False') {
var dialogResult = false;
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
Continue: function () {
resultfn.call( this, true );
$(this).dialog("close");
},
Cancel: function () {
resultfn.call( this, false );
$(this).dialog("close").slideUp();
}
}
});
}
Put the if statement in "resultfn"
I had a similar frustrating problem where the jQuery dialog box would submit a form before the user had a chance to choose Yes or No.
Example HTML:
<form id="myForm" method="POST" action="/Where/To/Go">
<input type="submit" value="Submit" onclick="submitForm()"/>
</form>
And jQuery:
function submitForm() {
$('<div title="Submit Form>Are you sure you wish to submit the form?</div>').dialog({
modal: true,
buttons: [
{
text: "Yes",
click: function () {
$('#myForm').submit();
$(this).dialog("close");
}
}, {
text: "No",
click: function () {
$(this).dialog("close");
}
}
]
});
}
To fix the issue I changed the button from a submit type to a button type which stopped it submitting and triggering the jQuery dialog at the same time:
<input type="button" value="Submit" onclick="submitForm()"/>

Categories

Resources