JSF custom component will lose input focus on ajax update

I am writing a custom autocomplete component as a training exercise with JSF 2.1.3. The idea (which is probably pretty familiar) is to enter some text in and the input component and present a list box with the corresponding values. The idea is to trigger an input javascript event that calls jsf.ajax.request () to update the component. So far I have a component that I can enable like this:

<mycc:autocomplete id="myauto" searchMethod="#{bean.doSearch}"/> 

This displays the html as follows:

 <span id="myauto"> <input type="text" id="myauto_input" name="myauto_input" onkeyup="com.myco.ajaxRequest(this, event)"/> <select id="myauto_listbox" name="myauto_listbox"> <option value="1st">First</option> <option value="2nd">Second</option> </select> </span> 

The javascript function com.myco.ajaxRequest () (keyup) does this:

 jsf.ajax.request(comp, null, { execute: 'myauto', render: 'myauto' }); 

So, because I want to rebuild and rewrite the list with list clauses, I will reprogram the custom component "myauto". By specifying execute: "myauto" executes the decode () method, and I can get the input value. From the definition of render: 'myauto' encode methods ... () execute to regenerate the html.

This is normal, but because I pass the parent element to the myauto_input component, I lose input focus every time the keyup event fires.

If I specify something like render: 'myauto_listbox' (I really want to rerender listbox after all) the problem is that the encode methods ... () are not executed, since they are intended for the user component as a whole, and not just for a list. And that would be in one of the encode methods ... (), which I am rebuilding a list containing sentences.

The component extends UIInput, and I generate the markup in a separate renderer (componentFamily = "javax.faces.Input") in the encodeEnd () method (so it always starts after any supplied converter is not yet implemented). I believe that focusing with javascript is a terrible hack and should be avoided.

I'm a little unsure where to go with this, but I suspect that what I see indicates that I am somehow approaching this wrong. If anyone would be good enough to point me in the right direction, I would really appreciate it.

+6
source share
1 answer

I spent some time studying this and the general problem of losing focus after ajax update is quite common and described in the Jim Driscoll blog (see "Keeping focus").

In the case of my custom component, I (I think ...) need to update the custom component which is the parent input element, so I will lose focus as a result of ajax, and it is as it is. So I looked at what should be to restore focus, and it seems that in my visualization code I just have to forcefully restore focus to the input, but only when responding to POST sent from the onkeyup jsf.ajax.request event. I use jQuery and just calling .focus () is not enough, because you also need to get the cursor position to the end of any existing input. This code below works fine:

 <script> jQuery(function($){var cid='#myauto_input';$(cid).focus().focus().click();$(cid).val($(cid).val());}); </script> 

(note:. focus (). focus (). click () is required for IE8, just .focus () works on chrome ...)

So, it seems like a terrible hack saved the day. I wondered if there would be any difference if I used jQuery ajax routines and not the jsf ajax library, but I don’t think it would matter.

+1
source

Source: https://habr.com/ru/post/895631/


All Articles