Skip to content

Commit

Permalink
Table field updates
Browse files Browse the repository at this point in the history
  • Loading branch information
engram-design committed Nov 1, 2020
1 parent 45d5377 commit 86f5fee
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 48 deletions.
14 changes: 14 additions & 0 deletions src/templates/_special/form-template/fields/table/_row.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,17 @@
</td>
{% endswitch %}
{% endfor %}

{% set buttonAttributes = {
class: 'fui-btn fui-table-remove-btn',
type: 'button',
data: {
'remove-table-row': field.handle,
}
} %}

<td data-col-remove>
<button {{ attr(buttonAttributes) }}>
{{ 'Remove' | t('formie') }}
</button>
</td>
58 changes: 39 additions & 19 deletions src/templates/_special/form-template/fields/table/index.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{{ hiddenInput(field.handle, '') }}

{% namespace field.handle %}
<fieldset class="fui-fieldset">
{{ formieInclude('_includes/legend', { position: 'above' }) }}
Expand All @@ -17,7 +19,7 @@
</tr>
</thead>

<tbody>
<tbody class="fui-table-rows">
{% if value %}
{% for rowId, row in value %}
<tr class="fui-table-row">
Expand All @@ -35,20 +37,40 @@
} %}
</tr>
{% endfor %}
{% elseif field.minRows > 0 %}
{% for i in 1..field.minRows %}
<tr class="fui-table-row">
{% include 'fields/table/_row' with {
index: loop.index0,
row: null,
} %}
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>

{% set buttonAttributes = {
class: 'fui-btn fui-table-add-btn',
type: 'button',
data: {
'min-rows': field.minRows,
'max-rows': field.maxRows,
'add-table-row': field.handle,
}
} %}

