You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Pablo dos Reis <pa...@gmail.com> on 2010/04/28 21:20:24 UTC

GSOC 2010 - ACCEPTED

Hi tapestry users,

My proposal for GSOC 2010 was accepted.

I will do the components:


*SelectWithAutocomplete and Tapestry Drag and Drop Palette *
*
*
*I am creating a wiki to display my evolution when finished I post it here.
*






-- 
Pablo Henrique dos Reis

Re: GSOC 2010 - ACCEPTED

Posted by Pablo dos Reis <pa...@gmail.com>.
Tks Joost,

I will read  then more later tell about your components.




2010/5/1 Joost Schouten (ml) <jo...@jsportal.com>

> Hi Pablo,
>
> This all can be achieved with Mixins.
>
> For the autocomplete-select I add my own ForceAutocomplete Mixin (which
> extends Autocomplete)  to a TextField. I have my ForceAutocomplete add a
> link (downward arrow img) behind the input which will trigger the
> "autocomplete" event. In stead of passing the textfield value, I pass a
> static identifier indicating this is a call from the link allowing the
> Tapestry providecompletions event to return full list, or whatever other
> requirements you might have.
>
> I've posted some code here below. I apologize where it might be slightly
> unclear as I have not yet had the time to refactor so it is clear and clean.
> A fair bit of code is also in place to cater for the
> FORCE_AUTOCOMPLETE_ON_CHANGE which is triggered when a user selects an item
> from the list to allow for another list of options to be shown. We use this
> for selections where you need to drill down to a deeper child.
>
> As for the drag and drop; this one is quite easy. Though we have the code
> embedded in our calendar component, it's quite easy to write a mixin that
> take a handleDomId and a dropableDomId (or whatever other droppable method
> you wish to use) and have it create the appropriate javascript. In the
> Draggable.onEnd() method you can have it trigger an ajax call with an T5
> event identifier, so that your Tapestry component can respond appropriately
> if needed.
>
> I hope this is not too unclear and can help you a little bit in getting
> started. Don't focus too much on our code I would say but just get started
> with your own mixin.
>
> Cheers,
> Joost
>
>
> [1]:
> ForceAutocomplete
> @IncludeJavaScriptLibrary("ForceAutocomplete.js")
> @IncludeStylesheet("ForceAutocomplete.css")
> public class ForceAutocomplete extends Autocomplete{
>     public static final String NAME_ID_DEVIDER = "_NID_";
>     public static final String DOM_ID_ITEM_ID_DEVIDER = "_DIIID_";
>
>   public static final String FORCE_AUTOCOMPLETE_ON_CLICK =
> "FORCE_AUTOCOMPLETE_ON_CLICK";
>     public static final String FORCE_AUTOCOMPLETE_ON_CHANGE =
> "FORCE_AUTOCOMPLETE_ON_CHANGE";
>     public static final String OPTIONS_DEVIDER_END = " ----";
>
>   public static final String OPTIONS_DEVIDER_START = "---- ";
>
>   @Parameter(value = "prop:componentResources.id", defaultPrefix =
> "literal")
>   private String clientId;
>     @Parameter(required = false, defaultPrefix = "literal")
>   private String idFieldClass;
>     @Inject
>   private RenderSupport renderSupport;
>     @Inject
>   private ComponentResources resources;
>     @Persist
>   private String autocompleteFieldId;
>     /**
>    * setting this to true will force an autocomplete call to be fired on
> every change
>    */
>   @Parameter(required = true, defaultPrefix = "literal")
>   private boolean addOnchangeCall;
>     @Inject
>   @Path("drop_down_arrow.gif")
>   private Asset dropdownArrow;
>     @Inject
>   @Path("context:/static/images/themes/jsportal/loader.gif")
>   private Asset jsLoaderImage;
>     private String loaderId;
>       @AfterRender
>   private void after(MarkupWriter writer) {
>       Element container = writer.getElement();
>       Element autoCompField = null;
>       for(Node node : container.getChildren()) {
>           if(node instanceof Element) {
>               Element el = (Element) node;
>               if(el.getName().toLowerCase().equals("input") &&
>                       el.getAttribute("type").equals("text")) {
>                   autoCompField = el;
>                   break;
>               }
>           }
>       }
>       autoCompField.addClassName("forceAutocompleteField");
>       autocompleteFieldId = autoCompField.getAttribute("id");
>             loaderId = autocompleteFieldId + ":js_loader";
>             Element forceAutocompleteFieldContainer = writer.element("div",
>               "class",
>               "forceAutocompleteFieldContainer");
>       writer.end();
>             autoCompField.moveToBottom(forceAutocompleteFieldContainer);
>             forceAutocompleteFieldContainer.element("img",
>               "src", jsLoaderImage.toClientURL(),
>               "class", "t-autoloader-icon " + CSSClassConstants.INVISIBLE,
>               "id", loaderId);
>             String handleId = autocompleteFieldId + ":handle_anchor";
>       Element handleAnchor = forceAutocompleteFieldContainer.element("a",
>               "class", "handleAnchor",
>               "id", handleId);
>       handleAnchor.element("img",
>               "class", "forceAutocompleteHandler",
>               "src", dropdownArrow.toClientURL());
>             StringBuffer script = new StringBuffer();
>       script.append("$T('" + autocompleteFieldId + "').forceAutocompleter =
> new ForceAutocomplete($('" + autocompleteFieldId + "'), '" +
> getAutocompleteUrl() + "', " + addOnchangeCall);
>       if(idFieldClass != null) {
>           script.append(", '" + idFieldClass + "'");
>       }
>             script.append(");");
>             renderSupport.addScript(script.toString());
>   }
>     protected void configure(JSONObject config){
>       config.remove("indicator");
>       config.put("indicator", loaderId);
>   }
>     public String getAutocompleteUrl() {
>       return
> resources.getContainerResources().createEventLink("autocomplete").toAbsoluteURI();
>   }
>     /**
>    * Overwrites the Autocomplete method to add a title to each li
>    */
>   @Override
>   protected void generateResponseMarkup(MarkupWriter writer, List matches){
>       writer.element("ul");
>
>       for (Object o : matches){
>           String name = o.toString();
>                               Element li = writer.element("li",
>                   "title", name);
>
> if(name.indexOf(ForceAutocomplete.OPTIONS_DEVIDER_START) != -1 &&
>                   name.indexOf(ForceAutocomplete.OPTIONS_DEVIDER_END) !=
> -1) {
>               li.addClassName("devider");
>           }
>           writer.write(name);
>           writer.end();
>       }
>
>       writer.end(); // ul
>   }
>
> }
>
>
> ForceAutocomplete.js:
>
> Ajax.Autocompleter.addMethods({
>   onBlur: function() {
>       fa = $T(this.element).forceAutocompleter;
>       fa.inputFocus = false;
>       fa.onBlurSelectorItem();
>   }
> });
>
> var FORCE_AUTOCOMPLETE_CHANGED_EVENT =
> 'joostschouten:FORCE_AUTOCOMPLETE_CHANGED_EVENT';
>
> function ForceAutocomplete (elem, ajaxUrl, includeChange, idFieldClass) {
>   this.elem = elem;
>   $T(this.elem).forceAutocompleter = this;
>   this.hideTimeoutIndex = null;
>   this.ajaxUrl = ajaxUrl;
>   this.includeChange = includeChange;
>   this.forceAutocompleteFieldContainer =
> this.elem.up('.forceAutocompleteFieldContainer');
>   this.handle = this.forceAutocompleteFieldContainer.down('.handleAnchor');
>   this.lastSelected = null;
>   this.selectedIdField = null;
>   if(idFieldClass) {
>       this.selectedIdField =
> this.forceAutocompleteFieldContainer.previous('.' + idFieldClass);
>       this.lastSelected = this.selectedIdField.value;
>   }
>   this.handle.observe('click',
> this.handleForcedUpdate.bindAsEventListener(this));
>   this.elem.observe('focus', this.onInputFocus.bindAsEventListener(this));
>   //this.elem.observe('keydown',
> this.handleKeyDown.bindAsEventListener(this));
>
> window.setTimeout(this.registerNewOnCompleteMethod.bindAsEventListener(this),
> 5);
> }
>
> ForceAutocomplete.prototype = {
>   registerNewOnCompleteMethod : function () {
>       this.autocompleter = $T(this.elem).autocompleter;
>       if(this.autocompleter) {
>           //stop observing the blur eveny on the AutoComplete
>           this.autocompleter.onBlur =
> this.onBlurSelectorItem.bindAsEventListener(this);
>                     this.autocompleter.options.onComplete =
> this.onComplete.bindAsEventListener(this);
>           this.autocompleter.options.onHide =
> this.onHide.bindAsEventListener(this);
>           this.autocompleter.options.onShow =
> this.onShow.bindAsEventListener(this);
>       }
>       else {
>
> window.setTimeout(this.registerNewOnCompleteMethod.bindAsEventListener(this),
> 100);
>       }
>   },
>   onHide : function () {
>       this.autocompleter.update.hide();
>   },
>   onShow : function () {
>       update = this.autocompleter.update;
>       if(!update.style.position || update.style.position=='absolute') {
>         update.style.position = 'absolute';
>         Position.clone(this.elem, update, {
>           setHeight: false,
>           offsetTop: this.elem.offsetHeight
>         });
>       }
>       update.show();
>   },
>   onComplete : function (transport) {
>             var autoCompleter = $T(this.elem).autocompleter;
>       autoCompleter.changed = false;
>       autoCompleter.hasFocus = true;
>       autoCompleter.active = true;
>
>       autoCompleter.update.update(transport.responseText);
>       lis = autoCompleter.update.down().childElements();
>                   if(lis.length>0) {
>           valueMatchesOption = false;
>           for(i = 0;i<lis.length;i++) {
>               if(!valueMatchesOption && lis[i].innerHTML ==
> this.elem.value) {
>                   valueMatchesOption = true;
>               }
>               if(lis[i].innerHTML != this.elem.value &&
> !lis[i].hasClassName('devider')) {
>                   lis[i].observe('click',
> this.handleForcedUpdateFromChange.bindAsEventListener(this));
>               }
>           }
>                     if(!valueMatchesOption && this.selectedIdField != null)
> {
>               //set the selected value to null as the option does not exist
>               this.selectedIdField.value = '';
>           }
>                     if(lis.length == 1 && lis[0].innerHTML ==
> this.elem.value) {
>               // if there is one exact match, set it and don't show
> suggestions
>               this.loadValueFromItem(lis[0]);
>           }
>           else {
>               //focus on the input field so that the update list will not
> be hidden
>               this.elem.focus();
>               autoCompleter.show();
>           }
>       }
>       else {
>           autoCompleter.hide();
>       }
>       autoCompleter.stopIndicator();
>   },
>   onCompleteFromChange : function (transport) {
>       this.onComplete(transport);
>       this.elem.fire(FORCE_AUTOCOMPLETE_CHANGED_EVENT);
>   },
>   handleForcedUpdate : function(event) {
>       var autoCompleter = $T(this.elem).autocompleter;
>             //focus on the input field so that the update list will not be
> hidden
>       this.elem.focus();
>                   actionName = 'FORCE_AUTOCOMPLETE_ON_CLICK_' +
> this.elem.value;
>             if(this.lastSelected != null) {
>           actionName = actionName + '_NID_' + this.lastSelected;
>       }
>             //in case when the list is already showing, hide it when
> clicked
>       if(autoCompleter.update.visible()) {
>           autoCompleter.update.hide();
>       }
>       else {
>           autoCompleter.startIndicator();
>           event.stop();
>           var myAjax = new Ajax.Request( this.ajaxUrl , {method: 'post',
> parameters: 't:input=' + actionName, onSuccess:
> this.onComplete.bindAsEventListener(this)} );
>             }
>   },
>   handleForcedUpdateFromChange : function (event) {          li =
> Event.findElement(event, 'LI');
>       this.loadValueFromItem(li);
>   },
>   loadValueFromItem : function(li) {
>             liCont = li.innerHTML;
>       if(li.hasClassName('devider')) {
>           return false;
>       }
>             if(this.elem.value != liCont) {
>           this.elem.value = liCont;
>       }
>             //set the value to the content of the li
>       if(this.includeChange) {
>           $T(this.elem).autocompleter.startIndicator();
>           passValue = liCont;
>           //strip of the DOM id before passing
>           if(li.id && li.id != null) {
>               itemId = li.id;
>               if(itemId.indexOf('_DIIID_') != -1) {
>                   itemId = itemId.split('_DIIID_')[1];
>               }
>               passValue = passValue + '_NID_' + itemId;
>           }
>           tokens =  passValue.split('_')
>           this.lastSelected = tokens[tokens.length-1];
>           actionName = 'FORCE_AUTOCOMPLETE_ON_CHANGE_' + passValue;
>           var myAjax = new Ajax.Request( this.ajaxUrl , {method: 'post',
> parameters: 't:input=' + actionName, onSuccess:
> this.onCompleteFromChange.bindAsEventListener(this)} );
>       }
>   },
>   /**
>    * called by each item of the selector. Checks to see if any field of the
> selector is
>    * focus'ed if so, don't hide the options, if not, hide
>    */
>   onBlurSelectorItem:function(event) {
>       autoComp = $T(this.elem).autocompleter;
>       this.hideTimeoutIndex = setTimeout(autoComp.hide.bind(autoComp),
> 250);
>       this.hasFocus = false;
>       this.active = false;
>   },
>   onInputFocus:function() {
>       if(this.hideTimeoutIndex != null) {
>           clearTimeout(this.hideTimeoutIndex);
>
>       }
>   }
> }
>
> Pablo dos Reis wrote:
>
>> Joost,
>>
>> I liked the video very much.
>> If you can pass at least the idea of components I thank.
>> How was it implemented? What javascript was use?
>> The code would bee good too.
>>
>>
>> And I think interesting you post here for all users can see.
>>
>>
>>
>> tks
>>
>> 2010/4/30 Joost Schouten (ml) <jo...@jsportal.com>
>>
>>
>>
>>> Pablo,
>>>
>>> If interested we have created a full drag and drop calendar and select
>>> with
>>> auto-complete for our internal project. I could share some of our code to
>>> give you a head start. The product is not yet launched but these these
>>> features are partly shown in this video [1]
>>>
>>> Let me know if you would like to have a look
>>>
>>> Cheers,
>>> Joost
>>>
>>> [1]:http://www.youtube.com/watch?v=_GVW0JvkDkg
>>>
>>>
>>> Pablo dos Reis wrote:
>>>
>>>
>>>
>>>> Tks everybody
>>>>
>>>> Now I am studing about Scriptaculous
>>>> I already create a wiki
>>>> http://wiki.apache.org/general/PabloGSOC2010
>>>>
>>>> I accept sugestions for it
>>>>
>>>> Soon I' ll post my doubts here.
>>>>
>>>>
>>>>
>>>> 2010/4/28 Charith Madusanka <ch...@gmail.com>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>> Hi Pablo,
>>>>>
>>>>> Congratulations and Good luck...............!!!
>>>>>
>>>>> Charith
>>>>>
>>>>> On Thu, Apr 29, 2010 at 5:05 AM, Thiago H. de Paula Figueiredo <
>>>>> thiagohp@gmail.com> wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> On Wed, 28 Apr 2010 20:01:23 -0300, Pablo dos Reis <
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> pablodosreis@gmail.com>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> wrote:
>>>>>>
>>>>>>  There are ohters students working in tapestry project through GSOC?
>>>>>>     You're the only one with an approved proposal.
>>>>>>
>>>>>> --
>>>>>> 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-unsubscribe@tapestry.apache.org
>>>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>>
>>>
>>
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Pablo Henrique dos Reis

