Example usage for org.apache.wicket.extensions.ajax.markup.html.autocomplete AutoCompleteSettings setUseSmartPositioning

List of usage examples for org.apache.wicket.extensions.ajax.markup.html.autocomplete AutoCompleteSettings setUseSmartPositioning

Introduction

In this page you can find the example usage for org.apache.wicket.extensions.ajax.markup.html.autocomplete AutoCompleteSettings setUseSmartPositioning.

Prototype

public AutoCompleteSettings setUseSmartPositioning(final boolean useSmartPositioning) 

Source Link

Document

Sets whether the popup positioning will take into account browser window visible area or not.

Usage

From source file:com.servoy.j2db.server.headlessclient.dataui.WebDataLookupField.java

License:Open Source License

private void init() {

    add(new HeaderContributor(new IHeaderContributor() {
        private static final long serialVersionUID = 1L;

        public void renderHead(IHeaderResponse response) {
            response.renderCSSReference(
                    new CompressedResourceReference(WebDataLookupField.class, "servoy_lookupfield.css")); //$NON-NLS-1$
        }//  w  w  w  .j  a  v a  2 s.  com
    }) {
        @Override
        public boolean isEnabled(Component component) {
            return !getScriptObject().isReadOnly() && getScriptObject().isEnabled();
        }
    });

    setOutputMarkupPlaceholderTag(true);

    AutoCompleteSettings behSettings = new AutoCompleteSettings();
    behSettings.setMaxHeightInPx(200);
    behSettings.setPreselect(true);
    behSettings.setShowCompleteListOnFocusGain(true);
    behSettings.setAdjustInputWidth(false);

    ClientProperties clp = (application.getApplicationType() != IApplication.HEADLESS_CLIENT
            ? ((WebClientInfo) Session.get().getClientInfo()).getProperties()
            : null); // in case of batch processors/jsp, we can't get browser info because UI is not given by web client components
    if (clp != null && (!clp.isBrowserInternetExplorer() || clp.getBrowserVersionMajor() >= 8)) {
        // smart positioning doesn't work on IE < 8 (probably because of unreliable clientWidth/clientHeight browser element js properties)
        behSettings.setUseSmartPositioning(true);
        behSettings.setUseHideShowCoveredIEFix(false); // don't know if the problem this setting is for can still be reproduced (I couldn't reproduce it)... this is true by default and makes fields in IE and Opera appear/dissapear if they would be covered by type-ahead popup
    } else {
        behSettings.setUseSmartPositioning(false);
        behSettings.setUseHideShowCoveredIEFix(true);
    }
    behSettings.setThrottleDelay(500);

    IAutoCompleteRenderer<Object> renderer = new IAutoCompleteRenderer<Object>() {
        protected String getTextValue(Object object) {
            String str = ""; //$NON-NLS-1$
            if (object instanceof DisplayString) {
                str = object.toString();
            } else if (object != null && !(object instanceof String)) {
                IConverter con = getConverter(object.getClass());
                if (con != null) {
                    str = con.convertToString(object, getLocale());
                } else {
                    str = object.toString();
                }
            } else if (object != null) {
                str = object.toString();
            }
            if (str == null || str.trim().equals("")) //$NON-NLS-1$
                str = "&nbsp;"; //$NON-NLS-1$
            return str;
        }

        protected void renderChoice(Object object, Response response, String criteria) {
            if (IValueList.SEPARATOR_DESIGN_VALUE.equals(object))
                return;
            String renderedObject = getTextValue(object);
            // escape the markup if it is not html or not just an empty none breaking space (null or empty string object)
            if (!renderedObject.equals("&nbsp;") && !HtmlUtils.hasHtmlTag(renderedObject)) //$NON-NLS-1$
                renderedObject = HtmlUtils.escapeMarkup(renderedObject, true, false).toString();
            response.write(renderedObject);
        }

        /*
         * (non-Javadoc)
         *
         * @see org.apache.wicket.extensions.ajax.markup.html.autocomplete.IAutoCompleteRenderer#render(java.lang.Object, org.apache.wicket.Response,
         * java.lang.String)
         */
        public void render(Object object, Response response, String criteria) {
            String textValue = getTextValue(object);
            if (textValue == null) {
                throw new IllegalStateException(
                        "A call to textValue(Object) returned an illegal value: null for object: "
                                + object.toString());
            }
            textValue = textValue.replaceAll("\\\"", "&quot;");

            response.write("<li textvalue=\"" + textValue + "\"");
            response.write(">");
            renderChoice(object, response, criteria);
            response.write("</li>");
        }

        /*
         * (non-Javadoc)
         *
         * @see org.apache.wicket.extensions.ajax.markup.html.autocomplete.IAutoCompleteRenderer#renderHeader(org.apache.wicket.Response)
         */
        @SuppressWarnings("nls")
        public void renderHeader(Response response) {
            StringBuffer listStyle = new StringBuffer();
            listStyle.append("style=\"");

            String fFamily = "Tahoma, Arial, Helvetica, sans-serif";
            String bgColor = "#ffffff";
            String fgColor = "#000000";
            String fSize = TemplateGenerator.DEFAULT_FONT_SIZE + "px";
            String padding = "2px";
            String margin = "0px";
            if (getFont() != null) {
                Font f = getFont();
                if (f != null) {
                    if (f.getFamily() != null) {
                        fFamily = f.getFamily();
                        if (fFamily.contains(" "))
                            fFamily = "'" + fFamily + "'";
                    }
                    if (f.getName() != null) {
                        String fName = f.getName();
                        if (fName.contains(" "))
                            fName = "'" + fName + "'";
                        fFamily = fName + "," + fFamily;
                    }
                    if (f.isBold())
                        listStyle.append("font-weight:bold; ");
                    if (f.isItalic())
                        listStyle.append("font-style:italic; ");

                    fSize = Integer.toString(f.getSize()) + "px";
                }
            }

            if (getListColor() != null && getListColor().getAlpha() == 255) {
                // background shouldn't be transparent
                bgColor = getWebColor(getListColor().getRGB());
            }
            if (getForeground() != null) {
                fgColor = getWebColor(getForeground().getRGB());
            }
            Insets _padding = getPadding();
            if (getPadding() != null)
                padding = _padding.top + "px " + _padding.right + "px " + _padding.bottom + "px "
                        + _padding.left + "px";

            listStyle.append("font-family:" + fFamily + "; ");
            listStyle.append("background-color: " + bgColor + "; ");
            listStyle.append("color: " + fgColor + "; ");
            listStyle.append("font-size:" + fSize + "; ");
            listStyle.append("min-width:" + (getSize().width - 6) + "px; "); // extract padding and border
            listStyle.append("margin: " + margin + "; ");
            listStyle.append("padding: " + padding + "; ");
            listStyle.append(
                    "text-align:" + TemplateGenerator.getHorizontalAlignValue(getHorizontalAlignment()));
            listStyle.append("\"");

            response.write("<ul " + listStyle + ">");
        }

        /*
         * (non-Javadoc)
         *
         * @see org.apache.wicket.extensions.ajax.markup.html.autocomplete.IAutoCompleteRenderer#renderFooter(org.apache.wicket.Response)
         */
        public void renderFooter(Response response) {
            response.write("</ul>"); //$NON-NLS-1$
        }

        /**
         * Returns web color representation of int rgba color by
         * removing the alpha value
         *
         * @param color int representation of rgba color
         * @return web color of form #rrggbb
         */
        private String getWebColor(int color) {
            String webColor = Integer.toHexString(color);
            int startIdx = webColor.length() - 6;
            if (startIdx < 0)
                startIdx = 0;
            webColor = webColor.substring(startIdx);

            StringBuilder sb = new StringBuilder();
            sb.append('#');
            int nrMissing0 = 6 - webColor.length();
            for (int i = 0; i < nrMissing0; i++) {
                sb.append('0');
            }
            sb.append(webColor);

            return sb.toString();
        }
    };

    AutoCompleteBehavior<Object> beh = new AutoCompleteBehavior<Object>(renderer, behSettings) {
        private static final long serialVersionUID = 1L;

        /**
         * @see org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteBehavior#getChoices(java.lang.String)
         */
        @Override
        protected Iterator<Object> getChoices(String input) {
            String filteredInput = filterInput(input);
            if (changeListener != null)
                dlm.getValueList().removeListDataListener(changeListener);
            try {
                dlm.fill(parentState, getDataProviderID(), filteredInput, false);
                return dlm.iterator();
            } catch (Exception ex) {
                Debug.error(ex);
            } finally {
                if (changeListener != null)
                    dlm.getValueList().addListDataListener(changeListener);
            }
            return Collections.emptyList().iterator();
        }

        /**
         * filters the input in case of masked input (removes the mask)
         */
        private String filterInput(String input) {
            String displayFormat = WebDataLookupField.this.parsedFormat.getDisplayFormat();
            if (displayFormat != null && displayFormat.length() > 0
                    && input.length() == displayFormat.length()) {
                int index = firstBlankSpacePosition(input, displayFormat);
                if (index == -1)
                    return input;
                return input.substring(0, index);
            }
            return input;
        }

        /**
         * Computes the index of the first space char found in the input and is not ' ' nor '*' in the format
         * Example:
         * input  '12 - 3  -  '
         * format '## - ## - #'
         * returns 6
         * @param input
         * @param displayFormat
         * @return The index of the first space char found in the input and is not ' ' nor '*' in the format
         */
        private int firstBlankSpacePosition(String input, String displayFormat) {
            for (int i = 0; i < input.length(); i++) {
                if ((input.charAt(i) == ' ') && (displayFormat.charAt(i) != ' ')
                        && (displayFormat.charAt(i) != '*'))
                    return i;
            }
            return 0;
        }

        /**
         * @see org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#getFailureScript()
         */
        @Override
        protected CharSequence getFailureScript() {
            return "onAjaxError();"; //$NON-NLS-1$
        }

        /**
         * @see org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#getPreconditionScript()
         */
        @Override
        protected CharSequence getPreconditionScript() {
            return "onAjaxCall();" + super.getPreconditionScript(); //$NON-NLS-1$
        }

        // need to set this behavior to true (enterHidesWithNoSelection) because otherwise the onKeyDown events
        // or other events for the component with type ahead would be null in Firefox, and would not execute as
        // expected on the other browsers...
        @Override
        public void renderHead(IHeaderResponse response) {
            settings.setShowListOnEmptyInput(Boolean.TRUE.equals(UIUtils.getUIProperty(getScriptObject(),
                    application, IApplication.TYPE_AHEAD_SHOW_POPUP_WHEN_EMPTY, Boolean.TRUE)));
            settings.setShowListOnFocusGain(Boolean.TRUE.equals(UIUtils.getUIProperty(getScriptObject(),
                    application, IApplication.TYPE_AHEAD_SHOW_POPUP_ON_FOCUS_GAIN, Boolean.TRUE)));
            if (!getScriptObject().isReadOnly() && getScriptObject().isEnabled()) {
                super.renderHead(response);
                response.renderJavascript("Wicket.AutoCompleteSettings.enterHidesWithNoSelection = true;", //$NON-NLS-1$
                        "AutocompleteSettingsID"); //$NON-NLS-1$
            }
        }

        /**
         * @see org.apache.wicket.behavior.AbstractBehavior#isEnabled(org.apache.wicket.Component)
         */
        @Override
        public boolean isEnabled(Component component) {
            IFormUIInternal<?> formui = findParent(IFormUIInternal.class);
            if (formui != null && formui.isDesignMode()) {
                return false;
            }
            return super.isEnabled(component) && WebClientSession.get().useAjax();
        }
    };
    add(beh);
}

