sandra1n
sandra1n

Reputation: 143

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;
  });

Upvotes: 7

Views: 20723

Answers (5)

Edward Li
Edward Li

Reputation: 61

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;
  };

Upvotes: 6

Renato Gama
Renato Gama

Reputation: 16519

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.

Upvotes: 1

sandino
sandino

Reputation: 3842

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}'
        ),  

Upvotes: 0

HMagdy
HMagdy

Reputation: 3295

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')});

Upvotes: 0

Paul S
Paul S

Reputation: 1239

Try adding a return to the onclick:

a href="http://example.com" onclick="return confirm("you want to go?")">

Upvotes: -3

Related Questions