Re: GSOC 2010 - ACCEPTED

Posted by "Joost Schouten (ml)" <jo...@jsportal.com>.
Hi Pablo,

This all can be achieved with Mixins.

For the autocomplete-select I add my own ForceAutocomplete Mixin (which 
extends Autocomplete)  to a TextField. I have my ForceAutocomplete add a 
link (downward arrow img) behind the input which will trigger the 
"autocomplete" event. In stead of passing the textfield value, I pass a 
static identifier indicating this is a call from the link allowing the 
Tapestry providecompletions event to return full list, or whatever other 
requirements you might have.

I've posted some code here below. I apologize where it might be slightly 
unclear as I have not yet had the time to refactor so it is clear and 
clean. A fair bit of code is also in place to cater for the 
FORCE_AUTOCOMPLETE_ON_CHANGE which is triggered when a user selects an 
item from the list to allow for another list of options to be shown. We 
use this for selections where you need to drill down to a deeper child.

As for the drag and drop; this one is quite easy. Though we have the 
code embedded in our calendar component, it's quite easy to write a 
mixin that take a handleDomId and a dropableDomId (or whatever other 
droppable method you wish to use) and have it create the appropriate 
javascript. In the Draggable.onEnd() method you can have it trigger an 
ajax call with an T5 event identifier, so that your Tapestry component 
can respond appropriately if needed.