From source file:org.hippoecm.frontend.plugins.console.menu.node.NodeDialog.java

License:Apache License

public NodeDialog(IModelReference<Node> modelReference) {
    this.modelReference = modelReference;
    final IModel<Node> nodeModel = modelReference.getModel();
    setModel(nodeModel);/*w  w  w.j  a  v  a2  s. c o m*/

    getParent().add(CssClass.append("node-dialog"));

    // list defined child node names and types for automatic completion
    final Node node = nodeModel.getObject();
    try {
        NodeType pnt = node.getPrimaryNodeType();
        for (NodeDefinition nd : pnt.getChildNodeDefinitions()) {
            if (!nd.isProtected()) {
                for (NodeType nt : nd.getRequiredPrimaryTypes()) {
                    if (!nt.isAbstract()) {
                        addNodeType(nd, nt);
                    }
                    for (NodeType subnt : getDescendantNodeTypes(nt)) {
                        addNodeType(nd, subnt);
                    }
                }
            }
        }
        for (NodeType nt : node.getMixinNodeTypes()) {
            for (NodeDefinition nd : nt.getChildNodeDefinitions()) {
                if (!nd.isProtected()) {
                    for (NodeType cnt : nd.getRequiredPrimaryTypes()) {
                        if (!cnt.isAbstract()) {
                            addNodeType(nd, cnt);
                        }
                        for (NodeType subnt : getDescendantNodeTypes(cnt)) {
                            addNodeType(nd, subnt);
                        }
                    }
                }
            }
        }
    } catch (RepositoryException e) {
        log.warn("Unable to populate autocomplete list for child node names", e);
    }

    AutoCompleteSettings settings = new AutoCompleteSettings();
    settings.setAdjustInputWidth(false);
    settings.setUseSmartPositioning(true);
    settings.setShowCompleteListOnFocusGain(true);
    settings.setShowListOnEmptyInput(true);
    // Setting a max height will trigger a correct recalculation of the height when the list of items is filtered
    settings.setMaxHeightInPx(400);

    final Model<String> typeModel = new Model<String>() {
        @Override
        public String getObject() {
            if (name != null && namesToTypes.containsKey(name)) {
                Collection<String> types = namesToTypes.get(name);
                if (types.size() == 1) {
                    type = types.iterator().next();
                }
            } else if (namesToTypes.size() == 1) {
                Collection<String> types = namesToTypes.values().iterator().next();
                if (types.size() == 1) {
                    type = types.iterator().next();
                }
            }
            return type;
        }

        @Override
        public void setObject(String s) {
            type = s;
        }
    };
    typeField = new AutoCompleteTextFieldWidget<String>("type", typeModel, settings) {
        @Override
        protected Iterator<String> getChoices(final String input) {
            Collection<String> result = new TreeSet<>();
            if (!Strings.isEmpty(name)) {
                if (namesToTypes.get(name) != null) {
                    result.addAll(namesToTypes.get(name));
                }
                if (namesToTypes.get("*") != null) {
                    result.addAll(namesToTypes.get("*"));
                }
            } else {
                namesToTypes.values().forEach(result::addAll);
            }
            Iterator<String> resultIter = result.iterator();
            while (resultIter.hasNext()) {
                if (!resultIter.next().contains(input)) {
                    resultIter.remove();
                }
            }
            return result.iterator();
        }

        @Override
        protected void onUpdate(final AjaxRequestTarget target) {
            if (isVisibleInHierarchy()) {
                target.add(nameField);
            }
        }
    };
    typeField.setRequired(true);
    add(typeField);

    final Model<String> nameModel = new Model<String>() {
        @Override
        public String getObject() {
            if (type != null && typesToNames.containsKey(type)) {
                if (name == null) {
                    Collection<String> names = typesToNames.get(type);
                    if (names.size() == 1) {
                        String _name = names.iterator().next();
                        if (!_name.equals("*")) {
                            name = _name;
                        }
                    }
                }
            } else if (typesToNames.size() == 1) {
                Collection<String> names = typesToNames.values().iterator().next();
                if (names.size() == 1) {
                    String _name = names.iterator().next();
                    if (!_name.equals("*")) {
                        name = _name;
                    }
                }
            }
            return name;
        }

        @Override
        public void setObject(String s) {
            name = s;
        }
    };
    nameField = new AutoCompleteTextFieldWidget<String>("name", nameModel, settings) {
        @Override
        protected Iterator<String> getChoices(String input) {
            Collection<String> result = new TreeSet<>();
            if (type != null && !type.isEmpty()) {
                if (typesToNames.get(type) != null) {
                    result.addAll(typesToNames.get(type));
                }
            } else {
                for (String nodeName : namesToTypes.keySet()) {
                    if (!nodeName.equals("*") && nodeName.contains(input)) {
                        result.add(nodeName);
                    }
                }
            }
            return result.iterator();
        }

        @Override
        protected void onUpdate(final AjaxRequestTarget target) {
            if (isVisibleInHierarchy()) {
                target.add(typeField);
            }
        }
    };
    nameField.setRequired(true);

    add(setFocus(nameField));
}

