0
# Utilities and Global API
1
2
Core utilities, helper functions, and the global M object providing framework-wide functionality including auto-initialization, form utilities, animation helpers, and development tools.
3
4
## Capabilities
5
6
### Global M Object
7
8
Central namespace containing all Materialize functionality and utilities.
9
10
```javascript { .api }
11
/**
12
* Global Materialize object containing all framework functionality
13
*/
14
declare const M: {
15
/** Framework version string */
16
version: string; // "1.0.0"
17
18
/** jQuery availability indicator */
19
jQueryLoaded: boolean;
20
21
/** Tab key press state tracking */
22
tabPressed: boolean;
23
24
/** General key down state tracking */
25
keyDown: boolean;
26
27
/** Key code constants */
28
keys: {
29
TAB: 9;
30
ENTER: 13;
31
ESC: 27;
32
ARROW_UP: 38;
33
ARROW_DOWN: 40;
34
};
35
36
/** Auto-initialize all components within context */
37
AutoInit(context?: Element): void;
38
39
/** Update text field labels after dynamic content changes */
40
updateTextFields(): void;
41
42
/** Validate individual form field */
43
validate_field(field: Element): boolean;
44
45
/** Auto-resize textarea to fit content */
46
textareaAutoResize(textarea: Element): void;
47
48
/** Show toast notification */
49
toast(options: ToastOptions | { html: string }): Toast;
50
51
/** Generate unique random ID */
52
guid(): string;
53
54
/** Escape hash string special characters */
55
escapeHash(hash: string): string;
56
57
/** Check if element or parent has fixed positioning */
58
elementOrParentIsFixed(element: Element): boolean;
59
60
/** Check if bounding box is within container */
61
checkWithinContainer(container: Element, bounding: BoundingBox, offset: number): Edges;
62
63
/** Check possible alignments for positioning */
64
checkPossibleAlignments(el: Element, container: Element, bounding: BoundingBox, offset: number): AlignmentInfo;
65
66
/** Get overflow parent element */
67
getOverflowParent(element: Element): Element | null;
68
69
/** Extract ID from trigger element */
70
getIdFromTrigger(trigger: Element): string;
71
72
/** Cross-browser document scroll top */
73
getDocumentScrollTop(): number;
74
75
/** Cross-browser document scroll left */
76
getDocumentScrollLeft(): number;
77
78
/** Throttle function execution */
79
throttle(func: Function, wait: number, options?: ThrottleOptions): Function;
80
81
/** Initialize jQuery wrapper for component */
82
initializeJqueryWrapper(plugin: any, pluginName: string, classRef: string): void;
83
84
/** Generate selector string for jQuery object */
85
objectSelectorString(obj: any): string;
86
87
// Component classes
88
Autocomplete: typeof Autocomplete;
89
Carousel: typeof Carousel;
90
CharacterCounter: typeof CharacterCounter;
91
Chips: typeof Chips;
92
Collapsible: typeof Collapsible;
93
Datepicker: typeof Datepicker;
94
Dropdown: typeof Dropdown;
95
FloatingActionButton: typeof FloatingActionButton;
96
FormSelect: typeof FormSelect;
97
Materialbox: typeof Materialbox;
98
Modal: typeof Modal;
99
Parallax: typeof Parallax;
100
Pushpin: typeof Pushpin;
101
Range: typeof Range;
102
ScrollSpy: typeof ScrollSpy;
103
Sidenav: typeof Sidenav;
104
Slider: typeof Slider;
105
Tabs: typeof Tabs;
106
TapTarget: typeof TapTarget;
107
Timepicker: typeof Timepicker;
108
Toast: typeof Toast;
109
Tooltip: typeof Tooltip;
110
};
111
```
112
113
### Auto-Initialization
114
115
Automatic component initialization system that scans the DOM and initializes components based on CSS classes.
116
117
```javascript { .api }
118
/**
119
* Auto-initialize all components within context
120
* @param context - DOM element to search within (default: document.body)
121
*/
122
M.AutoInit(context?: Element): void;
123
```
124
125
**Usage Examples:**
126
127
```javascript
128
// Initialize all components on page load
129
document.addEventListener('DOMContentLoaded', function() {
130
M.AutoInit();
131
});
132
133
// Initialize components in specific container
134
const container = document.getElementById('dynamic-content');
135
M.AutoInit(container);
136
137
// Components that auto-initialize:
138
const autoInitComponents = {
139
'Autocomplete': '.autocomplete:not(.no-autoinit)',
140
'Carousel': '.carousel:not(.no-autoinit)',
141
'Chips': '.chips:not(.no-autoinit)',
142
'Collapsible': '.collapsible:not(.no-autoinit)',
143
'Datepicker': '.datepicker:not(.no-autoinit)',
144
'Dropdown': '.dropdown-trigger:not(.no-autoinit)',
145
'Materialbox': '.materialboxed:not(.no-autoinit)',
146
'Modal': '.modal:not(.no-autoinit)',
147
'Parallax': '.parallax:not(.no-autoinit)',
148
'Pushpin': '.pushpin:not(.no-autoinit)',
149
'ScrollSpy': '.scrollspy:not(.no-autoinit)',
150
'FormSelect': 'select:not(.no-autoinit)',
151
'Sidenav': '.sidenav:not(.no-autoinit)',
152
'Tabs': '.tabs:not(.no-autoinit)',
153
'TapTarget': '.tap-target:not(.no-autoinit)',
154
'Timepicker': '.timepicker:not(.no-autoinit)',
155
'Tooltip': '.tooltipped:not(.no-autoinit)',
156
'FloatingActionButton': '.fixed-action-btn:not(.no-autoinit)'
157
};
158
```
159
160
### Form Utilities
161
162
Helper functions for form handling and validation.
163
164
```javascript { .api }
165
/**
166
* Update all text field labels and styling
167
* Call after dynamically adding form elements
168
*/
169
M.updateTextFields(): void;
170
171
/**
172
* Validate individual form field
173
* @param field - Form field element to validate
174
* @returns Boolean indicating if field is valid
175
*/
176
M.validate_field(field: Element): boolean;
177
178
/**
179
* Auto-resize textarea element to fit content
180
* @param textarea - Textarea element to resize
181
*/
182
M.textareaAutoResize(textarea: Element): void;
183
```
184
185
**Usage Examples:**
186
187
```javascript
188
// Update text fields after AJAX content load
189
fetch('/api/form-data')
190
.then(response => response.json())
191
.then(data => {
192
// Populate form fields
193
document.getElementById('name').value = data.name;
194
document.getElementById('email').value = data.email;
195
196
// Update labels
197
M.updateTextFields();
198
});
199
200
// Validate form on submission
201
document.getElementById('myForm').addEventListener('submit', function(e) {
202
e.preventDefault();
203
204
const inputs = this.querySelectorAll('input[type="text"], input[type="email"]');
205
let isValid = true;
206
207
inputs.forEach(input => {
208
if (!M.validate_field(input)) {
209
isValid = false;
210
}
211
});
212
213
if (isValid) {
214
// Submit form
215
this.submit();
216
}
217
});
218
219
// Auto-resize textareas
220
document.querySelectorAll('textarea').forEach(textarea => {
221
M.textareaAutoResize(textarea);
222
});
223
```
224
225
### Toast Notifications
226
227
Global toast notification system for user feedback.
228
229
```javascript { .api }
230
/**
231
* Show toast notification
232
* @param options - Toast configuration options
233
* @returns Toast instance
234
*/
235
M.toast(options: ToastOptions | { html: string }): Toast;
236
237
interface ToastOptions {
238
/** Toast message HTML content */
239
html: string;
240
241
/** Display duration in milliseconds */
242
displayLength?: number; // default: 4000
243
244
/** Enter animation duration */
245
inDuration?: number; // default: 300
246
247
/** Exit animation duration */
248
outDuration?: number; // default: 375
249
250
/** Additional CSS classes */
251
classes?: string;
252
253
/** Callback when toast is dismissed */
254
completeCallback?: () => void;
255
256
/** Percentage of drag distance to activate dismissal */
257
activationPercent?: number; // default: 0.8
258
}
259
```
260
261
**Usage Examples:**
262
263
```javascript
264
// Simple toast
265
M.toast({html: 'Hello World!'});
266
267
// Styled toast
268
M.toast({
269
html: 'Success! Data saved.',
270
classes: 'green rounded',
271
displayLength: 2000
272
});
273
274
// Toast with callback
275
M.toast({
276
html: 'Processing...',
277
completeCallback: () => console.log('Toast dismissed')
278
});
279
280
// Toast with action button
281
M.toast({
282
html: `<span>Email sent</span><button class="btn-flat toast-action">Undo</button>`,
283
classes: 'rounded'
284
});
285
```
286
287
### Animation and Timing Utilities
288
289
Helper functions for animation and performance optimization.
290
291
```javascript { .api }
292
/**
293
* Throttle function execution to improve performance
294
* @param func - Function to throttle
295
* @param wait - Milliseconds to wait between calls
296
* @param options - Throttle options
297
* @returns Throttled function
298
*/
299
M.throttle(func: Function, wait: number, options?: ThrottleOptions): Function;
300
301
interface ThrottleOptions {
302
/** Execute on leading edge */
303
leading?: boolean; // default: true
304
305
/** Execute on trailing edge */
306
trailing?: boolean; // default: true
307
}
308
309
/**
310
* Generate unique random ID
311
* @returns UUID-style string
312
*/
313
M.guid(): string;
314
```
315
316
**Usage Examples:**
317
318
```javascript
319
// Throttle scroll handler for performance
320
const handleScroll = M.throttle(function() {
321
console.log('Scroll event:', window.scrollY);
322
}, 100);
323
324
window.addEventListener('scroll', handleScroll);
325
326
// Throttle resize handler
327
const handleResize = M.throttle(function() {
328
// Expensive resize operations
329
recalculateLayout();
330
}, 250, { leading: false });
331
332
window.addEventListener('resize', handleResize);
333
334
// Generate unique IDs
335
const uniqueId = M.guid(); // e.g., "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
336
```
337
338
### Element Utilities
339
340
Helper functions for DOM element manipulation and positioning.
341
342
```javascript { .api }
343
/**
344
* Check if element or any parent has fixed positioning
345
* @param element - Element to check
346
* @returns Boolean indicating fixed positioning
347
*/
348
M.elementOrParentIsFixed(element: Element): boolean;
349
350
/**
351
* Escape hash string special characters for CSS selectors
352
* @param hash - Hash string to escape
353
* @returns Escaped hash string
354
*/
355
M.escapeHash(hash: string): string;
356
357
/**
358
* Extract ID from trigger element (data-target or href)
359
* @param trigger - Trigger element
360
* @returns Target ID string
361
*/
362
M.getIdFromTrigger(trigger: Element): string;
363
364
/**
365
* Get cross-browser document scroll position
366
* @returns Scroll top position in pixels
367
*/
368
M.getDocumentScrollTop(): number;
369
370
/**
371
* Get cross-browser document scroll position
372
* @returns Scroll left position in pixels
373
*/
374
M.getDocumentScrollLeft(): number;
375
376
/**
377
* Get overflow parent of element
378
* @param element - Element to find overflow parent for
379
* @returns Overflow parent element or null
380
*/
381
M.getOverflowParent(element: Element): Element | null;
382
```
383
384
**Usage Examples:**
385
386
```javascript
387
// Check for fixed positioning
388
const isFixed = M.elementOrParentIsFixed(document.getElementById('myElement'));
389
if (isFixed) {
390
// Handle fixed positioning
391
}
392
393
// Escape hash for selector
394
const hash = '#my:special.id';
395
const escaped = M.escapeHash(hash); // '#my\\:special\\.id'
396
document.querySelector(escaped);
397
398
// Get target ID from trigger
399
const trigger = document.querySelector('[data-target="modal1"]');
400
const targetId = M.getIdFromTrigger(trigger); // 'modal1'
401
402
// Cross-browser scroll position
403
const scrollTop = M.getDocumentScrollTop();
404
const scrollLeft = M.getDocumentScrollLeft();
405
406
// Find overflow parent
407
const overflowParent = M.getOverflowParent(myElement);
408
```
409
410
### Positioning Utilities
411
412
Advanced positioning and alignment helper functions.
413
414
```javascript { .api }
415
/**
416
* Check if bounding box is within container boundaries
417
* @param container - Container element
418
* @param bounding - Bounding box to check
419
* @param offset - Offset from edges
420
* @returns Object indicating which edges are exceeded
421
*/
422
M.checkWithinContainer(container: Element, bounding: BoundingBox, offset: number): Edges;
423
424
/**
425
* Check possible alignments for positioning
426
* @param el - Element to position
427
* @param container - Container element
428
* @param bounding - Bounding box
429
* @param offset - Offset value
430
* @returns Alignment possibilities and space information
431
*/
432
M.checkPossibleAlignments(el: Element, container: Element, bounding: BoundingBox, offset: number): AlignmentInfo;
433
434
interface BoundingBox {
435
left: number;
436
top: number;
437
width: number;
438
height: number;
439
}
440
441
interface Edges {
442
top: boolean;
443
right: boolean;
444
bottom: boolean;
445
left: boolean;
446
}
447
448
interface AlignmentInfo {
449
top: boolean;
450
right: boolean;
451
bottom: boolean;
452
left: boolean;
453
spaceOnTop: number | null;
454
spaceOnRight: number | null;
455
spaceOnBottom: number | null;
456
spaceOnLeft: number | null;
457
}
458
```
459
460
### jQuery Integration
461
462
Automatic jQuery wrapper generation for seamless integration.
463
464
```javascript { .api }
465
/**
466
* Initialize jQuery wrapper for component
467
* @param plugin - Component class
468
* @param pluginName - jQuery plugin name
469
* @param classRef - Class reference name
470
*/
471
M.initializeJqueryWrapper(plugin: any, pluginName: string, classRef: string): void;
472
473
/**
474
* Generate selector string for jQuery object
475
* @param obj - jQuery object
476
* @returns Selector string
477
*/
478
M.objectSelectorString(obj: any): string;
479
```
480
481
**jQuery Usage Patterns:**
482
483
```javascript
484
// When jQuery is loaded, components get jQuery wrappers
485
$(document).ready(function(){
486
// jQuery-style initialization
487
$('.modal').modal({
488
dismissible: false,
489
opacity: 0.5
490
});
491
492
// Method calling
493
$('.modal').modal('open');
494
495
// Getter methods
496
const isOpen = $('.modal').modal('isOpen');
497
498
// Chaining
499
$('.dropdown-trigger').dropdown().addClass('active');
500
});
501
```
502
503
## Development and Debugging Utilities
504
505
### Component Instance Management
506
507
```javascript
508
// Get component instances
509
const modalInstance = M.Modal.getInstance(document.getElementById('modal1'));
510
const dropdownInstance = M.Dropdown.getInstance(document.querySelector('.dropdown-trigger'));
511
512
// Check instance existence
513
if (modalInstance) {
514
console.log('Modal is initialized');
515
console.log('Modal is open:', modalInstance.isOpen);
516
}
517
518
// List all instances of a component type
519
const allModals = document.querySelectorAll('.modal');
520
allModals.forEach(modal => {
521
const instance = M.Modal.getInstance(modal);
522
if (instance) {
523
console.log('Modal instance found:', instance);
524
}
525
});
526
```
527
528
### Performance Optimization
529
530
```javascript
531
// Throttle expensive operations
532
const expensiveOperation = M.throttle(function() {
533
// Expensive DOM calculations
534
recalculatePositions();
535
}, 16); // ~60fps
536
537
// Debounce user input
538
function debounce(func, wait) {
539
let timeout;
540
return function executedFunction(...args) {
541
const later = () => {
542
clearTimeout(timeout);
543
func(...args);
544
};
545
clearTimeout(timeout);
546
timeout = setTimeout(later, wait);
547
};
548
}
549
550
const debouncedSearch = debounce(function(query) {
551
performSearch(query);
552
}, 300);
553
```
554
555
### Error Handling Patterns
556
557
```javascript
558
// Safe component initialization
559
function safeInit() {
560
try {
561
// Auto-initialize components
562
M.AutoInit();
563
} catch (error) {
564
console.error('Component initialization failed:', error);
565
566
// Initialize components individually
567
const components = [
568
{ selector: '.modal', init: M.Modal.init },
569
{ selector: '.dropdown-trigger', init: M.Dropdown.init },
570
{ selector: '.sidenav', init: M.Sidenav.init }
571
];
572
573
components.forEach(({ selector, init }) => {
574
try {
575
const elems = document.querySelectorAll(selector);
576
if (elems.length > 0) {
577
init(elems);
578
}
579
} catch (err) {
580
console.warn(`Failed to initialize ${selector}:`, err);
581
}
582
});
583
}
584
}
585
586
// Check for component availability
587
function checkComponentSupport() {
588
const requiredComponents = ['Modal', 'Dropdown', 'Sidenav'];
589
const missing = requiredComponents.filter(component => !M[component]);
590
591
if (missing.length > 0) {
592
console.warn('Missing components:', missing);
593
return false;
594
}
595
596
return true;
597
}
598
```
599
600
### Waves Effect System
601
602
Material Design ripple effect system for adding visual feedback to interactive elements. Waves is automatically initialized but can be manually controlled for custom implementations.
603
604
```javascript { .api }
605
/**
606
* Waves ripple effect system for Material Design interactions
607
*/
608
declare const Waves: {
609
/**
610
* Display ripple effect with optional configuration
611
* @param options - Animation configuration options
612
*/
613
displayEffect(options?: WaveOptions): void;
614
615
/**
616
* Attach waves effect to specific element
617
* @param element - Element to attach waves effect to
618
*/
619
attach(element: Element): void;
620
621
/** Effect duration in milliseconds */
622
duration: number; // default: 750
623
};
624
625
interface WaveOptions {
626
/** Animation duration in milliseconds */
627
duration?: number; // default: 750
628
}
629
```
630
631
**Usage Examples:**
632
633
```html
634
<!-- Elements with automatic waves effect -->
635
<button class="btn waves-effect">Button</button>
636
<a class="btn-floating waves-effect waves-light red">
637
<i class="material-icons">add</i>
638
</a>
639
640
<!-- Different wave colors -->
641
<button class="btn blue waves-effect waves-light">Light Waves</button>
642
<button class="btn blue waves-effect waves-dark">Dark Waves</button>
643
644
<!-- Waves on other elements -->
645
<div class="card waves-effect">
646
<div class="card-content">
647
<span class="card-title">Clickable Card</span>
648
</div>
649
</div>
650
651
<!-- Input elements (automatically wrapped) -->
652
<input type="button" class="btn waves-effect" value="Input Button">
653
```
654
655
```javascript
656
// Manual waves initialization (usually not needed)
657
Waves.displayEffect({
658
duration: 500
659
});
660
661
// Attach waves to dynamically created elements
662
const newButton = document.createElement('button');
663
newButton.className = 'btn waves-effect';
664
newButton.textContent = 'Dynamic Button';
665
document.body.appendChild(newButton);
666
667
// Manually attach waves effect
668
Waves.attach(newButton);
669
670
// Custom duration for all waves
671
Waves.displayEffect({
672
duration: 1000
673
});
674
```
675
676
**CSS Classes:**
677
678
- `.waves-effect` - Base class required for waves functionality
679
- `.waves-light` - Light-colored ripple effect (for dark backgrounds)
680
- `.waves-dark` - Dark-colored ripple effect (for light backgrounds)
681
- `.waves-red`, `.waves-yellow`, `.waves-orange`, `.waves-purple`, `.waves-green`, `.waves-teal` - Colored ripple effects
682
683
**Features:**
684
685
- Automatic initialization on page load
686
- Touch and mouse event support
687
- Automatic input element wrapping
688
- Customizable animation duration
689
- Multiple color variations
690
- Works with any clickable element
691
692
### Common Utility Patterns
693
694
```javascript
695
// Dynamic component management
696
class ComponentManager {
697
constructor() {
698
this.instances = new Map();
699
}
700
701
init(selector, ComponentClass, options = {}) {
702
const elements = document.querySelectorAll(selector);
703
elements.forEach(el => {
704
const instance = new ComponentClass(el, options);
705
this.instances.set(el, instance);
706
});
707
}
708
709
destroy(selector) {
710
const elements = document.querySelectorAll(selector);
711
elements.forEach(el => {
712
const instance = this.instances.get(el);
713
if (instance && instance.destroy) {
714
instance.destroy();
715
this.instances.delete(el);
716
}
717
});
718
}
719
720
reinit(selector, ComponentClass, options = {}) {
721
this.destroy(selector);
722
this.init(selector, ComponentClass, options);
723
}
724
}
725
726
// Usage
727
const manager = new ComponentManager();
728
manager.init('.modal', M.Modal, { dismissible: false });
729
manager.reinit('.modal', M.Modal, { dismissible: true });
730
```