0
# JavaScript Integration
1
2
Integration with popular JavaScript libraries including Markdown rendering, syntax highlighting, interactive components, and client-side scripting utilities.
3
4
## Capabilities
5
6
### JavaScript Library Integration
7
8
Pre-configured JavaScript library loaders for popular front-end libraries.
9
10
```python { .api }
11
def MarkdownJS(*c, **kw):
12
"""
13
Markdown parsing and rendering.
14
15
Integrates markdown-it library for client-side markdown
16
parsing and HTML rendering.
17
18
Args:
19
*c: Content or configuration
20
**kw: Library configuration options
21
22
Returns:
23
Script elements for markdown functionality
24
"""
25
26
def KatexMarkdownJS(*c, **kw):
27
"""
28
Markdown with KaTeX math support.
29
30
Combines markdown parsing with KaTeX for mathematical
31
formula rendering in markdown content.
32
33
Args:
34
*c: Content or configuration
35
**kw: Library and math rendering options
36
37
Returns:
38
Script elements for markdown with math support
39
"""
40
41
def HighlightJS(*c, **kw):
42
"""
43
Syntax highlighting.
44
45
Integrates highlight.js for syntax highlighting
46
of code blocks in various programming languages.
47
48
Args:
49
*c: Configuration or language specifications
50
**kw: Highlighting options and themes
51
52
Returns:
53
Script and style elements for syntax highlighting
54
"""
55
56
def SortableJS(*c, **kw):
57
"""
58
Drag-and-drop sorting.
59
60
Integrates SortableJS for drag-and-drop functionality
61
on lists and grid elements.
62
63
Args:
64
*c: Configuration options
65
**kw: Sortable behavior settings
66
67
Returns:
68
Script elements for drag-and-drop functionality
69
"""
70
71
def MermaidJS(*c, **kw):
72
"""
73
Diagram and flowchart rendering.
74
75
Integrates Mermaid.js for rendering diagrams,
76
flowcharts, and other visualizations from text.
77
78
Args:
79
*c: Diagram definitions or configuration
80
**kw: Rendering options and themes
81
82
Returns:
83
Script elements for diagram rendering
84
"""
85
```
86
87
### Client-Side Scripting Utilities
88
89
Enhanced JavaScript execution and client-side scripting capabilities.
90
91
```python { .api }
92
def Surreal(*c, **kw):
93
"""
94
Surreal JavaScript code block.
95
96
Creates Surreal.js code blocks for enhanced DOM
97
manipulation and client-side interactions.
98
99
Args:
100
*c: Surreal.js code content
101
**kw: Script attributes and options
102
103
Returns:
104
Script element with Surreal.js code
105
"""
106
107
def On(*c, **kw):
108
"""
109
Event handler JavaScript.
110
111
Creates JavaScript event handlers with simplified
112
syntax for DOM events.
113
114
Args:
115
*c: Event handler code
116
**kw: Event options and attributes
117
118
Returns:
119
JavaScript code for event handling
120
"""
121
122
def Prev(*c, **kw):
123
"""
124
Previous element event handler.
125
126
Creates event handlers that target the previous
127
sibling element in the DOM.
128
129
Args:
130
*c: Handler code
131
**kw: Event configuration
132
133
Returns:
134
JavaScript code for previous element targeting
135
"""
136
137
def Now(*c, **kw):
138
"""
139
Immediate JavaScript execution.
140
141
Executes JavaScript code immediately when the
142
element is rendered.
143
144
Args:
145
*c: JavaScript code to execute
146
**kw: Execution options
147
148
Returns:
149
Script element with immediate execution
150
"""
151
152
def AnyNow(*c, **kw):
153
"""
154
JavaScript execution on any element.
155
156
Executes JavaScript code on any matching element
157
when rendered or modified.
158
159
Args:
160
*c: JavaScript code
161
**kw: Element selection and execution options
162
163
Returns:
164
Script element with flexible execution
165
"""
166
167
def run_js(code: str):
168
"""
169
Execute JavaScript code.
170
171
Executes JavaScript code in the browser context
172
with proper error handling.
173
174
Args:
175
code: JavaScript code to execute
176
177
Returns:
178
Script element with code execution
179
"""
180
```
181
182
### CDN Library Loading
183
184
Utility for loading JavaScript libraries from CDN services.
185
186
```python { .api }
187
def jsd(library: str, version: str = None, **kwargs):
188
"""
189
JavaScript library loader from CDN.
190
191
Loads JavaScript libraries from jsDelivr CDN with
192
version management and dependency handling.
193
194
Args:
195
library: Library name (e.g., 'jquery', 'lodash')
196
version: Specific version to load (latest if None)
197
**kwargs: Additional loading options
198
199
Returns:
200
Script element with CDN library loading
201
"""
202
```
203
204
### Surreal.js Client-Side Scripting
205
206
Surreal.js integration for DOM manipulation and event handling without traditional JavaScript syntax.
207
208
```python { .api }
209
def Surreal(code: str):
210
"""
211
Wrap JavaScript code in Surreal.js domReadyExecute.
212
213
Args:
214
code: JavaScript code to execute when DOM is ready
215
216
Returns:
217
Script element with Surreal.js DOM ready wrapper
218
"""
219
220
def On(code: str, event='click', sel='', me=True):
221
"""
222
Event handler with Surreal.js syntax.
223
224
Args:
225
code: JavaScript code to execute on event
226
event: DOM event type (click, submit, etc.)
227
sel: CSS selector for target elements
228
me: Whether to include 'me' context
229
230
Returns:
231
Surreal.js event handler script
232
"""
233
234
def Prev(code: str, event='click'):
235
"""
236
Event handler on previous sibling element.
237
238
Args:
239
code: JavaScript code to execute
240
event: DOM event type
241
242
Returns:
243
Surreal.js previous sibling event handler
244
"""
245
246
def Now(code: str, sel=''):
247
"""
248
Execute JavaScript immediately on page load.
249
250
Args:
251
code: JavaScript code to execute
252
sel: CSS selector for context
253
254
Returns:
255
Immediate execution script
256
"""
257
258
def AnyNow(sel: str, code: str):
259
"""
260
Execute JavaScript on any selector match.
261
262
Args:
263
sel: CSS selector to match
264
code: JavaScript code to execute
265
266
Returns:
267
Conditional execution script
268
"""
269
270
def run_js(js: str, id=None, **kwargs):
271
"""
272
Execute JavaScript with automatic ID generation.
273
274
Args:
275
js: JavaScript code to run
276
id: Element ID (auto-generated if None)
277
**kwargs: Additional script attributes
278
279
Returns:
280
Script element with executable JavaScript
281
"""
282
```
283
284
### HTMX JavaScript Integration
285
286
JavaScript utilities specifically designed for HTMX interactions.
287
288
```python { .api }
289
def HtmxOn(eventname: str, code: str):
290
"""
291
HTMX event handler script generator.
292
293
Creates JavaScript event handlers that work
294
seamlessly with HTMX requests and responses.
295
296
Args:
297
eventname: HTMX event name (e.g., 'htmx:afterSwap')
298
code: JavaScript code to execute on event
299
300
Returns:
301
Script element with HTMX event handler
302
"""
303
304
def clear(id: str):
305
"""
306
Clear element content by ID.
307
308
Generates JavaScript to clear element content,
309
compatible with HTMX workflows.
310
311
Args:
312
id: Element ID to clear
313
314
Returns:
315
JavaScript code for clearing element content
316
"""
317
```
318
319
### JavaScript Source Constants
320
321
Pre-defined JavaScript source URLs and code snippets.
322
323
```python { .api }
324
htmxsrc: str
325
"""HTMX JavaScript source URL."""
326
327
fhjsscr: str
328
"""FastHTML JavaScript source code."""
329
330
surrsrc: str
331
"""Surreal.js JavaScript source URL."""
332
333
scopesrc: str
334
"""Scope JavaScript source code."""
335
```
336
337
## Usage Examples
338
339
### Markdown Rendering
340
341
```python
342
from fasthtml.common import *
343
344
app, rt = fast_app()
345
346
@rt('/markdown')
347
def markdown_demo():
348
return Titled("Markdown Rendering",
349
Container(
350
H1("Markdown with JavaScript"),
351
352
# Markdown input area
353
Div(
354
H2("Write Markdown"),
355
Textarea(
356
id="markdown-input",
357
placeholder="# Hello World\n\nType your **markdown** here...",
358
rows="10",
359
style="width: 100%; font-family: monospace;"
360
),
361
Button(
362
"Render Markdown",
363
onclick="renderMarkdown()",
364
cls="primary"
365
)
366
),
367
368
# Rendered output
369
Div(
370
H2("Rendered Output"),
371
Div(id="markdown-output", style="border: 1px solid #ccc; padding: 1rem; min-height: 200px;")
372
),
373
374
# Include Markdown.js
375
MarkdownJS(),
376
377
# Custom JavaScript for rendering
378
Script("""
379
function renderMarkdown() {
380
const input = document.getElementById('markdown-input').value;
381
const output = document.getElementById('markdown-output');
382
383
// Using markdown-it library
384
const md = window.markdownit();
385
const rendered = md.render(input);
386
output.innerHTML = rendered;
387
}
388
389
// Auto-render on load if there's content
390
document.addEventListener('DOMContentLoaded', function() {
391
const input = document.getElementById('markdown-input');
392
if (input.value.trim()) {
393
renderMarkdown();
394
}
395
});
396
""")
397
)
398
)
399
400
@rt('/markdown-math')
401
def markdown_math_demo():
402
return Titled("Markdown with Math",
403
Container(
404
H1("Markdown with KaTeX Math"),
405
406
# Sample content with math
407
Div(id="math-content", """
408
# Mathematical Expressions
409
410
Inline math: $E = mc^2$
411
412
Block math:
413
$$
414
\\int_{-\\infty}^{\\infty} e^{-x^2} dx = \\sqrt{\\pi}
415
$$
416
417
More complex equation:
418
$$
419
\\frac{1}{\\sqrt{2\\pi\\sigma^2}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}
420
$$
421
"""),
422
423
# Include Markdown.js with KaTeX
424
KatexMarkdownJS(),
425
426
Script("""
427
document.addEventListener('DOMContentLoaded', function() {
428
const content = document.getElementById('math-content');
429
const md = window.markdownit({
430
html: true,
431
typographer: true
432
});
433
434
// Render markdown with math
435
const rendered = md.render(content.textContent);
436
content.innerHTML = rendered;
437
438
// Render KaTeX math
439
renderMathInElement(content, {
440
delimiters: [
441
{left: "$$", right: "$$", display: true},
442
{left: "$", right: "$", display: false}
443
]
444
});
445
});
446
""")
447
)
448
)
449
```
450
451
### Syntax Highlighting
452
453
```python
454
from fasthtml.common import *
455
456
app, rt = fast_app()
457
458
@rt('/syntax-highlighting')
459
def syntax_demo():
460
return Titled("Syntax Highlighting",
461
Container(
462
H1("Code Syntax Highlighting"),
463
464
# Python code example
465
Div(
466
H2("Python Code"),
467
Pre(Code("""
468
def fibonacci(n):
469
\"\"\"Generate Fibonacci sequence up to n terms.\"\"\"
470
if n <= 0:
471
return []
472
elif n == 1:
473
return [0]
474
elif n == 2:
475
return [0, 1]
476
477
sequence = [0, 1]
478
for i in range(2, n):
479
sequence.append(sequence[i-1] + sequence[i-2])
480
481
return sequence
482
483
# Generate first 10 Fibonacci numbers
484
result = fibonacci(10)
485
print(f"First 10 Fibonacci numbers: {result}")
486
""", cls="language-python"))
487
),
488
489
# JavaScript code example
490
Div(
491
H2("JavaScript Code"),
492
Pre(Code("""
493
class Calculator {
494
constructor() {
495
this.result = 0;
496
}
497
498
add(value) {
499
this.result += value;
500
return this;
501
}
502
503
multiply(value) {
504
this.result *= value;
505
return this;
506
}
507
508
getValue() {
509
return this.result;
510
}
511
}
512
513
// Usage example
514
const calc = new Calculator();
515
const result = calc.add(5).multiply(3).add(2).getValue();
516
console.log(`Result: ${result}`); // Result: 17
517
""", cls="language-javascript"))
518
),
519
520
# SQL code example
521
Div(
522
H2("SQL Code"),
523
Pre(Code("""
524
-- Create users table
525
CREATE TABLE users (
526
id SERIAL PRIMARY KEY,
527
username VARCHAR(50) UNIQUE NOT NULL,
528
email VARCHAR(100) UNIQUE NOT NULL,
529
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
530
);
531
532
-- Insert sample data
533
INSERT INTO users (username, email) VALUES
534
('john_doe', 'john@example.com'),
535
('jane_smith', 'jane@example.com');
536
537
-- Query with join
538
SELECT u.username, u.email, p.title
539
FROM users u
540
LEFT JOIN posts p ON u.id = p.user_id
541
WHERE u.created_at > '2024-01-01'
542
ORDER BY u.created_at DESC;
543
""", cls="language-sql"))
544
),
545
546
# Include Highlight.js
547
HighlightJS(),
548
549
# Initialize highlighting
550
Script("""
551
document.addEventListener('DOMContentLoaded', function() {
552
hljs.highlightAll();
553
});
554
""")
555
)
556
)
557
```
558
559
### Drag and Drop Functionality
560
561
```python
562
from fasthtml.common import *
563
564
app, rt = fast_app()
565
566
@rt('/drag-drop')
567
def sortable_demo():
568
return Titled("Drag and Drop",
569
Container(
570
H1("Sortable Lists"),
571
572
# Simple sortable list
573
Div(
574
H2("Task List"),
575
Ul(
576
Li("Complete project proposal", id="task-1", cls="sortable-item"),
577
Li("Review code changes", id="task-2", cls="sortable-item"),
578
Li("Update documentation", id="task-3", cls="sortable-item"),
579
Li("Run test suite", id="task-4", cls="sortable-item"),
580
Li("Deploy to staging", id="task-5", cls="sortable-item"),
581
id="task-list",
582
style="list-style: none; padding: 0;"
583
),
584
P("Drag and drop to reorder tasks.")
585
),
586
587
# Sortable grid
588
Div(
589
H2("Image Gallery"),
590
Div(
591
*[Div(
592
Img(src=f"https://picsum.photos/150/150?random={i}", alt=f"Image {i}"),
593
P(f"Image {i}", style="text-align: center; margin: 0.5rem 0;"),
594
cls="gallery-item",
595
style="border: 1px solid #ddd; padding: 0.5rem; margin: 0.5rem;"
596
) for i in range(1, 9)],
597
id="image-gallery",
598
style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem;"
599
),
600
P("Drag images to rearrange the gallery.")
601
),
602
603
# Include SortableJS
604
SortableJS(),
605
606
# Initialize sortable functionality
607
Script("""
608
document.addEventListener('DOMContentLoaded', function() {
609
// Make task list sortable
610
const taskList = document.getElementById('task-list');
611
new Sortable(taskList, {
612
animation: 150,
613
ghostClass: 'sortable-ghost',
614
onEnd: function(evt) {
615
console.log('Task moved from', evt.oldIndex, 'to', evt.newIndex);
616
// Here you could send the new order to the server
617
}
618
});
619
620
// Make image gallery sortable
621
const gallery = document.getElementById('image-gallery');
622
new Sortable(gallery, {
623
animation: 150,
624
ghostClass: 'sortable-ghost',
625
onEnd: function(evt) {
626
console.log('Image moved from', evt.oldIndex, 'to', evt.newIndex);
627
}
628
});
629
});
630
"""),
631
632
# CSS for sortable items
633
Style("""
634
.sortable-item {
635
padding: 0.75rem;
636
margin: 0.25rem 0;
637
background: #f8f9fa;
638
border: 1px solid #dee2e6;
639
border-radius: 0.25rem;
640
cursor: move;
641
transition: all 0.2s;
642
}
643
644
.sortable-item:hover {
645
background: #e9ecef;
646
transform: translateY(-1px);
647
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
648
}
649
650
.sortable-ghost {
651
opacity: 0.4;
652
background: #007bff !important;
653
color: white;
654
}
655
656
.gallery-item {
657
cursor: move;
658
transition: transform 0.2s;
659
}
660
661
.gallery-item:hover {
662
transform: scale(1.05);
663
}
664
""")
665
)
666
)
667
```
668
669
### Interactive Diagrams
670
671
```python
672
from fasthtml.common import *
673
674
app, rt = fast_app()
675
676
@rt('/diagrams')
677
def diagram_demo():
678
return Titled("Interactive Diagrams",
679
Container(
680
H1("Mermaid.js Diagrams"),
681
682
# Flowchart
683
Div(
684
H2("Process Flowchart"),
685
Div("""
686
graph TD
687
A[Start] --> B{Is it working?}
688
B -->|Yes| C[Great!]
689
B -->|No| D[Debug]
690
D --> E[Fix Issues]
691
E --> B
692
C --> F[Deploy]
693
F --> G[End]
694
""", cls="mermaid")
695
),
696
697
# Sequence diagram
698
Div(
699
H2("API Sequence Diagram"),
700
Div("""
701
sequenceDiagram
702
participant Client
703
participant API
704
participant Database
705
706
Client->>API: POST /users
707
API->>Database: INSERT user
708
Database-->>API: User created
709
API-->>Client: 201 Created
710
711
Client->>API: GET /users/123
712
API->>Database: SELECT user
713
Database-->>API: User data
714
API-->>Client: 200 OK
715
""", cls="mermaid")
716
),
717
718
# Gantt chart
719
Div(
720
H2("Project Timeline"),
721
Div("""
722
gantt
723
title Project Development Timeline
724
dateFormat YYYY-MM-DD
725
section Planning
726
Requirements :req, 2024-01-01, 2024-01-15
727
Design :design, after req, 10d
728
section Development
729
Backend :backend, 2024-01-20, 20d
730
Frontend :frontend, after design, 25d
731
section Testing
732
Unit Tests :test1, after backend, 5d
733
Integration :test2, after frontend, 10d
734
section Deployment
735
Staging :staging, after test2, 3d
736
Production :prod, after staging, 2d
737
""", cls="mermaid")
738
),
739
740
# Include Mermaid.js
741
MermaidJS(),
742
743
# Initialize Mermaid
744
Script("""
745
document.addEventListener('DOMContentLoaded', function() {
746
mermaid.initialize({
747
startOnLoad: true,
748
theme: 'default',
749
flowchart: {
750
useMaxWidth: true,
751
htmlLabels: true
752
}
753
});
754
});
755
""")
756
)
757
)
758
```
759
760
### Client-Side Interactions with Surreal.js
761
762
```python
763
from fasthtml.common import *
764
765
app, rt = fast_app(surreal=True)
766
767
@rt('/surreal-demo')
768
def surreal_demo():
769
return Titled("Surreal.js Demo",
770
Container(
771
H1("Client-Side Interactions"),
772
773
# DOM manipulation examples
774
Div(
775
H2("DOM Manipulation"),
776
Button("Change Text", id="change-text-btn"),
777
Button("Add Item", id="add-item-btn"),
778
Button("Toggle Visibility", id="toggle-btn"),
779
P("This text will change", id="dynamic-text"),
780
Ul(id="dynamic-list"),
781
Div("This div will toggle", id="toggle-div", style="margin-top: 1rem; padding: 1rem; background: #f0f0f0;")
782
),
783
784
# Form interactions
785
Div(
786
H2("Form Interactions"),
787
Input(type="text", id="name-input", placeholder="Enter your name"),
788
Button("Greet", id="greet-btn"),
789
P(id="greeting-output")
790
),
791
792
# Surreal.js code
793
Surreal("""
794
// DOM manipulation examples
795
$("#change-text-btn").on("click", () => {
796
$("#dynamic-text").text("Text changed at " + new Date().toLocaleTimeString());
797
});
798
799
$("#add-item-btn").on("click", () => {
800
const itemCount = $("#dynamic-list li").length + 1;
801
$("#dynamic-list").append(`<li>Item ${itemCount}</li>`);
802
});
803
804
$("#toggle-btn").on("click", () => {
805
$("#toggle-div").toggle();
806
});
807
808
// Form interactions
809
$("#greet-btn").on("click", () => {
810
const name = $("#name-input").value;
811
if (name) {
812
$("#greeting-output").text(`Hello, ${name}! Nice to meet you.`);
813
} else {
814
$("#greeting-output").text("Please enter your name first.");
815
}
816
});
817
818
// Real-time input feedback
819
$("#name-input").on("input", (e) => {
820
const value = e.target.value;
821
if (value.length > 0) {
822
$("#greet-btn").removeAttribute("disabled");
823
} else {
824
$("#greet-btn").setAttribute("disabled", "true");
825
}
826
});
827
""")
828
)
829
)
830
```
831
832
### CDN Library Integration
833
834
```python
835
from fasthtml.common import *
836
837
app, rt = fast_app()
838
839
@rt('/cdn-libraries')
840
def cdn_demo():
841
return Titled("CDN Library Integration",
842
Container(
843
H1("External Library Integration"),
844
845
# Chart.js example
846
Div(
847
H2("Chart Visualization"),
848
Canvas(id="chart-canvas", width="400", height="200"),
849
Button("Update Chart", id="update-chart-btn")
850
),
851
852
# Lodash utility example
853
Div(
854
H2("Data Processing"),
855
Pre(id="data-output", style="background: #f8f9fa; padding: 1rem; border-radius: 0.25rem;"),
856
Button("Process Data", id="process-data-btn")
857
),
858
859
# Load Chart.js from CDN
860
jsd("chart.js", "3.9.1"),
861
862
# Load Lodash from CDN
863
jsd("lodash", "4.17.21"),
864
865
# Custom JavaScript using loaded libraries
866
Script("""
867
document.addEventListener('DOMContentLoaded', function() {
868
// Chart.js example
869
const ctx = document.getElementById('chart-canvas').getContext('2d');
870
let chart = new Chart(ctx, {
871
type: 'bar',
872
data: {
873
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
874
datasets: [{
875
label: 'Votes',
876
data: [12, 19, 3, 5, 2, 3],
877
backgroundColor: [
878
'rgba(255, 99, 132, 0.5)',
879
'rgba(54, 162, 235, 0.5)',
880
'rgba(255, 205, 86, 0.5)',
881
'rgba(75, 192, 192, 0.5)',
882
'rgba(153, 102, 255, 0.5)',
883
'rgba(255, 159, 64, 0.5)'
884
]
885
}]
886
},
887
options: {
888
responsive: true,
889
scales: {
890
y: {
891
beginAtZero: true
892
}
893
}
894
}
895
});
896
897
// Update chart with random data
898
document.getElementById('update-chart-btn').addEventListener('click', function() {
899
chart.data.datasets[0].data = chart.data.datasets[0].data.map(() =>
900
Math.floor(Math.random() * 20) + 1
901
);
902
chart.update();
903
});
904
905
// Lodash example
906
document.getElementById('process-data-btn').addEventListener('click', function() {
907
const rawData = [
908
{ name: 'John', age: 30, city: 'New York' },
909
{ name: 'Jane', age: 25, city: 'San Francisco' },
910
{ name: 'Bob', age: 35, city: 'New York' },
911
{ name: 'Alice', age: 28, city: 'San Francisco' },
912
{ name: 'Charlie', age: 32, city: 'Chicago' }
913
];
914
915
// Use Lodash to process data
916
const groupedByCity = _.groupBy(rawData, 'city');
917
const avgAgeByCity = _.mapValues(groupedByCity, (people) =>
918
_.round(_.meanBy(people, 'age'), 1)
919
);
920
const sortedCities = _.sortBy(Object.keys(avgAgeByCity));
921
922
const result = {
923
'Total People': rawData.length,
924
'Cities': sortedCities,
925
'Average Age by City': avgAgeByCity,
926
'Oldest Person': _.maxBy(rawData, 'age'),
927
'Youngest Person': _.minBy(rawData, 'age')
928
};
929
930
document.getElementById('data-output').textContent =
931
JSON.stringify(result, null, 2);
932
});
933
});
934
""")
935
)
936
)
937
```