Add form value persistence across cache revalidation re-renders 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
203 lines
4.9 KiB
Markdown
Executable File
203 lines
4.9 KiB
Markdown
Executable File
---
|
|
name: jquery-extensions
|
|
description: RSX jQuery extensions including the click() override that auto-prevents default, existence checks, component-aware traversal, and form validation helpers. Use when working with click handlers, checking element existence, finding sibling components, or understanding why links don't navigate.
|
|
---
|
|
|
|
# RSX jQuery Extensions
|
|
|
|
## Critical: Click Override
|
|
|
|
**RSX overrides jQuery `.click()` to automatically call `e.preventDefault()`**
|
|
|
|
This is the most important thing to know. All click handlers prevent default behavior automatically:
|
|
|
|
```javascript
|
|
// RSX - preventDefault is automatic
|
|
$('.btn').click(function(e) {
|
|
do_something(); // Link won't navigate, form won't submit
|
|
});
|
|
|
|
// Vanilla jQuery - must remember to call it
|
|
$('.btn').click(function(e) {
|
|
e.preventDefault(); // Easy to forget!
|
|
do_something();
|
|
});
|
|
```
|
|
|
|
**Why**: `preventDefault` is correct 95% of the time. Making it automatic eliminates a common source of bugs.
|
|
|
|
---
|
|
|
|
## When You Need Native Behavior
|
|
|
|
Use `.click_allow_default()` for the rare cases where you want native browser behavior:
|
|
|
|
```javascript
|
|
// Analytics tracking before navigation
|
|
$('a.external').click_allow_default(function(e) {
|
|
analytics.track('external_link');
|
|
// Navigation happens after handler
|
|
});
|
|
|
|
// Conditional preventDefault
|
|
$('button[type=submit]').click_allow_default(function(e) {
|
|
if (!validate_form()) {
|
|
e.preventDefault(); // Only prevent if invalid
|
|
}
|
|
});
|
|
```
|
|
|
|
**Valid use cases for `.click_allow_default()`**:
|
|
- Analytics tracking before navigation
|
|
- Conditional form submission
|
|
- Progressive enhancement fallbacks
|
|
|
|
**Invalid use cases** (use standard `.click()` instead):
|
|
- Opening modals
|
|
- Triggering Ajax actions
|
|
- Any case where you don't want navigation
|
|
|
|
---
|
|
|
|
## Existence Checks
|
|
|
|
```javascript
|
|
// RSX - cleaner syntax
|
|
if ($('.element').exists()) {
|
|
// Element is in DOM
|
|
}
|
|
|
|
// Vanilla jQuery equivalent
|
|
if ($('.element').length > 0) { ... }
|
|
```
|
|
|
|
---
|
|
|
|
## Visibility and State
|
|
|
|
```javascript
|
|
// Is element visible (not display:none)?
|
|
if ($('.modal').is_visible()) {
|
|
$('.modal').fadeOut();
|
|
}
|
|
|
|
// Is element attached to DOM?
|
|
if ($('.dynamic').is_in_dom()) {
|
|
// Element is live in the page
|
|
}
|
|
|
|
// Is element in viewport?
|
|
if ($('.lazy-image').is_in_viewport()) {
|
|
load_image($(this));
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Component-Aware Traversal
|
|
|
|
### shallowFind(selector)
|
|
|
|
Finds child elements without descending into nested components of the same type:
|
|
|
|
```javascript
|
|
// Only finds direct Form_Field children, not fields in nested sub-forms
|
|
this.$.shallowFind('.Form_Field').each(function() {
|
|
// Process only this form's fields
|
|
});
|
|
```
|
|
|
|
Example DOM:
|
|
```
|
|
Component_A
|
|
└── div
|
|
└── Widget (found)
|
|
└── span
|
|
└── Widget (not found - has Widget parent)
|
|
```
|
|
|
|
### closest_sibling(selector)
|
|
|
|
Searches for elements within progressively higher ancestor containers. Useful for component-to-component communication:
|
|
|
|
```javascript
|
|
// Country selector finding its related state selector
|
|
this.tom_select.on('change', () => {
|
|
const state_input = this.$.closest_sibling('.State_Select_Input');
|
|
if (state_input.exists()) {
|
|
state_input.component().set_country_code(this.val());
|
|
}
|
|
});
|
|
```
|
|
|
|
Algorithm:
|
|
1. Get parent, search within it
|
|
2. If not found, move to parent's parent
|
|
3. Repeat until found or reaching `<body>`
|
|
|
|
---
|
|
|
|
## Form Validation
|
|
|
|
```javascript
|
|
// Check if form passes HTML5 validation
|
|
if ($('form').checkValidity()) {
|
|
submit_form();
|
|
}
|
|
|
|
// Show browser's native validation UI
|
|
if (!$('form').reportValidity()) {
|
|
return; // Browser shows validation errors
|
|
}
|
|
|
|
// Programmatically submit (triggers validation)
|
|
$('form').requestSubmit();
|
|
```
|
|
|
|
---
|
|
|
|
## Other Helpers
|
|
|
|
```javascript
|
|
// Get lowercase tag name
|
|
if ($element.tagname() === 'a') {
|
|
// It's a link
|
|
}
|
|
|
|
// Check if link is external
|
|
if ($('a').is_external()) {
|
|
$(this).attr('target', '_blank');
|
|
}
|
|
|
|
// Scroll to bring element into view
|
|
$('.error-field').scroll_up_to(300); // 300ms animation
|
|
```
|
|
|
|
---
|
|
|
|
## RSX vs Vanilla jQuery Comparison
|
|
|
|
| Operation | Vanilla jQuery | RSX |
|
|
|-----------|---------------|-----|
|
|
| Click with preventDefault | `e.preventDefault()` required | Automatic |
|
|
| Existence check | `.length > 0` | `.exists()` |
|
|
| Form validation | `$('form')[0].checkValidity()` | `$('form').checkValidity()` |
|
|
| Native click behavior | `.click()` | `.click_allow_default()` |
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
**Problem**: Links not navigating when they should
|
|
**Solution**: Use `.click_allow_default()` instead of `.click()`
|
|
|
|
**Problem**: Form submitting unexpectedly
|
|
**Solution**: This shouldn't happen - `.click()` prevents submission. If using `.click_allow_default()`, add explicit `e.preventDefault()`
|
|
|
|
**Problem**: Want to use `.on('click')` to avoid preventDefault
|
|
**Solution**: Don't - it defeats the framework's safety. Use `.click_allow_default()` to make intent explicit
|
|
|
|
## More Information
|
|
|
|
Details: `php artisan rsx:man jquery`
|