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