This document summarizes the non-obvious, codebase-specific conventions and patterns observed in the provided examples. It focuses on the distinctive or less common choices this codebase uses (not general best practices).
-
Wrap modules in an IIFE and initialize inside jQuery ready:
- Pattern: (function(){ jQuery(document).ready(function($){ /* module body */ }); })();
- Purpose: isolates scope and injects jQuery as
$inside the ready callback.
-
Use jQuery as the primary DOM API (selectors, traversal, manipulation, events).
- Cache selections into local variables (e.g.
var resultList = $('table#result_list');). - Use chainable jQuery construction for DOM elements:
var tr = $('<tr>');,$('<th>').attr('colspan',n).text(label).
- Cache selections into local variables (e.g.
-
Access raw DOM nodes when needed via
.get(0)or.get():- Common when integrating with non-jQuery APIs (e.g.
iframe.contentWindow). - Example:
var iframe = $('<iframe>').attr(...).on('load', fn).attr('src', url).get(0);
- Common when integrating with non-jQuery APIs (e.g.
-
Prefer
.on('event', handler)for programmatic elements and.click(fn)shorthand for simpler cases.- Both are used;
.on('load', ...)is used on dynamically created iframes.
- Both are used;
-
Manipulating iframes:
- Create iframe with jQuery and then use
.get(0)to obtain the DOM window/frame to accesscontentWindow. - Example pattern to wire callbacks into the iframe controller: var iframe = $('<iframe>').attr(...).on('load', function(){ var showHideController = iframe.contentWindow.xataface.controllers.ShowHideColumnsController; showHideController.saveCallbacks.push(function(data){ ... }); }).get(0);
- Create iframe with jQuery and then use
-
Data in HTML attributes:
- Use
data-attributes but read them via.attr('data-...')(not.data()). - Some attributes contain serialized JS (legacy):
data-xataface-querymay hold a JS object literal string — the code useseval('window.xataface.query = '+queryJson+';')to restore it.- Note: this codebase intentionally uses
evalfor legacy formatted data-attributes. ConsiderJSON.parseonly if the attribute is guaranteed to be valid JSON.
- Note: this codebase intentionally uses
- Use
-
Global "namespace" pattern:
- Create a global
window.xatafaceobject if undefined and attach sub-objects:if (typeof(window.xataface) == 'undefined') window.xataface = {}; window.xataface.query = {}; - Read/write to
window.xatafacefor cross-frame/controller state.
- Create a global
-
Event handling quirks:
- Stop bubbling where necessary, for example preventing inner link clicks from triggering header click handlers:
$('a', th).click(function(e){ e.stopPropagation(); });
- Stop bubbling where necessary, for example preventing inner link clicks from triggering header click handlers:
-
DOM layout animation/resizing:
- Measure container dimensions and animate input width via
$('input', this).animate({width: width-2}, 500); - Use
.css({...})with an object to set multiple CSS properties.
- Measure container dimensions and animate input width via
-
Small but consistent practices:
- Use
clone()to duplicate DOM nodes for reuse into other table sections (thead → tfoot). - Use
eachloops withfunction(){ var self = this; ... }when DOM node reference is required inside deeper scopes.
- Use
-
Class naming:
- Controller/action classes are lowercase with underscores, e.g.
class dataface_actions_copy_replace { ... }. - Internal method names use camelCase (e.g.
getFieldsForRecord,getKeysForRecord,getTableForm).
- Controller/action classes are lowercase with underscores, e.g.
-
Legacy/compatibility constructs:
- Frequent use of references and old-style assignments (
=&) and returning by reference (function &getTableForm(...)) — keep these patterns when interacting with legacy APIs. @operator is used to suppress warnings in many places (e.g.@$_POST['-copy_replace:submit']).
- Frequent use of references and old-style assignments (
-
Translation function:
- Calls use
df_translate(key, defaultString)throughout. Always provide the key and a fallback default string.
- Calls use
-
Form names & naming conventions:
- Long, namespaced input names to avoid collisions. Example QuickForm naming pattern:
- Form name:
'copy_replace_form' - Element names:
-copy_replace_form:replace[FIELDNAME] - Hidden control names:
-copy_replace:fields,-copy_replace:copy,-copy_replace:submit
- Form name:
- Use these prefixed names consistently to group action-specific form fields.
- Long, namespaced input names to avoid collisions. Example QuickForm naming pattern:
-
QuickForm & renderer usage:
- Build fields via a per-table QuickForm builder (
getTableForm) and attach rendered templates withsetElementTemplate. - Use
$form->setDefaults()and$form->addElement('hidden', ...)to propagate upstream query parameters into the form.
- Build fields via a per-table QuickForm builder (
-
Data access & permissions:
- Use
df_get_selected_records($query)and fallback to fetching whole result sets with-limitadjustments when no selection. - Check permissions per-record (
$record->checkPermission('edit'),'copy') and per-field ($record->checkPermission('edit', array('field'=>$key))) and collect warnings.
- Use
-
Error handling:
- Use PEAR-style checking:
if (PEAR::isError($res)) { ... }. - Use
Dataface_Error::permissionDenied()to create permission errors.
- Use PEAR-style checking:
-
Legacy array syntax:
- Use
array()for arrays (not short[]syntax).
- Use
-
Hints for maintainers:
- When adding new features, prefer to follow existing reference-return and QuickForm integration patterns for compatibility with other Dataface components.
-
Icon font & ligatures:
- Use @font-face to load Material Icons with multiple fallbacks and
local()lookups. - Use a
.material-iconsclass and enablefont-feature-settings: 'liga';to allow ligature-based icons.
- Use @font-face to load Material Icons with multiple fallbacks and
-
Vendor fallbacks & progressive enhancement:
- Include both vendor-prefixed and standard properties for compatibility:
- border-radius:
-moz-,-webkit-and standardborder-radius. - box-sizing:
-webkit-box-sizing,-moz-box-sizing, andbox-sizing. - box-shadow and opacity fallbacks:
.yui-ac-shadowuses both-moz-opacity/opacityandfilter:alpha(opacity=10).
- border-radius:
- Include both vendor-prefixed and standard properties for compatibility:
-
Advanced selectors and features used:
- Attribute selectors:
input:not([type="submit"])for styling input types excluding submit. - Child selectors
>and combinators to scope styles tightly (e.g..mobile-list-settings-wrapper > div). - Pseudo-element content used as small UI bits:
:before/:afterwithcontent. - Media query for prints:
@media print { ... }. - Flexbox for compact mobile controls:
display:flexon.mobile-list-settings-wrapper > div.
- Attribute selectors:
-
CSS utility and behavioral classes:
.stop-scrollingtoggles overflow to freeze body (used during modal dialog)..hiddenStructureis an accessibility/visually-hidden utility class that preserves content for assistive tech..expanded/.collapsedtoggle display states for text reveal controls.
-
Layout and theming patterns:
- Mixed use of background images plus colors for button and header visuals (legacy support).
- Many list and menu patterns implemented via absolute-positioned dropdown containers (e.g.
.xf-dropdown ul).
-
Data attributes:
- Use HTML attributes prefixed with
data-for carrying meta info (e.g.data-xataface-query,data-search-column,data-column). - Reading is done with jQuery
.attr('data-...')rather than.data()to preserve raw string content (important when the value is a JS literal string).
- Use HTML attributes prefixed with
-
Form field naming:
- Namespaced names (example
-copy_replace_form:replace[FIELDNAME]) to isolate action-specific values and facilitate server-side parsing.
- Namespaced names (example
-
Table structure:
- Tables for result lists include
thead,tbody,tfootand template rows (classtemplate) intfootthat are removed / processed by JS.
- Tables for result lists include
-
Cross-frame communication:
- Controllers expose arrays of callbacks on the iframe window object (e.g.
iframe.contentWindow.xataface.controllers.ShowHideColumnsController.saveCallbacks.push(fn)). - The parent page registers callbacks by accessing
contentWindowafter iframe load.
- Controllers expose arrays of callbacks on the iframe window object (e.g.
-
Dialog interaction:
- jQuery UI Dialog is used to host iframes; the code attaches to dialog
create,beforeClose, andbuttonsto coordinate actions (e.g. clicking a Save button in parent triggers a button inside iframe).
- jQuery UI Dialog is used to host iframes; the code attaches to dialog
- The codebase intentionally retains several legacy constructs for compatibility:
eval()used to parse legacy JS literal strings stored in attributes.&reference semantics and=&assignments in PHP.- PEAR style error objects and Dataface helper functions.
- Old vendor-prefixed CSS alongside modern properties.
When updating or refactoring, keep backward compatibility with older browsers/framework components in mind unless a coordinated upgrade is planned.
If you want, I can:
- Produce quick linting rules or ESLint/PHP-CS-Fixer configuration snippets to begin enforcing these conventions.
- Extract the most important "do not change" items into a short checklist for reviewers.