What's the best way to DRY between edit and show?

Maybe I’m misguided, but I’d like to be able to share formatting and
layout between the editing and viewing of an object - for instance,
re-use a single _form.rhtml whether an item is being viewed or edited.
The alternative strikes me as redundant.

What I’m doing now, but don’t like, is adding a “disabled” attribute to
editable fields if the action is “show”.

Does anyone have a better strategy, or advice to the effect of: “don’t
do that”?

thanks in advance…

Most applications I don’t even do show.
Recipe 33 in the rails recipes book shows you how to combine
edit/create/new and update into one action. Unless you need it you can
also dispense with ‘show’

Ross

On 9/30/06, joeb [email protected] wrote:

do that"?

thanks in advance…


Ross R.
www.sorrylies.com

joeb,

Ross R.'s suggestion is good if you hare having issues with your
controller’s, but I believe your are talking about your VIEW. I had
this same problem as well. I have a MASSIVE form, some several hundred
lines and I found myself updating my edit form but forgetting to make
coresponding changes in my show. So I came up with a hack.

First, I create a partial and try to follow this convention:

_form.rthml

Field Label <%= text_field :object, :method %> <%= @object.method %>
######

This is a very simple approach which lets you put your input and output
right next to each other - very easy to manage because everything is in
one place.

Then in my views that use the partial, I use javascript to hide the
part of the form which I don’t want to use. Example:

new.rhtml or edit.rhtml

<% @page_heading = “Page Name” %>
<% @body_onload = “hideOutput();” %>

<%= start_form_tag …%>
<%= render :partial => “form” %>
<%= end form_tag %>

The @page_heading and @body_onload are references in my layout that
allow me to uniformly display the page’s title and a heading as well as
add javascript to body’s onload tag.

The javascript to do this is fairly tricky and another hack which I dug
up on the web. You can have javascript read the class tag’s to see if
it maches what you’re looking for. I found these functions and tweaked
them for my own needs. Unfortunately, I can’t remember exactly how
they work. I know it has something to do with the order of your CSS
rules. (Maybe someone else could suggest some improvements for this
section.)

appliaction.js
########
function getRules() {
var theRules = new Array();
if (document.styleSheets[0].cssRules) {
theRules = document.styleSheets[0].cssRules;
} else if (document.styleSheets[0].rules) {
theRules = document.styleSheets[0].rules;
}
return theRules;
}

function hideInput(){
var css = getRules();

css[0].style.display = ‘none’; //hide input class, (i.e. the
css[0] would be first line of css rule)
css[2].style.fontSize = ‘medium’; //make label size smaller
css[3].style.fontSize = ‘medium’; //make required label smaller size
css[4].style.backgroundColor = ‘white’; //make modifiable label
background white
css[4].style.fontSize = ‘medium’; //make modifiable label smaller
size
css[3].style.backgroundColor = ‘white’; //make modifiable label
background white
}

function hideOutput(){
var css = getRules();

css[1].style.display = ‘none’; //hide output class, (the second line
of css)
}
###########

So to wrap this up, this approach gives a couple of great pros:
(1) One place for both input and output in your forms, so you can’t get
input and output “out-of-sync” with each other.
(2) You’re using CSS so you get a lot of controller over what your form
looks like.
(3) You can use Javascript to hack up the views even further if need
be. (For example, when printing, you can just remove all the output
fields so it prints nicely.)

This approach is not without it’s cons as well:
(1) It’s kind of a hack and who knows if it will work for everyone.
(This is my first time sharing it and I’d love some feedback.)
(2) I’ve not tested its cross-browser compatibility. I’m lucky I only
have to worry about IE.
(3) Using the line numbers of your CSS is very brittle and could break
by simply adding an new line of CSS to the top.
(4) Your form can get VERY large. My form is now a 946 lines, but is
also the core of my application. I’m sure it will get refactored time
and again into smaller bits, but it certainly can inflate the size of
your partials.

