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.
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.
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}";
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'}";
21 // We'll use this array to populate project dropdown when client is not selected.
23 projects = new Array();
24 {foreach $project_list as $project}
25 projects[idx] = new Array("{$project.id}", "{$project.name|escape:'javascript'}");
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}";
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'}";
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'}';
44 // The populateDropdowns 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);
50 fillTaskDropdown(document.timeRecordForm.project.value);
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;
61 // Remove existing content.
63 var project_reset = true;
64 // Add mandatory top option.
65 dropdown.options[0] = new Option(empty_label_project, '', true);
67 // Populate project dropdown.
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;
79 var ids = new Array();
80 ids = str_ids.split(",");
83 for (var i = 0; i < len; 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;
93 // If project selection was reset - clear the tasks dropdown.
95 dropdown = document.getElementById("task");
97 dropdown.options[0] = new Option(empty_label_task, '', true);
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];
106 var dropdown = document.getElementById("task");
107 if (dropdown == null) return; // Nothing to do.
109 // Determine previously selected item.
110 var selected_item = dropdown.options[dropdown.selectedIndex].value;
112 // Remove existing content.
114 // Add mandatory top option.
115 dropdown.options[0] = new Option(empty_label_task, '', true);
117 // Populate the dropdown from the task_names array.
119 var ids = new Array();
120 ids = str_ids.split(",");
121 var len = ids.length;
124 for (var i = 0; i < len; i++) {
126 if (task_names[t_id]) {
127 dropdown.options[idx] = new Option(task_names[t_id], t_id);
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;
143 // The formDisable function disables some fields depending on what we have in other fields.
144 function formDisable(formField) {
145 formFieldValue = eval("document.timeRecordForm." + formField + ".value");
146 formFieldName = eval("document.timeRecordForm." + formField + ".name");
148 if (((formFieldValue != "") && (formFieldName == "start")) || ((formFieldValue != "") && (formFieldName == "finish"))) {
149 var x = eval("document.timeRecordForm.duration");
152 x.style.background = "#e9e9e9";
155 if (((formFieldValue == "") && (formFieldName == "start") && (document.timeRecordForm.finish.value == "")) || ((formFieldValue == "") && (formFieldName == "finish") && (document.timeRecordForm.start.value == ""))) {
156 var x = eval("document.timeRecordForm.duration");
159 x.style.background = "white";
162 if ((formFieldValue != "") && (formFieldName == "duration")) {
163 var x = eval("document.timeRecordForm.start");
166 x.style.background = "#e9e9e9";
167 var x = eval("document.timeRecordForm.finish");
170 x.style.background = "#e9e9e9";
173 if ((formFieldValue == "") && (formFieldName == "duration")) {
174 var x = eval("document.timeRecordForm.start");
176 x.style.background = "white";
177 var x = eval("document.timeRecordForm.finish");
179 x.style.background = "white";
183 // The setNow function fills a given field with current time.
184 function setNow(formField) {
185 var x = eval("document.timeRecordForm.start");
187 x.style.background = "white";
188 var x = eval("document.timeRecordForm.finish");
190 x.style.background = "white";
191 var today = new Date();
192 var time_format = '{$user->time_format}';
193 var obj = eval("document.timeRecordForm." + formField);
194 obj.value = today.strftime(time_format);
195 formDisable(formField);
198 function get_date() {
199 var date = new Date();
200 return date.strftime("%Y-%m-%d");
203 function get_time() {
204 var date = new Date();
205 return date.strftime("%H:%M");
215 {$forms.timeRecordForm.open}
216 <table cellspacing="4" cellpadding="0" border="0">
220 {if $on_behalf_control}
222 <td align="right">{$i18n.label.user}:</td>
223 <td>{$forms.timeRecordForm.onBehalfUser.control}</td>
226 {if in_array('cl', explode(',', $user->plugins))}
228 <td align="right">{$i18n.label.client}{if in_array('cm', explode(',', $user->plugins))} (*){/if}:</td>
229 <td>{$forms.timeRecordForm.client.control}</td>
232 {if in_array('iv', explode(',', $user->plugins))}
234 <td align="right"> </td>
235 <td><label>{$forms.timeRecordForm.billable.control}{$i18n.form.time.billable}</label></td>
238 {if ($custom_fields && $custom_fields->fields[0])}
240 <td align="right">{$custom_fields->fields[0]['label']|escape:'html'}{if $custom_fields->fields[0]['required']} (*){/if}:</td><td>{$forms.timeRecordForm.cf_1.control}</td>
243 {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
245 <td align="right">{$i18n.label.project} (*):</td>
246 <td>{$forms.timeRecordForm.project.control}</td>
249 {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
251 <td align="right">{$i18n.label.task} (*):</td>
252 <td>{$forms.timeRecordForm.task.control}</td>
255 {if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}
257 <td align="right">{$i18n.label.start}:</td>
258 <td>{$forms.timeRecordForm.start.control} <input onclick="setNow('start');" type="button" tabindex="-1" value="{$i18n.button.now}"></td>
261 <td align="right">{$i18n.label.finish}:</td>
262 <td>{$forms.timeRecordForm.finish.control} <input onclick="setNow('finish');" type="button" tabindex="-1" value="{$i18n.button.now}"></td>
265 {if (($smarty.const.TYPE_DURATION == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}
267 <td align="right">{$i18n.label.duration}:</td>
268 <td>{$forms.timeRecordForm.duration.control} {$i18n.form.time.duration_format}</td>
275 <tr><td>{$forms.timeRecordForm.date.control}</td></tr>
283 <td align="right">{$i18n.label.note}:</td>
284 <td align="left">{$forms.timeRecordForm.note.control}</td>
287 <td align="center" colspan="2">{$forms.timeRecordForm.btn_submit.control}</td>
295 <table border='0' cellpadding='3' cellspacing='1' width="100%">
297 {if in_array('cl', explode(',', $user->plugins))}
298 <td width="20%" class="tableHeader">{$i18n.label.client}</td>
300 {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
301 <td class="tableHeader">{$i18n.label.project}</td>
303 {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
304 <td class="tableHeader">{$i18n.label.task}</td>
306 {if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}
307 <td width="5%" class="tableHeader" align='right'>{$i18n.label.start}</td>
308 <td width="5%" class="tableHeader" align='right'>{$i18n.label.finish}</td>
310 <td width="5%" class="tableHeader">{$i18n.label.duration}</td>
311 <td class="tableHeader">{$i18n.label.note}</td>
312 <td width="5%" class="tableHeader">{$i18n.label.edit}</td>
314 {foreach $time_records as $record}
315 <tr bgcolor="{cycle values="#f5f5f5,#ccccce"}" {if !$record.billable} class="not_billable" {/if}>
316 {if in_array('cl', explode(',', $user->plugins))}
317 <td valign='top'>{$record.client|escape:'html'}</td>
319 {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
320 <td valign='top'>{$record.project|escape:'html'}</td>
322 {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
323 <td valign='top'>{$record.task|escape:'html'}</td>
325 {if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))}
326 <td nowrap align='right' valign='top'>{if $record.start}{$record.start}{else} {/if}</td>
327 <td nowrap align='right' valign='top'>{if $record.finish}{$record.finish}{else} {/if}</td>
329 <td align='right' valign='top'>{if $record.duration <> '0:00'}{$record.duration}{else}<font color="#ff0000">{$i18n.form.time.uncompleted}</font>{/if}</td>
330 <td valign='top'>{if $record.comment}{$record.comment|escape:'html'}{else} {/if}</td>
331 <td valign='top' align='center'>
332 {if $record.invoice_id}
335 <a href='time_edit.php?id={$record.id}'>{$i18n.label.edit}</a>
336 {if $record.duration == '0:00'}
337 <input type='hidden' name='record_id' value='{$record.id}'>
338 <input type='hidden' name='browser_date' value=''>
339 <input type='hidden' name='browser_time' value=''>
340 <input type='submit' id='btn_stop' name='btn_stop' onclick='browser_date.value=get_date();browser_time.value=get_time()' value='{$i18n.button.stop}'>
352 <table cellpadding="3" cellspacing="1" width="720">
354 <td align="left">{$i18n.label.week_total}: {$week_total}</td>
355 <td align="right">{$i18n.label.day_total}: {$day_total}</td>
359 {$forms.timeRecordForm.close}