views:

453

answers:

2

I'm using YUI 2.7.0 and Struts for my project and have a form with two submit buttons. One is for Save and the other is for Delete. The form submits to a DispatchAction. I've added the onclick listeners successfully, but the problem is that the form submits before the listeners execute. I need to set the dispatch parameter before the form submits. How do I do this? Below is what I have so far:

<form name="adminUserForm" method="post" action="manage_user.do">
  <input type="hidden" id="dispatch" name="dispatch" value="unspecified"/>
  <!-- other form fields here -->
  <input type="submit" value="Save User" id="saveUser">
  <input type="submit" value="Delete User" id="deleteUser">
</form>
<script type="text/javascript"> 
  function confirmDelete(msg)
  {
    if (confirm(msg))
    {
      return setDispatchMethod("delete");
    }
    else
      return false;
  }
  function setDispatchMethod(methodName)
  {
    dispatchField = document.getElementById("dispatch");
    dispatchField.value = methodName
    return true;
  }
  var onClickSaveUser = function (e)
  {
    return setDispatchMethod('save');
  };
  var onClickDeleteUser = function (e)
  {
    return confirmDelete('Are you sure you want to delete the user?');
  };
  new YAHOO.widget.Button("deleteUser",   {onclick: {fn: onClickDeleteUser }});
  new YAHOO.widget.Button("saveUser",     {onclick: {fn: onClickSaveUser   }});
</script>
A: 

here is an easy solution

<form>
    <input type="submit" name='dispatch' value="Save User" id="saveUser">
    <input type="submit" name='dispatch' value="Delete User" id="deleteUser">
</form>

you can remove the hidden input

and your dispatch request variable will be set to "Save User" if the first button is clicked

or "Delete User" is the 2nd is clicked

Dapeng
Except that the value of "dispatch" must be used as the name of the method in the DispatchAction class.
Gary Kephart
+1  A: 

The problem is Yahoo's code for the Button widget handles the click event, and in it, they programatically submit the form. Their event handler is called before yours, so the form is submitted before your event handler even gets called.

Here are some ideas (they all work):

METHOD 1

Handle the mousedown event instead of the click event (mousedown fires before click).

var deleteUserButton = new YAHOO.widget.Button("deleteUser");
deleteUserButton.on("mousedown", onClickDeleteUser);

var deleteUserButton = new YAHOO.widget.Button("saveUser");
deleteUserButton.on("mousedown", onClickSaveUser);

//Using this, you can easily stop the form from submitting
//by using YAHOO's event utility (by adding this code, you
//will prevent the click event from firing as well).

YAHOO.util.Event.preventDefault(e); 

METHOD 2

Use type=link instead of type=submit (default). They only submit the form if the type = submit (I haven't tested this enough to see if the form still submits by itself - you may have to manually call form.submit())

new YAHOO.widget.Button("deleteUser", { type: 'link', onclick: { fn: onClickDeleteUser} });
new YAHOO.widget.Button("saveUser", { type: 'link', onclick: { fn: onClickSaveUser} });

METHOD 3

Looking at their code, I noticed that they create a hidden field with the name of the button that was clicked to submit the form (ONLY that button). The input tag has to have a name attribute, and yours doesn't, so you would have to add one. Then on the server, you just check for that hidden field's value (your value attribute).

No matter which of these methods you use, you should be using this to stop the form from submitting:

YAHOO.util.Event.preventDefault(e); 
Gabriel McAdams
Hmm, sounds close, but the missing element, which I may not have expressed clearly in my example code (onClickDeleteUser should return the value of confirmDelete, which should return true/false), is that if Delete User is pressed, I don't want the form submitted. According to this link, though, it still would be:http://yuilibrary.com/forum/viewtopic.php?p=1216
Gary Kephart
@Gary: I have added much more detail to my answer. Please have a look.
Gabriel McAdams