Hello,

I have migrated my application from Wicket 1.4 to 1.7. Everything is
working fine except default focus behavior for
page with dynamic number of text area. The behavior is working fine with
1.4.

Here is my requirement:
On clicking row from the grid, application opens modal window with left and
right frame. Left frame has tabs with different
panels associated with each tab. Right side frame shows page with list of
(radio choice + text area). The number of items in
this list is dynamic; based upon number of responses from database.

Now when the modal is displayed, I want the default focus set to the first
text area component on right side whose radio choice
is not yet selected. Once user makes the choice and update the result, the
focus should then go to the next unchecked text area
component (allowing user to mark the radio choice without manual scroll).

The focus is working fine, but issue is that half of the time the page is
not scrolled up to that text area, so user needs to manually scroll
to that component. This was not the case with 1.4. The focus was set as
well as the page was auto scrolled(every time)
to the component; making that component visible.

Following is the code snippet for reference. The CustomerDetailsModalPage
has left and right frame. Right frame contains the
CustomerDetailsResponsePage.
CustomerDetailsResponsePage has ListView<Responses> which has radio and
text area panel (CustomerDetailsResponsePanel inside CollapsiblePanel).
CustomerDetailsResponsePanel has TextArea with DefaultFocusBehavior
(Behavior class at the bottom).

Could anybody please help or guide me here? My apologies if
description/code is confusing.


Class CustomerDetailsModalPage
================================
public CustomerDetailsModalPage() {
        super();

        CustomerDetailsRequestPage leftFramePage = new
CustomerDetailsRequestPage();
        getSession().getPageManager().touchPage(leftFramePage);

        // get the url to that page
        IRequestHandler leftFrameHandler = new RenderPageRequestHandler(new
PageProvider(leftFramePage));

        FramePage leftPage = new FramePage("leftFrame", leftFrameHandler);
        add(leftPage);


        CustomerDetailsResponsePage rightFramePage = new
CustomerDetailsResponsePage();
        getSession().getPageManager().touchPage(rightFramePage);

        // get the url to that page
        IRequestHandler rightFrameHandler = new
RenderPageRequestHandler(new PageProvider(rightFramePage));

        FramePage rightPage = new FramePage("rightFrame",
rightFrameHandler);
        add(rightPage);

}


Class CustomerDetailsResponsePage:
====================================

 ListView<Responses> responseList = new ListView<Responses>("object.list") {

.....
//Generate TextArea and radio button panel component for each response from
the list.
@Override
    protected void populateItem(final ListItem<Responses> item) {
final Responses response = item.getModelObject();
//Add Radio choice for Y/N radio buttons
RadioChoice matchFlag = new RadioChoice("matchFlag",
yesNoList).setSuffix("&nbsp;&nbsp;&nbsp;&nbsp;");
matchFlag.setMarkupId("matchFlagId".concat(String.valueOf(item.getIndex()))).setOutputMarkupId(true);
item.add(matchFlag);
//Add Accordion style panel to show Text Area with response text
CollapsiblePanel collapsiblePanel = new CollapsiblePanel("collPanel",
                        new Model<String>("Matching Criteria " +
matchingContent), true) {
@Override
protected Panel getInnerPanel(String markupId) {
//Set Page focus if needed by checking if response already marked match Y
or N.
//If nothing selected then set the focus to the associated text area
component
if (response.getMatchFlag() == null){
response.setMatchFlagIndicator(AppConstants.SET_FOCUS);// SET_FOCUS = 1
}
//Reusable Panel with Text Area
return new CustomerDetailsResponsePanel(markupId, response.getContent(),
response.getMatchFlagIndicator());
}
}
collapsiblePanel.setOutputMarkupId(true);
item.add(collapsiblePanel);
}
 }

Class CustomerDetailsResponsePanel
===================================
public CustomerDetailsResponsePanel(String id, String responseContent,
final int setFocus) {
super(id);

if (responseContent != null) {
responseContent = responseContent.replaceAll("(&#10)", "");
responseContent = responseContent.replaceAll(";{2,}", ";");
responseContent = responseContent.replaceAll(";", "\n");
}

TextArea<String> response = new TextArea<String>("response", new
Model<String>(responseContent));
response.setOutputMarkupId(true);
if (setFocus == AppConstants.SET_FOCUS) {
response.add(new DefaultFocusBehavior());
}
add(response);
}


Class DefaultFocusBehavior
===========================
public class DefaultFocusBehavior extends Behavior {
    private static final long serialVersionUID = -4891399118136854774L;

    private Component component;
    String markupId;

    public DefaultFocusBehavior() {
    }

    @Override
    public void bind(Component component) {
        if (!(component instanceof FormComponent)) {
            throw new IllegalArgumentException("DefaultFocusBehavior:
component must be instanceof FormComponent");
        }
        this.component = component;
        component.setOutputMarkupId(true);
    }


    @Override
    public void renderHead(Component component, IHeaderResponse
iHeaderResponse) {

        super.renderHead(component, iHeaderResponse);

        String focusStr = "setTimeout(function() {
document.getElementById('"
   + component.getMarkupId()
+ "').focus(); }, 100);";

        iHeaderResponse.render(OnLoadHeaderItem.forScript(focusStr));

        String ieFocusStr = "if (navigator.appName == 'Microsoft Internet
Explorer')  setTimeout(function() { document.getElementById('"
                + component.getMarkupId()
                + "').focus(); }, 400)";
        iHeaderResponse.render(OnLoadHeaderItem.forScript(ieFocusStr));
    }
}

Reply via email to