A bit of cleanup in JavaScript, removed repeated var declarations.
[timetracker.git] / WEB-INF / templates / time.tpl
1 <script>
2 // We need a few arrays to populate project and task dropdowns.
3 // When client selection changes, the project dropdown must be re-populated with only relevant projects.
4 // When project selection changes, the task dropdown must be repopulated similarly.
5 // Format:
6 // project_ids[143] = "325,370,390,400";  // Comma-separated list of project ids for client.
7 // project_names[325] = "Time Tracker";   // Project name.
8 // task_ids[325] = "100,101,302,303,304"; // Comma-separated list ot task ids for project.
9 // task_names[100] = "Coding";            // Task name.
10
11 // Prepare an array of project ids for clients.
12 project_ids = new Array();
13 {foreach $client_list as $client}
14   project_ids[{$client.id}] = "{$client.projects}";
15 {/foreach}
16 // Prepare an array of project names.
17 project_names = new Array();
18 {foreach $project_list as $project}
19   project_names[{$project.id}] = "{$project.name|escape:'javascript'}";
20 {/foreach}
21 // We'll use this array to populate project dropdown when client is not selected.
22 var idx = 0;
23 projects = new Array();
24 {foreach $project_list as $project}
25   projects[idx] = new Array("{$project.id}", "{$project.name|escape:'javascript'}");
26   idx++;
27 {/foreach}
28
29 // Prepare an array of task ids for projects.
30 task_ids = new Array();
31 {foreach $project_list as $project}
32   task_ids[{$project.id}] = "{$project.tasks}";
33 {/foreach}
34 // Prepare an array of task names.
35 task_names = new Array();
36 {foreach $task_list as $task}
37   task_names[{$task.id}] = "{$task.name|escape:'javascript'}";
38 {/foreach}
39
40 // Mandatory top options for project and task dropdowns.
41 empty_label_project = '{$i18n.dropdown.select|escape:'javascript'}';
42 empty_label_task = '{$i18n.dropdown.select|escape:'javascript'}';
43
44 // The fillDropdowns function populates the "project" and "task" dropdown controls
45 // with relevant values.
46 function fillDropdowns() {
47   if(document.body.contains(document.timeRecordForm.client))
48     fillProjectDropdown(document.timeRecordForm.client.value);
49
50   fillTaskDropdown(document.timeRecordForm.project.value);
51 }
52
53 // The fillProjectDropdown function populates the project combo box with
54 // projects associated with a selected client (client id is passed here as id).
55 function fillProjectDropdown(id) {
56   var str_ids = project_ids[id];
57   var dropdown = document.getElementById("project");
58   // Determine previously selected item.
59   var selected_item = dropdown.options[dropdown.selectedIndex].value;
60
61   // Remove existing content.
62   dropdown.length = 0;
63   var project_reset = true;
64   // Add mandatory top option.
65   dropdown.options[0] = new Option(empty_label_project, '', true);
66
67   // Populate project dropdown.
68   if (!id) {
69     // If we are here, client is not selected.
70     var len = projects.length;
71     for (var i = 0; i < len; i++) {
72       dropdown.options[i+1] = new Option(projects[i][1], projects[i][0]);
73       if (dropdown.options[i+1].value == selected_item)  {
74         dropdown.options[i+1].selected = true;
75         project_reset = false;
76       }
77     }
78   } else if (str_ids) {
79     var ids = new Array();
80     ids = str_ids.split(",");
81     var len = ids.length;
82
83     for (var i = 0; i < len; i++) {
84       var p_id = ids[i];
85       dropdown.options[i+1] = new Option(project_names[p_id], p_id);
86       if (dropdown.options[i+1].value == selected_item)  {
87         dropdown.options[i+1].selected = true;
88         project_reset = false;
89       }
90     }
91   }
92
93   // If project selection was reset - clear the tasks dropdown.
94   if (project_reset) {
95     dropdown = document.getElementById("task");
96     dropdown.length = 0;
97     dropdown.options[0] = new Option(empty_label_task, '', true);
98   }
99 }
100
101 // The fillTaskDropdown function populates the task combo box with
102 // tasks associated with a selected project (project id is passed here as id).
103 function fillTaskDropdown(id) {
104   var str_ids = task_ids[id];
105
106   var dropdown = document.getElementById("task");
107   if (dropdown == null) return; // Nothing to do.
108
109   // Determine previously selected item.
110   var selected_item = dropdown.options[dropdown.selectedIndex].value;
111
112   // Remove existing content.
113   dropdown.length = 0;
114   // Add mandatory top option.
115   dropdown.options[0] = new Option(empty_label_task, '', true);
116
117   // Populate the dropdown from the task_names array.
118   if (str_ids) {
119     var ids = new Array();
120     ids = str_ids.split(",");
121     var len = ids.length;
122
123     var idx = 1;
124     for (var i = 0; i < len; i++) {
125       var t_id = ids[i];
126       if (task_names[t_id]) {
127         dropdown.options[idx] = new Option(task_names[t_id], t_id);
128         idx++;
129       }
130     }
131
132     // If a previously selected item is still in dropdown - select it.
133     if (dropdown.options.length > 0) {
134       for (var i = 0; i < dropdown.options.length; i++) {
135         if (dropdown.options[i].value == selected_item)  {
136           dropdown.options[i].selected = true;
137         }
138       }
139     }
140   }
141 }
142
143 // The formDisable function disables some fields depending on what we have in other fields.
144 function formDisable(formField) {
145   var formFieldValue = eval("document.timeRecordForm." + formField + ".value");
146   var formFieldName = eval("document.timeRecordForm." + formField + ".name");
147   var x;
148
149   if (((formFieldValue != "") && (formFieldName == "start")) || ((formFieldValue != "") && (formFieldName == "finish"))) {
150     x = eval("document.timeRecordForm.duration");
151     x.value = "";
152     x.disabled = true;
153     x.style.background = "#e9e9e9";
154   }
155
156   if (((formFieldValue == "") && (formFieldName == "start") && (document.timeRecordForm.finish.value == "")) || ((formFieldValue == "") && (formFieldName == "finish") && (document.timeRecordForm.start.value == ""))) {
157     x = eval("document.timeRecordForm.duration");
158     x.value = "";
159     x.disabled = false;
160     x.style.background = "white";
161   }
162
163   if ((formFieldValue != "") && (formFieldName == "duration")) {
164     x = eval("document.timeRecordForm.start");
165     x.value = "";
166     x.disabled = true;
167     x.style.background = "#e9e9e9";
168     x = eval("document.timeRecordForm.finish");
169     x.value = "";
170     x.disabled = true;
171     x.style.background = "#e9e9e9";
172   }
173
174   if ((formFieldValue == "") && (formFieldName == "duration")) {
175     x = eval("document.timeRecordForm.start");
176     x.disabled = false;
177     x.style.background = "white";
178     x = eval("document.timeRecordForm.finish");
179     x.disabled = false;
180     x.style.background = "white";
181   }
182 }
183
184 // The setNow function fills a given field with current time.
185 function setNow(formField) {
186   var x = eval("document.timeRecordForm.start");
187   x.disabled = false;
188   x.style.background = "white";
189   x = eval("document.timeRecordForm.finish");
190   x.disabled = false;
191   x.style.background = "white";
192   var today = new Date();
193   var time_format = '{$user->time_format}';
194   var obj = eval("document.timeRecordForm." + formField);
195   obj.value = today.strftime(time_format);
196   formDisable(formField);
197 }
198
199 function get_date() {
200   var date = new Date();
201   return date.strftime("%Y-%m-%d");
202 }
203
204 function get_time() {
205   var date = new Date();
206   return date.strftime("%H:%M");
207 }
208 </script>
209
210 <style>
211 .not_billable td {
212   color: #ff6666;
213 }
214 </style>
215
216 {$forms.timeRecordForm.open}
217 <table cellspacing="4" cellpadding="0" border="0">
218   <tr>
219     <td valign="top">
220       <table>
221 {if $on_behalf_control}
222         <tr>
223           <td align="right">{$i18n.label.user}:</td>
224           <td>{$forms.timeRecordForm.onBehalfUser.control}</td>
225         </tr>
226 {/if}
227 {if $user->isPluginEnabled('cl')}
228         <tr>
229           <td align="right">{$i18n.label.client}{if $user->isPluginEnabled('cm')} (*){/if}:</td>
230           <td>{$forms.timeRecordForm.client.control}</td>
231         </tr>
232 {/if}
233 {if $user->isPluginEnabled('iv')}
234         <tr>
235           <td align="right">&nbsp;</td>
236           <td><label>{$forms.timeRecordForm.billable.control}{$i18n.form.time.billable}</label></td>
237         </tr>
238 {/if}
239 {if ($custom_fields && $custom_fields->fields[0])}
240         <tr>
241           <td align="right">{$custom_fields->fields[0]['label']|escape}{if $custom_fields->fields[0]['required']} (*){/if}:</td><td>{$forms.timeRecordForm.cf_1.control}</td>
242         </tr>
243 {/if}
244 {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
245         <tr>
246           <td align="right">{$i18n.label.project} (*):</td>
247           <td>{$forms.timeRecordForm.project.control}</td>
248         </tr>
249 {/if}
250 {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
251         <tr>
252           <td align="right">{$i18n.label.task}:</td>
253           <td>{$forms.timeRecordForm.task.control}</td>
254         </tr>
255 {/if}
256 {if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}
257         <tr>
258           <td align="right">{$i18n.label.start}:</td>
259           <td>{$forms.timeRecordForm.start.control}&nbsp;<input onclick="setNow('start');" type="button" tabindex="-1" value="{$i18n.button.now}"></td>
260         </tr>
261         <tr>
262           <td align="right">{$i18n.label.finish}:</td>
263           <td>{$forms.timeRecordForm.finish.control}&nbsp;<input onclick="setNow('finish');" type="button" tabindex="-1" value="{$i18n.button.now}"></td>
264         </tr>
265 {/if}
266 {if (($smarty.const.TYPE_DURATION == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}
267         <tr>
268           <td align="right">{$i18n.label.duration}:</td>
269           <td>{$forms.timeRecordForm.duration.control}&nbsp;{$i18n.form.time.duration_format}</td>
270         </tr>
271 {/if}
272       </table>
273     </td>
274     <td valign="top">
275       <table>
276         <tr><td>{$forms.timeRecordForm.date.control}</td></tr>
277       </table>
278     </td>
279   </tr>
280 </table>
281
282 <table>
283   <tr>
284     <td align="right">{$i18n.label.note}:</td>
285     <td align="left">{$forms.timeRecordForm.note.control}</td>
286   </tr>
287   <tr>
288     <td align="center" colspan="2">{$forms.timeRecordForm.btn_submit.control}</td>
289   </tr>
290 </table>
291
292 <table width="720">
293 <tr>
294   <td valign="top">
295 {if $time_records}
296       <table border="0" cellpadding="3" cellspacing="1" width="100%">
297       <tr>
298   {if $user->isPluginEnabled('cl')}
299         <td width="20%" class="tableHeader">{$i18n.label.client}</td>
300   {/if}
301   {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
302         <td class="tableHeader">{$i18n.label.project}</td>
303   {/if}
304   {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
305         <td class="tableHeader">{$i18n.label.task}</td>
306   {/if}
307   {if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}
308         <td width="5%" class="tableHeader" align="right">{$i18n.label.start}</td>
309         <td width="5%" class="tableHeader" align="right">{$i18n.label.finish}</td>
310   {/if}
311         <td width="5%" class="tableHeader">{$i18n.label.duration}</td>
312         <td class="tableHeader">{$i18n.label.note}</td>
313         <td width="5%" class="tableHeader">{$i18n.label.edit}</td>
314       </tr>
315   {foreach $time_records as $record}
316       <tr bgcolor="{cycle values="#f5f5f5,#ccccce"}" {if !$record.billable} class="not_billable" {/if}>
317     {if $user->isPluginEnabled('cl')}
318         <td valign="top">{$record.client|escape}</td>
319     {/if}
320     {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
321         <td valign="top">{$record.project|escape}</td>
322     {/if}
323     {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
324         <td valign="top">{$record.task|escape}</td>
325     {/if}
326     {if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}
327         <td nowrap align="right" valign="top">{if $record.start}{$record.start}{else}&nbsp;{/if}</td>
328         <td nowrap align="right" valign="top">{if $record.finish}{$record.finish}{else}&nbsp;{/if}</td>
329     {/if}
330         <td align="right" valign="top">{if ($record.duration == '0:00' && $record.start <> '')}<font color="#ff0000">{$i18n.form.time.uncompleted}</font>{else}{$record.duration}{/if}</td>
331         <td valign="top">{if $record.comment}{$record.comment|escape}{else}&nbsp;{/if}</td>
332         <td valign="top" align="center">
333     {if $record.invoice_id}
334           &nbsp;
335     {else}
336           <a href="time_edit.php?id={$record.id}">{$i18n.label.edit}</a>
337       {if ($record.duration == '0:00' && $record.start <> '')}
338           <input type="hidden" name="record_id" value="{$record.id}">
339           <input type="hidden" name="browser_date" value="">
340           <input type="hidden" name="browser_time" value="">
341           <input type="submit" id="btn_stop" name="btn_stop" onclick="browser_date.value=get_date();browser_time.value=get_time()" value="{$i18n.button.stop}">
342       {/if}
343     {/if}
344         </td>
345       </tr>
346   {/foreach}
347     </table>
348 {/if}
349   </td>
350 </tr>
351 </table>
352 {if $time_records}
353 <table cellpadding="3" cellspacing="1" width="720">
354   <tr>
355     <td align="left">{$i18n.label.week_total}: {$week_total}</td>
356     <td align="right">{$i18n.label.day_total}: {$day_total}</td>
357   </tr>
358   {if $user->isPluginEnabled('mq')}
359   <tr>
360     <td align="left">{$i18n.label.month_total}: {$month_total}</td>
361     {if $over_quota}
362     <td align="right">{$i18n.form.time.over_quota}: <span style="color: green;">{$quota_remaining}</span></td>
363     {else}
364     <td align="right">{$i18n.form.time.remaining_quota}: <span style="color: red;">{$quota_remaining}</span></td>
365     {/if}
366   </tr>
367   {/if}
368 </table>
369 {/if}
370 {$forms.timeRecordForm.close}