Wicket
  1. Wicket
  2. WICKET-1716

make autocompleter more customizable

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.3.5, 1.4-M3
    • Component/s: wicket-extensions
    • Labels:
      None

      Description

      disclaimer: Excuse this somehow large explanation

      Problems in current wicket autocompleter implementation (including patch)

      Wicket will by default make the width of the autocompleter the same as the width of the related input field. This is often useful but also can be really nasty sometimes. Imagine you have a text input field to enter the ISBN of a book (size: 13 digits). While typing any parts of the book's title, author, genre, year or ISBN the autocompleter should pop up a list of book entries which contain the matching input string:

      autocompleter output (structure)

      — item 1 —
      ISBN 1
      AUTHOR 1
      TITLE 1
      GENRE 1
      YEAR 1
      — item 2 —
      ISBN 2
      AUTHOR 2
      TITLE 2
      GENRE 2
      YEAR 2
      --------------
      ...
      — item n —

      When pressing enter the input field will be set to the ISBN of the currently selected book.

      BTW since WICKET-488 is resolved the other read-only fields of the form will contain title, author, etc. (Thanks, Igor!!

      Now the problem: Typically the width of the autocompleter entry shown in the popup (especially the book title) will be a lot longer than the 13 digit ISBN number. The only chance to grow the wicket autocompleter window to the required size is to make the input field ridiculously long so the windows will adjust to that size. This is really ugly and wastes a lot of space in the user interface for no reason. Also it will confuse the user who thinks the input really needs to be that long.

      Typically wicket's autocompleter markup looks like this:

      HTML

      <div id="isbn1-autocomplete-container" style="overflow: auto; position: absolute; left: 8px; top: 30px; width: 155px;" class="wicket-aa-container">
      <div class="wicket-aa" id="text1-autocomplete">
      <ul>
      <li class="selected" textvalue="978-1932394986">.....</li>
      <li textvalue="978-1932394222">.....</li>
      ....
      <li textvalue="978-1932311186">.....</li>
      </ul>
      </div>
      </div>

      The 'style' attribute in the <div> contains 'width:155px' and is impossible to override from CSS because 'style' is "stronger" (the 'cascading' in css).

      So I attached a patch to enable / disable the adjustment of the width to the input field.

      JAVA

      final AutoCompleteSettings opts = new AutoCompleteSettings();
      opts.setAdjustInputWidth(false);
      field.add(new AutoCompleteBehavior(renderer, opts)
      ...

      The markup will now look like this:

      HTML

      <div id="isbn1-autocomplete-container" style="overflow: auto; position: absolute; left: 8px; top: 30px;" class="wicket-aa-container">

      Notice the lack of the 'width' attribute...

      Now to resolve the problem you could write:

      MYSTYLE.CSS

      .wicket-aa-container

      { width: 300px; }

      However this will not only grow the great book autocompleter to the desired width but also all other autocompleters ever being used on the same page (or the scope of the CSS). Also you can NOT do this:

      MYSTYLE.CSS

      #isbn1-autocomplete-container

      { width: 300px; }

      Because a linked stylesheet is typically static (and cached by the browser) and the DOM id of the autocompleter is generated dynamically. And, no: I don't consider generating dynamic CSS an option for such a simple problem.

      So what would be just great is the possibility to add an extra css class to the container tag:

      JAVA

      final AutoCompleteSettings opts = new AutoCompleteSettings();
      opts.setCssClassName("book-autocompleter");
      opts.setAdjustInputWidth(false);
      field.add(new AutoCompleteBehavior(renderer, opts)
      ...

      HTML

      <div id="isbn1-autocomplete-container" style="overflow: auto; position: absolute; left: 8px; top: 30px;" class="wicket-aa-container book-autocompleter">

      You will immediately notice the additional class name 'book-autocompleter'

      MYSTYLE.CSS

      .book-autocompleter

      { width: 300px; }

      To summarize my patch:

      Two extra methods in org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteSettings

      /**

      • Sets an CSS class name to add to the autocompleter markup container
      • <p/>
      • This makes it easier to have multiple autocompleters in your application
      • with different style and layout.
        *
      • @param cssClassName valid CSS class name
        */
        public void setCssClassName(final String cssClassName)

      /**

      • Adjust the width of the autocompleter selection window to the width of the related input field.
      • <p/>
      • Otherwise the size will depend on the default browser behavior and CSS.
        *
      • @param adjustInputWidth <code>true</code> if the autocompleter should have the same size as
      • the input field, <code>false</code> for default browser behavior
        */
        public void setAdjustInputWidth(final boolean adjustInputWidth)

      Unless you call these methods the autocompleter will behave exactly as before so this will not break previous code.

      Would be just great to see this patch applied

        Activity

        Hide
        Peter Ertl added a comment -

        Wow, that was quick! Thank you

        Show
        Peter Ertl added a comment - Wow, that was quick! Thank you
        Hide
        Unua added a comment - - edited

        Hum sorry to come again on that problem but it's still the same.
        When adjust with is false, width is write as "auto" value. So it's not possible to override it with css as width is indicates in style attribut.

        Why not just not output it ?

        Show
        Unua added a comment - - edited Hum sorry to come again on that problem but it's still the same. When adjust with is false, width is write as "auto" value. So it's not possible to override it with css as width is indicates in style attribut. Why not just not output it ?
        Hide
        Unua added a comment -

        Sorry for my previous comment.
        Just use the div inside container to set the width.

        Show
        Unua added a comment - Sorry for my previous comment. Just use the div inside container to set the width.

          People

          • Assignee:
            Igor Vaynberg
            Reporter:
            Peter Ertl
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development