├── LICENSE.md
├── README.md
├── composer.json
├── screenshots
├── after.png
├── before.png
├── settings.png
├── table.png
└── types.png
└── settable
├── SetTablePlugin.php
├── fieldtypes
└── SetTableFieldType.php
├── resources
└── css
│ └── settable.css
└── templates
├── field.html
├── settings-table.html
└── settings.html
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Josh Crawford
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Set Table
2 |
3 | Set Table is a Craft CMS field type to allow you to create static tables. Set Table is essentially identical to a regular Table field, apart from a few small differences. The aim of this plugin is to provide end-users with a set collection of rows for their table - defined in the field settings.
4 |
5 | **Label Type**
6 |
7 | In addition to the regular column options for a table (text, multi-line text, select, checkbox), you can set a column's type to be a Label. This will display the provided value as a read-only label.
8 |
9 |
10 |
11 | ###Use Case
12 |
13 | By now you might be a bit confused as to why Set Table even exists, being that you can simply use a regular table to do the same thing. However there are potential cases where read-only portions of a table might be helpful to your end user. Likewise for the number of rows in the table.
14 |
15 | A good use case would be a list of social media fields, containing links to your website's various social media pages.
16 |
17 | Firstly, you could simply use a collection of text fields like so:
18 |
19 |
20 |
21 | This is a little messy visually, and unnecessary amount of fields. You'd be better off with a regular table:
22 |
23 |
24 |
25 | Great! Nice and neat. We can even use it to define the icon class for templating.
26 |
27 | But what if you don't want your users to be able to edit the Name and Icon Class fields? If you're using an icon font, this will certainly break things on the site. And maybe you also don't want users to add any more social links? What if they try to add a service without an icon?
28 |
29 | Obviously there are ways around the above (provide a placeholder when no icon, and educate your editors on table fields), but here's a Set Table.
30 |
31 |
32 |
33 | There's also some small visual tweaks to the table compared to a regular one.
34 |
35 | ###Field Settings
36 |
37 | If you can edit a Table, you can edit a Set Table.
38 |
39 |
40 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "engram-design/settable",
3 | "description": "A Craft CMS field type to allow you to create static tables.",
4 | "homepage": "https://github.com/engram-design/SetTable",
5 | "type": "craft-plugin",
6 | "keywords": ["craft","plugin"],
7 | "license": "MIT",
8 | "authors": [{
9 | "name": "S. Group",
10 | "email": "joshua@sgroup.com.au",
11 | "homepage": "http://sgroup.com.au/"
12 | }],
13 | "require": {
14 | "composer/installers": "~1.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/screenshots/after.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verbb/SetTable/a3e0383077887fae65e9511838c06e17e41ae94a/screenshots/after.png
--------------------------------------------------------------------------------
/screenshots/before.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verbb/SetTable/a3e0383077887fae65e9511838c06e17e41ae94a/screenshots/before.png
--------------------------------------------------------------------------------
/screenshots/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verbb/SetTable/a3e0383077887fae65e9511838c06e17e41ae94a/screenshots/settings.png
--------------------------------------------------------------------------------
/screenshots/table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verbb/SetTable/a3e0383077887fae65e9511838c06e17e41ae94a/screenshots/table.png
--------------------------------------------------------------------------------
/screenshots/types.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verbb/SetTable/a3e0383077887fae65e9511838c06e17e41ae94a/screenshots/types.png
--------------------------------------------------------------------------------
/settable/SetTablePlugin.php:
--------------------------------------------------------------------------------
1 | getSettings()->columns;
19 | $tableData = $this->getSettings()->tableData;
20 |
21 | if (!$columns)
22 | {
23 | $columns = array('col1' => array('heading' => '', 'handle' => '', 'type' => 'singleline'));
24 |
25 | // Update the actual settings model for getInputHtml()
26 | $this->getSettings()->columns = $columns;
27 | }
28 |
29 | if ($tableData === null)
30 | {
31 | $tableData = array('row1' => array());
32 | }
33 |
34 | $columnSettings = array(
35 | 'heading' => array(
36 | 'heading' => Craft::t('Column Heading'),
37 | 'type' => 'singleline',
38 | 'autopopulate' => 'handle'
39 | ),
40 | 'handle' => array(
41 | 'heading' => Craft::t('Handle'),
42 | 'class' => 'code',
43 | 'type' => 'singleline'
44 | ),
45 | 'width' => array(
46 | 'heading' => Craft::t('Width'),
47 | 'class' => 'code',
48 | 'type' => 'singleline',
49 | 'width' => 50
50 | ),
51 | 'type' => array(
52 | 'heading' => Craft::t('Type'),
53 | 'class' => 'thin',
54 | 'type' => 'select',
55 | 'options' => array(
56 | 'label' => Craft::t('Label'),
57 | 'singleline' => Craft::t('Single-line Text'),
58 | 'multiline' => Craft::t('Multi-line text'),
59 | 'number' => Craft::t('Number'),
60 | 'checkbox' => Craft::t('Checkbox'),
61 | )
62 | ),
63 | );
64 |
65 | craft()->templates->includeCssResource('settable/css/settable.css');
66 |
67 | craft()->templates->includeJsResource('js/TableFieldSettings.js');
68 | craft()->templates->includeJs('new Craft.TableFieldSettings(' .
69 | '"'.craft()->templates->namespaceInputName('columns').'", ' .
70 | '"'.craft()->templates->namespaceInputName('tableData').'", ' .
71 | JsonHelper::encode($columns).', ' .
72 | JsonHelper::encode($tableData).', ' .
73 | JsonHelper::encode($columnSettings) .
74 | ');');
75 |
76 | $columnsField = craft()->templates->render('settable/settings', array(
77 | 'label' => Craft::t('Table Columns'),
78 | 'instructions' => Craft::t('Define the columns your table should have.'),
79 | 'id' => 'columns',
80 | 'name' => 'columns',
81 | 'cols' => $columnSettings,
82 | 'rows' => $columns,
83 | 'addRowLabel' => Craft::t('Add a column'),
84 | 'initJs' => false
85 | ));
86 |
87 | $tableDataField = craft()->templates->render('settable/settings', array(
88 | 'label' => Craft::t('Table Values'),
89 | 'instructions' => Craft::t('Define the set values for the field.'),
90 | 'id' => 'tableData',
91 | 'name' => 'tableData',
92 | 'cols' => $columns,
93 | 'rows' => $tableData,
94 | 'initJs' => false
95 | ));
96 |
97 | return $columnsField.$tableDataField;
98 | }
99 |
100 | public function getInputHtml($name, $value)
101 | {
102 | $input = '';
103 |
104 | $tableHtml = $this->_getInputHtml($name, $value, false);
105 |
106 | if ($tableHtml) {
107 | $input .= $tableHtml;
108 | }
109 |
110 | return $input;
111 | }
112 |
113 | public function prepValueFromPost($value)
114 | {
115 | return $value;
116 | }
117 |
118 | public function prepValue($value)
119 | {
120 | if (is_array($value) && ($columns = $this->getSettings()->columns)) {
121 | // Make the values accessible from both the col IDs and the handles
122 | foreach ($value as &$row) {
123 | foreach ($columns as $colId => $col) {
124 | if ($col['handle']) {
125 | $row[$col['handle']] = (isset($row[$colId]) ? $row[$colId] : null);
126 | }
127 | }
128 | }
129 |
130 | return $value;
131 | }
132 | }
133 |
134 | protected function defineSettings()
135 | {
136 | return array(
137 | 'columns' => AttributeType::Mixed,
138 | 'tableData' => AttributeType::Mixed,
139 | );
140 | }
141 |
142 | public function prepSettings($settings)
143 | {
144 | if (!isset($settings['tableData'])) {
145 | $settings['tableData'] = array();
146 | }
147 |
148 | return $settings;
149 | }
150 |
151 | private function _getInputHtml($name, $value, $static)
152 | {
153 | $columns = $this->getSettings()->columns;
154 | $tableData = $this->getSettings()->tableData;
155 |
156 | if ($columns) {
157 | // Translate the column headings
158 | foreach ($columns as &$column) {
159 | if (!empty($column['heading'])) {
160 | $column['heading'] = Craft::t($column['heading']);
161 | }
162 | }
163 |
164 | // Minor fix for Backwards-compatibility - migrate old data into new key
165 | if ($value && is_array($value)) {
166 | foreach ($value as $key => $val) {
167 | if (is_numeric($key)) {
168 | $value['row'.($key+1)] = $val;
169 | unset($value[$key]);
170 | }
171 | }
172 | }
173 |
174 | if (!$value) {
175 | if (is_array($tableData)) {
176 | $value = $tableData;
177 | }
178 | } else {
179 | // Merge the saved existing values and any new rows
180 | foreach ($tableData as $key => $val) {
181 | if (!isset($value[$key])) {
182 | $value[$key] = $val;
183 | }
184 | }
185 | }
186 |
187 | $id = craft()->templates->formatInputId($name);
188 |
189 | return craft()->templates->render('settable/field', array(
190 | 'id' => $id,
191 | 'name' => $name,
192 | 'cols' => $columns,
193 | 'rows' => $value,
194 | ));
195 | }
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/settable/resources/css/settable.css:
--------------------------------------------------------------------------------
1 | .setTable {
2 | position: relative;
3 | margin-bottom: 10px;
4 | border-radius: 3px;
5 | background: #f9fafa;
6 | padding: 1px 0 0 0;
7 |
8 | -webkit-user-select: none;
9 | -moz-user-select: none;
10 | -ms-user-select: none;
11 |
12 | outline: none;
13 | -webkit-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
14 | -moz-box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
15 | box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
16 | }
17 |
18 | .setTable thead {
19 | border-radius: 2px 2px 0 0;
20 | background: #eef0f1;
21 | color: #b9bfc6;
22 | }
23 |
24 | .setTable thead tr th:first-child {
25 | border-left: 1px #DFE0E0 solid;
26 | border-radius: 2px 0 0 0;
27 | }
28 |
29 | .setTable thead tr th:last-child {
30 | border-right: 1px #DFE0E0 solid;
31 | border-radius: 0 2px 0 0;
32 | }
33 |
34 | .setTable thead tr th,
35 | .setTable tbody tr td {
36 | padding-left: 14px;
37 | }
38 |
39 | .setTable thead tr th:last-child,
40 | .setTable tbody tr td:last-child {
41 | padding-right: 14px;
42 | }
43 |
44 |
45 | /* Settings */
46 |
47 | table.editable tbody tr td.type-label {
48 | background: #f9fafa;
49 | }
50 |
51 | table.editable tbody tr td.type-label textarea {
52 | background: transparent;
53 | }
54 |
--------------------------------------------------------------------------------
/settable/templates/field.html:
--------------------------------------------------------------------------------
1 | {% import "_includes/forms" as forms %}
2 |
3 | {% includeCssResource 'settable/css/settable.css' %}
4 |
5 |
{{ col.heading ? col.heading : ' ' }} | 11 | {% endfor %} 12 |
---|
22 | {% if col.type == 'select' %} 23 | {{ forms.selectField({ 24 | class: 'small', 25 | id: cellName, 26 | name: cellName, 27 | options: col.options, 28 | value: value, 29 | }) }} 30 | {% elseif col.type == 'checkbox' %} 31 | {{ forms.checkboxField({ 32 | id: cellName, 33 | name: cellName, 34 | checked: value, 35 | }) }} 36 | {% elseif col.type == 'label' %} 37 | 38 | {{ value }} 39 | {% else %} 40 | {{ forms.textField({ 41 | id: cellName, 42 | name: cellName, 43 | value: value 44 | }) }} 45 | {% endif %} 46 | | 47 | {% endfor %} 48 |
{{ warning }}
29 | {% endif %} 30 | {% include "_includes/forms/errorList" with { errors: errors } %} 31 |