Mockup: subclassing/extending widget patterns

Suppose I want to "subclass" PickADate (I do). How does one subclass an existing widget?

My goal is to be able to call PickADate's init() within the init() of my pattern extending it, hoping to do something like this:

  var UpiqADate = PickADate.extend({
    name: 'upiq-date',
    trigger: '.pat-upiq-date',
    init: function() {
      UpiqADate.__super__.init.call(this);
      // ...
    }
  });

I suspect this may have worked with mockup 1.x, but does not work with current mockup. Any ideas on subclassing and calling superclass methods in patterns?

Sean

This is how I did it when subclassing the modal pattern:

define([
    'pat-base',
    'mockup-patterns-modal'
], function(Base, Modal) {
    'use strict';
    var ModalEdit = Base.extend({
        name: 'plone-modaledit',
        trigger: '.pat-plone-modaledit',
        parser: 'mockup',
        init: function() {
            var options = {
                actionOptions: {
                    displayInModal: true,
                    redirectOnResponse: true
                }
            }
            var modal = new Modal(this.$el, options);
        }
    });
    return ModalEdit;
});

The important thing here is, that I create a new Modal instance within the init function. I do not do tricky things within the new modal's init function, but just adjust some default options.
I don't know, if that helps with your use case....

I see your preference for composition to inheritance. :wink:

Seriously, though, wrapping an existing pattern seems a pretty reasonable idea.

I need to consider how I intend to tackle, though, for PickADate, because I need the date picker bound to a hidden input synced with a keyboard-friendly input (e.g. typing locale-sensitive short dates). If the UX of this pans out to be reasonable/desirable by others, I may properly port this feature to mockup.

Sean

That was just a pragmatic approach. Initially I wanted to extend the Modal pattern like you showed with PickADate, but that didn't worked.

It is funny: I did end up with success wrapping existing pattern, but that preference for wrapping vs. subclassing (composition over inheritance) led me to write.... wait for it... an adapter [1].

This is currently sitting in one of my unrelated add-ons, but is going to get this pattern and widget moved to a new package I intend to call collective.typeadate, which will have releases for both Plone 4 and Plone 5.

Having good keyboard integration for Pick-A-Date makes it a much easier beast for the user.

Sean

ha :smiley:

regarding the pattern - i'm looking forward to see it. does it support free time-entry or is it still the fixed list of predefined times at a configurable time-interval?

IMO a fix, allowing free time entry is a must have and should go into mockup directly.
I've seen a quite simple solution at the pick-a-date site.

even more unrelated: regarding patterns packaged in collective.* packages: i'd prefer to have it as a Patternslib compatible pattern-only package under the pat-* namespace.
More information here: http://patternslib.com/creating-a-pattern/#main-content
And here a recent example from me: http://github.com/patternslib/pat-leaflet

Entry ignores the interval, however fine our coarse. So if you have a 15 minute interval, but want to save the time 14:03, it will preserve without rounding, round-trip.

Agreed, but do you extend that scope to date entry too?

I want a place folks can test this out. I'm making assumptions about all the different locales I can support (there are only a small number of variants when parsing using moment, and not needing to format). Making this a Plone add-on first was my hope for sharing this with the community, but I would rather see this go into mockup core if there's a simpler way to just share the pattern.

I would rather just contribute this type-a-date pattern to mockup, but not as a modification to the pick-a-date pattern, I would rather this be a distinct pattern leveraging pick-a-date as part of the solution.

Sean

+1 for not mixing actual pattern enhancements, with Plone plumbing. This makes it more viable to use the patterns standalone, and/or to do your own Plone integration. We do both in Quaive Ploneintranet: we have a non-Plone design prototype with all patterns, and we integrate the prototype javascript bundle directly into Plone ourselves.

Having no Plone dependency in the javascript parts of our stack makes it possible for non-Plone devs to iterate much faster on pattern fixes and enhancements.

Actually, my proposed solution to customize an existing pattern did not work for me. Instead, this is a solution, which seems to work out:

define([
    'pat-fancyoverlay'
], function(FancyOverlay) {
    'use strict';
    var Modal = FancyOverlay.extend({
        name: 'plone-modal',
        trigger: '.pat-plone-modal'
    });
    return Modal;
});

Here, I have a pattern called pat-fancyoverlay. I want to use this instead of Plone core modal pattern. This extends the fancy overlay pattern and registers it in the Patternslib registry under a new name.

For the records, but unrelated to @seanupton original problem, I register this pattern in require.js via our portal registry in registry.xml like so:

<records prefix="plone.resources/mockup-patterns-modal" interface='Products.CMFPlone.interfaces.IResourceRegistry'>
    <value key="js">++plone++my.projectspecific.resourcedirectory/patterns/mockup-patterns-modal.js</value>
</records>

And here fancy overlay, which will be moved to somewhere else (github/patternslib is accepted), once I feel it's ready: