Multiple forms and sub-tables in a single view |
Let me start by saying this question isn't about how to have multiple forms in a single view, nor is it about how to validate multiple forms via a single controller. I already know how to do that.
The question is a bit more complex so I've put some visual examples together. Let's say I have a model called "order" which in the database would consist of an `orders` table. Orders would also contain items so there would be a sub table called `order_items` which contain the items for an order, with a foreign key back to the `orders` table. Keeping it simple, if an order consists of a customer name and email address I could have a view like this: Then, to add items to an order, I could have a separate controller and view which looks like this: This works fine, but it's cumbersome to have to switch between two pages/views to see data from the two different tables. Another option is to have two forms in one view, like this: These two forms can be linked to the same controller, or to two separate controllers (which call the same view), it doesn't really matter. However the issue with this is that it's unclear whether after clicking on "Add Product" you also have to click on "Save Details" (as it happens, you don't, but it's not clear). Furthermore, if you change the customer's name and don't click on "Save Details" but instead click on "Add Product" the customer's name change would be lost. So the whole thing becomes ambiguous from a usability point of view. I guess what I want in an ideal world is this: I think this makes the most sense from a user's perspective - there is a single "Save" button and if you don't click it your changes don't get saved (including the addition of items). But I don't know how to implement this. At the moment adding an item to an order physically adds it to the `order_items` table in the database. The order model calculates things like tax and shipping at the time of adding items to the `order_items` table, as well as calling some database triggers. So I can't just add a "faux" item to the html view prior to clicking on "Save Details" as the tax and shipping (as well as various other things that I've omitted from this example) would be unknown. I guess what I am looking for is some way of inserting items into the `order_items` table temporarily but then rolling those changes back if the "Save Order" button isn't clicked and the changes aren't committed. Does anyone have any advice as to the best way to handle this?
Perhaps a different sequence of data collection would make this easier. Collect the items first and associate them to an 'orders' table entry later. Here's what I mean.
On the stand-alone 'items' view change the "Save Details" button to "Place Order" which, when clicked, opens the name/email view. On that screen change "Save Details" to "Continue". That click creates the 'orders' table entry saving the name/email data along with the foreign key value you've been using to group the items. Once saved, you go to a previously undiscussed "complete order" view. Clearly the foreign key value - in 'orders' pointing to 'order_items' - cannot be taken from an auto-increment field of the 'orders' table' but will instead have to be generated during the item selection process. Garbage collection of unordered items can be accomplished by checking the 'order_items" table for records where the 'order_number' column is not found in the 'orders' table. When to do GC however is an interesting question. I assume you already have a scheme for clearing orders+items that never actually get ordered.
Thanks for your reply. It's a good suggestion but the problem is, you can go back and edit an order later which means the two components are still split across two views.
(10-30-2017, 02:34 AM)CINewb Wrote: Thanks for your reply. It's a good suggestion but the problem is, you can go back and edit an order later which means the two components are still split across two views. Assuming I understand what is happening here: I think this is more a "human engineering" issue than a coding problem. Adding to that, is the form or forms to be used inhouse, in which case the user could get by with a very simple reminder of what is happening, or does it have to be more complex to explain to a newbie user how they can foul up? Going back and editing an order that is already processed is not a good idea. I think it should be a "change order" type of view, that will actually call up the already processed order so that inventory/shipping/payment whomever will know what is happening. Fiddling with a non-proessed order is nowhere near as serioius.
I think you are conflating separate concerns here and obviously it is causing issues. This may be to the abstract nature of your example, but in a real situation this would not arise.
As a user, my name and email address is not going to change during an order, but my order might and probably will, as I fiddle with quantities and products etc. As a user, my name and email would come after I have built my order together, unless I am not a new user and logging in to my account, in which case you would know them anyway and again they are unlikely to change very often. I would expect to build my order in my shopping cart before proceeding to give my details, delivery addresses and finally payment. Why you would have a combined form where I can fiddle with the order and my details on the same page I have no idea. So this problem disappears once it is placed into a real world context. Having said all that, I would build the order in a temporary order table, and only when the order was confirmed later in a confirmation screen would I write the order to a confirmed order table and remove it from the temp table. Once an order is confirmed there should be no way to edit it by the user. Finally with your first side by side example, I would disable (or even hide it entirely) the button 'save details' until they have changed. Then you need a new button below the two sections to 'Confirm Order and Details and Proceed', perhaps with some explanatory text. I would make this button bold, green and stand out obvious, whilst the other two buttons more minor, greyish, less stand out buttons (like sub-buttons). So three buttons, one to save details, one to add products and a third to confirm and proceed. Hope that helps, Paul
Right on @PaulD
In addition see how Google Enhanced E-commerce works and what kind of events it captures, because at a given moment you probably will be asked to implement it. Here are the events approximately: - preview any page - preview product category - preview product page - add a product to cart - remove a product from cart - checkout - additional steps after checkout (if any, add contact data, delivery options, final preview before the transaction) - transaction (order/payment) a.k.a. "Thank you" page. So, better make a cart where you can fill it with products. Implement the navigation from the checkout to the final transaction as a wizard - several pages (not many, shrink this path as it is possible) with "Back" and "Forward" ("Buy") buttons. Lately, when it becomes necessary, with this page structure you could relatively easily add the JavaScripts for tracking. In your pictures I wonder why the "Add Product" button has been placed exactly there and what it does. |
Welcome Guest, Not a member yet? Register Sign In |