views:

85

answers:

5

Goal

I've got a web page with a table of items. Each item has a delete button beside it. When that button is clicked, I want to

  • Ask the user to confirm
  • Delete the corresponding item from the database
  • Remove that item's row from the list

Current solution

Right now, I'm doing something like this:

$('button.delete').click(function(){
  thisRow = $(this).parent();
  itemID = $(this).parent().attr('id');
  if (confirm('Are you sure?')){
   $.post('/manage_items.php', {"action":"delete", "itemid":itemID}, function(){
     thisRow.hide("slow").remove();
   });
  } 
}

This solution works because each button.delete can determine which row and item it belongs to, and act accordingly.

Desired solution

Instead of the clunky "OK or Cancel" alert box, I'd like to use a jQuery UI dialog box. But I'm not sure how to let the dialog know which row and item it should handle on any given click.

Here's how you set it up:

1) Define a dialog box div

<div class="dialogbox" id="confirmdeleteitem" title="Really DELETE this item?">
   <p>Gee golly, are you s-s-s-sure you want to do that?!</p>
</div>

2) Set up the dialog box behavior

$('#cofirmdeleteitem').dialog({
                //other options - not relevant here
      buttons: {
        "Nevermind": function() {
   //do nothing
         },
                  "Alright! Woo!": function(){
                   //do something
                  }
       }
 });

3) Set the click event that will open the dialog

$('button.delete').click(function(){
    $('#confirmdeleteitem').dialog('open');    
});

In this last step, I'd like to be able to pass some information to the dialog - which delete button was clicked, for example. But I don't see a way to do that.

I could insert a hidden dialog div.dialog into each item row up front, or insert one into a particular row after its button is clicked. Then the $(this).parent() references would grab the correct row...

Is there an easier way to do this?

A: 

You could store the row in a global variable, like this:

var deletingId;
$('button.delete').click(function() {
    deletingId = $(this).parent().attr('id');

    $('#confirmdeleteitem').dialog('open');    
});
$('#confirmdeleteitem').dialog({
    //other options - not relevant here
    buttons: {
        "Never mind": function() { },
        "Alright! Woo!": function(){
            $.post(
                '/manage_items.php', 
                { action: "delete", itemid: deletingId },
                function() {
                    $('#' + deletingId).hide("slow").remove();
                }
            );
        }
    }
});

This will only work if the dialog is modal; otherwise, the user could click two different delete links, and you'd need multiple dialogs.

SLaks
A: 

Why can't you just call a setup method to build the dialog as you see fit?

setupMyDialog( '#confirmdeleteitem', info1, info2 ); 
$('#confirmdeleteitem').dialog...

Alternatively, just store the information in global space before you show the dialog. Remember that your javascript variables can have global scope, or you can store information arbitrarily on objects/functions (which are just objects).

myDataStore = {};

myDataStore.row = foo;
myDataStore.col = bar;
Stefan Kendall
+1  A: 

i do something like this:

        function ConfirmationDialog(title, question, options) {
            var d = $('<div title="' + title + '"><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>' + question + '</p></div>');
            d.dialog({
                bgiframe: true,
                resizable: false,
                height: 190,
                width: 350,
                modal: true,
                overlay: {
                    backgroundColor: '#000',
                    opacity: 0.5
                },
                buttons: options
            });
        }

and then call my function from the click event.

hyun
A: 

You could add the "rel" attribute to the dialog and store it there, instead. That way you don't need to worry about global variables, and it's semantically not-too-bad, since you are defining a relationship between the dialog and a row. So it'd just be $('#confirmdeleteitem').attr('rel', $(this).parent().attr('id').dialog('open');

Nathan
A: 

It ended up being most straightforward to set up the dialog behavior inside the click function itself. Actually, it's not much different than my original example.

$('button.delete').click(function(){
    thisRow = $(this).parent().parent();
    thisRow.css("background-color","red");
    skuid = $(this).parent().parent('tr').attr('id').substr(5);
    $('#dialogbox').dialog({
      autoOpen: false,
      modal: true,
      draggable: true,
      width: 600,
      buttons: {
        "Actually, I can just mark it inactive": function() {
          thisRow.css("background-color","inherit");
          $(this).dialog("close");
        },
        "This SKU needs to be deleted": function() {
          $.post('/intranet/backstage/modify_sku_info.php', {"action":"delete", "skuid":skuid}, function(result){
            thisRow.hide("slow").remove();
          });
          $(this).dialog("close");
        }
      }
    });
    $('#dialogbox').dialog('open');
    return false;
  });

Since div#dialogbox doesn't get hidden until $('#dialogbox').dialog() is called, I just gave it an inline style of display:none.

If I end up needing something that can be generalized, as hyun suggested, I'll revisit the issue.

Nathan Long