0

I have a drop-down menu:

<ace:selectMenu value="#{MenuBean.cityList}" valueChangeListener="#{MenuBean.ChCountry}">
    <f:selectItems itemValue="cityList.id" itemLabel="cityList_nm_city" />
</ace:selectMenu>

City List

and an input field

<h:inputText id="form:nm" value="#{MenuBean.nm}" />  

TEXT Box

which uses jQuery autocomplete

$(document).ready(function() {
    $("#form\\:nm").autocomplete({
        source : function(request, response) {
            $.ajax({
                url : url,
                data : {
                    method : "getnm",
                },
                success : function(data) {
                    alert("success");
                }
            });
        }
    });
});

When I change the drop-down and update JSF components, then jQuery autocomplete does not work anymore. How is this caused and how can I solve it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Ravi Kavaiya
  • 829
  • 6
  • 16

1 Answers1

2

If I got it right, my guess is that you re-rendering the input somewhere.

Remember that re-rendering a component will not make the $(document).ready function execute again, so #form\\:nm won't have the autocomplete wired to it. If you're using an f:ajax to refresh a component, just create a JS funciton that wires the autocomplete to the component and call it on the onevent of that f:ajax.

Something like this:

function loadAutocompleteField(data) {
    if(data.status == "success") {
        $("#form\\:nm").autocomplete({
            source : function(request, response) {
                $.ajax({
                    url : url ,
                    data : {
                        method : "getnm",
                    },
                    success : function(data) {
                        alert("success");
                    }
                });
            }
        });
    }
}

Again, for example, if you use an f:ajax:

<f:ajax render="yourComponent" onevent="loadAutocompleteField" />

If you use another mechanism, you just need to invoke the loadAutocompleteField function once you're done.


Edit

Indeed my original answer was inefficient. My usual approach was to search for a widget-related CSS and, if it was loaded, I'd avoid wiring the widget again. Turns out that f:ajax's onevent function can receive a data argument which contains the status of the whole ajax request cycle (before ajax request is sent > complete means that the ajax response has arrived > success updating the components based on the ajax response).

You'll want to check up that argument and wire the component only after the DOM has been updated.

Thanks to BalusC for helping me to sort this out. That's SO for you, I've learnt something by answering a question.

Fritz
  • 9,987
  • 4
  • 30
  • 49
  • This is inefficient. The `onevent` handler is invoked 3 times during an ajax request. – BalusC Jun 25 '13 at 15:52
  • @BalusC Well, yes, indeed, I didn't consider that. Since autocomplete doesn't nest the related components on the element it is wired on it COULD be possible to restrict the `autocomplete` from being added thrice by adding a check that determines if the widget has been already loaded, but this might get tricky if the OP has more than one autocomplete. I'll search a couple of things before fixing my mess. – Fritz Jun 25 '13 at 16:19
  • Related: http://stackoverflow.com/questions/13540298/proccess-onclick-function-after-ajax-call-fajax/13540905#13540905 and http://stackoverflow.com/questions/13081129/how-to-re-execute-javascript-function-after-form-rerender/13085569#13085569 – BalusC Jun 25 '13 at 16:21
  • @BalusC You have my thanks (again). God! is there ANYTHING you don't know about JSF? – Fritz Jun 25 '13 at 16:59
  • 1
    That's better. JSF is after all just Java code and all it generates is after all just HTML and JS. I know Java, HTML and JS pretty well :) – BalusC Jun 25 '13 at 17:07