const CHECKBOX = 'checkbox';
const DATE = 'date';
const RADIO = 'radio';
+ const SELECT = 'select';
const TEXT = 'text';
const TEXTAREA = 'textarea';
*/
public function field($name, $settings = []) {
+ $field = $this->getField($name);
+ if (!$field) return false;
+
$default_settings = [
- 'hide_labels' => false,
- 'placeholder' => true,
+ 'class' => '',
+ 'title_class' => '',
+ 'input_class' => '',
+ 'show_title' => true,
+ 'show_labels' => true,
+ 'placeholder' => $field['title'],
+ 'field_before' => '',
+ 'field_after' => '',
];
-
$settings = array_merge($default_settings, $settings);
- $field = $this->getField($name);
- if (!$field) return false;
+ $res = '';
- $res = '<div class="form-field-title">'. $field['title'] .'</div>';
+ if ($settings['show_title']) {
+ $res .= '<div class="form-field-title '. $settings['title_class'] .'">'. $field['title'] .'</div>';
+ }
+
+ // Special input styling for checkbox / radio fields
+ if (in_array($field['type'], [self::BINARY, self::CHECKBOX, self::RADIO])) {
+ $settings['input_class'] .= ' custom-checkbox';
+ }
if (method_exists($this, $field['type'])) {
- $res .= '<div class="form-field-'. $field['type'] .'">';
+ $res .= '<div class="form-field-input form-field-'. $field['type'] .' '. $settings['input_class'] .'">';
+ $res .= $settings['field_before'];
$res .= $this->{$field['type']}($name, $settings);
+ $res .= $settings['field_after'];
$res .= '</div>';
} else {
$res .= 'Unrecognised field: '. $field['type'];
}
- return '<div class="form-field">'. $res .'</div>';
+ return '<div class="form-field '. $settings['class'] .'">'. $res .'</div>';
}
/**
$res .= '<label title="'. $option .'">';
$res .= '<input type="'. $type .'" name="'. $input_name .'" value="'. $option .'">';
- if (!$settings['hide_labels']) {
+ if ($settings['show_labels']) {
$res .= '<span class="form-label">'. $option .'</span>';
}
return $this->radio_or_checkbox($name, $settings, 'radio');
}
+ /**
+ * Textarea field
+ * @param $name
+ * @param $settings
+ * @return string
+ */
+ public function textarea($name, $settings) {
+ return '<textarea name="'. $name .'"></textarea>';
+ }
+
+ /**
+ * Text input field with placeholder
+ * @param $name
+ * @param $settings
+ * @return string
+ */
+ public function text($name, $settings) {
+ return '<input type="text" name="'. $name .'" placeholder="'. $settings['placeholder'] .'">';
+ }
+
+
+ /**
+ * Select box
+ * @param $name
+ * @param $settings
+ * @return string
+ */
+ public function select($name, $settings) {
+
+ $options = isset($settings['options']) ? $settings['options'] : $this->fields[$name]['options'];
+
+ $res = '<select name="'. $name .'">';
+ foreach ($options as $value => $label) {
+ $res .= '<option value="'. $value .'">'. $label .'</option>';
+ }
+ $res .= '</select>';
+
+ return $res;
+ }
+
/**
* Set multiple fields at once
{
function __construct() {
+ //== SYMPTOMS
$this->addField('main-problem', __('Problème principal', 'ccv'), self::RADIO,
[
__('Cervicales', 'ccv'),
$this->addField('date-pain-since', __('Douleurs permanentes depuis (le cas échéant) :', 'ccv'), self::DATE);
$this->addField('pain-arms-legs', __('Avez-vous des douleurs dans les bras ou les jambes (sciatiques, cruralgies, névralgies) ?', 'ccv'), self::BINARY);
+
$this->addField('pain-arms-legs-detail', __('Si oui, cochez les membres concernés :', 'ccv'), self::CHECKBOX,
[
__('Haut du bras gauche', 'ccv'),
]
);
+ $this->addField('main-pain', __('La douleur principale est-elle ?', 'ccv'), self::RADIO,
+ [
+ __('Dans la colonne', 'ccv'),
+ __('Dans les membres', 'ccv'),
+ __('Les deux', 'ccv'),
+ ]
+ );
+
+ $this->addField('tingling-numbness', __('Avez-vous des fourmillements ou une sensation d’engourdissement dans un des membres ? ', 'ccv'), self::BINARY);
+
+ $this->addField('tingling-numbness-date', __('Si oui depuis quand ?', 'ccv'), self::DATE);
+
+ $this->addField('strength-loss', __('Avez-vous une perte de force importante dans un des membres ?', 'ccv'), self::BINARY);
+
+ $this->addField('strength-loss-date', __('Si oui depuis quand ?', 'ccv'), self::DATE);
+
+ //=== TREATMENTS
+ $this->addField('medication', __('Indiquez ici les médicaments que vous avez pris pour vos douleurs (le cas échéant)', 'ccv'), self::TEXTAREA);
+
+ $this->addField('kine-osteo', __('Kinésithérapie ou ostéopathie', 'ccv'), self::BINARY);
+ $this->addField('corset', __('Corset ou ceinture lombaire', 'ccv'), self::BINARY);
+ $this->addField('hospitalisation', __('Séjour en hospitalisation', 'ccv'), self::BINARY);
+ $this->addField('infiltration', __('Infiltration ou thermocoagulation', 'ccv'), self::BINARY);
+
+ $this->addField('surgeries', __('Indiquez ici vos précédentes chirurgies de la colonne et leurs dates (le cas échéant)', 'ccv'), self::TEXTAREA);
+
+ //=== IMAGERY
+ $this->addField('imagery', __('Imagerie', 'ccv'), null); // This is a special case and will be output manually so only using this for the e-mail label
+
+ //=== PERSONAL INFORMATION
+ $this->addField('last-name', _x('Nom', 'Nom de famille', 'ccv'), self::TEXT);
+ $this->addField('first-name', __('Prénom', 'ccv'), self::TEXT);
+ $this->addField('profession', __('Profession', 'ccv'), self::TEXT);
+ $this->addField('city', __('Ville', 'ccv'), self::TEXT);
+ $this->addField('country', __('Pays', 'ccv'), self::TEXT);
+ $this->addField('phone', __('Tel', 'ccv'), self::TEXT);
+ $this->addField('email', __('Email', 'ccv'), self::TEXT);
+ $this->addField('sex', __('Sexe', 'ccv'), self::RADIO, [_x('M', 'Sexe (M)', 'ccv'), _x('F', 'Sexe (F)', 'ccv')]);
+ $this->addField('age', __('Âge :', 'ccv'), self::TEXT);
+ $this->addField('message', __('Avez vous un message (ou une demande) spécifique à nous formuler ?', 'ccv'), self::TEXTAREA);
+ $this->addField('surgeon', __('Chirurgien spécifique'), self::SELECT,
+ [
+ '' => __('Sélectionner'),
+ // TODO: figure out where this list should come from and what action is needed when a specific surgeon is selected
+ ]);
}
}
// Apply spacing between elements but not before first one
// Ref: https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/
-.spaced * + *
+.spaced > * + *
margin-top: 1.5em
+.spaced-horizontal > * + *
+ margin-left: 0.75em
// Generate utility classes for padding/margin based on vw units
// This will generate classes like pt-1v, pt-2v, pr-1v etc.
appearance: none
border: none
border-radius: 0
- padding: 0.5em 0
- border-bottom: 2px solid
+ padding: 0.25em 0
+ border-bottom: 1px solid
width: 100%
font-smoothing()
// background-size: 1em auto
textarea
- border: 2px solid theme('colors.dark')
+ border: 1px solid theme('colors.dark')
width: 100%
min-height: 200px
padding: 1em
.custom-checkbox
position: relative
- label
- &:before
+ .form-label:before,
+ .form-label-reversed:after
content: ''
display: inline-block
vertical-align: middle
width: 24px
height: @width
- margin-right: 0.5em
- border: 2px solid #000
+ border: 1px solid #000
background-color: #fff
- background-image: url("data:image/svg+xml,%3Csvg width='32' height='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.414 11L4 12.414l5.414 5.414L20.828 6.414 19.414 5l-10 10z' fill='%23fff' fill-rule='nonzero'/%3E%3C/svg%3E")
- background-repeat: no-repeat
- background-position: 20% 20%
+ box-shadow: inset 0 0 0 4px #fff // Inner border for checkbox
cursor: pointer
- input:checked ~ label
- &:before
- background-color: #000
- border-color: @background-color
+ .form-label:before
+ margin-right: 0.5em
+ .form-label-reversed:after
+ margin-left: 0.5em
+
+ input:checked ~ .form-label:before,
+ input:checked ~ .form-label-reversed:after
+ @apply bg-pink
input
position: absolute
// Common form styling
-.form-two-cols
+.form-field-title
+ font-weight: 400
+ margin-bottom: 0.5em
+
+.form-field-input
+ > *:not(:last-child)
+ margin-right: 1.5em
+
+ label
+ white-space: nowrap // Ensure text stays beside input control
+
+.form-cols-2, .form-cols-4
display: flex
flex-wrap: wrap
justify-content: space-between
+
+.form-cols-2
> *
flex-basis: 47%
+below(500px)
flex-basis: 100%
+ margin-bottom: 1.5em
+
+.form-cols-4
+ > *
+ flex-basis: 23%
+
+ +below(1100px)
+ flex-basis: 47%
+ margin-bottom: 1.5em
+ +below(500px)
+ flex-basis: 100%
// HTML Forms Plugin styling
{{-- CONSULTATION FORM --}}
+@php /* @var $form \Cube\Forms\Consultation */ @endphp
+
+{{--Todo: check out Tailwind forms: https://tailwindcss-custom-forms.netlify.com/ --}}
+{{--Todo: check visibleIf for ideas: https://www.useragentman.com/blog/2010/06/20/visibleif-html5-custom-data-attributes-with-javascript-make-dynamic-interactive-forms/--}}
+
+{{--
+LINKS
+
+https://www.smashingmagazine.com/2012/07/12-commandments-software-localization/
+https://www.cleverbridge.com/corporate/3-tips-to-localize-your-form-fields/
+
+https://parsleyjs.org/doc/#installation-localization
+https://github.com/flatpickr/flatpickr
+--}}
{{-- SYMPTOMS --}}
-<div class="bg-light py-2v pl-4v pr-3v">
+<div class="bg-light py-2v pl-4v pr-3v text-block-body">
<h2>{{ __('1. Vos symptômes') }}</h2>
- <ul>
- <li>{!! $form->field('main-problem') !!}</li>
- <li>{!! $form->field('date-first-symptoms') !!}</li>
- <li>{!! $form->field('date-pain-since') !!}</li>
- <li>{!! $form->field('pain-arms-legs') !!}</li>
- <li>{!! $form->field('pain-arms-legs-detail', ['hide_labels' => true]) !!}</li>
- </ul>
+ <div class="flex md:flex-wrap">
+
+ <ul class="spaced w-1/2 pr-1v md:w-full md:pr-0 md:mb-6">
+ <li>{!! $form->field('main-problem') !!}</li>
+ <li>{!! $form->field('date-first-symptoms', ['class' => 'flex items-center spaced-horizontal', 'title_class' => 'mb-0']) !!}</li>
+ <li>{!! $form->field('date-pain-since', ['class' => 'flex items-center spaced-horizontal', 'title_class' => 'mb-0']) !!}</li>
+ <li>{!! $form->field('pain-arms-legs') !!}</li>
+ <li>{!! $form->field('pain-arms-legs-detail') !!}</li>
+ </ul>
+
+ <ul class="spaced w-1/2 pl-1v md:w-full md:pl-0">
+ <li>{!! $form->field('main-pain') !!}</li>
+ <li>{!! $form->field('tingling-numbness') !!}</li>
+ <li>{!! $form->field('tingling-numbness-date', ['class' => 'flex items-center spaced-horizontal', 'title_class' => 'mb-0']) !!}</li>
+ <li>{!! $form->field('strength-loss') !!}</li>
+ <li>{!! $form->field('strength-loss-date', ['class' => 'flex items-center spaced-horizontal', 'title_class' => 'mb-0']) !!}</li>
+ </ul>
+
+ </div>
+
</div>
{{-- TREATMENTS --}}
<div class="bg-white py-2v pl-4v pr-3v">
<h2>{{ __('2. Vos traitements réalisés') }}</h2>
+
+ <div class="spaced">
+ {!! $form->field('medication') !!}
+
+ <div class="form-cols-4">
+ {!! $form->field('kine-osteo') !!}
+ {!! $form->field('corset') !!}
+ {!! $form->field('hospitalisation') !!}
+ {!! $form->field('infiltration') !!}
+ </div>
+
+ {!! $form->field('surgeries') !!}
+ </div>
+
</div>
{{-- IMAGERY --}}
{{-- CONTACT DETAILS --}}
<div class="bg-white py-2v pl-4v pr-3v">
<h2>{{ __('4. Vos informations') }}</h2>
+
+ <div class="form-cols-2">
+
+ <div class="spaced">
+ {!! $form->field('last-name', ['show_title' => false]) !!}
+ {!! $form->field('first-name', ['show_title' => false]) !!}
+ {!! $form->field('profession', ['show_title' => false]) !!}
+ {!! $form->field('city', ['show_title' => false]) !!}
+ {!! $form->field('country', ['show_title' => false]) !!}
+ {!! $form->field('phone', ['show_title' => false]) !!}
+ {!! $form->field('email', ['show_title' => false]) !!}
+ </div>
+
+ <div class="spaced">
+ {!! $form->field('sex', ['class' => 'flex items-center spaced-horizontal', 'title_class' => 'mb-0']) !!}
+ {!! $form->field('age', [
+ 'class' => 'flex items-center spaced-horizontal',
+ 'title_class' => 'mb-0',
+ 'input_class' => 'flex items-center w-16',
+ 'placeholder' => '',
+ 'field_after' => __('ans')
+ ]) !!}
+ {!! $form->field('message') !!}
+
+ <div class="mt-6">
+ <div class="custom-checkbox">
+ <label>
+ <input type="checkbox" name="send-to-team" value="{{ __('Oui') }}" checked class="ml-2">
+ <span class="form-label-reversed">{{ __("J'envoie ma demande à l'équipe du CCV", 'ccv') }}</span>
+ </label>
+ </div>
+ {{ __("ou je souhaite l'envoyer à un chirurgien spécifique :", 'ccv') }}
+ {!! $form->field('surgeon', ['show_title' => false]) !!}
+ </div>
+ </div>
+
+ </div>
+
+ <button class="btn block mt-1v ml-auto">{{ __('Envoyer votre demande') }}</button>
+
</div>