I hope this helps and I’d appricate any suggestions.

Brian

I think I understand what you’re saying, but maybe you can flesh the
idea out a bit more - I’d like to hear what you have in mind.

thanks corporate_hippy for such a thorough response, and it’s great to
know that others (well at least one) are dealing with the same issue.

I’m not going to be looking at this in detail until Tuesday, but one
thought occurs to me off the top of my head. I’m no expert, but unless
I’m missing something I’d think it would be possible to toggle the
hiding and displaying with CSS only, without having to resort to
javascript. Much in the way you can use the media attribute to toggle
style sheets for printing and the screen, perhaps your views can select
the approprate style sheet based on action. Make sense?

On 10/1/06, joeb [email protected] wrote:

Does anyone have a better strategy, or advice to the effect of: “don’t
do that”?

thanks in advance…

I posted a very similar question a couple of days ago without any
response.

Basically what I’ve been thinking is to use in place editors in my show
action that are active if someone is allowed to edit. That way no edit
view
is needed at all, and users only need to identify with one data layout
for
each type of information, in terms of editing and viewing.

I don’t know if it’s a good idea, that was basically my question to
everyone
or is it a don’t do this kind of thing?

Daniel,

This is an interesting approach, but how does it work when you are
creating a new entry into the system? For me, I’d find it a pain in
the ass to have to click “edit” for every field in a new entry to the
system. You know what I mean? I think it’s a good strategy though.

Another part of this question that I think needs attention is, how to
make forms dynamic. For example, if user chooses A, then B appears.
If user chooses C then D appears. I’ve ended up using Javascript to
show and hide elements based on the selection. I think an observe_form
in conjunction with AJAX is the way to go on this, but I haven’t worked
it out yet. Any experience in this area???

On 10/2/06, corporate_hippy [email protected] wrote:

Daniel,

This is an interesting approach, but how does it work when you are
creating a new entry into the system? For me, I’d find it a pain in
the ass to have to click “edit” for every field in a new entry to the
system. You know what I mean? I think it’s a good strategy though.

This was the part that I got stuck on as well. I have been thinking of
wrapping the in_place_editor up into a helper, that puts in some blank
text
if there is no data yet, and some logic to swap between editing and
showing
only.

Another part of this question that I think needs attention is, how to

make forms dynamic. For example, if user chooses A, then B appears.
If user chooses C then D appears. I’ve ended up using Javascript to
show and hide elements based on the selection. I think an observe_form
in conjunction with AJAX is the way to go on this, but I haven’t worked
it out yet. Any experience in this area???

I have done some of this before with radio buttons and check boxes etc
very
basic tho. I also used javascript to hide / show elements. From what
I’ve
read on the list over a while, some people also use this method for
wizard
type behaviour.

On 10/2/06, Daniel N [email protected] wrote:

the ass to have to click “edit” for every field in a new entry to the
system. You know what I mean? I think it’s a good strategy though.

This was the part that I got stuck on as well. I have been thinking of
wrapping the in_place_editor up into a helper, that puts in some blanktext if there is no data yet, and some logic to swap between editing and
showing only.

One other point that I raised in another thread, was regarding
validations.
The in_place_editor uses update_attriburte. This method does not use
validations!! I cannot understand why validations aren’t used with
update_attribute but IMHO it renders the use of in_place_edit_field
useless. The update_attribute method initially does validations but
it’s
overwritten in the validations module so that validations aren’t
applied.

I don’t understand why this is. I’m hopeing that there is a good reason
for
it.

This is something that would be convenient for my information-heavy site
as well. I had planned to make new/edit and show separate but now this
thread makes me want to combine them too in the interest of DRY.

Of course there is one simple solution: display all the data in ‘show’
within a form. Just control the display of the submit button and protect
the appropriate methods. For most cases I’m sure this makes the ‘show’
view too ugly or limiting though…