I hope this is not too unclear and can help you a little bit in getting 
started. Don't focus too much on our code I would say but just get 
started with your own mixin.

Cheers,
Joost


[1]:
ForceAutocomplete
@IncludeJavaScriptLibrary("ForceAutocomplete.js")
@IncludeStylesheet("ForceAutocomplete.css")
public class ForceAutocomplete extends Autocomplete{
   
    public static final String NAME_ID_DEVIDER = "_NID_";
   
    public static final String DOM_ID_ITEM_ID_DEVIDER = "_DIIID_";

    public static final String FORCE_AUTOCOMPLETE_ON_CLICK = 
"FORCE_AUTOCOMPLETE_ON_CLICK";
   
    public static final String FORCE_AUTOCOMPLETE_ON_CHANGE = 
"FORCE_AUTOCOMPLETE_ON_CHANGE";
   
    public static final String OPTIONS_DEVIDER_END = " ----";

    public static final String OPTIONS_DEVIDER_START = "---- ";

    @Parameter(value = "prop:componentResources.id", defaultPrefix = 
"literal")
    private String clientId;
   
    @Parameter(required = false, defaultPrefix = "literal")
    private String idFieldClass;
   
    @Inject
    private RenderSupport renderSupport;
   
    @Inject
    private ComponentResources resources;
   
