Sorry to revive an old thread, however I have since come up with something that seems to work 100%. I thought I should share in-case someone else finds it useful.

Firstly, you need to override the default CSS for tapestry. It is wrong in some areas eg ul margin and just ugly in others (who uses brown by default?):

div.t-autocomplete-menu ul {border:1px solid #ccc; background-color:#fff; margin:0; padding:0; box-shadow:0 3px 8px rgba(0, 0, 0, 0.3);} div.t-autocomplete-menu ul li {border:none; color:#000; padding:0 5px;} div.t-autocomplete-menu ul li.selected {background-color:#eee; font-weight:normal;}

Everyone who uses the autocomplete should do this, whether you go on to patch the JS or not. I would also suggest this (or similar) makes it into the tapestry-core code because what is currently in there will never line up properly.

Secondly, there is a bug with prototype.Element.clonePosition which (unless margins are not used) will make the options impossible to line up with the input field on all browsers. It is mentioned here: https://prototype.lighthouseapp.com/projects/8886/tickets/1139-elementcloneposition-delta-wrong

This was however was never resolved, however I found the poster's patch to work well for this case. Since it didn't pass the prototypejs tests I only use the patch for this case.

/**
 * adapted from post by capripot
* https://prototype.lighthouseapp.com/projects/8886/tickets/1139-elementcloneposition-delta-wrong
 */
var PrototypePatch = {Element: {clonePosition: function(element, source) {
    var options = Object.extend({
        setLeft:    true,
        setTop:     true,
        setWidth:   true,
        setHeight:  true,
        offsetTop:  0,
        offsetLeft: 0
      }, arguments[2] || { });

      source = $(source);
var p = Element.viewportOffset(source), delta = [0, 0], parent = null;

      element = $(element);

      if (Element.getStyle(element, 'position') == 'absolute') {
        parent = Element.getOffsetParent(element);
        delta = Element.viewportOffset(parent);
      }

      if (parent == document.body)
        delta[0] = delta[1] = 0;

if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; if (options.setWidth) element.style.width = source.offsetWidth + 'px'; if (options.setHeight) element.style.height = source.offsetHeight + 'px';
      return element;
    }}};

Now, to get this patch used by the component, you need to set the options.onShow for the js component constructor. To do this you will need to override the tapestry Autocomplete mixin and implement 'configure'

    @Override
    protected void configure(JSONObject config)
    {
        super.configure(config);

// change the behavior for showing the menu - this resolves issues with the scriptaculous component
        config.put("onShow", new JSONLiteral("AutocompletePatch.onShow"));
    }

And then the new mixin will need to find the js somewhere:

// adapted from Scriptaculous 1.9.0 controls.js to fix its bugs
AutocompletePatch.onShow = function(element, update)
{
    if (!update.style.position || update.style.position == "absolute")
    {
        update.style.position = "absolute";
        PrototypePatch.Element.clonePosition(update, element, {
            setHeight: false,
            offsetTop: element.getHeight()
        });
    }
    Effect.Appear(update,{duration:0.15});
};

So to wire all this together you will need

1. a new Mixing extending the tapestry.mixin.Autocomplete
2. Give the new mixin a css Import
3. Give the new mixin a js Import

I've written a mixin for this which also adds support for the 'afterUpdateElement' handler in the scriptaculous component so that I can execute client side/server side code when an option is selected.

Regards, Paul.

On 14/05/2010 6:53 PM, Paul Stanton wrote:
actually, further investigation shows that the value for 'top' cannot be overridden by js at 'onload' or similar, because the 'top' value is set every time the div is displayed. i suppose if i could attach a client side listener for 'menuDisplayed' (or the like) i could change the value.

further, having tested in both IE and FF the positioning of the div is inconsistent.

in IE, the right hand side of the div is aligned to the right hand side of the text box (bad), and it sits directly under the text box (good).

in FF, the div is the same width as the text box (good), the div is aligned to the text box (good), and it sits 17px below the text box (bad).

I'm not sure why the behaviours are different, or if some of this is configurable.

p.

Paul Stanton wrote:
yes, i was hoping to be able to change the value for 'top' before the component was rendered on the page (if that were possible), but i'm sure i can change the value after the page is rendered. i will try.

fyi, changing the definition of the class 't-autocomplete-menu' would not override the inline style attribute value, the only clientside solution would be to get the div by id and set the top programmatically.

p.

Steve Eynon wrote:
Ol' Firebug tells me the autocomplete div looks like this:

<div
    id="countryName:menu"
    class="t-autocomplete-menu"
    style="position: absolute; left: 152px; top: 126px; width: 146px;
display: none;">

So I guess you should be looking to CSS style-ise #countryName:menu or
.t-autocomplete-menu

Steve.


On 13 May 2010 23:48, Thiago H. de Paula Figueiredo <thiag...@gmail.com> wrote:

On Fri, 14 May 2010 00:24:12 -0300, Paul Stanton <p...@mapshed.com.au>
wrote:

i've just started using the autocomplete mixin after reading this demo:


http://jumpstart.doublenegative.com.au:8080/jumpstart/examples/javascript/autocompletemixin

one thing i'd like to change is how far away the search result div appears
from the input text. i'd like to reduce the gap to 0 pixels if at all
possible..
Just use ordinary CSS style override.

--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and
instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to