diff --git a/include/ajax.forms.php b/include/ajax.forms.php index 2142e8e4faa947b5060539e79a8ef9d2b535025a..1ec760b077e1c934ee13cffa568147eb22897344 100644 --- a/include/ajax.forms.php +++ b/include/ajax.forms.php @@ -36,5 +36,19 @@ class DynamicFormsAjaxAPI extends AjaxController { else $field->save(); } + + function deleteAnswer($entry_id, $field_id) { + global $thisstaff; + + if (!$thisstaff) + Http::response(403, 'Login required'); + + $ent = DynamicFormEntryAnswer::lookup(array( + 'entry_id'=>$entry_id, 'field_id'=>$field_id)); + if (!$ent) + Http::response(404, 'Answer not found'); + + $ent->delete(); + } } ?> diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php index c58a22f4644e3d768caf172579fe5b2c2310ff4a..263850e0241efc86d4782a3ee19e9200af244654 100644 --- a/include/class.dynamic_forms.php +++ b/include/class.dynamic_forms.php @@ -592,11 +592,15 @@ class DynamicFormEntry extends VerySimpleModel { * entry. */ function addMissingFields() { + // Track deletions + foreach ($this->getAnswers() as $answer) + $answer->deleted = true; + foreach ($this->getForm()->getDynamicFields() as $field) { $found = false; foreach ($this->getAnswers() as $answer) { if ($answer->get('field_id') == $field->get('id')) { - $found = true; break; + $answer->deleted = false; $found = true; break; } } if (!$found && ($field = $field->getImpl($field)) @@ -605,6 +609,7 @@ class DynamicFormEntry extends VerySimpleModel { array('field_id'=>$field->get('id'), 'entry_id'=>$this->id)); $a->field = $field; $a->entry = $this; + $a->deleted = false; // Add to list of answers $this->_values[] = $a; $this->_fields[] = $field; @@ -710,6 +715,7 @@ class DynamicFormEntryAnswer extends VerySimpleModel { var $field; var $form; var $entry; + var $deleted = false; var $_value; function getEntry() { @@ -742,6 +748,10 @@ class DynamicFormEntryAnswer extends VerySimpleModel { return $this->get('value_id'); } + function isDeleted() { + return $this->deleted; + } + function toString() { return $this->getField()->toString($this->getValue()); } diff --git a/include/staff/templates/dynamic-form.tmpl.php b/include/staff/templates/dynamic-form.tmpl.php index 09d97ab650ab3d79df393153cda76fb999eeb980..a1fee6a9befab48c7cd801a36156432f0418defe 100644 --- a/include/staff/templates/dynamic-form.tmpl.php +++ b/include/staff/templates/dynamic-form.tmpl.php @@ -15,13 +15,29 @@ else { ?> <td class="multi-line <?php if ($field->get('required')) echo 'required'; ?>" style="min-width:120px;"> <?php echo Format::htmlchars($field->get('label')); ?>:</td> - <td><?php + <td><div style="position:relative"><?php } $field->render(); ?> <?php if ($field->get('required')) { ?> <font class="error">*</font> <?php } + if (($a = $field->getAnswer()) && $a->isDeleted()) { + ?><a class="action-button danger overlay" title="Delete this data" + href="#delete-answer" + onclick="javascript:if (confirm('You sure?')) + $.ajax({ + url: 'ajax.php/form/answer/' + +$(this).data('entryId') + '/' + $(this).data('fieldId'), + type: 'delete', + success: $.proxy(function() { + $(this).closest('tr').fadeOut(); + }, this) + });" + data-field-id="<?php echo $field->getAnswer()->get('field_id'); + ?>" data-entry-id="<?php echo $field->getAnswer()->get('entry_id'); + ?>"> <i class="icon-trash"></i> </a></div><?php + } if ($field->get('hint') && !$field->isBlockLevel()) { ?> <br /><em style="color:gray;display:inline-block"><?php echo Format::htmlchars($field->get('hint')); ?></em> @@ -31,7 +47,7 @@ <br /> <font class="error"><?php echo Format::htmlchars($e); ?></font> <?php } ?> - </td> + </div></td> </tr> <?php } diff --git a/scp/ajax.php b/scp/ajax.php index b13822d17c0ebefd04d02a89d4af76c79d8c9980..6be3aadd48656c68a1021813aecc1a6aa439a35c 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -53,7 +53,8 @@ $dispatcher = patterns('', url('^/form/', patterns('ajax.forms.php:DynamicFormsAjaxAPI', url_get('^help-topic/(?P<id>\d+)$', 'getFormsForHelpTopic'), url_get('^field-config/(?P<id>\d+)$', 'getFieldConfiguration'), - url_post('^field-config/(?P<id>\d+)$', 'saveFieldConfiguration') + url_post('^field-config/(?P<id>\d+)$', 'saveFieldConfiguration'), + url_delete('^answer/(?P<entry>\d+)/(?P<field>\d+)$', 'deleteAnswer') )), url('^/report/overview/', patterns('ajax.reports.php:OverviewReportAjaxAPI', # Send diff --git a/scp/css/scp.css b/scp/css/scp.css index 50bea7ea4bc26d2cc5634889b0ff35e6c9ec3d34..c6554afb966cc6b6118a8fe67c21bfa8130551d1 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -1559,3 +1559,31 @@ div.selected-signature { div.selected-signature .inner { opacity: 0.5; } + +.action-button.danger:hover { + opacity: 1.0; + border-color: rgba(95,75,0,0.8) !important; + background: #fc9f41; /* Old browsers */ + color: rgba(255,255,255,0.8) !important; + /* IE9 SVG, needs conditional override of 'filter' to 'none' */ + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZjOWY0MSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjZTgxMTQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); + background: -moz-linear-gradient(top, #fc9f41 0%, #ce8114 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fc9f41), color-stop(100%,#ce8114)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #fc9f41 0%,#ce8114 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #fc9f41 0%,#ce8114 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #fc9f41 0%,#ce8114 100%); /* IE10+ */ + background: linear-gradient(to bottom, #fc9f41 0%,#ce8114 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fc9f41', endColorstr='#ce8114',GradientType=0 ); /* IE6-8 */ +} +.action-button.danger { + color: #999 !important; + background-color: rgba(220,220,220,0.5); + opacity: 0.6; +} + +.action-button.overlay { + float: none; + position: absolute; + top: 4px; + right: 5px; +}