Skip to content
Snippets Groups Projects
Commit 3a86781d authored by David Suissa's avatar David Suissa
Browse files

Issue #3291229 by DYdate: Replaced 'bootstrap' specific display logic with...

Issue #3291229 by DYdate: Replaced 'bootstrap' specific display logic with simple stand-alone CSS. Simplified theming output by moving preprocessing function's logic to template file.
parent b7c4d9f2
Branches
Tags
No related merge requests found
bootstrap: false
field_types: []
\ No newline at end of file
field_types: []
......@@ -2,11 +2,8 @@ grid_field_formatter.settings:
type: config_object
label: "Setting for Grid Field Formatter module"
mapping:
bootstrap:
type: boolean
label: 'Enable Bootstrap compatibility'
field_types:
type: sequence
label: 'List of field types supporting Grid Field Formatter'
sequence:
- type: string
\ No newline at end of file
- type: string
@-ms-viewport {
width: device-width;
}
.visible-xs,
.visible-sm,
.visible-md,
.visible-lg {
display: none !important;
}
.visible-xs-block,
.visible-xs-inline,
.visible-xs-inline-block,
.visible-sm-block,
.visible-sm-inline,
.visible-sm-inline-block,
.visible-md-block,
.visible-md-inline,
.visible-md-inline-block,
.visible-lg-block,
.visible-lg-inline,
.visible-lg-inline-block {
display: none !important;
}
@media (max-width: 767px) {
.visible-xs {
display: block !important;
}
table.visible-xs {
display: table;
}
tr.visible-xs {
display: table-row !important;
}
th.visible-xs,
td.visible-xs {
display: table-cell !important;
}
}
@media (max-width: 767px) {
.visible-xs-block {
display: block !important;
}
}
@media (max-width: 767px) {
.visible-xs-inline {
display: inline !important;
}
}
@media (max-width: 767px) {
.visible-xs-inline-block {
display: inline-block !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm {
display: block !important;
}
table.visible-sm {
display: table;
}
tr.visible-sm {
display: table-row !important;
}
th.visible-sm,
td.visible-sm {
display: table-cell !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm-block {
display: block !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm-inline {
display: inline !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm-inline-block {
display: inline-block !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md {
display: block !important;
}
table.visible-md {
display: table;
}
tr.visible-md {
display: table-row !important;
}
th.visible-md,
td.visible-md {
display: table-cell !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md-block {
display: block !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md-inline {
display: inline !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md-inline-block {
display: inline-block !important;
}
}
@media (min-width: 1200px) {
.visible-lg {
display: block !important;
}
table.visible-lg {
display: table;
}
tr.visible-lg {
display: table-row !important;
}
th.visible-lg,
td.visible-lg {
display: table-cell !important;
}
}
@media (min-width: 1200px) {
.visible-lg-block {
display: block !important;
}
}
@media (min-width: 1200px) {
.visible-lg-inline {
display: inline !important;
}
}
@media (min-width: 1200px) {
.visible-lg-inline-block {
display: inline-block !important;
}
}
@media (max-width: 767px) {
.hidden-xs {
display: none !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.hidden-sm {
display: none !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
.hidden-md {
display: none !important;
}
}
@media (min-width: 1200px) {
.hidden-lg {
display: none !important;
}
}
.visible-print {
display: none !important;
}
@media print {
.visible-print {
display: block !important;
}
table.visible-print {
display: table;
}
tr.visible-print {
display: table-row !important;
}
th.visible-print,
td.visible-print {
display: table-cell !important;
}
}
.visible-print-block {
display: none !important;
}
@media print {
.visible-print-block {
display: block !important;
}
}
.visible-print-inline {
display: none !important;
}
@media print {
.visible-print-inline {
display: inline !important;
}
}
.visible-print-inline-block {
display: none !important;
}
@media print {
.visible-print-inline-block {
display: inline-block !important;
}
}
@media print {
.hidden-print {
display: none !important;
}
}
.container {
margin-right: auto;
margin-left: auto;
padding-left: 15px;
padding-right: 15px;
}
@media (min-width: 768px) {
.container {
width: 750px;
}
}
@media (min-width: 992px) {
.container {
width: 970px;
}
}
@media (min-width: 1200px) {
.container {
width: 1170px;
}
}
.container-fluid {
margin-right: auto;
margin-left: auto;
padding-left: 15px;
padding-right: 15px;
}
.row {
margin-left: -15px;
margin-right: -15px;
}
.col, .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
position: relative;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
}
.col, .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
float: left;
}
.col-xs-12 {
width: 100%;
}
.col-xs-11 {
width: 91.66666667%;
}
.col-xs-10 {
width: 83.33333333%;
}
.col-xs-9 {
width: 75%;
}
.col-xs-8 {
width: 66.66666667%;
}
.col-xs-7 {
width: 58.33333333%;
}
.col-xs-6 {
width: 50%;
}
.col-xs-5 {
width: 41.66666667%;
}
.col-xs-4 {
width: 33.33333333%;
}
.col-xs-3 {
width: 25%;
}
.col-xs-2 {
width: 16.66666667%;
}
.col-xs-1 {
width: 8.33333333%;
}
.col-xs-pull-12 {
right: 100%;
}
.col-xs-pull-11 {
right: 91.66666667%;
}
.col-xs-pull-10 {
right: 83.33333333%;
}
.col-xs-pull-9 {
right: 75%;
}
.col-xs-pull-8 {
right: 66.66666667%;
}
.col-xs-pull-7 {
right: 58.33333333%;
}
.col-xs-pull-6 {
right: 50%;
}
.col-xs-pull-5 {
right: 41.66666667%;
}
.col-xs-pull-4 {
right: 33.33333333%;
}
.col-xs-pull-3 {
right: 25%;
}
.col-xs-pull-2 {
right: 16.66666667%;
}
.col-xs-pull-1 {
right: 8.33333333%;
}
.col-xs-pull-0 {
right: auto;
}
.col-xs-push-12 {
left: 100%;
}
.col-xs-push-11 {
left: 91.66666667%;
}
.col-xs-push-10 {
left: 83.33333333%;
}
.col-xs-push-9 {
left: 75%;
}
.col-xs-push-8 {
left: 66.66666667%;
}
.col-xs-push-7 {
left: 58.33333333%;
}
.col-xs-push-6 {
left: 50%;
}
.col-xs-push-5 {
left: 41.66666667%;
}
.col-xs-push-4 {
left: 33.33333333%;
}
.col-xs-push-3 {
left: 25%;
}
.col-xs-push-2 {
left: 16.66666667%;
}
.col-xs-push-1 {
left: 8.33333333%;
}
.col-xs-push-0 {
left: auto;
}
.col-xs-offset-12 {
margin-left: 100%;
}
.col-xs-offset-11 {
margin-left: 91.66666667%;
}
.col-xs-offset-10 {
margin-left: 83.33333333%;
}
.col-xs-offset-9 {
margin-left: 75%;
}
.col-xs-offset-8 {
margin-left: 66.66666667%;
}
.col-xs-offset-7 {
margin-left: 58.33333333%;
}
.col-xs-offset-6 {
margin-left: 50%;
}
.col-xs-offset-5 {
margin-left: 41.66666667%;
}
.col-xs-offset-4 {
margin-left: 33.33333333%;
}
.col-xs-offset-3 {
margin-left: 25%;
}
.col-xs-offset-2 {
margin-left: 16.66666667%;
}
.col-xs-offset-1 {
margin-left: 8.33333333%;
}
.col-xs-offset-0 {
margin-left: 0%;
}
@media (min-width: 768px) {
.col, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
float: left;
}
.col-sm-12 {
width: 100%;
}
.col-sm-11 {
width: 91.66666667%;
}
.col-sm-10 {
width: 83.33333333%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-8 {
width: 66.66666667%;
}
.col-sm-7 {
width: 58.33333333%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-5 {
width: 41.66666667%;
}
.col-sm-4 {
width: 33.33333333%;
}
.col-sm-3 {
width: 25%;
}
.col-sm-2 {
width: 16.66666667%;
}
.col-sm-1 {
width: 8.33333333%;
}
.col-sm-pull-12 {
right: 100%;
}
.col-sm-pull-11 {
right: 91.66666667%;
}
.col-sm-pull-10 {
right: 83.33333333%;
}
.col-sm-pull-9 {
right: 75%;
}
.col-sm-pull-8 {
right: 66.66666667%;
}
.col-sm-pull-7 {
right: 58.33333333%;
}
.col-sm-pull-6 {
right: 50%;
}
.col-sm-pull-5 {
right: 41.66666667%;
}
.col-sm-pull-4 {
right: 33.33333333%;
}
.col-sm-pull-3 {
right: 25%;
}
.col-sm-pull-2 {
right: 16.66666667%;
}
.col-sm-pull-1 {
right: 8.33333333%;
}
.col-sm-pull-0 {
right: auto;
}
.col-sm-push-12 {
left: 100%;
}
.col-sm-push-11 {
left: 91.66666667%;
}
.col-sm-push-10 {
left: 83.33333333%;
}
.col-sm-push-9 {
left: 75%;
}
.col-sm-push-8 {
left: 66.66666667%;
}
.col-sm-push-7 {
left: 58.33333333%;
}
.col-sm-push-6 {
left: 50%;
}
.col-sm-push-5 {
left: 41.66666667%;
}
.col-sm-push-4 {
left: 33.33333333%;
}
.col-sm-push-3 {
left: 25%;
}
.col-sm-push-2 {
left: 16.66666667%;
}
.col-sm-push-1 {
left: 8.33333333%;
}
.col-sm-push-0 {
left: auto;
}
.col-sm-offset-12 {
margin-left: 100%;
}
.col-sm-offset-11 {
margin-left: 91.66666667%;
}
.col-sm-offset-10 {
margin-left: 83.33333333%;
}
.col-sm-offset-9 {
margin-left: 75%;
}
.col-sm-offset-8 {
margin-left: 66.66666667%;
}
.col-sm-offset-7 {
margin-left: 58.33333333%;
}
.col-sm-offset-6 {
margin-left: 50%;
}
.col-sm-offset-5 {
margin-left: 41.66666667%;
}
.col-sm-offset-4 {
margin-left: 33.33333333%;
}
.col-sm-offset-3 {
margin-left: 25%;
}
.col-sm-offset-2 {
margin-left: 16.66666667%;
}
.col-sm-offset-1 {
margin-left: 8.33333333%;
}
.col-sm-offset-0 {
margin-left: 0%;
}
}
@media (min-width: 992px) {
.col, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
float: left;
}
.col-md-12 {
width: 100%;
}
.col-md-11 {
width: 91.66666667%;
}
.col-md-10 {
width: 83.33333333%;
}
.col-md-9 {
width: 75%;
}
.col-md-8 {
width: 66.66666667%;
}
.col-md-7 {
width: 58.33333333%;
}
.col-md-6 {
width: 50%;
}
.col-md-5 {
width: 41.66666667%;
}
.col-md-4 {
width: 33.33333333%;
}
.col-md-3 {
width: 25%;
}
.col-md-2 {
width: 16.66666667%;
}
.col-md-1 {
width: 8.33333333%;
}
.col-md-pull-12 {
right: 100%;
}
.col-md-pull-11 {
right: 91.66666667%;
}
.col-md-pull-10 {
right: 83.33333333%;
}
.col-md-pull-9 {
right: 75%;
}
.col-md-pull-8 {
right: 66.66666667%;
}
.col-md-pull-7 {
right: 58.33333333%;
}
.col-md-pull-6 {
right: 50%;
}
.col-md-pull-5 {
right: 41.66666667%;
}
.col-md-pull-4 {
right: 33.33333333%;
}
.col-md-pull-3 {
right: 25%;
}
.col-md-pull-2 {
right: 16.66666667%;
}
.col-md-pull-1 {
right: 8.33333333%;
}
.col-md-pull-0 {
right: auto;
}
.col-md-push-12 {
left: 100%;
}
.col-md-push-11 {
left: 91.66666667%;
}
.col-md-push-10 {
left: 83.33333333%;
}
.col-md-push-9 {
left: 75%;
}
.col-md-push-8 {
left: 66.66666667%;
}
.col-md-push-7 {
left: 58.33333333%;
}
.col-md-push-6 {
left: 50%;
}
.col-md-push-5 {
left: 41.66666667%;
}
.col-md-push-4 {
left: 33.33333333%;
}
.col-md-push-3 {
left: 25%;
}
.col-md-push-2 {
left: 16.66666667%;
}
.col-md-push-1 {
left: 8.33333333%;
}
.col-md-push-0 {
left: auto;
}
.col-md-offset-12 {
margin-left: 100%;
}
.col-md-offset-11 {
margin-left: 91.66666667%;
}
.col-md-offset-10 {
margin-left: 83.33333333%;
}
.col-md-offset-9 {
margin-left: 75%;
}
.col-md-offset-8 {
margin-left: 66.66666667%;
}
.col-md-offset-7 {
margin-left: 58.33333333%;
}
.col-md-offset-6 {
margin-left: 50%;
}
.col-md-offset-5 {
margin-left: 41.66666667%;
}
.col-md-offset-4 {
margin-left: 33.33333333%;
}
.col-md-offset-3 {
margin-left: 25%;
}
.col-md-offset-2 {
margin-left: 16.66666667%;
}
.col-md-offset-1 {
margin-left: 8.33333333%;
}
.col-md-offset-0 {
margin-left: 0%;
}
}
@media (min-width: 1200px) {
.col, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
float: left;
}
.col-lg-12 {
width: 100%;
}
.col-lg-11 {
width: 91.66666667%;
}
.col-lg-10 {
width: 83.33333333%;
}
.col-lg-9 {
width: 75%;
}
.col-lg-8 {
width: 66.66666667%;
}
.col-lg-7 {
width: 58.33333333%;
}
.col-lg-6 {
width: 50%;
}
.col-lg-5 {
width: 41.66666667%;
}
.col-lg-4 {
width: 33.33333333%;
}
.col-lg-3 {
width: 25%;
}
.col-lg-2 {
width: 16.66666667%;
}
.col-lg-1 {
width: 8.33333333%;
}
.col-lg-pull-12 {
right: 100%;
}
.col-lg-pull-11 {
right: 91.66666667%;
}
.col-lg-pull-10 {
right: 83.33333333%;
}
.col-lg-pull-9 {
right: 75%;
}
.col-lg-pull-8 {
right: 66.66666667%;
}
.col-lg-pull-7 {
right: 58.33333333%;
}
.col-lg-pull-6 {
right: 50%;
}
.col-lg-pull-5 {
right: 41.66666667%;
}
.col-lg-pull-4 {
right: 33.33333333%;
}
.col-lg-pull-3 {
right: 25%;
}
.col-lg-pull-2 {
right: 16.66666667%;
}
.col-lg-pull-1 {
right: 8.33333333%;
}
.col-lg-pull-0 {
right: auto;
}
.col-lg-push-12 {
left: 100%;
}
.col-lg-push-11 {
left: 91.66666667%;
}
.col-lg-push-10 {
left: 83.33333333%;
}
.col-lg-push-9 {
left: 75%;
}
.col-lg-push-8 {
left: 66.66666667%;
}
.col-lg-push-7 {
left: 58.33333333%;
}
.col-lg-push-6 {
left: 50%;
}
.col-lg-push-5 {
left: 41.66666667%;
}
.col-lg-push-4 {
left: 33.33333333%;
}
.col-lg-push-3 {
left: 25%;
}
.col-lg-push-2 {
left: 16.66666667%;
}
.col-lg-push-1 {
left: 8.33333333%;
}
.col-lg-push-0 {
left: auto;
}
.col-lg-offset-12 {
margin-left: 100%;
}
.col-lg-offset-11 {
margin-left: 91.66666667%;
}
.col-lg-offset-10 {
margin-left: 83.33333333%;
}
.col-lg-offset-9 {
margin-left: 75%;
}
.col-lg-offset-8 {
margin-left: 66.66666667%;
}
.col-lg-offset-7 {
margin-left: 58.33333333%;
}
.col-lg-offset-6 {
margin-left: 50%;
}
.col-lg-offset-5 {
margin-left: 41.66666667%;
}
.col-lg-offset-4 {
margin-left: 33.33333333%;
}
.col-lg-offset-3 {
margin-left: 25%;
}
.col-lg-offset-2 {
margin-left: 16.66666667%;
}
.col-lg-offset-1 {
margin-left: 8.33333333%;
}
.col-lg-offset-0 {
margin-left: 0%;
}
}
.clearfix,
.clearfix:before,
.clearfix:after,
.container:before,
.container:after,
.container-fluid:before,
.container-fluid:after,
.row:before,
.row:after {
content: " ";
display: table;
}
.clearfix:after,
.container:after,
.container-fluid:after,
.row:after {
clear: both;
}
.center-block {
display: block;
margin-left: auto;
margin-right: auto;
}
.pull-right {
float: right !important;
}
.pull-left {
float: left !important;
}
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/**
* @file
* Required CSS styles to display a responsive HTML table with 'div' tags.
*/
/* .resp-table: table */
.grid-field-formatter .resp-table {
display: table;
margin: 10px 0;
width: 100%;
}
/* .resp-table-body: tbody */
.grid-field-formatter .resp-table-body {
display: table-row-group;
}
/* .resp-table-row: tr */
.grid-field-formatter .resp-table-row {
display: table-row;
background: rgba(0, 0, 0, 0.063);
padding: 0.1em 0.6em;
}
/* .table-body-cell: td */
.grid-field-formatter .table-body-cell{
display: table-cell;
border: 1px solid #fff;
text-align: left;
padding: 4px 9px;
}
grid_field_formatter:
responsive-div-table:
version: VERSION
css:
component:
css/grid12.css: {}
css/responsive-div-table.css: {}
<?php
/**
* @file
* Module that gives you a field formatter, which enables field layout with
* Grid contents to a destination.
*/
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FormatterInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Template\Attribute;
define('GRID_FIELD_FORMATTER_DEFAULT_COLUMNS', 1);
/**
* Implements hook_field_formatter_third_party_settings_form().
*/
function grid_field_formatter_field_formatter_third_party_settings_form(FormatterInterface $plugin, FieldDefinitionInterface $field_definition, $view_mode, $form, FormStateInterface $form_state) {
$element = [];
// Add Grid Field Formatter if matching an enabled field type.
if (grid_field_formatter_is_eligible($field_definition)) {
$default_values = $plugin->getThirdPartySetting('grid_field_formatter', 'grid_field_formatter');
$element['grid_field_formatter'] = [
'#type' => 'container',
'#attributes' => ['class' => ['grided-field-wrapper']],
];
// Add a checkbox to the formatter settings form to enabled a grid layout.
$element['grid_field_formatter']['grid_enable'] = [
'#title' => t('Enable multi-value field display with a grid layout.'),
'#type' => 'checkbox',
'#default_value' => isset($default_values['grid_enable']) ? $default_values['grid_enable'] : NULL,
];
// Add a conditional text field for the number of columns of the grid.
$element['grid_field_formatter']['columns'] = [
'#title' => t('Grid layout number of columns'),
'#type' => 'textfield',
'#default_value' => isset($default_values['columns']) ? $default_values['columns'] : GRID_FIELD_FORMATTER_DEFAULT_COLUMNS,
'#description' => t('Enter the number of columns for each row for the grid table layout.'),
'#element_validate' => ['grid_field_formatter_element_validate_columns'],
'#states' => [
'visible' => [
'input[name$="[grid_field_formatter][grid_field_formatter][grid_enable]"]' => ['checked' => TRUE],
],
],
];
}
return $element;
}
/**
* Form element validation handler for columns field in settings form.
*/
function grid_field_formatter_element_validate_columns($element, FormStateInterface $form_state) {
$value = $element['#value'];
// The number of columns must be valid number and between 1 and 12.
if (!(is_numeric($value) && $value > 0 && $value < 13)) {
$form_state->setError($element, t('The number of columns must be valid number and between 1 and 12.'));
}
}
/**
* Implements hook_field_formatter_settings_summary_alter().
*/
function grid_field_formatter_field_formatter_settings_summary_alter(&$summary, $context) {
if (grid_field_formatter_is_eligible($context['field_definition'])) {
$settings = $context['formatter']->getThirdPartySetting('grid_field_formatter', 'grid_field_formatter');
if (isset($settings['grid_enable']) && $settings['grid_enable']) {
$summary[] = t('Multi-value Grid display: enabled');
$summary[] = t('Number of columns: @columns', ['@columns' => $settings['columns']]);
}
}
}
/**
* Implements hook_entity_display_build_alter().
*/
function grid_field_formatter_entity_display_build_alter(&$build, $context) {
$entity = $context['entity'];
// Only act on content entities.
if (!($entity instanceof FieldableEntityInterface)) {
return;
}
// Append RDF term mappings on displayed taxonomy links.
foreach (Element::children($build) as $field_name) {
$field = &$build[$field_name];
$field_definition = $entity->getFieldDefinition($field_name);
// If the field has no value to display or is not eligible, skip processing.
if (!empty($field['#items']) && grid_field_formatter_is_eligible($field_definition)) {
// Get the field formatter settings.
$entity_display = EntityViewDisplay::collectRenderDisplay($entity, $context['view_mode']);
$field_display = $entity_display->getComponent($field_name);
// Get Grid Field Formatter settings.
$grid_enabled = isset($field_display['third_party_settings']['grid_field_formatter']['grid_field_formatter']['grid_enable']) ? $field_display['third_party_settings']['grid_field_formatter']['grid_field_formatter']['grid_enable'] : FALSE;
$columns = isset($field_display['third_party_settings']['grid_field_formatter']['grid_field_formatter']['columns']) ? $field_display['third_party_settings']['grid_field_formatter']['grid_field_formatter']['columns'] : GRID_FIELD_FORMATTER_DEFAULT_COLUMNS;
if ($grid_enabled) {
$field['#theme'] = 'grid_field_formatter';
$field['#columns'] = $columns;
}
}
}
}
/**
* Theme preprocess function for grid_field_formatter.
*
* This function essentially extends the core field module theming methods, in
* particular template_preprocess_field. It also introduces new field template
* suggestions such as:
* - grid-field-formatter.tpl.php
* - grid-field-formatter--[FIELD_TYPE].tpl.php
* - grid-field-formatter--[FIELD_NAME].tpl.php
* - grid-field-formatter--[FIELD_NAME]--[BUNDLE].tpl.php
*
* @see grid-field-formatter.tpl.php
*/
function template_preprocess_grid_field_formatter(&$variables, $hook) {
// Extend the core field module theming functions.
template_preprocess_field($variables, $hook);
// Add colummns number.
$number_of_columns = $variables['element']['#columns'];
$variables['columns'] = $number_of_columns;
// Build row attributes.
$variables['row_attributes'] = new Attribute([
'class' => ['row'],
]);
// Build column layout number.
$variables['column_layout'] = floor(12 / $number_of_columns);
// Add Grid Field Formatter css if bootstrap is not enabled.
$bootstrap_enabled = \Drupal::config('grid_field_formatter.settings')->get('bootstrap');
if (!$bootstrap_enabled) {
$variables['#attached']['library'][] = 'grid_field_formatter/grid_field_formatter';
}
}
/**
* Implements hook_theme_suggestions_HOOK().
*/
function grid_field_formatter_theme_suggestions_grid_field_formatter(array $variables) {
$suggestions = array();
$element = $variables['element'];
$suggestions[] = 'grid_field_formatter__' . $element['#field_type'];
$suggestions[] = 'grid_field_formatter__' . $element['#field_name'];
$suggestions[] = 'grid_field_formatter__' . $element['#entity_type'] . '__' . $element['#bundle'];
$suggestions[] = 'grid_field_formatter__' . $element['#entity_type'] . '__' . $element['#field_name'];
$suggestions[] = 'grid_field_formatter__' . $element['#entity_type'] . '__' . $element['#field_name'] . '__' . $element['#bundle'];
return $suggestions;
}
/**
* Check if the given field is eligible to Grid Field Formatter options.
*/
function grid_field_formatter_is_eligible(FieldDefinitionInterface $field_definition) {
// Grid Field Formatter is useless on single value fields.
if ($field_definition->getFieldStorageDefinition()->getCardinality() == 1) {
return FALSE;
}
// Get the Grid Field Formatter enabled field types.
$field_types = \Drupal::config('grid_field_formatter.settings')->get('field_types');
// Add Grid Field Formatter if matching an enabled field type.
if ($field_types[$field_definition->getType()] != $field_definition->getType()) {
// Check preconfigured fields.
$field_type_class = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_definition->getType())['class'];
if (is_subclass_of($field_type_class, '\Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface')) {
foreach ($field_type_class::getPreconfiguredOptions() as $key => $option) {
if ($field_types['field_ui:' . $field_definition->getType() . ':' . $key]) {
return TRUE;
}
}
}
return FALSE;
}
return TRUE;
}
/**
* Implements hook_theme().
*/
function grid_field_formatter_theme() {
return [
'grid_field_formatter' => [
'render element' => 'element',
],
];
}
<?php
/**
* @file
* Module that gives you a field formatter, which enables field layout with
* Grid contents to a destination.
*/
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FormatterInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Template\Attribute;
define('GRID_FIELD_FORMATTER_DEFAULT_COLUMNS', 1);
/**
* Implements hook_field_formatter_third_party_settings_form().
*/
function grid_field_formatter_field_formatter_third_party_settings_form(FormatterInterface $plugin, FieldDefinitionInterface $field_definition, $view_mode, $form, FormStateInterface $form_state) {
$element = [];
// Add Grid Field Formatter if matching an enabled field type.
if (grid_field_formatter_is_eligible($field_definition)) {
$default_values = $plugin->getThirdPartySetting('grid_field_formatter', 'grid_field_formatter');
$element['grid_field_formatter'] = [
'#type' => 'container',
'#attributes' => ['class' => ['grided-field-wrapper']],
];
// Add a checkbox to the formatter settings form to enabled a grid layout.
$element['grid_field_formatter']['grid_enable'] = [
'#title' => t('Enable multi-value field display with a grid layout.'),
'#type' => 'checkbox',
'#default_value' => isset($default_values['grid_enable']) ? $default_values['grid_enable'] : NULL,
];
// Add a conditional text field for the number of columns of the grid.
$element['grid_field_formatter']['columns'] = [
'#title' => t('Grid layout number of columns'),
'#type' => 'textfield',
'#default_value' => isset($default_values['columns']) ? $default_values['columns'] : GRID_FIELD_FORMATTER_DEFAULT_COLUMNS,
'#description' => t('Enter the number of columns for each row for the grid table layout.'),
'#element_validate' => ['grid_field_formatter_element_validate_columns'],
'#states' => [
'visible' => [
'input[name$="[grid_field_formatter][grid_field_formatter][grid_enable]"]' => ['checked' => TRUE],
],
],
];
}
return $element;
}
/**
* Form element validation handler for columns field in settings form.
*/
function grid_field_formatter_element_validate_columns($element, FormStateInterface $form_state) {
$value = $element['#value'];
// The number of columns must be a valid number and greater than 0.
if (!(is_numeric($value) && $value > 0)) {
$form_state->setError($element, t('The number of columns must be valid number and greater than 0.'));
}
}
/**
* Implements hook_field_formatter_settings_summary_alter().
*/
function grid_field_formatter_field_formatter_settings_summary_alter(&$summary, $context) {
if (grid_field_formatter_is_eligible($context['field_definition'])) {
$settings = $context['formatter']->getThirdPartySetting('grid_field_formatter', 'grid_field_formatter');
if (isset($settings['grid_enable']) && $settings['grid_enable']) {
$summary[] = t('Multi-value Grid display: enabled');
$summary[] = t('Number of columns: @columns', ['@columns' => $settings['columns']]);
}
}
}
/**
* Implements hook_entity_display_build_alter().
*/
function grid_field_formatter_entity_display_build_alter(&$build, $context) {
$entity = $context['entity'];
// Only act on content entities.
if (!($entity instanceof FieldableEntityInterface)) {
return;
}
// Append RDF term mappings on displayed taxonomy links.
foreach (Element::children($build) as $field_name) {
$field = &$build[$field_name];
$field_definition = $entity->getFieldDefinition($field_name);
// If the field has no value to display or is not eligible, skip processing.
if (!empty($field['#items']) && grid_field_formatter_is_eligible($field_definition)) {
// Get the field formatter settings.
$entity_display = EntityViewDisplay::collectRenderDisplay($entity, $context['view_mode']);
$field_display = $entity_display->getComponent($field_name);
// Get Grid Field Formatter settings.
$grid_enabled = isset($field_display['third_party_settings']['grid_field_formatter']['grid_field_formatter']['grid_enable']) ? $field_display['third_party_settings']['grid_field_formatter']['grid_field_formatter']['grid_enable'] : FALSE;
$columns = isset($field_display['third_party_settings']['grid_field_formatter']['grid_field_formatter']['columns']) ? $field_display['third_party_settings']['grid_field_formatter']['grid_field_formatter']['columns'] : GRID_FIELD_FORMATTER_DEFAULT_COLUMNS;
if ($grid_enabled) {
// Override theming output with module's template.
$field['#theme'] = 'grid_field_formatter';
$field['#columns'] = $columns;
// Ensure module's CSS library is loaded.
$field['#attached']['library'][] = 'grid_field_formatter/responsive-div-table';
}
}
}
}
/**
* Implements hook_theme_suggestions_HOOK().
*/
function grid_field_formatter_theme_suggestions_grid_field_formatter(array $variables) {
$suggestions = array();
$element = $variables['element'];
$suggestions[] = 'grid_field_formatter__' . $element['#field_type'];
$suggestions[] = 'grid_field_formatter__' . $element['#field_name'];
$suggestions[] = 'grid_field_formatter__' . $element['#entity_type'] . '__' . $element['#bundle'];
$suggestions[] = 'grid_field_formatter__' . $element['#entity_type'] . '__' . $element['#field_name'];
$suggestions[] = 'grid_field_formatter__' . $element['#entity_type'] . '__' . $element['#field_name'] . '__' . $element['#bundle'];
return $suggestions;
}
/**
* Check if the given field is eligible to Grid Field Formatter options.
*/
function grid_field_formatter_is_eligible(FieldDefinitionInterface $field_definition) {
// Grid Field Formatter is useless on single value fields.
if ($field_definition->getFieldStorageDefinition()->getCardinality() == 1) {
return FALSE;
}
// Get the Grid Field Formatter enabled field types.
$field_types = \Drupal::config('grid_field_formatter.settings')->get('field_types');
// Add Grid Field Formatter if matching an enabled field type.
if ($field_types[$field_definition->getType()] != $field_definition->getType()) {
// Check preconfigured fields.
$field_type_class = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_definition->getType())['class'];
if (is_subclass_of($field_type_class, '\Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface')) {
foreach ($field_type_class::getPreconfiguredOptions() as $key => $option) {
if ($field_types['field_ui:' . $field_definition->getType() . ':' . $key]) {
return TRUE;
}
}
}
return FALSE;
}
return TRUE;
}
/**
* Implements hook_theme().
*/
function grid_field_formatter_theme() {
return [
'grid_field_formatter' => [
// Extend core field module's theming functions.
'base hook' => 'field',
],
];
}
......@@ -2,14 +2,12 @@
namespace Drupal\grid_field_formatter\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Settings form for Grid Field Formatter module.
*/
......@@ -73,19 +71,12 @@ class GridFieldFormatterSettingsForm extends ConfigFormBase {
$field_type_options[$name] = $field_type['label'];
}
$form['bootstrap'] = array(
'#title' => $this->t('Enable Bootstrap compatibility.'),
'#type' => 'checkbox',
'#description' => $this->t('If uncheck, Grid Field Formatter will add some custom CSS. Check this if your theme or a module of your site loads Bootstrap CSS.'),
'#default_value' => $config->get('bootstrap'),
);
$form['field_types'] = array(
$form['field_types'] = [
'#title' => $this->t('Please select the field type for which Grid Field Formatter should be available.'),
'#type' => 'checkboxes',
'#options' => $field_type_options,
'#default_value' => $config->get('field_types'),
);
];
return parent::buildForm($form, $form_state);
}
......@@ -96,7 +87,6 @@ class GridFieldFormatterSettingsForm extends ConfigFormBase {
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('grid_field_formatter.settings');
$config->set('field_types', $form_state->getValue('field_types'));
$config->set('bootstrap', $form_state->getValue('bootstrap'));
$config->save();
}
......
......@@ -33,12 +33,6 @@
* - field_type: The type of the field.
* - label_display: The display settings for the label.
*
* Added with specific ones from Grid Field Formatter:
* - columns: the number of columns of the grid.
* - row_attributes: attributes for the row.
* - column_layout number: based on the bootstrap 12 layout grid system, the
* number of columns size for a single item.
*
* @see template_preprocess_grid_field_formatter()
* @see template_preprocess_field()
*
......@@ -46,6 +40,10 @@
*/
#}
{# Get the number of columns from element's render array '#columns' property. #}
{# See preferred syntax in issue #2160611. #}
{% set number_of_columns = attribute(element, '#columns') %}
{%
set title_classes = [
'field__label',
......@@ -55,6 +53,7 @@
{%
set classes = [
'grid-field-formatter',
'container-fluid',
'field',
'field--name-' ~ field_name|clean_class,
......@@ -63,15 +62,16 @@
]
%}
{%
set row_classes = [
{# Create empty attribute and assign it row classes. #}
{% set row_attributes = create_attribute().addClass([
'resp-table-row',
'field__items',
]
])
%}
{%
set column_classes = [
'col-sm-' ~ column_layout,
'table-body-cell',
'field__item',
]
%}
......@@ -81,11 +81,15 @@
<div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
{% endif %}
{% for row in items|batch(columns) %}
<div{{ row_attributes.addClass(row_classes) }}>
{% for item in row %}
<div{{ item.attributes.addClass(column_classes) }}>{{ item.content }}</div>
<div class="resp-table">
<div class="resp-table-body">
{% for row in items|batch(number_of_columns) %}
<div{{ row_attributes }}>
{% for item in row %}
<div{{ item.attributes.addClass(column_classes) }}>{{ item.content }}</div>
{% endfor %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
\ No newline at end of file
</div>
</div>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment