Skip to content

Commit 496b868

Browse files
committed
docs: enhance documentation on using unique class names to prevent conflicts with Unraid's JavaScript
1 parent c46f033 commit 496b868

3 files changed

Lines changed: 86 additions & 16 deletions

File tree

docs/ui/icons-and-styling.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,23 @@ Tips for theme compatibility:
149149

150150
## Custom CSS
151151

152+
### Namespace Your Class Names
153+
154+
Unraid's core pages use common class names with unscoped jQuery selectors. If your plugin uses the same class names, Unraid's JavaScript may inadvertently modify your elements, causing visual glitches.
155+
156+
Always prefix your CSS classes with your plugin name:
157+
158+
| Generic (avoid) | Namespaced (use) |
159+
|-----------------|------------------|
160+
| `.sortable` | `.myplugin-sortable` |
161+
| `.updatecolumn` | `.myplugin-updatecolumn` |
162+
| `.container` | `.myplugin-container` |
163+
| `.status` | `.myplugin-status` |
164+
165+
This is especially important when adding tabs to existing Unraid pages like the Docker menu, where your tab's DOM shares the page with Unraid's JavaScript.
166+
167+
### Adding Custom Styles
168+
152169
Add custom styles in your page file:
153170

154171
```php

docs/ui/javascript-patterns.md

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -581,24 +581,26 @@ $(document).on('keydown.mymodal', function(e) {
581581

582582
When your plugin adds a tab to an existing Unraid page (like adding a tab to the Docker menu), your JavaScript runs in the same context as that page's JavaScript. Unscoped selectors can accidentally target elements from the parent page, causing visual glitches or broken functionality.
583583

584-
Common classes like `.auto_start`, `.advanced`, `.basic`, and `.updatecolumn` are used by multiple Unraid pages. jQuery plugins like `switchButton` should never be re-initialized on elements that are already set up.
584+
Common classes like `.auto_start`, `.advanced`, `.basic`, `tr.sortable`, and `.updatecolumn` are used by multiple Unraid pages. jQuery plugins like `switchButton` should never be re-initialized on elements that are already set up.
585585

586586
```javascript
587-
// BAD - Selects ALL .auto_start elements on the page
588-
// If Docker tab already initialized these, you'll break them
589-
$('.auto_start').switchButton({labels_placement:'right', on_label:'On', off_label:'Off'});
590-
591-
// BAD - Toggles ALL .advanced elements, including Docker tab's columns
592-
$('.advanced').toggle();
593-
594-
// GOOD - Scope to your plugin's container
595-
$('#myplugin_table .auto_start').switchButton({labels_placement:'right', on_label:'On', off_label:'Off'});
587+
// BAD - Selects ALL tr.sortable rows on the page
588+
// Docker tab uses this class too, so you'll iterate over Docker containers
589+
$('tr.sortable').each(function() {
590+
var $updateCell = $(this).find('.updatecolumn');
591+
$updateCell.html('<i class="fa fa-refresh fa-spin"></i> checking...');
592+
});
596593

