Skip to content

Commit

Permalink
add a detailed example of the usage of multi-select fields with many …
Browse files Browse the repository at this point in the history
…comments
  • Loading branch information
lovasoa committed Sep 13, 2024
1 parent d01e3a8 commit 289f681
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
98 changes: 98 additions & 0 deletions examples/todo application (PostgreSQL)/batch.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
-- Include 'shell.sql' to generate the page header and footer
select 'dynamic' as component, sqlpage.run_sql('shell.sql') as properties;

-- Define a Common Table Expression (CTE) named 'updated'
-- CTEs are temporary named result sets, useful for complex queries
-- Here, it's used to perform the update and capture the results in one step
with updated as (
-- Update the 'todos' table and return the modified rows
-- This approach allows us to both update the data and use it for reporting
update todos set
-- Modify the title based on user input for labels
-- The CASE statements handle different scenarios for label management
title = case
-- If :remove_label is null, we keep the existing title as is
when :remove_label is null then
title
else
-- Remove any existing labels (text within parentheses)
-- This uses a regular expression to strip out (label) from the end
regexp_replace(title, '\s*\(.*\)', '')
end
-- Concatenate the result with a new label if provided
||
case
-- If no new label is provided, we don't add anything
when :new_label is null or :new_label = '' then
''
else
-- Add the new label in parentheses at the end
' (' || :new_label || ')'
end
-- Determine which todos to update based on user selection
where
-- Update specific todos if their IDs are in the :todos parameter
-- :todos is a JSON array of todo string IDs, e.g. ["1", "2", "3"]
-- that optionally includes "all" to update all todos
id in (
-- Parse the JSON array of todo IDs and convert each to integer
-- This allows for multiple todo selection in the UI
select e::int from jsonb_array_elements_text(:todos::jsonb) e
where e != 'all'
)
-- If 'all' is the only selected, update every todo (by making the where condition always true)
or :todos = '["all"]'
-- Return all updated rows for counting and potential further use
returning *
)
-- Generate an alert component to inform the user about the update result
-- This provides immediate feedback on the operation's outcome
select 'alert' as component,
'Batch update' as title,
-- Create a dynamic message with the count of updated todos
format('%s todos updated', (select count(*) from updated)) as description
-- Only display the alert if at least one todo was updated
-- This prevents showing unnecessary alerts for no-op updates
where exists (select * from updated);

-- Create a form component for the batch update interface
-- This sets up the structure for the user input form
select 'form' as component,
'Batch update' as title,
'Update all todos' as contents;

-- Create a select input for choosing which todos to update
-- This allows users to pick multiple todos or all todos for updating
select
'select' as type,
'Update these todos' as label,
'todos[]' as name,
true as multiple,
true as dropdown,
true as required,
-- Combine a static "all" option with dynamic options for each todo
-- This uses JSON functions to build a complex data structure for the UI
-- The JSON structure is used to set the label, value, and selection state for each option
-- The generated JSON looks like this:
-- [{"label":"Update all todos","value":"all","selected":true},{"label":"Todo 1","value":"1","selected":false}]
jsonb_build_array(jsonb_build_object( -- json_build_object takes a list of key-value pairs and returns a JSON object
'label', 'Update all todos', -- The label of the option
'value', 'all', -- The value of the option
'selected', :todos = '["all"]' or :todos is null -- Pre-select 'all' only if it was previously chosen or if :todos is not set (the page was just loaded)
)) ||
-- Generate an option for each todo in the database
jsonb_agg(jsonb_build_object(
'label', title,
'value', id,
-- Pre-select this todo if it was in the previous selection
'selected', (id in (select e::int from jsonb_array_elements_text(:todos::jsonb) e where e != 'all'))
)) as options
from todos;

-- Create a text input for entering a new label
-- This allows users to specify the label to be added to the selected todos
select 'new_label' as name, 'New label' as label;

-- Create a checkbox for optionally removing existing labels
-- This gives users the choice to strip old labels before adding a new one
select 'checkbox' as type, 'Remove previous labels' as label, 'remove_label' as name;
1 change: 1 addition & 0 deletions examples/todo application (PostgreSQL)/shell.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
select
'shell' as component,
format ('Todo list (%s)', count(*)) as title,
'batch' as menu_item,
'timeline' as menu_item
from
todos;

0 comments on commit 289f681

Please sign in to comment.