{# Disable the button straight away if we're making it static #}
{% if field.minRows != '' and field.maxRows != '' %}
{% if field.minRows == field.maxRows %}
{% set buttonAttributes = buttonAttributes | merge({
class: buttonAttributes.class ~ ' fui-disabled',
disabled: true,
}) %}
{% endif %}
{% endif %}

{% if not field.static %}
{% set buttonAttributes = {
class: 'fui-btn',
type: 'button',
data: {
'min-rows': field.minRows,
'max-rows': field.maxRows,
'add-table-row': field.handle,
}
} %}
<button {{ attr(buttonAttributes) }}>{{ field.addRowLabel }}</button>
{% endif %}

Expand All @@ -58,12 +80,10 @@
</fieldset>
{% endnamespace %}

{% if not field.static %}
<script type="text/template" data-table-template="{{ field.handle }}">
{% namespace field.handle %}
{% include 'fields/table/_row' with {
index: '__ROW__'
} %}
{% endnamespace %}
</script>
{% endif %}
<script type="text/template" data-table-template="{{ field.handle }}">
{% namespace field.handle %}
{% include 'fields/table/_row' with {
index: '__ROW__'
} %}
{% endnamespace %}
</script>
2 changes: 1 addition & 1 deletion src/web/assets/frontend/dist/css/formie-theme.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/frontend/dist/js/fields/table.js

Large diffs are not rendered by default.

106 changes: 81 additions & 25 deletions src/web/assets/frontend/src/js/fields/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,74 +21,130 @@ export class FormieTable {
}

initTable() {
const $addButton = this.$field.querySelector('[data-add-table-row]');
const $rows = this.getRows();

// Assign this instance to the field's DOM, so it can be accessed by third parties
this.$field.table = this;

if ($addButton) {
this.form.addEventListener($addButton, eventKey('click'), e => {
// Save a bunch of properties
this.$addButton = this.$field.querySelector('[data-add-table-row]');

// Bind the click event to the add button
if (this.$addButton) {
this.minRows = parseInt(this.$addButton.getAttribute('data-min-rows'));
this.maxRows = parseInt(this.$addButton.getAttribute('data-max-rows'));

// Add the click event, but use a namespace so we can track these dynamically-added items
this.form.addEventListener(this.$addButton, eventKey('click'), e => {
this.addRow(e);
});
}

// Initialise any rendered rows
if ($rows && $rows.length) {
$rows.forEach(($row) => {
this.initRow($row);
});
}

// Emit an "init" event
this.$field.dispatchEvent(new CustomEvent('init', {
bubbles: true,
detail: {
table: this,
},
}));
}

initRow($row) {
if (!$row) {
console.error($row);
return;
}

const $removeButton = $row.querySelector('[data-remove-table-row]');

if ($removeButton) {
// Add the click event, but use a namespace so we can track these dynamically-added items
this.form.addEventListener($removeButton, eventKey('click'), e => {
this.removeRow(e);
});
}
}

addRow(e) {
const button = e.target;
const handle = button.getAttribute('data-add-table-row');
const maxRows = parseInt(button.getAttribute('data-max-rows'));
const handle = this.$addButton.getAttribute('data-add-table-row');
const template = document.querySelector(`[data-table-template="${handle}"]`);
const numRows = this.getNumRows();

if (template) {
const numRows = this.getNumRows();
if (numRows >= maxRows) {
if (numRows >= this.maxRows) {
return;
}

const id = `${numRows + 1}`;
const html = template.innerHTML.replace(/__ROW__/g, id);
const $newRow = document.createElement('tr');

let $newRow = document.createElement('tr');
$newRow.className = 'fui-table-row';
$newRow.innerHTML = html;

this.$field.querySelector('tbody').appendChild($newRow);

setTimeout(() => {
if (this.getNumRows() >= maxRows) {
button.className += ' fui-disabled';
button.setAttribute('disabled', 'disabled');

return;
}
this.updateButton();

this.$field.dispatchEvent(new CustomEvent('append', {
const event = new CustomEvent('append', {
bubbles: true,
detail: {
row: $newRow,
form: this.$form,
},
}));
}, 0);
});
this.$field.dispatchEvent(event);

this.initRow(event.detail.row);
}, 50);
}
}

getRows() {
return this.$field.querySelectorAll('.fui-table-row');
}
removeRow(e) {
const button = e.target;
const $row = button.closest('.fui-table-row');

if ($row) {
const numRows = this.getNumRows();

if (numRows <= this.minRows) {
return;
}

getLastRow() {
const rows = this.getRows();
$row.parentNode.removeChild($row);

if (rows.length > 0) {
return rows[rows.length - 1];
this.updateButton();
}
}

return null;
getRows() {
return this.$field.querySelectorAll('.fui-table-row');
}

getNumRows() {
return this.getRows().length;
}

updateButton() {
if (this.$addButton) {
if (this.getNumRows() >= this.maxRows) {
this.$addButton.classList.add = 'fui-disabled';
this.$addButton.setAttribute('disabled', 'disabled');
} else {
this.$addButton.classList.remove = 'fui-disabled';
this.$addButton.removeAttribute('disabled');
}
}
}
}

window.FormieTable = FormieTable;
44 changes: 44 additions & 0 deletions src/web/assets/frontend/src/scss/fields/_table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,47 @@
}
}
}

.fui-table [data-col-remove] {
width: 1px;
}

.fui-table-add-btn {
position: relative;
padding-left: 2rem;

&::after {
content: '';
position: absolute;
top: 0.75rem;
left: 0.75rem;
width: 14px;
height: 14px;
display: block;
background-repeat: no-repeat;
background-image: url("data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='far' data-icon='plus' class='svg-inline--fa fa-plus fa-w-12' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3E%3Cpath fill='currentColor' d='M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z'%3E%3C/path%3E%3C/svg%3E");
}
}

.fui-table-remove-btn {
position: relative;
border-radius: 50%;
height: 0;
width: 0;
padding: 13px;
text-indent: -9999px;
border: 1px solid $border-color;

&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 9px;
height: 14px;
transform: translate(-50%, -50%);
display: block;
background-repeat: no-repeat;
background-image: url("data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='far' data-icon='times' class='svg-inline--fa fa-times fa-w-10' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E%3Cpath fill='currentColor' d='M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z'%3E%3C/path%3E%3C/svg%3E");
}
}
4 changes: 2 additions & 2 deletions src/web/assets/mix-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
"/forms/dist/css/style.css": "/forms/dist/css/style.css?id=b92b778e8b46832f781d",
"/repeater/dist/css/style.css": "/repeater/dist/css/style.css?id=878cdd98ce56c13b9c78",
"/frontend/dist/css/formie-base.css": "/frontend/dist/css/formie-base.css?id=889b2aecb6c4427b54e9",
"/frontend/dist/css/formie-theme.css": "/frontend/dist/css/formie-theme.css?id=41cbb16ddb5cb6c48bd4",
"/frontend/dist/css/formie-theme.css": "/frontend/dist/css/formie-theme.css?id=c1a296e56e6e02cb1946",
"/frontend/dist/css/fields/tags.css": "/frontend/dist/css/fields/tags.css?id=12d7d3c75f0d71e19ab4",
"/cp/dist/css/formie-cp.css": "/cp/dist/css/formie-cp.css?id=1e58f3a5f5dd03056712",
"/frontend/dist/js/fields/checkbox-radio.js": "/frontend/dist/js/fields/checkbox-radio.js?id=512657f3e6e8835404f5",
"/frontend/dist/js/fields/file-upload.js": "/frontend/dist/js/fields/file-upload.js?id=79bc709c95c8b79c7a9b",
"/frontend/dist/js/fields/repeater.js": "/frontend/dist/js/fields/repeater.js?id=1711b57ee19f21007112",
"/frontend/dist/js/fields/rich-text.js": "/frontend/dist/js/fields/rich-text.js?id=b660f47e4742f1f0167f",
"/frontend/dist/js/fields/table.js": "/frontend/dist/js/fields/table.js?id=8a85ee08ab92bf48543d",
"/frontend/dist/js/fields/table.js": "/frontend/dist/js/fields/table.js?id=29152bf596e9623f0a1a",
"/frontend/dist/js/fields/tags.js": "/frontend/dist/js/fields/tags.js?id=7a0e7d5eef5c4a9517bf",
"/frontend/dist/js/fields/text-limit.js": "/frontend/dist/js/fields/text-limit.js?id=5b8e242f8c8abbdbae22",
"/frontend/dist/js/formie.js": "/frontend/dist/js/formie.js?id=cd557c762401f215fcba",
Expand Down

0 comments on commit 86f5fee

Please sign in to comment.