2

I have a problem on a production financial system where when users change the value of a numeric input field (so onchange function fires) and immediately click the form submit button, nothing happens - the submit button just remains active (pushed in) but form does not submit.

In real system I thought it was AJAX causing this but when I created this simplified version it still happens (I have included the button styles so you can see the stuck down button in Firefox). Happens in IE also but button does not remain stuck in.

i.e

  1. If you click into field and then click submit it works (form submits).

  2. If you click into field, change the value of field, click somewhere else (so onchange fires), and then click submit it works.

but..

  1. If you click into field, change the value of field, and then immediately click submit (without clicking anywhere else) it does not work (form does not submit but onchange function fires)

What am I doing wrong? I thought it was a focus problem or a return true false from function problem but it is beyond me now...

Can't ask financial users to click somewhere else after changing values before submission...

Using FF46 and IE11

EDIT: actually I notice that removing the alert from the onchange function fixes it, but in real system the function contains AJAX calls such as:

new Ajax.Updater ('amount_1','/path/page-ajax',{asynchronous:false,method:'post',parameters:'widget_name=amount_1&row=1&local_currency='+55+'&payment_id='+552+'&currency_code_id='+$F('currency_code_id')+'&currency_amount='+$F('amount')+'&update_amount_total_p=0'});

and the problem reappears when there is AJAX in the onchange function.

<html lang="en">
<head>

<script type="text/javascript">
function convertAmount(Obj)
    {
    alert('convertAmount');
    }
</script>

<style>
input[type="button"], input[type="reset"], input[type="submit"] {
    background: rgba(0, 0, 0, 0) linear-gradient(to bottom, rgba(246, 248, 249, 1) 0%, rgba(229, 235, 238, 1) 50%, rgba(215, 222, 227, 1) 51%, rgba(245, 247, 249, 1) 100%) repeat scroll 0 0;
    border: 1px outset #eee;
    border-radius: 4px;
    color: #536c80;
    cursor: pointer;
    font-family: "Trebuchet MS",Arial,Helvetica,sans-serif;
    font-weight: normal;
    margin: 2px;
    overflow: visible;
    padding: 4px 15px;
}
input[type="button"]:hover, input[type="reset"]:hover, input[type="submit"]:hover {
    background: rgba(0, 0, 0, 0) linear-gradient(to bottom, rgba(246, 248, 249, 1) 0%, rgba(237, 237, 192, 1) 50%, rgba(226, 226, 170, 1) 51%, rgba(245, 247, 249, 1) 100%) repeat scroll 0 0;
}
input[type="button"]:active, input[type="reset"]:active, input[type="submit"]:active {
    background: rgba(0, 0, 0, 0) linear-gradient(to bottom, rgba(246, 248, 249, 1) 0%, rgba(237, 237, 192, 1) 33%, rgba(226, 226, 170, 1) 37%, rgba(245, 247, 249, 1) 100%) repeat scroll 0 0;
    border: 1px inset #fff;
}

</style>
</head>

<body onsubmit="alert('submit');">

<form action="testbug2" method="post">

<input id="amount" type="text" maxlength="20" size="15" onchange="convertAmount(this);" value="2,612" name="amount">

<input type="submit" value="Save" name="formbutton:save">

</form>

</body>
</html>
geogan
  • 55
  • 7

2 Answers2

1

It's the alert call in convertAmount that is causing the problem. If you change alert('convertAmount') to console.log('convertAmount'), for example, it behaves as you would expect.

See http://jsbin.com/qoqifikehi/edit?html,console,output

Joe Attardi
  • 4,381
  • 3
  • 39
  • 41
  • Yes I just found that myself a few minutes ago, I have edited the question - the problem still happens in real system when there are AJAX calls in the onchange function, so whatever the alert call does, it appears AJAX calls do too. – geogan May 26 '16 at 15:20
  • @geogan Its probably when there is change outside the document - alert is browser, AJAX is server? Would an onclick event function for the ""save" input be better - it can do whatever and then submit? – TBB May 26 '16 at 15:43
  • @TBB The AJAX calls must be on the input fields. They modify others fields on form and lots of other server side DB stuff that user needs. Can't move them to submit button. – geogan May 26 '16 at 15:48
  • @geogan I am a TOTAL js novice and shouldn't be here. But your issue appears to me to boil down to causing a "focus loss" on the active input. Can't a function triggered by save onclick include a statement to do that before doing the submit action? For similar thinking, see here: http://stackoverflow.com/questions/23112925/trigger-input-onchange-while-input-is-active-focus and here on http://stackoverflow.com/questions/6458840/on-input-change-event – TBB May 26 '16 at 16:26
0

Per my comment, the problem seems to be ACTIVE state of the input (IE in focus AND contents changed - not just in focus). When active, clicking the Save submit fires the onchange event and the submit action is done.

So you want to change the active state and trigger the alert before the submit action.

One work-around might be to change the active state before the submit action by using mouseover on the submit button - although this could also be built into a function fired by onclick of the submit too.

Using your example, here is the mouseover work-around:

<html lang="en">
<head>

<script type="text/javascript">
function convertAmount(Obj)
    {
    alert('convertAmount');
    }
function loseFocus() {
    var focusedElement = document.activeElement;
    {focusedElement.blur();}

}
</script>

<style>
input[type="button"], input[type="reset"], input[type="submit"] {
    background: rgba(0, 0, 0, 0) linear-gradient(to bottom, rgba(246, 248, 249, 1) 0%, rgba(229, 235, 238, 1) 50%, rgba(215, 222, 227, 1) 51%, rgba(245, 247, 249, 1) 100%) repeat scroll 0 0;
    border: 1px outset #eee;
    border-radius: 4px;
    color: #536c80;
    cursor: pointer;
    font-family: "Trebuchet MS",Arial,Helvetica,sans-serif;
    font-weight: normal;
    margin: 2px;
    overflow: visible;
    padding: 4px 15px;
}
input[type="button"]:hover, input[type="reset"]:hover, input[type="submit"]:hover {
    background: rgba(0, 0, 0, 0) linear-gradient(to bottom, rgba(246, 248, 249, 1) 0%, rgba(237, 237, 192, 1) 50%, rgba(226, 226, 170, 1) 51%, rgba(245, 247, 249, 1) 100%) repeat scroll 0 0;
}
input[type="button"]:active, input[type="reset"]:active, input[type="submit"]:active {
    background: rgba(0, 0, 0, 0) linear-gradient(to bottom, rgba(246, 248, 249, 1) 0%, rgba(237, 237, 192, 1) 33%, rgba(226, 226, 170, 1) 37%, rgba(245, 247, 249, 1) 100%) repeat scroll 0 0;
    border: 1px inset #fff;
}


</style>
</head>

<body onsubmit="alert('submit');" >

<form action="testbug2" method="post">

<input id="amount" type="text" maxlength="20" size="15" onchange="convertAmount(this);" value="2,612" name="amount">

<input id="thingy" type="submit" value="Save" onmouseover="loseFocus()" name="formbutton:save">

</form>

</body>
</html>

I was going to comment again because I am a JS novice, but it was easier to use this for size reasons.

TBB
  • 1,207
  • 1
  • 14
  • 25
  • Yes that appears to work alright. I'll just have to see how easy it is to put this into the production system where all elements are built dynamically (including the submit buttons) and test it out and then get back to you... I wonder though, if the AJAX calls (four or five I think) in the onchange take some time to run (maybe a second or more), would they immediately stop or cancel if the focus changes as user hovers over submit and submit runs (which triggers more AJAX calls during submit)... I'll have to see – geogan May 27 '16 at 11:54