    @Persist
    private String autocompleteFieldId;
   
    /**
     * setting this to true will force an autocomplete call to be fired 
on every change
     */
    @Parameter(required = true, defaultPrefix = "literal")
    private boolean addOnchangeCall;
   
    @Inject
    @Path("drop_down_arrow.gif")
    private Asset dropdownArrow;
   
    @Inject
    @Path("context:/static/images/themes/jsportal/loader.gif")
    private Asset jsLoaderImage;
   
    private String loaderId;
   
   
    @AfterRender
    private void after(MarkupWriter writer) {
        Element container = writer.getElement();
        Element autoCompField = null;
        for(Node node : container.getChildren()) {
            if(node instanceof Element) {
                Element el = (Element) node;
                if(el.getName().toLowerCase().equals("input") &&
                        el.getAttribute("type").equals("text")) {
                    autoCompField = el;
                    break;
                }
            }
        }
        autoCompField.addClassName("forceAutocompleteField");
        autocompleteFieldId = autoCompField.getAttribute("id");
       
        loaderId = autocompleteFieldId + ":js_loader";
       
        Element forceAutocompleteFieldContainer = writer.element("div",
                "class",
                "forceAutocompleteFieldContainer");
        writer.end();
       
        autoCompField.moveToBottom(forceAutocompleteFieldContainer);
       
        forceAutocompleteFieldContainer.element("img",
                "src", jsLoaderImage.toClientURL(),
                "class", "t-autoloader-icon " + CSSClassConstants.INVISIBLE,
                "id", loaderId);
       
        String handleId = autocompleteFieldId + ":handle_anchor";
        Element handleAnchor = forceAutocompleteFieldContainer.element("a",
                "class", "handleAnchor",
                "id", handleId);
        handleAnchor.element("img",
                "class", "forceAutocompleteHandler",
                "src", dropdownArrow.toClientURL());
       
        StringBuffer script = new StringBuffer();
        script.append("$T('" + autocompleteFieldId + 
"').forceAutocompleter = new ForceAutocomplete($('" + 
autocompleteFieldId + "'), '" + getAutocompleteUrl() + "', " + 
addOnchangeCall);
        if(idFieldClass != null) {
            script.append(", '" + idFieldClass + "'");
        }
       
        script.append(");");
       
        renderSupport.addScript(script.toString());
    }
   
