1

I'm trying to implement select (and focus) the component based on validation decision.

For example:

  • login form (2 inputs: username, password; 1 submit button)
  • if the validation fail on username, <h:inputText id="name"> will be focused
  • if the validation fail on password, <h:inputSecret id="password"> will be focused
  • page will not be refreshed, submit is an ajax button

What I've tried:

without ajax call (this is working fine - componentId is set in bean in validation proccess, and selected/focused after each page refresh/submit):

$(document).ready(function() {
  document.getElementById('form:#{bean.componentId}').focus();
  document.getElementById('form:#{bean.componentId}').select();
});
...
<h:commandButton id="save" action="#{bean.save}" type="submit"/>

BUT with ajax call:

function myFunc(data) {
  if (data.status == "success") {
    var element = document.getElementById('form:#{bean.componentId}');
    element.focus();
    element.select();
}}
...
<h:commandButton id="save" action="#{bean.save}" type="submit">
  <f:ajax execute="@form" render="@form" onevent="myFunc"/>
</h:commandButton>

This way is also working, problem is, componentId is still the same (the one, which is inicialized during bean creation).

Previous questions related to this topic:

How can I use ajax submit button and select/focus to the field with validation error???

Community
  • 1
  • 1
gaffcz
  • 3,469
  • 14
  • 68
  • 108

1 Answers1

3

The non-ajax submit re-renders basically the entire page, including the scripts. The ajax submit re-renders only a part of the page, which is in your particular case only the form itself (as controlled by <f:ajax render> attribute). The scripts are apparently not placed in the form and hence they keep the "old" values (you know, EL #{} runs in webserver and doesn't run in webbrowser, so at the moment the webbrowser retrieves the HTML/JS code, EL has already run for long, it won't be re-executed when you call the JS code).

You need to put the script block with those EL expressions in the same form as well, so that it will also be updated on ajax submit.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Interesting. It really appears to be working. I've placed the script inside the form, `componentId` is choosen almost correctly but It's retarded of one cycle (first submit leads to initial value of `componentId`, the next one focus to the field which should be focused step before, etc.etc.), and sometimes, all the ajax submit buttons completely stops working (no response) – gaffcz Nov 25 '12 at 15:07
  • When I keep the script outside the form and use ``, it works better, but it's a bit slower and the ajax submits also stop working. After page reload, everything seems to be "ok" – gaffcz Nov 25 '12 at 15:16
  • Next thing I've tried - changing `onevent` attr in `f:ajax` by `onclick` attr in `h:commandButton` leads to correct `componentId` choosing and buttons are working always. But its behaviour is very strange, data are saved to DTB twice (with step about 200ms), and so on :( – gaffcz Nov 25 '12 at 15:53
  • It's easier to understand if you in turn understand that JSF is just a HTML code generator. Open page in browser, rightclick and *View Source*. You don't see any line of JSF code in there. JavaScript runs as being a client side language in browser only, not in server. – BalusC Nov 25 '12 at 16:27
  • As to the concrete functional requirement, all this mess can more nicely be solved by OmniFaces' ``. See also https://showcase-omnifaces.rhcloud.com/showcase/components/highlight.xhtml – BalusC Nov 25 '12 at 16:28
  • Aha, thank you. I know that JSF generate HTML code, but I'm not able find the problem there. Working and non working submit button are completely the same. But I'll try to check it out. And the last question before I start to investigate omnifaces, are they able to highlight server side validation error (my componentId choosing)? Thank you, Balusc – gaffcz Nov 25 '12 at 17:28