I have a table which uses a large number of form fields (the HTML variety - i.e. without runat=server). When a postback occurs, these populate the Requests.Form object, and they appear to be inserted in the same order as they're defined in the page HTML.
Is this behaviour documented and consistent across browsers? I'd like to be able to access the elements by index, which would provide a simple way to find the fields, given that they may be inserted or deleted on the client side.
Edit:
Each row in the table has a hidden field which contains the row ID. This field is named according to the order it was displayed at render time. e.g. the first row has a field like <input type="hidden" name="row0" value="RowID_555252" />, and so on.
Of course the row numbers will be wrong as soon as a row is inserted or deleted in the middle of the table, so the only solution I can think of is to use Javascript to update the row numbers of the entire table whenever the rows move about. The backend would then retreive rows in order by scanning Request.Form for row0, row1, etc until the element is NULL.
Is this behaviour documented ...
Yes it is.
The overall algorithm is here: http://dev.w3.org/html5/spec/constraints.html#concept-form-submit and this defines that it uses a form data set built using the algorithm at http://dev.w3.org/html5/spec/constraints.html#constructing-the-form-data-set.
While that algorithm is quite complicated, in essence it says that the form elements will be put into the form data set in node order. That's not quite the same thing as what they were in the page HTML, for instance, the elements can be moved by JavaScript.
There are further algorithms to turn the form data set into query strings or HTTP content but these too preserve the node order.
There are known to be web pages that depend on this order. (The HTML5 parser has a strange quirk where input elements of most types, placed inside tables but not inside table cells are ejected from the table through a process known as foster parenting, but input elements of type "hidden" are not ejected in this way. This happens because that's the only way to preserve the legacy submit ordering behaviour of browsers.)
...and consistent across browsers?
The whole algorithm of what gets submitted is definitely not consistent - for example, the submissions resulting from clicking on an input element of type "image" are known to vary significantly.
I believe that the order of the submitted elements may well be consistent across browser implementations. However, I would not rely on it being so, and encourage you to find a more robust solution.
Is this behaviour documented and consistent across browsers?
No, it is not documented and it is not guaranteed to be consistent across browsers. That this is how it occurs happens to be an implementation detail of the browser/s you have used.
You could of course use the index, but you cannot assume that this will correspond to the order of the form elements. Furthermore, it is brittle - what happens if you add a new field at the start of the form? Your logic completely breaks.
Related
Question in short: How can you map/calculate a derived field using JDO/DataNucleus?
Example
An Order can have one or more Items. The field totalItemAmount is the sum of all Items and their amounts. totalItemAmount should not exist as a field in the datastore, but should be calculated.
With Hibernate one could use #Formula to annotate totalItemAmount- see https://stackoverflow.com/a/2986354/2294031 .
Is there an equivalent for JDO/DataNucleus?
Workarounds
Because I have not found anything yet, I considered using alternative approaches. But I am not sure which one would be appropriate.
Implementing totalItemAmount as a method: The total amount of items could be calculated with a method (eg. Order.getTotalItemAmount()). The method iterates over all Items of the Order and sums up the amount of each Item. But I imagine this approach would be very slow if I want to display an overview of many orders. Because each time getTotalItemAmount() gets called, all Items of the Order will be (unnecessarily) fetched.
Defining a custom query: Is it possible to define a custom query, which will be used, when DataNucleus obtains Orders from the datastore?
Treating totalItemAmount as a "normal" column (like number): totalItemAmount will be an integer column and everytime the list of Items from the Order gets updated, the totalItemAmount will be updated also. But I do not like this approach, because it could lead to inconsistency - If the order gets modified outside the context (eg. using plain SQL), the content of totalItemAmount could be wrong.
Using a SQL view: I could define a view as described in Hibernate Derived Properties - Performance and Portability. But this would introduce a considerable amount of work and future maintenance - imho too much for the gain.
Is there another way to solve this problem?
Off-Topic: Feel free to comment on my writing, as I really would like to improve it.
I'm writing a Notes Client application. Web compatibility is a secondary concern. The language is LotusScript.
The specification: a form to enter lines from receipts. The lines are all saved as part of the same document so that they can be signed as an atomic unit.
When a line is added, it is to be formatted into a table for presentation. Ultimately, this architecture is like an input/datastore/presentation split.
I've managed to get the data stored and signed, and I think I've managed to get it deserializing properly (the LotusScript debugger makes it difficult to see, but it looks right). The problem now is the UI.
Looking at the Programmable Table, it is always a tabbed table with only one row shown per tab. I need a programmable table which can dynamically have rows added to it for display, without forcing new tabs to be created.
This suggests that I would need to use a Rich Text field to contain a table, but thus far my attempts to get anything to display when I try to update a Rich Text field in edit mode have failed. I am forced to conclude that it is impossible.
I cannot figure out how I'm supposed to do a dynamically-displayed list of tabular data like this. Any advice?
Most people just create a table with one row and N columns, with a multi-valued field in each column, and use code to append values to each of the fields in parallel. You don't get borders between rows this way or the ability to do variable formatting of cells, and you have to be careful to avoid letting data length exceed column widths in order to keep everything aligned properly.
If you truly want a dynamic table for presentation with all the bells and whistles that you can get in terms of cell formatting, then the Midas Rich Text API from Genii Software is a commercial solution that can do the job.
I blogged about this a couple of years ago: http://blog.texasswede.com/dynamic-tables-in-classic-notes/
This is a non-XPages solution, but of course you can also use XPages to achieve the same/similar result. It does not use tabs, as each row is a separate table.
Alternatively, you can build your Rich Text Table in another NotesDocument, which you then save. Then use NotesUIDocument.ImportItem (which is undocumented, but present in the R8.5 mail template) to update your NotesUIDocument.
Don't forget to delete the other NotesDocument when you're done.
Another option is to build the table in HTML in computed text, and re-open the document every time you modify it. I have inherited a system that does that, and I hate it...so be warned :)
Use Case:
End-User searches for something and an ArrayCollection is returned with Result objects. This is displayed in a data grid.
End-User selects a few of the search results and "moves" it over to another datagrid for use later.
End-User does another search.
PROBLEM:
Some of the search results might contain something the user already previously selected and moved over to the second datagrid. I want to remove these from the second search result.
How can I do this quickly, and efficiently in Flex code?
disableAutoUpdate() on both array collection
loop through the first one and for each item of the second remove it if it's present in the first one (or adapt the algorithm based on what you really want - unsure)
enableAutoUpdate() at the end.
Looping through array collection can be quick if no events are dispatched.
Second option, you could also loop through a cheap copy made up of an array, which is arraycollection.source.concat(), or even a vector if all your items are of the same type. That will give the maximum speed, but you might lose in the long run as you need to convert back to an array collection at the end.
So I would stick to the first option.
For the time being, I've implemented a hash collection (extends ArrayCollection). Hash only allows unique values, so in the end, it serves my purpose even though the UI might be confusing to the user. Will probably implement the above method at a later date. :)
Suppose I have a list of a couple of thousand organizations and a user needs to be able to select one of them. The list is too large to populate in a dropdown at page load, and the user often knows what they want but it's not the first part of the organization name. That is, they know "Collections" but not that the precise name of the organization is "Department of Collections". So the user will need/want to type in some information.
It's easy enough to use an autocompleting textbox of some kind, but I don't want to allow the user to type in random text - they have to choose one of the organizations explicitly.
What's the best solution?
IMO I will simplify the UI to:
a textbox to enter the string
a drop down to set the filter options like: "contains | starts with | ends with"
a button "Find"
Then, I will populate a view based on the search string & let the user choose the valid item or refine the search
IMO with something like an auto-complete, you will end up writing a lot of parsing code to get to the string & then there might be server-side load considerations...
HTH.
In additional check if 'facetted navigation' is something you need. Ref.: http://www.alistapart.com/articles/design-patterns-faceted-navigation/
So it seems to me your main challenges are to
Express that the user needs to select an organization from the list (and only from the list).
Express that there are a lot of organizations on the list.
Provide some means for the user to quickly find the organization on the list.
I would say present a selector control that fits in with the rest of your design with a search box just above it. You should then page the list as there will be lots of pages with that many elements indicating that the user should definitely use the search. The search essentially acts like the auto complete, but instead of the found options changing the text, it will change the contents of the paginated list. If you do this on a character by character basis (or throttle using Reactive Extensions), it's very clear that you're just filtering the list to make selection easier.
You could use a CustomValidator to ensure that the TextBoxes content in contained in your collection.
You could use the Ajax AutoComplete Control: http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/AutoComplete/AutoComplete.aspx. You can opt to only do a lookup if the user has typed in a certain number of characters.
You'd create a static Web Method to query the collection (you could use LINQ) and return matching organizations.
You'd obviously need to validate the textbox input afterwards.
Is it possible to structure your list a bit more like a tree, so that it is not a single list. E.g. Could you have a grouping like "Government Depts" and then add Dept of Collections to that. Then ask you users to first select the top level grouping then show them a shorter lists of organizations in that group?
It sounds to me as if your data list should really be in either a database or at least stored well away from the UI.
Wherever its really stored, place a keyword for each entry, say "Collection". The list of keywords could be available as part of your auto-complete functionality. Then search on the keyword alone.
If you could divide items in categories, would using some kind of tree control help?
So, when user clicks on a node you load only items in that node. And so on.
I'd break it into two paths...
Use an autocompleting textbox, for the person who types the correct title (i.e., Department of Collections); and a separate search button to search for possible matches. The search button would take you to a results page to select the desired choice. This functionality would be similar to the way search on MSDN works.
Initially a tree view sounds cool, but are you certain that a single classification will reduce the data into manageable sets? If 80% of your data gets classified as "government dept" this doesn't really help things.
The problem is you want criteria that allows users to quickly split a large list into smaller sets that are easier to consume. Additionally, there should be enough flexibility to react to changes in data.
I'd suggest using a tagging pattern like iTunes. In my library "rock" describes 80% of my collection - but is still a useful categorization for something like random shuffle. I also have the ability to stack tags so I can use genre="rock", decade="1990" and quickly sift my data down to whatever is of interest.
In the UI, I'd recommend a section that allows the user to apply "filters" which is nothing more than selecting specific values for tags. Break the list out into pages and allow them to see a tally of potential matches.
Scenerio:
- Navigate to screeen XYZ and see there are 10,000 companies to pick from
- Click "classification" and select "Government dept" and the list updates to indicate there are now 1,000.
- Click "region" and select "South" and see my list drop to 200.
- Sort list by name and then select (or scroll through, whatever)
I'm working on an ASP.NET project that replaces many existing paper forms. One of the requirements is that the user can save the form in any state, i.e. they could create a new blank form and immediately save it with no data or with partial data. I'm validating for data type on every save but validation for required fields does not occur until the user marks the form as completed.
I'm not sure what the best approach is to handle this requirement in the database and domain model. As I see it, I have two options:
Allow nulls for any field that may not have data. This feels like the "correct" approach but it requires that almost every database field allow nulls and I have to code around a lot of nullable types. Also, when the form is finalized none of the required fields are enforced in the database.
Populate my business objects with meaningful default values. In some cases, there are meaningful default values for many (but not all) fields that I could use. This approach verges on "magic numbers" which makes me uncomfortable.
Which approach is best? Or is there a third way? I'm not willing to go to extremes, such as splitting the tables.
Edited to add: I wanted to expand on this a bit since I accepted a response. The primary reason that I'm not interested in splitting the tables is that once a project is submitted, the data on the forms is used to generate data for another system that is the system of record. At that point the original form data is unlikely to be revised or used for reporting.
I don't understand why you don't want to split the tables. I don't know what domain you're in but in any I could imagine there are two classes of people:
people who have submitted the form
people who haven't
And as a business executive I don't care about the second. But the first I care deeply about, and they need to have all their data in correctly.
It also improves efficiency - most of your queries about aggregate data will be over the first table, not the second. The second table will only be used for index seeks.
If splitting the table(s) (are there more than one?) is not an option, I would consider creating single table to store serialisations of objects of incomplete forms, and only commit a form to the "real" tables when the form is fully submitted by the user.
If there isn't a sensible default, and you don't want to split the data, then nulls are almost certainly your best option. Re the db not being to verify that they are not null when completed... well, if you don't want to split the table there isn't much you can do (short of using a CHECK constraint, or an INSTEAD OF trigger to run validation). But the DB isn't the only place responsible for data validation. Your app logic can do that too.
You could use a temporary table with "allow nulls" on every column to store the form containing partial or no data and copy / move the data to the final table when the user marks the form as completed. This way, you do not depend on default values (which the user may forget to change), you can save in any state, and you still have the validation in the end.
This is a situation that cries out for split tables. I know you said you don't want to do that, and in a comment even said "this project doesn't warrant that level of effort". but it's really the best solution.
Set up preliminary table(s) with everything except your key nullable. When the user marks the form complete, and it passes validation, move it to the final table(s). not only is this The Right Thing To Do, but it's probably less effort than "coding around nullable values" when working with finished forms.
If you need to see all forms, finished or not, make a Union view.
I'd take the first option but add a column to the database tables so that when the form is completed this is flagged. Then for anything using the form data it merely needs to check that the form has been completed.
That's my suggestion for a way around this.
NULL values are not searchable by the indexes.
If you'll need to issue a query like "select first 10 forms with a certain field unfilled", this query will use a FULL TABLE SCAN which may be not efficient.
Oracle does not distinguish between NULL and empty string, but other databases do. You'll probably want to make an empty string to be the DEFAULT for unfilled fields and use it in a search.
If you don't need to search on unfilled fields, then just make them NULL.
NULL generally means "Don't Know" (in a database) whereas an empty string could actually represent an empty string.
I would tend to use NULL as the "Don't Know" value in your case. When you print out data you'll just have to assume that any NULL value means an empty string.
CHECK CONSTRAINT + VIEW
if you don't have a status field add one so you can tell that it is finished.
add a check constraint on that status field so it can't be marked finished if any of the columns are null.
When you write your queries on "finished" forms you can ignore checking for nulls everywhere if you do one of these two options:
just add Status="F"inished in the where clause
make a view of only finished ones
when using the "finished view" you don't have to do all the validation checks or worry about unfinished ones showing up in the results
I've had a similar situation, and while I haven't yet come up with a solution, I have been toying with the idea of just using simple XML serialization to store the temporary document data. If you generate simple classes that model the data in the objects (using nullable types where needed, perhaps), it would be easy to stuff data from the screen into those objects, serialize them to XML and then store them in a temporary "staging" table. When your users are done working and want to submit or finalize the document, then you perform all of your needed validation against the serialized data, eventually putting into the "real" table with the proper data structures and constraints.