I think there really needs a framework for this kind of wizard-based
form building. It’s such a critical part of creating
information-intensive apps. The problem that I find with taking
Microsoft’s wizard approach is that many times, users want to be able
to edit many parts different “sections” of the data and a wizard can
end up slowing them down. This is why I think the show/hide approach
is much better. The problem is that if you need complex show/hide
rules, Javascript quickly becomes a nightmare. This is a top priority
for me in terms of improving my codebase.

Any ideas how to move this out of Javascript? I think observe_form +
RJS may be the key.

I think you answered your own question with this Carl…using the same
forms that you have for input is probably not what most users expect.
They might be confused when they see they can edit the fields in the
page, but there is no save button. Although, perhaps there is a way
around this as well using Javascript, but like I said above, I think
it’s best to get away from that idea.

On 10/2/06, corporate_hippy [email protected] wrote:

for me in terms of improving my codebase.

Any ideas how to move this out of Javascript? I think observe_form +
RJS may be the key.

I’ve also thought a bit about this but I havn’t come up with anything
concrete yet.

I’ve used check boxes with observe_field to hide and show and this
worked
ok.

I’ve also used links that fire javascript to show a fieldset. So there
is
like a heading that you can click to show the relevant part of the form.
Like personal information in a user form. Although required data I
don’t
really hide.

I guess the way I’m thinking at the moment is that anything that is not
a
required field, I put in a fieldset (or many) and show it with a link
that
fires javascript. Anything that is conditionally required I use an
observe_field to check when the right conditions are reached to show it.
I’m still not completely sold on this idea though. All that hiding and
showing could get tedious for the user.

I’ve used RJS up to this point for conditional logic, but I’m beginning
to
think that a pure client side js option would be the way to go. It
would be
way more responsive, and unless there is really a need to go to the
server,
it just seems like a waste. You can make use of the rails helpers to
generate the js for you.

I’d still like to find a way to use in_place editors though…

I hope this may give you some ideas…

corporate_hippy wrote:

I think I understand what you’re saying, but maybe you can flesh the
idea out a bit more - I’d like to hear what you have in mind.

Still a bunch more thinking to do, but here’s a simple test I just
tried and it worked.

Taking your form as a starting point:

_form.rthml

Field Label <%= text_field :object, :method %> <%= @object.method %>
######

in a style sheet do something like:

output_styles.css

td.field_input {display:none}

when you’re doing output, then

input_styles.css

td.field_output {display:none}

when doing input.

This effectively hides the unwanted cell based on styles, and without
javascript.

All you need to do is vary the stylesheet used based on the controller
action.

My problem with using client side javascript for mangaging show/hide
logic is that I have complex rules to determine what to show/hide. I
feel like RJS would allow me to code this much more elgantly in Ruby
avoiding nasty, ugly Javascript. But you are right, the performance
might become a problem.

I’ve managed to do it with Javascript this far…maybe I just need to
learn how to write Javascript better so I can turn it into a library
that others can use. Ideally, I’d like to use Helpers to write the
Javascript, similar in the way to how link_to_remote or observe_field
works. Would you like to collaborate on that with me perhaps? It’d my
first attempt at a collabrative effort, but I’d be willing to give it a
try…

That really makes a lot more sense! Good thinking. What I’m going to
try to do next is encapsulate that functionality using helpers. So for
example…

app/views/user/_form.rhtml
###########
<%= dry_form do |form| %>
<%= dry_field do |field| %>

<% field.id = "user_first_name" %>

<% field.title = "First Name" %>

<% field.input = <<-INPUT_CODE          #all input in INPUT_CODE

stored as string
text_field “user”, “first_name”
INPUT_CODE %>

<% field.output = <<-OUTPUT_CODE        #all input in INPUT_CODE

stored as string
user.first_name
OUTPUT_CODE %>

<% end %>
<% end %>
###########

Creates the equivalent of something like this…
############

....
First Name <%= text_field "user", "first_name" %> <%= user.first_name %>
.... ############

What do you think?

Not sure I get where you’re trying to go with this, corporate_hippy.