UNPKG

@ea-lab/reactive-json-docs

Version:

Complete documentation for Reactive-JSON - Components, examples and LLM-parsable guides

515 lines (442 loc) 17.2 kB
renderView: - type: Markdown content: | # Bulk Actions System This guide demonstrates how to implement a bulk action system that allows users to select multiple items in a list and perform actions on all selected items simultaneously. This pattern is commonly used in data tables, file managers, and admin interfaces. ## Core Concept The bulk action system uses a combination of: - **Selection state**: Track which items are selected using checkboxes - **Data attributes**: Mark selected rows in the DOM for CSS selector targeting - **Event delegation**: Use `triggerEvent` to programmatically trigger actions on multiple elements - **Conditional actions**: Ensure actions only execute on selected items - type: Markdown content: | ## Concepts We Will Use This pattern leverages several Reactive-JSON features: - **[Switch Component](../element/special/Switch.md)**: Iterate over a collection of items and render each with a template - **[SetAttributeValue Action](../action/Attribute/SetAttributeValue.md)**: Dynamically set HTML attributes (like `data-selected`) based on data state - **[triggerEvent Reaction](../reaction/triggerEvent.md)**: Programmatically dispatch events on multiple elements matching a CSS selector - **[Template Contexts](../getting-started/template-contexts-data-binding.md)**: Use `~.` for row-scoped data and `~~.` for global data - **[Conditional Actions](../getting-started/actions.md)**: Use `when` conditions to control when actions execute - type: Markdown content: | ## Prerequisites Before implementing bulk actions, you should understand: 1. **Template system**: How `Switch` renders items using templates 2. **Data binding**: The difference between `~.` (local template context) and `~~.` (global context) 3. **Actions and reactions**: How to define actions that respond to user interactions 4. **CSS selectors**: Basic understanding of attribute selectors like `[data-selected="true"]` - type: Markdown content: | ## Steps ### Step 1: Set Up Selection State Add a `selected` property to each item in your data array and a global `bulkAction` variable. - type: SyntaxHighlighter language: yaml title: "Data Structure" content: | data: items: [] bulkAction: "" - type: Markdown content: | Each item in the array should have a `selected` boolean property (can be initialized as `false` or added dynamically). ### Step 2: Add Selection Checkboxes Add checkboxes to each row to allow users to select individual items. - type: SyntaxHighlighter language: yaml title: "Checkbox in Row Template" content: | templates: itemRow: - type: tr content: - type: td content: - type: CheckBoxField dataLocation: ~.selected defaultFieldValue: false options: - label: "" value: true - type: Markdown content: | ### Step 3: Mark Selected Rows with Data Attributes Use `setAttributeValue` action to add a `data-selected` attribute to rows when they are selected. This allows CSS selectors to target selected rows. - type: SyntaxHighlighter language: yaml title: "Mark Selected Rows" content: | templates: itemRow: - type: tr actions: - what: setAttributeValue name: "data-selected" value: "true" mode: "replace" when: ~.selected is: true content: # ... row content - type: Markdown content: | **Important**: Use `mode: "replace"` to ensure the attribute is removed when `selected` becomes `false`. You may also want to add an action to remove the attribute when not selected. ### Step 4: Add Action Buttons with Data Attributes Add `data-action` attributes to action buttons so they can be targeted by CSS selectors. - type: SyntaxHighlighter language: yaml title: "Action Button with Data Attribute" content: | - type: button attributes: data-action: "process" type: "button" content: "Process" actions: - what: submitData on: click # ... action configuration - type: Markdown content: | ### Step 5: Create Bulk Action Controls Add a bulk action selector and execute button in your main view. - type: SyntaxHighlighter language: yaml title: "Bulk Action Controls" content: | renderView: - type: SelectField dataLocation: ~~.bulkAction defaultFieldValue: "" options: - value: "" label: "-- Choose action --" - value: "process" label: "Process selected items" - type: button content: "Execute" actions: - what: hide when: ~~.bulkAction isEmpty: true - what: triggerEvent on: click eventName: "click" selector: "tr[data-selected=\"true\"] button[data-action=\"process\"]" - type: Markdown content: | ### Step 6: Add Safety Conditions Add conditions to prevent actions from executing on items that shouldn't be processed. - type: SyntaxHighlighter language: yaml title: "Safety Conditions" content: | - type: button attributes: data-action: "process" actions: - what: hide when: ~.status is: "processed" # Hide button if already processed - what: submitData on: click # ... only executes if button is visible - type: RjBuildDescriber title: "Complete Example: File Management Table" description: | A complete example of a file management table with bulk processing. Users can select multiple files and process them all at once by clicking the "Execute" button. toDescribe: renderView: - type: div attributes: class: "p-4" content: - type: h2 attributes: class: "text-2xl font-bold mb-4" content: "File Management" - type: table attributes: class: "w-full border-collapse border border-gray-300 mb-4" content: - type: thead content: - type: tr content: - type: th attributes: class: "border border-gray-300 p-2 bg-gray-100" content: "Select" - type: th attributes: class: "border border-gray-300 p-2 bg-gray-100" content: "File Name" - type: th attributes: class: "border border-gray-300 p-2 bg-gray-100" content: "Status" - type: th attributes: class: "border border-gray-300 p-2 bg-gray-100" content: "Actions" - type: tbody content: - type: Switch content: ~~.files singleOption: load: fileRow - type: div attributes: class: "flex items-center gap-4 p-4 bg-gray-100 rounded" content: - type: label attributes: class: "font-medium" content: "Bulk action:" - type: SelectField dataLocation: ~~.bulkAction defaultFieldValue: "" inputAttributes: class: "border border-gray-300 p-2 rounded" options: - value: "" label: "-- Choose action --" - value: "process" label: "Process selected files" - type: button attributes: class: "bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600" content: "Execute" actions: - what: hide when: ~~.bulkAction isEmpty: true - what: triggerEvent on: click eventName: "click" selector: "tr[data-selected=\"true\"] button[data-action=\"process\"]" templates: fileRow: - type: tr attributes: class: "border-b" actions: - what: setAttributeValue name: "data-selected" value: "true" mode: "replace" when: ~.selected is: true - what: setAttributeValue name: "data-selected" value: "false" mode: "replace" when: ~.selected isNot: true content: - type: td attributes: class: "border border-gray-300 p-2" content: - type: CheckBoxField dataLocation: ~.selected defaultFieldValue: false options: - label: "" value: true attributes: class: "w-4 h-4" - type: td attributes: class: "border border-gray-300 p-2" content: ~.name - type: td attributes: class: "border border-gray-300 p-2" content: - type: span attributes: class: "px-2 py-1 rounded text-xs" content: ~.status - type: td attributes: class: "border border-gray-300 p-2" content: - type: button attributes: data-action: "process" class: "bg-blue-500 text-white px-3 py-1 rounded text-sm hover:bg-blue-600" type: "button" content: "Process" actions: - what: hide when: ~.status is: "processing" - what: hide when: ~.status is: "processed" - what: setData on: click path: ~.status value: "processing" - what: setData on: click path: ~.status value: "processed" delay: 2000 data: files: - id: "file1" name: "document.pdf" status: "pending" selected: false - id: "file2" name: "image.jpg" status: "pending" selected: false - id: "file3" name: "spreadsheet.xlsx" status: "pending" selected: false bulkAction: "" - type: Markdown content: | ## How It Works 1. **Selection**: Users check boxes to set `~.selected` to `true` for individual items 2. **Attribute marking**: `setAttributeValue` adds `data-selected="true"` to selected rows 3. **Bulk trigger**: When "Execute" is clicked, `triggerEvent` finds all `tr[data-selected="true"]` rows 4. **Action execution**: Within each selected row, it finds `button[data-action="process"]` and triggers a `click` event 5. **Individual processing**: Each button's `on: click` reactions execute, processing that specific item - type: Markdown content: | ## Go Further ### Select All Functionality Add a "Select All" checkbox in the table header to select/deselect all items at once. - type: SyntaxHighlighter language: yaml title: "Select All Checkbox" content: | - type: th content: - type: CheckBoxField dataLocation: ~~.selectAll defaultFieldValue: false options: - label: "" value: true actions: - what: setData on: change path: ~.selected value: ~~.selectAll # This would need to be in each row template - type: Markdown content: | ### Multiple Action Types Support multiple bulk actions by using different `data-action` values and dynamically constructing the selector. - type: SyntaxHighlighter language: yaml title: "Multiple Bulk Actions" content: | - type: SelectField dataLocation: ~~.bulkAction options: - value: "process" label: "Process" - value: "delete" label: "Delete" - value: "archive" label: "Archive" # In triggerEvent, dynamically construct selector: - what: triggerEvent on: click eventName: "click" selector: ["tr[data-selected=\"true\"] button[data-action=\"", ~~.bulkAction, "\"]"] - type: Markdown content: | ### Visual Feedback Add visual indicators for selected rows using CSS classes. - type: SyntaxHighlighter language: yaml title: "Visual Feedback for Selected Rows" content: | - type: tr attributes: class: "border-b" actions: - what: setAttributeValue name: "class" value: "bg-blue-100" mode: "append" when: ~.selected is: true - type: Markdown content: | ### Prevent Double Processing Add conditions to prevent processing items that are already being processed. - type: SyntaxHighlighter language: yaml title: "Prevent Double Processing" content: | - type: button attributes: data-action: "process" actions: - what: hide when: ~.status is: "processing" - what: hide when: ~.status is: "processed" # Actions only execute if button is visible - type: Markdown content: | ### Count Selected Items Display the number of selected items using the `Count` component. - type: SyntaxHighlighter language: yaml title: "Display Selection Count" content: | - type: div content: - "Selected: " - type: Count jsonPathPattern: "$.files[?(@.selected == true)]" - type: Markdown content: | ## Additional Notes ### Performance Considerations - **Concurrent requests**: Use `allowConcurrent: true` in `submitData` to process multiple items simultaneously - **Selector efficiency**: More specific selectors (like `tr[data-selected="true"]`) are faster than broad selectors - **Event delegation**: `triggerEvent` dispatches events sequentially using Promises to ensure reliability ### Accessibility - Ensure checkboxes have proper labels - Use ARIA attributes for screen readers: ```yaml - what: setAttributeValue name: "aria-selected" value: "true" when: ~.selected is: true ``` ### Error Handling Consider adding error handling for failed bulk operations: ```yaml - what: submitData on: click # ... submit configuration onError: - what: setData path: ~.status value: "error" ``` ### Alternative Approaches - **Message-based**: Use `postMessage` and `on: message` reactions (more complex but allows cross-component communication) - **Custom handlers**: Create a custom React component to handle bulk operations (more control but requires JavaScript) ### Best Practices 1. **Always use `mode: "replace"`** for `setAttributeValue` when toggling boolean attributes to ensure clean state 2. **Use specific selectors** to avoid unintended side effects 3. **Add safety conditions** to prevent actions on inappropriate items 4. **Provide visual feedback** so users know which items are selected 5. **Test with multiple selections** to ensure concurrent operations work correctly