Question

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>
Was it helpful?

Solution

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

OTHER TIPS

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

This question is several years old, but I still have a project using YUI 2.9.0 and I just ran into the same issue, so I'll share my solution in case someone else finds themselves in the same jam.

Several things worth noting about this question. First, the problem Gabriel describes, where the YUI 2.9.0 Button click handler submits the form before your click handler gets called is not a problem on IE, at least through IE9. On FireFox through at least FF12, the problem occurs. I suspect it would also be a problem in Chrome, Safari, and most if not all other browsers as well as I see what appears to be a special case for IE in the YUI Button click handler.

Also, I didn't like any of the solutions Gabriel suggested. Using a link button invalidated all the custom styling I had applied to my submit button, using the mousedown handler loses some of the user interface semantics of a click, and for some reason YUI Button was losing track of the original name I gave the submit button or, at least, it wasn't showing up in the POSTed values on the server side. In the spirit of Gabriel's link button, however, I replaced the submit button with an input button which does not submit by default, then added a hidden input and submitted the form myself:

...

<form id='form'>
    <input type="button" value="&gt;" id="start_survey">

...

function start_survey (p_oEvent, p_aArgs) {
    var input = document.createElement ('input');
    input.type = 'hidden';
    input.name = this.get ('name');
    input.value = '&gt;'

    var form = YAHOO.Dom.get ('form');
    form.appendChild (input);
    form.submit();
}

new YAHOO.widget.Button ("start_survey", {onclick: {fn: start_survey}});

...

Finally, since YUI is submitting the form on click, yet another solution should be just to catch the form's submit event and check if the event target is your button, do what you need to do, then let the submit go or stop it, as needed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top