add internal user disable-ing
[freeside.git] / httemplate / edit / elements / edit.html
1 <%
2
3   # options example...
4   #
5   # 'name'  =>
6   # 'table' =>
7   # #? 'primary_key' => #required when the dbdef doesn't know...???
8   # 'labels' => {
9   #               'column' => 'Label',
10   #             }
11   #
12   # listref - each item is a literal column name (or method) or hashref
13   #                                                          or (notyet) coderef
14   # if not specified all columns (except for the primary key) will be editable
15   # 'fields' => [
16   #               'columname',
17   #               { 'field' => 'another_columname',
18   #                 'type'  => 'text', #text, fixed, hidden, checkbox
19   #                                    #eventually more for <SELECT>, etc.
20   #                 'value' => 'Y', #only for checkbox
21   #               },
22   #             ]
23   #
24   # 'menubar'     => '', #menubar arrayref
25   #
26   # #run when re-displaying with an error
27   # 'error_callback' => sub { my( $cgi, $object ) = @_; },
28   #
29   # #run when editing
30   # 'edit_callback' => sub { my( $cgi, $object ) = @_; },
31   #
32   # # returns a hashref for the new object
33   # 'new_hashref_callback'
34   #
35   # #run when adding
36   # 'new_callback' => sub { my( $cgi, $object ) = @_; },
37   #
38   # #XXX describe
39   # 'field_callback' => sub { },
40   #
41   # #string or coderef of additional HTML to add before </TABLE>
42   # 'html_table_bottom' => '',
43   #
44   # 'viewall_dir' => '', #'search' or 'browse', defaults to 'search'
45   #
46   # 'html_bottom' => '', #string
47   # 'html_bottom' => sub {
48   #                        my $object = shift;
49   #                        # ...
50   #                        "html_string";
51   #                      },
52
53   my(%opt) = @_;
54
55   #false laziness w/process.html
56   my $table = $opt{'table'};
57   my $class = "FS::$table";
58   my $pkey = dbdef->table($table)->primary_key; #? $opt{'primary_key'} || 
59   my $fields = $opt{'fields'}
60                #|| [ grep { $_ ne $pkey } dbdef->table($table)->columns ];
61                || [ grep { $_ ne $pkey } fields($table) ];
62   #my @actualfields = map { ref($_) ? $_->{'field'} : $_ } @$fields;
63
64   my $object;
65   if ( $cgi->param('error') ) {
66
67     $object = $class->new( {
68       map { $_ => scalar($cgi->param($_)) } fields($table)
69     });
70
71     &{$opt{'error_callback'}}($cgi, $object)
72       if $opt{'error_callback'};
73
74   } elsif ( $cgi->keywords ) { #editing
75
76     my( $query ) = $cgi->keywords;
77     $query =~ /^(\d+)$/;
78     $object = qsearchs( $table, { $pkey => $1 } );
79     warn "$table $pkey => $1"
80       if $opt{'debug'};
81
82     &{$opt{'edit_callback'}}($cgi, $object)
83       if $opt{'edit_callback'};
84
85   } else { #adding
86
87     my $hashref = $opt{'new_hashref_callback'}
88                     ? &{$opt{'new_hashref_callback'}}
89                     : {};
90
91     $object = $class->new( $hashref );
92
93     &{$opt{'new_callback'}}($cgi, $object)
94       if $opt{'new_callback'};
95
96   }
97
98   my $action = $object->$pkey() ? 'Edit' : 'Add';
99
100   my $title = "$action $opt{'name'}";
101
102   my @menubar = ();
103   if ( $opt{'menubar'} ) {
104     @menubar = @{ $opt{'menubar'} };
105   } else {
106     @menubar = (
107       'Main menu' => $p, #eventually get rid of this when the ACL/UI update is done
108       #eventually use Lingua::bs to pluralize
109       "View all $opt{'name'}s" => $p. ( $opt{'viewall_dir'} || 'search' ).
110                                   "/$table.html",
111     );
112   }
113
114 %><%= include("/elements/header.html", $title,
115               include( '/elements/menubar.html', @menubar )
116            )
117 %>
118
119 <% if ( $cgi->param('error') ) { %>
120   <FONT SIZE="+1" COLOR="#ff0000">Error: <%= $cgi->param('error') %></FONT>
121   <BR><BR>
122 <% } %>
123
124 <FORM ACTION="<%= popurl(1) %>process/<%= $table %>.html" METHOD=POST>
125 <INPUT TYPE="hidden" NAME="<%= $pkey %>" VALUE="<%= $object->$pkey() %>">
126 <%= ( $opt{labels} && exists $opt{labels}->{$pkey} )
127       ? $opt{labels}->{$pkey}
128       : $pkey
129 %>
130 #<%= $object->$pkey() || "(NEW)" %>
131
132 <%= ntable("#cccccc",2) %>
133
134 <% foreach my $f ( map { ref($_) ? $_ : {'field'=>$_} }
135                        @$fields
136                  ) {
137
138     &{ $opt{'field_callback'} }( $f )
139       if $opt{'field_callback'};
140
141     my $field = $f->{'field'};
142     my $type = $f->{'type'} ||= 'text';
143
144 %>
145
146   <TR>
147
148     <TD ALIGN="right">
149       <%= ( $opt{labels} && exists $opt{labels}->{$field} )
150               ? $opt{labels}->{$field}
151               : $field
152       %>
153     </TD>
154
155     <% if ( $type eq 'fixed' ) { %>
156
157       <TD BGCOLOR="#dddddd"><%= $f->{'value'} %></TD>
158       <INPUT TYPE="hidden" NAME="<%= $field %>" VALUE="<%= $f->{'value'} %>">
159
160     <% } elsif ( $type eq 'checkbox' ) { %>
161
162       <TD>
163         <INPUT TYPE="checkbox" NAME="<%= $field %>" VALUE="<%= $f->{'value'} %>" <%= $object->$field() eq $f->{'value'} ? ' CHECKED' : '' %>>
164       </TD>
165
166     <% } else { %>
167
168       <TD>
169         <INPUT TYPE="<%= $type %>" NAME="<%= $field %>" VALUE="<%= $object->$field() %>">
170       <TD>
171
172     <% } %>
173
174   </TR>
175
176 <% } %>
177
178 <%= ref( $opt{'html_table_bottom'} )
179       ? &{ $opt{'html_table_bottom'} }( $object )
180       : $opt{'html_table_bottom'}
181 %>
182
183 </TABLE>
184
185 <%= ref( $opt{'html_bottom'} )
186       ? &{ $opt{'html_bottom'} }( $object )
187       : $opt{'html_bottom'}
188 %>
189
190 <BR>
191
192 <INPUT TYPE="submit" VALUE="<%= $object->$pkey() ? "Apply changes" : "Add $opt{'name'}" %>">
193
194 </FORM>
195
196 <%= include("/elements/footer.html") %>
197