Details
-
Type: Improvement
-
Status: Done/Fixed
-
Priority: Minor
-
Resolution: Fixed/Completed
-
Affects Version/s: 4.2.7
-
Fix Version/s: 4.5
-
Component/s: Core CiviCRM
-
Labels:None
-
Documentation Required?:Developer Doc
Description
== Problem Statement ==
When using sophisticated widgets (like rich-text editors, calendar popups, the new profile-selector, etc), one must initialize each widget by executing Javascript code. I'm not sure what our coding-convention is for initializing sophisticated widgets – if we don't have one, then we should. It should address issues like:
1. Working on all pages
2. Rendering widgets in the initial page-view
3. Rendering widgets after loading HTML snippets via AJAX/AHAH
4. Rendering a given widget once
5. Minimizing duplicate code transfer
6. Minimizing #codes required to use a widget
== Comments ==
- For the calendar widget, we use a technique that satisfies #1-4 – everytime we output markup for a widget, we also output a bunch of Javascript to initialize it. This basically works everywhere. However, it's a bit inefficient/complex. The consumer needs to provide three declarations. From the "Demographics" block:
PHP: $form->addDate('birth_date', ts('Date of birth'), FALSE, array('formatType' => 'birth'));
TPL: <div class="crm-label">{$form.birth_date.label}</div>
TPL:
(Aside: Given that we now have CRM_Core_Resources, I think we could make the third one unnecessary.)
- For the "View Contact - Inplace Editing", the lock UI needs to generate "Ignore/Restart" widgets. These are initialized by subscribing to a custom jQuery event, "crmFormError." The approach presents a trade-off which is basically the opposite of the calendar widget – the custom jQuery events are only supported on one page ("View Contact"), but most of the code is transferred in a .js file – one time.
- At one point, Coleman brought up the issue of replicating Drupal's "attachBehaviors". I wasn't familiar with the term and didn't understand at the time. I've read about it now. I get it now. Drupal solves the problem with a "Pub/Sub" model – every page-load (or AHAH load) triggers an "attachBehavior" event. To define Javascript logic for a new widget, one creates a .js file which binds a listener to the "attachBehavior" event.
- For the "Edit Survey" UI, the "Contact Info and Questions" tab is rendered via AHAH. The tab container directly calls a helper function to handle setup. This is a hack.
https://fisheye2.atlassian.com/changelog/CiviCRM?cs=45012
- The tabs in the "Edit Survey" UI are interesting for another reason – they trigger Drupal's attachBehavior event. (There's also a similar bit of code used on the "Edit Contact" page provided by way of additionalBlocks.tpl.) This presents an interesting point – when integrating with CMS's and supporting customized .tpl's, downstream developers probably expect that they can define widgets with the CMS's native convention – and those widgets should work everywhere. I'm not saying that we should proactively do much about this. However, I think we should daisy-chain – internally, we would support an 'attachBehavior' event on all our pages/forms/AHAH blocks; on Drupal, our 'attachBehavior' should also trigger Drupal's 'attachBehavior' event.
== Proposals ==
1. For 4.3, add a basic pub/sub mechanism like Drupal's attachBehavior. This is "the standard" for initializing rich widgets. Document and announce it. (Also: Document some cases that don't follow the standard and emphasize that they are not examples to emulate. Document that the implementation is incomplete in 4.3 – and that patches are welcome.)
2. For 4.3, support the pub/sub in a few key AHAH screens (the dashboard, "View Contact," "Edit Contact", and "Edit Survey"). But do*not rewrite everything to use it.
3. For all new features (enhancing widgets or adding widgets) after Jan 2013, require following the standard.
4. For 4.4, identify a few specific widgets (like the calendar) and open issues to refactor them.