I'd prefer using a data-delegated attribute than setting a special css class on items. In my opinion, css classes should not reflect business considerations, that's where data-* attributes are useful.
__ Cedric Gatay (@Cedric_Gatay <http://twitter.com/Cedric_Gatay>) http://code-troopers.com | http://www.bloggure.info | http://cedric.gatay.fr On Thu, Jul 11, 2013 at 5:08 PM, Sven Meier <s...@meiers.net> wrote: > bind on document, and it was slow. >> > > Sure, the higher you register a delegating event handler in the markup > tree, the slower it is. > > The same holds for using event delegation on a table with a deeply nested > cell structure. > > Sven > > > > On 07/11/2013 04:54 PM, Martin Grigorov wrote: > >> On Thu, Jul 11, 2013 at 5:22 PM, Martin Grigorov <mgrigo...@apache.org >> >wrote: >> >> >>> >>> On Thu, Jul 11, 2013 at 4:48 PM, Sven Meier <s...@meiers.net> wrote: >>> >>> Hi, >>>> >>>> >>>> The idea with plain JS solution I cannot visualize in my head yet. >>>>> >>>> EventDelegatingBehavior is just a collector of JavaScript snippets. The >>>> actual magic runs in the browser: a custom bubbling of events and >>>> delegation to the actual behavior. >>>> It should be possible to do this plain with JavaScript: >>>> >>>> public class DelegatingAjax implements IAjax { >>>> >>>> public ajax(IHeaderResponse response, Component component, >>>> AjaxRequestAttributes attributes) { >>>> CharSequence ajaxAttributes = renderAjaxAttributes(**** >>>> component, >>>> attributes); >>>> >>>> response.render(****OnDomReadyHeaderItem.**** >>>> forScript("Wicket.Event.*****delegate*(" >>>> + ajaxAttributes + ");"); >>>> } >>>> } >>>> >>>> This would be page-global though. >>>> >>> >>> This is an important detail! >>> I'll consult with my frontend colleagues but so far I don't see problems. >>> >>> And they say this is a bad idea. >> jQuery.live() (deprecated in 1.7.0) did the same, bind on document, and it >> was slow. >> See http://api.jquery.com/live/ >> Also see >> http://www.ultimatewebtips.**com/why-jquery-live-is-a-bad-** >> option-to-use/<http://www.ultimatewebtips.com/why-jquery-live-is-a-bad-option-to-use/> >> >> >> For every delegated component we can set special CSS class, e.g. >>> 'wicket-delegated'. >>> The binding will be: $(document).on('click', '.wicket-delegated', >>> function(event) {....}) >>> i.e. we will take advantage of jQuery delegation/live support. >>> This way even newly added items in the repeaters will be automatically >>> supported. >>> >>> >>> >>>> Sven >>>> >>>> >>>> >>>> On 07/11/2013 03:40 PM, Martin Grigorov wrote: >>>> >>>> On Thu, Jul 11, 2013 at 4:30 PM, Nick Pratt <nbpr...@gmail.com> wrote: >>>>> >>>>> I think this is great - we have some tables now with a ton of JS >>>>> events >>>>> >>>>>> on >>>>>> the child elements. Just to clarify, will this make the rendered page >>>>>> smaller since there will only be a single JS handler for the event for >>>>>> the >>>>>> container rather than N JS handlers? >>>>>> >>>>>> At the moment all attributes for an inner element are preserved. >>>>>> >>>>> 'e' (the event name), 'c' (the component markup id), pd (prevent >>>>> default), >>>>> sp (stop propagation) can be removed because they are not really used. >>>>> But every inner element can have its own call listeners, form >>>>> submitters >>>>> can also have custom settings ('f', 'sc', 'mp', 'm'), so I think they >>>>> have >>>>> to be preserved. >>>>> If you look in #updateAjaxAttributes() for your ajax behaviors in your >>>>> table cells you will probably notice that they have their own >>>>> attributes. >>>>> >>>>> >>>>> Making it switchable (I think how Sven suggested) would be an >>>>> >>>>>> improvement - >>>>>> we could leave it off by default, but provide a simple switch on a >>>>>> per-container (or per-app) basis that would allow the dev to choose. >>>>>> >>>>>> Yes, it looks as an improvement. >>>>>> >>>>> Moving the current code to such implementation is easy. >>>>> The idea with plain JS solution I cannot visualize in my head yet. >>>>> >>>>> >>>>> Regards >>>>> >>>>>> Nick >>>>>> >>>>>> On Thu, Jul 11, 2013 at 4:59 AM, Martin Grigorov < >>>>>> mgrigo...@apache.org >>>>>> >>>>>> wrote: >>>>>>> Hi, >>>>>>> >>>>>>> At >>>>>>> https://github.com/apache/****wicket/compare/event-**<https://github.com/apache/**wicket/compare/event-**> >>>>>>> delegating-behavioryou<https:/**/github.com/apache/wicket/** >>>>>>> compare/event-delegating-**behavioryou<https://github.com/apache/wicket/compare/event-delegating-behavioryou> >>>>>>> > >>>>>>> may see the diff between master and event-delegating-behavior >>>>>>> branches. >>>>>>> >>>>>>> The latter provides a new AjaxEventBehavior (AEB) - >>>>>>> >>>>>>> EventDelegatingBehavior >>>>>> >>>>>> (EDB), that suppresses the JS event binding for all >>>>>>> AjaxEventBehaviors >>>>>>> >>>>>>> for >>>>>> >>>>>> a given event type (click, submit, change, ...) in the children >>>>>>> >>>>>>> components >>>>>> >>>>>> of the host component of EDB. >>>>>>> >>>>>>> How EDB works: >>>>>>> >>>>>>> - until now AjaxEventBehavior#renderHead() renders ondomready header >>>>>>> item >>>>>>> with JS snippet like: >>>>>>> Wicket.Ajax.ajax(****attributesObject); >>>>>>> In the new branch there is a check if some parent has EDB for the >>>>>>> event >>>>>>> type of this AEB, and if there is such then the AEB "donates" its >>>>>>> attributes to the EDB. >>>>>>> >>>>>>> - EventDelegatingBehavior#****getCallbackScript() renders : >>>>>>> Wicket.Event.delegate('****edbComponentMarkupId', 'eventType', >>>>>>> edbAttributes, >>>>>>> childrenAttrsMap); >>>>>>> >>>>>>> - when a delegated component fires its event (e.g. the user clicks on >>>>>>> an >>>>>>> AjaxLink) the event is handled by EDB's event handler. It extracts >>>>>>> the >>>>>>> markupId of the inner HTML element and fires Wicket.Ajax.Call with >>>>>>> the >>>>>>> specific attributes for the extracted inner element. >>>>>>> >>>>>>> Pros: >>>>>>> >>>>>>> - simple to use - just add EDB to a container component around your >>>>>>> Ajax >>>>>>> heavy component (e.g. repeater with many Ajax behaviors). See the >>>>>>> demo >>>>>>> >>>>>>> app >>>>>> >>>>>> at >>>>>> https://issues.apache.org/****jira/browse/WICKET-5267<https://issues.apache.org/**jira/browse/WICKET-5267> >>>>>>> <https:**//issues.apache.org/jira/**browse/WICKET-5267<https://issues.apache.org/jira/browse/WICKET-5267> >>>>>>> > >>>>>>> >>>>>>> - faster JS execution >>>>>>> -- faster execution of the domready handler because there is just one >>>>>>> binding instead of N >>>>>>> -- faster reaction because the browser finds the event handler much >>>>>>> >>>>>>> faster. >>>>>> >>>>>> I wasn't able to prove this with numbers because there is no way to >>>>>>> >>>>>>> detect >>>>>> >>>>>> the 'start time', i.e. when the user makes the action. With JS the >>>>>>> >>>>>>> earliest >>>>>> >>>>>> point is when the browser has already looked up the event handler. >>>>>>> Chrome Dev tools (timeline, profiling, pagespeed) don't help too. So >>>>>>> my >>>>>>> reference that it is faster are the articles in the web and a use >>>>>>> case >>>>>>> in >>>>>>> our application. >>>>>>> >>>>>>> Cons: >>>>>>> >>>>>>> - AEB#renderHead() needs to check whether there is EDB up in the >>>>>>> >>>>>>> hierarchy >>>>>> >>>>>> to be able to decide what to do. >>>>>>> This is ugly, I agree. But I see no other solution that will preserve >>>>>>> the >>>>>>> transparent usage of something like EDB and will not require a major >>>>>>> rewrite of user applications to be able to use event delegation. >>>>>>> -- there are some optimizations to lower the impact of the new >>>>>>> checks: >>>>>>> --- a new setting (IAjaxSettings#****useEventDelegation) - a global >>>>>>> property >>>>>>> that prevents visiting the parent components and their behaviors for >>>>>>> all >>>>>>> apps which do not use EDB >>>>>>> --- when EDB is bound it registers a metadata for its event type in >>>>>>> the >>>>>>> page instance. This prevents visiting all behaviors of all parent >>>>>>> components >>>>>>> >>>>>>> >>>>>>> I have no more ideas how to further optimize it. >>>>>>> >>>>>>> Any feedback is welcome! Even if you have a completely different idea >>>>>>> how >>>>>>> to implement this functionality. >>>>>>> >>>>>>> Thanks for reading! >>>>>>> >>>>>>> >>>>>>> >