    protected void configure(JSONObject config){
        config.remove("indicator");
        config.put("indicator", loaderId);
    }
   
    public String getAutocompleteUrl() {
        return 
resources.getContainerResources().createEventLink("autocomplete").toAbsoluteURI();
    }
   
    /**
     * Overwrites the Autocomplete method to add a title to each li
     */
    @Override
    protected void generateResponseMarkup(MarkupWriter writer, List 
matches){
        writer.element("ul");

        for (Object o : matches){
            String name = o.toString();
           
           
            Element li = writer.element("li",
                    "title", name);
           
            if(name.indexOf(ForceAutocomplete.OPTIONS_DEVIDER_START) != 
-1 &&
                    name.indexOf(ForceAutocomplete.OPTIONS_DEVIDER_END) 
!= -1) {
                li.addClassName("devider");
            }
            writer.write(name);
            writer.end();
        }

        writer.end(); // ul
    }
   

}


ForceAutocomplete.js:

Ajax.Autocompleter.addMethods({
    onBlur: function() {
        fa = $T(this.element).forceAutocompleter;
        fa.inputFocus = false;
        fa.onBlurSelectorItem();
    }
});

var FORCE_AUTOCOMPLETE_CHANGED_EVENT = 
'joostschouten:FORCE_AUTOCOMPLETE_CHANGED_EVENT';

function ForceAutocomplete (elem, ajaxUrl, includeChange, idFieldClass) {
    this.elem = elem;
    $T(this.elem).forceAutocompleter = this;
    this.hideTimeoutIndex = null;
    this.ajaxUrl = ajaxUrl;
    this.includeChange = includeChange;
    this.forceAutocompleteFieldContainer = 
this.elem.up('.forceAutocompleteFieldContainer');
    this.handle = 
this.forceAutocompleteFieldContainer.down('.handleAnchor');
    this.lastSelected = null;
    this.selectedIdField = null;
    if(idFieldClass) {
        this.selectedIdField = 
this.forceAutocompleteFieldContainer.previous('.' + idFieldClass);
        this.lastSelected = this.selectedIdField.value;
    }
    this.handle.observe('click', 
this.handleForcedUpdate.bindAsEventListener(this));
    this.elem.observe('focus', this.onInputFocus.bindAsEventListener(this));
    //this.elem.observe('keydown', 
this.handleKeyDown.bindAsEventListener(this));
    
window.setTimeout(this.registerNewOnCompleteMethod.bindAsEventListener(this), 
5);
}