597-
// GOOD - Only affect your plugin's elements
598-
$('#myplugin_table .advanced').toggle();
599-
$('#myplugin_table .basic').toggle();
594+
// GOOD - Scope to your plugin's table
595+
$('#myplugin_table tr.sortable').each(function() {
596+
var $updateCell = $(this).find('.updatecolumn');
597+
$updateCell.html('<i class="fa fa-refresh fa-spin"></i> checking...');
598+
});
600599
```
601600

601+
{: .warning }
602+
> The Docker tab uses unscoped selectors like `$('tr.sortable')` and `$('.updatecolumn')`. If your plugin uses these same class names, clicking "Check for Updates" on Docker will animate *your* plugin's rows too. See [Namespace Your CSS Classes](#namespace-your-css-classes) below.
603+
602604
For elements added to shared areas (like the tab bar), use plugin-specific class names:
603605

604606
```javascript
@@ -615,7 +617,41 @@ $('.myplugin-advancedview').change(function(){
615617
});
616618
```
617619

618-
See [Tab Pages - Adding Tabs to Existing Pages](tab-pages.md#adding-tabs-to-existing-pages) for more details.
620+
See [Tab Pages - Adding Tabs to Existing Pages](tab-pages.md#adding-tabs-to-existing-pages) and [Icons and Styling - Namespace Your Class Names](icons-and-styling.md#namespace-your-class-names) for more details.
621+
622+
### Namespace Your CSS Classes
623+
624+
Even with scoped selectors in your own code, Unraid's core pages use unscoped selectors that will match your elements if you use common class names. The only reliable solution is to use plugin-specific class names.
625+
626+
Classes to avoid (used by Docker tab with unscoped selectors):
627+
- `sortable` - Used for drag-to-reorder rows
628+
- `updatecolumn` - Update status column
629+
- `ct-name` - Container name cells
630+
631+
```html
632+
<!-- BAD - Docker's JavaScript will target these rows -->
633+
<tr class="sortable" id="stack-row-1">
634+
<td class="ct-name">My Stack</td>
635+
<td class="updatecolumn">not checked</td>
636+
</tr>
637+
638+
<!-- GOOD - Unique class names prevent cross-tab interference -->
639+
<tr class="myplugin-sortable" id="stack-row-1">
640+
<td class="myplugin-name">My Stack</td>
641+
<td class="myplugin-updatecolumn">not checked</td>
642+
</tr>
643+
```
644+
645+
Update your JavaScript to match:
646+
647+
```javascript
648+
// Use your namespaced classes
649+
$('#myplugin_table tr.myplugin-sortable').each(function() {
650+
$(this).find('.myplugin-updatecolumn').html('checking...');
651+
});
652+
```
653+
654+
This approach ensures your plugin works correctly regardless of what selectors other tabs or Unraid core might use.
619655

620656
### Namespace Your Timers
621657

docs/ui/tab-pages.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,23 @@ $('#my_plugin_table .advanced').toggle();
237237

238238
### Use Unique Class Names
239239

240-
For elements that need to be globally unique (like an Advanced View toggle in the tab bar), use plugin-specific class names:
240+
Even with scoped selectors in your own code, Unraid's core pages use **unscoped selectors** that will still match your elements. For example, the Docker tab's JavaScript uses `$('tr.sortable')` and `$('.updatecolumn')` without scoping to its own container. If your plugin uses these class names, Docker's "Check for Updates" button will animate your plugin's rows too.
241+
242+
The only reliable solution is to use plugin-specific class names:
243+
244+
```html
245+
<!-- BAD - Docker's unscoped JavaScript will target these -->
246+
<tr class="sortable">
247+
<td class="updatecolumn">not checked</td>
248+
</tr>
249+
250+
<!-- GOOD - Unique class names prevent cross-tab interference -->
251+
<tr class="myplugin-sortable">
252+
<td class="myplugin-updatecolumn">not checked</td>
253+
</tr>
254+
```
255+
256+
For elements added to shared areas (like an Advanced View toggle in the tab bar), always use plugin-specific class names:
241257

242258
```javascript
243259
// BAD - may conflict with Docker tab's advancedview toggle
@@ -272,4 +288,5 @@ function loadMyPluginContent() {
272288

273289
- [Page Files]({% link docs/page-files.md %})
274290
- [Form Controls]({% link docs/ui/form-controls.md %})
275-
- [JavaScript Patterns]({% link docs/ui/javascript-patterns.md %})
291+
- [JavaScript Patterns]({% link docs/ui/javascript-patterns.md %}) - See "Scope Your Selectors" and "Namespace Your CSS Classes"
292+
- [Icons and Styling]({% link docs/ui/icons-and-styling.md %}) - See "Namespace Your Class Names"

0 commit comments

Comments
 (0)