From 89bf84056cddaafc0bfc745287448f1cd7843bab Mon Sep 17 00:00:00 2001 From: lovasoa Date: Thu, 6 Jul 2023 19:17:23 +0200 Subject: [PATCH] Rename nested-forms to Master-Detail Forms --- README.md | 1 + examples/master-detail-forms/README.md | 33 ++++++++++++++++++ .../edit_user.sql | 0 .../index.sql | 0 .../insert_address.sql | 0 .../insert_user.sql | 0 .../screenshots/db-schema.png | Bin 0 -> 23902 bytes .../screenshots}/home-screenshot.png | Bin .../screenshots}/user-add-screenshot.png | Bin .../sqlpage/migrations/0000_schema.sql | 0 examples/nested-forms/README.md | 13 ------- examples/read-and-set-http-cookies/Dockerfile | 3 ++ 12 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 examples/master-detail-forms/README.md rename examples/{nested-forms => master-detail-forms}/edit_user.sql (100%) rename examples/{nested-forms => master-detail-forms}/index.sql (100%) rename examples/{nested-forms => master-detail-forms}/insert_address.sql (100%) rename examples/{nested-forms => master-detail-forms}/insert_user.sql (100%) create mode 100644 examples/master-detail-forms/screenshots/db-schema.png rename examples/{nested-forms => master-detail-forms/screenshots}/home-screenshot.png (100%) rename examples/{nested-forms => master-detail-forms/screenshots}/user-add-screenshot.png (100%) rename examples/{nested-forms => master-detail-forms}/sqlpage/migrations/0000_schema.sql (100%) delete mode 100644 examples/nested-forms/README.md create mode 100644 examples/read-and-set-http-cookies/Dockerfile diff --git a/README.md b/README.md index f7edc61c..ebe0223c 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ to the user's browser. - [Tiny splitwise clone](./examples/splitwise): a shared expense tracker app - [Corporate Conundrum](./examples/corporate-conundrum/): a board game implemented in SQL +- [Master-Detail Form](./examples/master-detail-form/): shows how to implement a simple set of forms to insert data into database tables that have a one-to-many relationship. - [SQLPage's own official website and documentation](./examples/official-site/): The SQL source code for the project's official site, https://sql.ophir.dev ## Configuration diff --git a/examples/master-detail-forms/README.md b/examples/master-detail-forms/README.md new file mode 100644 index 00000000..afee92a9 --- /dev/null +++ b/examples/master-detail-forms/README.md @@ -0,0 +1,33 @@ +# Master-Detail Forms (Nested Forms) + +This example shows how to handle inserting data into multiple tables +with a one-to-many relationship. + +![db schema](./screenshots/db-schema.png) + +A single master page features two forms based on two related tables or views. +Users insert data in the master form first to update information from the parent table. +Then, they can insert data in the detail forms to update information from the child tables. + +This example application contains a main form to create users, +and a second form to create their addresses. + +Once an user has been added, multiple addresses can be added to it. + +See https://github.com/lovasoa/SQLpage/discussions/16 for more details. + +The main idea is to create two separate forms. +In this example, we put both forms on the same page, in [`edit-user.sql`](./edit-user.sql). +The first one is an edition form for the already-existing user record, +and the second is a form to add an address to the user. + +When you initially load the user creation form, +we do not display the address form. +Only when the user has been created, +you are redirected to the user edition form that contains the address form. + + +## Screenshots + +![homepage](./screenshots/home-screenshot.png) +![user addition](./screenshots//user-add-screenshot.png) diff --git a/examples/nested-forms/edit_user.sql b/examples/master-detail-forms/edit_user.sql similarity index 100% rename from examples/nested-forms/edit_user.sql rename to examples/master-detail-forms/edit_user.sql diff --git a/examples/nested-forms/index.sql b/examples/master-detail-forms/index.sql similarity index 100% rename from examples/nested-forms/index.sql rename to examples/master-detail-forms/index.sql diff --git a/examples/nested-forms/insert_address.sql b/examples/master-detail-forms/insert_address.sql similarity index 100% rename from examples/nested-forms/insert_address.sql rename to examples/master-detail-forms/insert_address.sql diff --git a/examples/nested-forms/insert_user.sql b/examples/master-detail-forms/insert_user.sql similarity index 100% rename from examples/nested-forms/insert_user.sql rename to examples/master-detail-forms/insert_user.sql diff --git a/examples/master-detail-forms/screenshots/db-schema.png b/examples/master-detail-forms/screenshots/db-schema.png new file mode 100644 index 0000000000000000000000000000000000000000..826b0ba838e642ef9de70a5fbd0a5d82aa1db30a GIT binary patch literal 23902 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