ForceAutocomplete.prototype = {
    registerNewOnCompleteMethod : function () {
        this.autocompleter = $T(this.elem).autocompleter;
        if(this.autocompleter) {
            //stop observing the blur eveny on the AutoComplete
            this.autocompleter.onBlur = 
this.onBlurSelectorItem.bindAsEventListener(this);
           
            this.autocompleter.options.onComplete = 
this.onComplete.bindAsEventListener(this);
            this.autocompleter.options.onHide = 
this.onHide.bindAsEventListener(this);
            this.autocompleter.options.onShow = 
this.onShow.bindAsEventListener(this);
        }
        else {
            
window.setTimeout(this.registerNewOnCompleteMethod.bindAsEventListener(this), 
100);
        }
    },
    onHide : function () {
        this.autocompleter.update.hide();
    },
    onShow : function () {
        update = this.autocompleter.update;
        if(!update.style.position || update.style.position=='absolute') {
          update.style.position = 'absolute';
          Position.clone(this.elem, update, {
            setHeight: false,
            offsetTop: this.elem.offsetHeight
          });
        }
        update.show();
    },
    onComplete : function (transport) {
       
        var autoCompleter = $T(this.elem).autocompleter;
        autoCompleter.changed = false;
        autoCompleter.hasFocus = true;
        autoCompleter.active = true;

        autoCompleter.update.update(transport.responseText);
        lis = autoCompleter.update.down().childElements();
       
       
        if(lis.length>0) {
            valueMatchesOption = false;
            for(i = 0;i<lis.length;i++) {
                if(!valueMatchesOption && lis[i].innerHTML == 
this.elem.value) {
                    valueMatchesOption = true;
                }
                if(lis[i].innerHTML != this.elem.value && 
!lis[i].hasClassName('devider')) {
                    lis[i].observe('click', 
this.handleForcedUpdateFromChange.bindAsEventListener(this));
                }
            }
           
            if(!valueMatchesOption && this.selectedIdField != null) {
                //set the selected value to null as the option does not 
exist
                this.selectedIdField.value = '';
            }
           
            if(lis.length == 1 && lis[0].innerHTML == this.elem.value) {
                // if there is one exact match, set it and don't show 
suggestions
                this.loadValueFromItem(lis[0]);
            }
            else {
                //focus on the input field so that the update list will 
not be hidden
                this.elem.focus();
                autoCompleter.show();
            }
        }
        else {
            autoCompleter.hide();
        }
        autoCompleter.stopIndicator();
    },
    onCompleteFromChange : function (transport) {
        this.onComplete(transport);
        this.elem.fire(FORCE_AUTOCOMPLETE_CHANGED_EVENT);
    },
    handleForcedUpdate : function(event) {
        var autoCompleter = $T(this.elem).autocompleter;
       
        //focus on the input field so that the update list will not be 
hidden
        this.elem.focus();
       
       
        actionName = 'FORCE_AUTOCOMPLETE_ON_CLICK_' + this.elem.value;
       
        if(this.lastSelected != null) {
            actionName = actionName + '_NID_' + this.lastSelected;
        }
       
        //in case when the list is already showing, hide it when clicked
        if(autoCompleter.update.visible()) {
            autoCompleter.update.hide();
        }
        else {
            autoCompleter.startIndicator();
            event.stop();
            var myAjax = new Ajax.Request( this.ajaxUrl , {method: 
'post', parameters: 't:input=' + actionName, onSuccess: 
this.onComplete.bindAsEventListener(this)} );
       
        }
    },
    handleForcedUpdateFromChange : function (event) {   
        li = Event.findElement(event, 'LI');
        this.loadValueFromItem(li);
    },
    loadValueFromItem : function(li) {
       
        liCont = li.innerHTML;
        if(li.hasClassName('devider')) {
            return false;
        }
       
        if(this.elem.value != liCont) {
            this.elem.value = liCont;
        }
       
        //set the value to the content of the li
        if(this.includeChange) {
            $T(this.elem).autocompleter.startIndicator();
            passValue = liCont;
            //strip of the DOM id before passing
            if(li.id && li.id != null) {
                itemId = li.id;
                if(itemId.indexOf('_DIIID_') != -1) {
                    itemId = itemId.split('_DIIID_')[1];
                }
                passValue = passValue + '_NID_' + itemId;
            }
            tokens =  passValue.split('_')
            this.lastSelected = tokens[tokens.length-1];
            actionName = 'FORCE_AUTOCOMPLETE_ON_CHANGE_' + passValue;
            var myAjax = new Ajax.Request( this.ajaxUrl , {method: 
'post', parameters: 't:input=' + actionName, onSuccess: 
this.onCompleteFromChange.bindAsEventListener(this)} );
        }
    },
    /**
     * called by each item of the selector. Checks to see if any field 
of the selector is
     * focus'ed if so, don't hide the options, if not, hide
     */
    onBlurSelectorItem:function(event) {
        autoComp = $T(this.elem).autocompleter;
        this.hideTimeoutIndex = setTimeout(autoComp.hide.bind(autoComp), 
250);
        this.hasFocus = false;
        this.active = false;
    },
    onInputFocus:function() {
        if(this.hideTimeoutIndex != null) {
            clearTimeout(this.hideTimeoutIndex);
        }
    }
}

