Two dimensiona forms

How would you structure a two dimension form? I have projects along the horizontal axis and users along the vertical axis and then check boxes at the intersections. I have it structured in html, but I can't figure out how name the fields so that when I post it I will be able to iterate through it in rails so that I'll be able to make sense of it.

What does this form do?

Basically There are users and projects. Each user can have access to any number of projects. Then the final colomn is for a company admin. The admin will have access to all projects. Here's what I want the hash to look like:

{"users"=>{"id"=>["1"=>{"project_id"=>["2","4"],"admin"=>"true"},"2"=>{"project_id"=>["4"],"admin"=>"false"},"3"=>{"project_id"=>["1","3","5"],"admin"=>"false"}]}

How about a select box with :multiple => true?

<%= select “users”, “projects”, @projects.map { |p| [p.name,p.id] }, { :multiple => true } %>

Ah, nevermind. You’re trying to edit all users at the same time. That’s something more complicated, sorry. You may be able to iterate through the users and do users[<%= user.id %>]

I can get that, but when I try and do users[<%= user.id%>][project_ids] I get an error when I submit the form. Saying:

  Status: 500 Internal Server Error   Conflicting types for parameter containers. Expected an instance of Hash but found an instance of String. This can be caused by colliding Array and Hash parameters like qs=value&qs[key]=value.

wbsmith83@gmail.com said the following on 13/01/08 07:51 PM:

How would you structure a two dimension form? I have projects along the horizontal axis and users along the vertical axis and then check boxes at the intersections. I have it structured in html, but I can't figure out how name the fields so that when I post it I will be able to iterate through it in rails so that I'll be able to make sense of it.

By a curious coincidence I was reading the O'Reilly "Rails Cookbook" yesterday and they had an example of this. ISBN: 0-596-52731-4

"5.10 Processing Dynamically Created Input Fields." The example used Users and Roles and a matrix of dynamically generated check-boxes.

There is a nested loop to generate the check-boxes in the view and a another nested loop in the controller to take apart the hash of the user.id-projects.id pairs that are handed back in the params entry.

What like about this, what I prefer over pull-down select lists, is that it makes the 'linkages' very visible.

What bothers me about it though is that it only makes for a limited number of columns. Too many and they don't fit on the screen. However for many applications I imagine that wouldn't an issue.

An extension to this ....

What I wonder about is how to do 'tri-state' check boxes. As in something like Apache's "Allow/Deny" hierarchy. A user might have explicitly stated Allow/Deny permission at one level, or not, in which the next level up, the owner, would apply.

For example, /etc/httpd/httpd.conf contains <Directory "/var/www/html">     .....     AllowOverride All     Order allow,deny     Allow from all </Directory>

but a .htaccess at /var/www/html/applications/blogerator/data could contain and

   Order deny,allow    Deny from spamlist    Allow from starbucks-wifi

I emphasise the "COULD". If the local override isn't there it defaults to the higher level. RTFM for more details http://httpd.apache.org/docs/2.0/mod/core.html#allowoverride //end of example

So the tri-state wouldn't be simple yes-no check-boxes, it would be "explicit-yes" (tick mark), "explicit-no" (cross mark) and "unmarked".

Any ideas?

wbsmith83@gmail.com said the following on 13/01/08 08:59 PM:

I can get that, but when I try and do users[<%= user.id%>][project_ids] I get an error when I submit the form. Saying:

  Status: 500 Internal Server Error   Conflicting types for parameter containers. Expected an instance of Hash but found an instance of String. This can be caused by colliding Array and Hash parameters like qs=value&qs[key]=value.

Ah, nevermind. You're trying to edit all users at the same time. That's something more complicated, sorry. You may be able to iterate through the users and do users[<%= user.id %>]

See my other post about "Rails Cookbook" Code fragments at http://www.oreilly.com/catalog/9780596527310/toc.html and O'Reilly Media - Technology and Business Training

Thanks. Too bad the oreilly stuff is limited unless I pay. Could you paste the view code?

Hey Anton,

I think that's more a matter of the widget you're using (checkbox) than Rails. Checkboxes only have 2 states. If you used a select box with 3 options ("explicit-yes", "explicit-no" and "unmarked") instead of the checkbox, that would work. Sure, it wouldn't look very good, but still...

Cheers, Sazima

Sazima said the following on 14/01/08 08:18 AM:

Hey Anton,

I think that's more a matter of the widget you're using (checkbox) than Rails. Checkboxes only have 2 states. If you used a select box with 3 options ("explicit-yes", "explicit-no" and "unmarked") instead of the checkbox, that would work. Sure, it wouldn't look very good, but still...

*sigh*

Yes, and the 'it wouldn't look good' means it won't be acceptable. This is still 'rows and columns' application like the one mbsmth asked about. It's essentially a dashboard - it must be very clear at a glance what state for each cross-point

The sketch I have looks something like this (I've altered it to suit this thread) Read "[-]" as 'explicit-no' and "[+]" as 'explicit-yes' The sketch is colour-enhanced, which I can't show here.

           canRead canWrite canExec canChmod defaults [+] [-] [-] [-]

By inserting select elements with three options and converting them to tri-state checkboxes in an unobtrusive JavaScript script triggered by dom:loaded (custom Prototype event).

I'm pretty sure that there are scripts for tri-state check boxes, although I've never used one. When you've found such a script that suits your needs it's almost trivial to apply it.

Michael

Michael Schuerig said the following on 14/01/08 10:22 AM:

Michael Schuerig said the following on 14/01/08 10:22 AM: >> What I wonder about is how to do 'tri-state' check boxes. > > By inserting select elements with three options and converting them > to tri-state checkboxes in an unobtrusive JavaScript script > triggered by dom:loaded (custom Prototype event). > > I'm pretty sure that there are scripts for tri-state check boxes, > although I've never used one. When you've found such a script that > suits your needs it's almost trivial to apply it.

"... which is left as an exercise for the reader..."

Are there some tutorials about handing back javascript values to Rails?

There is no problem. Store the values, yes/no/don't know, in a hidden field with the same name as the original select element and all is fine. Assuming that you want the changes to take effect only when a submit button is clicked. If you want them to be effective immediately, you need ajax.

If you intend to have a go at this stuff yourself, I suggest you read a good JavaScript book before starting. My suggestions (choose what suits you)

As a tutorial that touches on (almost) advanced stuff

John Resig Pro JavaScript Techniques Apress 2006

For reference

David Flanagan JavaScript. The Definitive Guide. 5th Edition O'Reilly 2006

For Prototype.js

Christophe Portneuve Prototype and script.aculo.us Pragmatic Programmers 2007

Well, googling I found this http://www.thinkvitamin.com/features/design/web-app-without-makeup-th e-design-iterations-of-teamsnap which is _almost_ the discussion we had with the end users!

Looks like a good starting point for the visual aspect. For the mechanism in the background there doesn't appear to be a readymade solution. With some JavaScript knowledge you will be able to do it yourself, or you may want to find someone with the requisite skills.

Michael