From source file:org.hippoecm.frontend.plugins.console.menu.property.PropertyDialog.java

License:Apache License

public PropertyDialog(IModelReference<Node> modelReference) {
    this.modelReference = modelReference;
    final IModel<Node> model = modelReference.getModel();

    getParent().add(CssClass.append("property-dialog"));

    // list defined properties for automatic completion
    choiceModel = new LoadableDetachableModel<Map<String, List<PropertyDefinition>>>() {

        protected Map<String, List<PropertyDefinition>> load() {
            Map<String, List<PropertyDefinition>> choices = new HashMap<>();
            Node node = model.getObject();
            try {
                NodeType pnt = node.getPrimaryNodeType();
                for (PropertyDefinition pd : pnt.getPropertyDefinitions()) {
                    List<PropertyDefinition> list = choices.get(pd.getName());
                    if (list == null) {
                        list = new ArrayList<>(5);
                    }/*from  www .  j  ava2s .c  om*/
                    list.add(pd);
                    choices.put(pd.getName(), list);
                }
                for (NodeType nt : node.getMixinNodeTypes()) {
                    for (PropertyDefinition pd : nt.getPropertyDefinitions()) {
                        List<PropertyDefinition> list = choices.get(pd.getName());
                        if (list == null) {
                            list = new ArrayList<>(5);
                        }
                        list.add(pd);
                        choices.put(pd.getName(), list);
                    }
                }
                // remove already set properties from suggestions:
                final Set<String> properties = new HashSet<>(choices.keySet());
                for (String property : properties) {
                    if (!isResidual(property) && node.hasProperty(property)) {
                        choices.remove(property);
                    }
                }
            } catch (RepositoryException e) {
                log.warn("Unable to populate autocomplete list for property names", e);
            }
            return choices;
        }
    };

    // checkbox for property ismultiple
    final CheckBox checkBox = new CheckBox("isMultiple", new Model<Boolean>() {

        @Override
        public void setObject(Boolean multiple) {
            PropertyDialog.this.isMultiple = multiple;
        }

        @Override
        public Boolean getObject() {
            if (PropertyDialog.this.name != null) {
                List<PropertyDefinition> propdefs = choiceModel.getObject().get(PropertyDialog.this.name);
                if (propdefs != null) {
                    for (PropertyDefinition pd : propdefs) {
                        if (PropertyType.nameFromValue(pd.getRequiredType()).equals(type)) {
                            // somehow need to set isMultiple here, otherwise it doesn't get picked up...
                            PropertyDialog.this.isMultiple = pd.isMultiple();
                            return pd.isMultiple();
                        }
                    }
                }
            }
            return PropertyDialog.this.isMultiple;
        }
    });
    checkBox.setOutputMarkupId(true);
    add(checkBox);

    // dropdown for property type
    final DropDownChoice<String> ddChoice = new DropDownChoice<String>("types") {
        @Override
        public List<? extends String> getChoices() {
            if (PropertyDialog.this.name != null) {
                List<PropertyDefinition> propdefs = choiceModel.getObject().get(PropertyDialog.this.name);
                if (propdefs != null) {
                    List<String> result = new ArrayList<>(propdefs.size());
                    for (PropertyDefinition pd : propdefs) {
                        result.add(PropertyType.nameFromValue(pd.getRequiredType()));
                    }
                    return result;
                }
            }
            return ALL_TYPES;

        }
    };
    ddChoice.setModel(new Model<String>() {
        @Override
        public void setObject(String object) {
            type = object;
        }

        @Override
        public String getObject() {
            List<? extends String> choices = ddChoice.getChoices();
            if (choices.size() == 1) {
                type = choices.iterator().next();
            }
            return type;
        }
    });

    ddChoice.setRequired(true);
    ddChoice.setOutputMarkupId(true);
    ddChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
        @Override
        protected void onUpdate(AjaxRequestTarget target) {
        }
    });
    add(ddChoice);

    values = new LinkedList<>();
    values.add("");

    final WebMarkupContainer valuesContainer = new WebMarkupContainer("valuesContainer");
    valuesContainer.setOutputMarkupId(true);
    add(valuesContainer);

    valuesContainer.add(new ListView<String>("values", values) {

        @Override
        protected void populateItem(final ListItem<String> item) {
            final TextField textField = new TextField<>("val", item.getModel());
            textField.add(new OnChangeAjaxBehavior() {

                @Override
                protected void onUpdate(final AjaxRequestTarget target) {
                }

            });
            item.add(textField);

            if (focusOnLatestValue && item.getIndex() == (values.size() - 1)) {
                AjaxRequestTarget ajax = RequestCycle.get().find(AjaxRequestTarget.class);
                if (ajax != null) {
                    ajax.focusComponent(textField);
                }
                focusOnLatestValue = false;
            }

            final AjaxLink deleteLink = new AjaxLink("removeLink") {
                @Override
                public void onClick(final AjaxRequestTarget target) {
                    values.remove(item.getIndex());
                    target.add(valuesContainer);
                }

                @Override
                public boolean isVisible() {
                    return super.isVisible() && item.getIndex() > 0;
                }
            };

            deleteLink.add(TitleAttribute.set(getString("property.value.remove")));
            deleteLink.add(new InputBehavior(new KeyType[] { KeyType.Enter }, EventType.click) {
                @Override
                protected String getTarget() {
                    return "'" + deleteLink.getMarkupId() + "'";
                }
            });
            item.add(deleteLink);
        }
    });

    final AjaxLink addLink = new AjaxLink("addLink") {
        @Override
        public void onClick(final AjaxRequestTarget target) {
            values.add("");
            target.add(valuesContainer);
            focusOnLatestValue = true;
        }

        @Override
        public boolean isVisible() {
            return isMultiple;
        }
    };
    addLink.add(TitleAttribute.set(getString("property.value.add")));
    addLink.add(new InputBehavior(new KeyType[] { KeyType.Enter }, EventType.click) {
        @Override
        protected String getTarget() {
            return "'" + addLink.getMarkupId() + "'";
        }
    });
    valuesContainer.add(addLink);

    checkBox.add(new AjaxFormComponentUpdatingBehavior("onchange") {
        @Override
        protected void onUpdate(AjaxRequestTarget target) {
            target.add(valuesContainer);
            if (!isMultiple && values.size() > 1) {
                String first = values.get(0);
                values.clear();
                values.add(first);
            }
        }
    });

    // text field for property name
    AutoCompleteSettings settings = new AutoCompleteSettings();
    settings.setAdjustInputWidth(false);
    settings.setUseSmartPositioning(true);
    settings.setShowCompleteListOnFocusGain(true);
    settings.setShowListOnEmptyInput(true);
    // Setting a max height will trigger a correct recalculation of the height when the list of items is filtered
    settings.setMaxHeightInPx(400);

    final TextField<String> nameField = new AutoCompleteTextFieldWidget<String>("name",
            PropertyModel.of(this, "name"), settings) {

        @Override
        protected Iterator<String> getChoices(String input) {
            List<String> result = new ArrayList<>();
            for (String propName : choiceModel.getObject().keySet()) {
                if (propName.contains(input)) {
                    result.add(propName);
                }
            }
            return result.iterator();
        }

        @Override
        protected void onUpdate(final AjaxRequestTarget target) {
            super.onUpdate(target);

            target.add(ddChoice);
            target.add(checkBox);
            target.add(valuesContainer);
            focusOnLatestValue = true;
        }
    };

    nameField.setRequired(true);
    add(nameField);
    setFocus(nameField);
}