Pablo dos Reis wrote:
> Joost,
>
> I liked the video very much.
> If you can pass at least the idea of components I thank.
> How was it implemented? What javascript was use?
> The code would bee good too.
>
>
> And I think interesting you post here for all users can see.
>
>
>
> tks
>
> 2010/4/30 Joost Schouten (ml) <jo...@jsportal.com>
>
>   
>> Pablo,
>>
>> If interested we have created a full drag and drop calendar and select with
>> auto-complete for our internal project. I could share some of our code to
>> give you a head start. The product is not yet launched but these these
>> features are partly shown in this video [1]
>>
>> Let me know if you would like to have a look
>>
>> Cheers,
>> Joost
>>
>> [1]:http://www.youtube.com/watch?v=_GVW0JvkDkg
>>
>>
>> Pablo dos Reis wrote:
>>
>>     
>>> Tks everybody
>>>
>>> Now I am studing about Scriptaculous
>>> I already create a wiki
>>> http://wiki.apache.org/general/PabloGSOC2010
>>>
>>> I accept sugestions for it
>>>
>>> Soon I' ll post my doubts here.
>>>
>>>
>>>
>>> 2010/4/28 Charith Madusanka <ch...@gmail.com>
>>>
>>>
>>>
>>>       
>>>> Hi Pablo,
>>>>
>>>> Congratulations and Good luck...............!!!
>>>>
>>>> Charith
>>>>
>>>> On Thu, Apr 29, 2010 at 5:05 AM, Thiago H. de Paula Figueiredo <
>>>> thiagohp@gmail.com> wrote:
>>>>
>>>>
>>>>
>>>>         
>>>>> On Wed, 28 Apr 2010 20:01:23 -0300, Pablo dos Reis <
>>>>>
>>>>>
>>>>>           
>>>> pablodosreis@gmail.com>
>>>>
>>>>
>>>>         
>>>>> wrote:
>>>>>
>>>>>  There are ohters students working in tapestry project through GSOC?
>>>>>      You're the only one with an approved proposal.
>>>>>
>>>>> --
>>>>> 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-unsubscribe@tapestry.apache.org
>>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>           
>>>
>>>
>>>       
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>>     
>
>
>   


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


Re: GSOC 2010 - ACCEPTED

Posted by Pablo dos Reis <pa...@gmail.com>.
Joost,

I liked the video very much.
If you can pass at least the idea of components I thank.
How was it implemented? What javascript was use?
The code would bee good too.


And I think interesting you post here for all users can see.



tks

2010/4/30 Joost Schouten (ml) <jo...@jsportal.com>

> Pablo,
>
> If interested we have created a full drag and drop calendar and select with
> auto-complete for our internal project. I could share some of our code to
> give you a head start. The product is not yet launched but these these
> features are partly shown in this video [1]
>
> Let me know if you would like to have a look
>
> Cheers,
> Joost
>
> [1]:http://www.youtube.com/watch?v=_GVW0JvkDkg
>
>
> Pablo dos Reis wrote:
>
>> Tks everybody
>>
>> Now I am studing about Scriptaculous
>> I already create a wiki
>> http://wiki.apache.org/general/PabloGSOC2010
>>
>> I accept sugestions for it
>>
>> Soon I' ll post my doubts here.
>>
>>
>>
>> 2010/4/28 Charith Madusanka <ch...@gmail.com>
>>
>>
>>
>>> Hi Pablo,
>>>
>>> Congratulations and Good luck...............!!!
>>>
>>> Charith
>>>
>>> On Thu, Apr 29, 2010 at 5:05 AM, Thiago H. de Paula Figueiredo <
>>> thiagohp@gmail.com> wrote:
>>>
>>>
>>>
>>>> On Wed, 28 Apr 2010 20:01:23 -0300, Pablo dos Reis <
>>>>
>>>>
>>> pablodosreis@gmail.com>
>>>
>>>
>>>> wrote:
>>>>
>>>>  There are ohters students working in tapestry project through GSOC?
>>>>      You're the only one with an approved proposal.
>>>>
>>>> --
>>>> 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-unsubscribe@tapestry.apache.org
>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>
>>>>
>>>>
>>>>
>>>
>>
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Pablo Henrique dos Reis

Re: GSOC 2010 - ACCEPTED

Posted by "Joost Schouten (ml)" <jo...@jsportal.com>.
Pablo,

If interested we have created a full drag and drop calendar and select 
with auto-complete for our internal project. I could share some of our 
code to give you a head start. The product is not yet launched but these 
these features are partly shown in this video [1]

Let me know if you would like to have a look

Cheers,
Joost

[1]:http://www.youtube.com/watch?v=_GVW0JvkDkg

Pablo dos Reis wrote:
> Tks everybody
>
> Now I am studing about Scriptaculous
> I already create a wiki
> http://wiki.apache.org/general/PabloGSOC2010
>
> I accept sugestions for it
>
> Soon I' ll post my doubts here.
>
>
>
> 2010/4/28 Charith Madusanka <ch...@gmail.com>
>
>   
>> Hi Pablo,
>>
>> Congratulations and Good luck...............!!!
>>
>> Charith
>>
>> On Thu, Apr 29, 2010 at 5:05 AM, Thiago H. de Paula Figueiredo <
>> thiagohp@gmail.com> wrote:
>>
>>     
>>> On Wed, 28 Apr 2010 20:01:23 -0300, Pablo dos Reis <
>>>       
>> pablodosreis@gmail.com>
>>     
>>> wrote:
>>>
>>>  There are ohters students working in tapestry project through GSOC?
>>>       
>>> You're the only one with an approved proposal.
>>>
>>> --
>>> 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-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>>       
>
>
>
>   


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


Re: GSOC 2010 - ACCEPTED

Posted by Pablo dos Reis <pa...@gmail.com>.
Tks everybody

Now I am studing about Scriptaculous
I already create a wiki
http://wiki.apache.org/general/PabloGSOC2010

I accept sugestions for it

Soon I' ll post my doubts here.



2010/4/28 Charith Madusanka <ch...@gmail.com>

> Hi Pablo,
>
> Congratulations and Good luck...............!!!
>
> Charith
>
> On Thu, Apr 29, 2010 at 5:05 AM, Thiago H. de Paula Figueiredo <
> thiagohp@gmail.com> wrote:
>
> > On Wed, 28 Apr 2010 20:01:23 -0300, Pablo dos Reis <
> pablodosreis@gmail.com>
> > wrote:
> >
> >  There are ohters students working in tapestry project through GSOC?
> >>
> >
> > You're the only one with an approved proposal.
> >
> > --
> > 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-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>



-- 
Pablo Henrique dos Reis

Re: GSOC 2010 - ACCEPTED

Posted by Charith Madusanka <ch...@gmail.com>.
Hi Pablo,

Congratulations and Good luck...............!!!

Charith

On Thu, Apr 29, 2010 at 5:05 AM, Thiago H. de Paula Figueiredo <
thiagohp@gmail.com> wrote:

> On Wed, 28 Apr 2010 20:01:23 -0300, Pablo dos Reis <pa...@gmail.com>
> wrote:
>
>  There are ohters students working in tapestry project through GSOC?
>>
>
> You're the only one with an approved proposal.
>
> --
> 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-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: GSOC 2010 - ACCEPTED

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Wed, 28 Apr 2010 20:01:23 -0300, Pablo dos Reis  
<pa...@gmail.com> wrote:

> There are ohters students working in tapestry project through GSOC?

You're the only one with an approved proposal.

-- 
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-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: GSOC 2010 - ACCEPTED

Posted by Pablo dos Reis <pa...@gmail.com>.
There are ohters students working in tapestry project through GSOC?



2010/4/28 Thiago H. de Paula Figueiredo <th...@gmail.com>
>
> On Wed, 28 Apr 2010 16:20:24 -0300, Pablo dos Reis <pa...@gmail.com>
wrote:
>
>> Hi tapestry users,
>
> Hi, Pablo!
>
>> My proposal for GSOC 2010 was accepted.
>
> Congratulations!
>
>> I will do the components:
>> SelectWithAutocomplete and Tapestry Drag and Drop Palette
>
> Please start as soon as possible and post your questions here. :)
>
> --
> 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-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>



--
Pablo Henrique dos Reis

Re: GSOC 2010 - ACCEPTED

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Wed, 28 Apr 2010 16:20:24 -0300, Pablo dos Reis  
<pa...@gmail.com> wrote:

> Hi tapestry users,

Hi, Pablo!

> My proposal for GSOC 2010 was accepted.

Congratulations!

> I will do the components:
> SelectWithAutocomplete and Tapestry Drag and Drop Palette

Please start as soon as possible and post your questions here. :)

-- 
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-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org