Need help with checkbox customization

Hi!
I’m searching for help with checkbox customization.
Now by default Grav displays checkboxes with this markup:

<div class="form-field form-group ">
    <div class="form-label-wrapper"><label class="form-label">3</label></div>
	<div class="form-data" data-grav-field="text" data-grav-disabled="" data-grav-default="[&quot;option1&quot;,&quot;option2&quot;]">
		<div class="form-input-wrapper ">
			<input name="data[3]" value="option1,option2" type="text" class="form-input custom-checkboxes ">
		</div>
	</div>
</div>

The default code is used:

  my_field:
  type: checkboxes
  label: false
default:
  - option1
  - option2
options:
  option1: Option 1
  option2: Option 2		
classes: custom-checkboxes
While I need completely different markup:

<div class="fields-group-head">
	<h3>Pre-heading</h3>
</div>

<div class="fields-group-controls custom-checkboxes">

	<div class="type-selection type-selection form-group col-md-4 col-sm-12" data-delay="3">
		<input type="checkbox" name="planner_project_type_checkbox" id="bio" value="Text value ONE">
		<label for="web" class="icon-web">Web OPTION</label>
	</div>

	<div class="type-selection type-selection form-group col-md-4 col-sm-12" data-delay="4">
		<input type="checkbox" name="planner_project_type_checkbox" id="geo" value="Text value TWO">
		<label for="graphic" class="icon-graphic">graphic option</label>
	</div>

</div>

How this could be achieved?

@01K, A remark and a kind request…

Remark:

  • You said:

    Now by default Grav displays checkboxes with this markup:

    • When I use your field definition I get a totally different HTML layout. By default I mean, a fresh Grav 1.7.30, Quark and the Form plugin. Which theme are you using?
    • Also your code is showing an <input> field with "type="text" while the Form plugin would create a field with type="checkbox". What changes have you made to plugin Form or the theme’s templates?

Kind request:
Help the community help you, by creating clear and concise questions. Show you have put effort into the question to save peoples time and effort, .

  • Instead of letting the community figure out what you are trying to achieve by comparing your code with default code generated by the form, would you mind sharing what you are trying to achieve in simple goals. For example:
    • I want a group of checkboxes layout according this picture…
    • I want the field names…
    • I want each checkbox wrapped in…
    • I want classes to be…
  • And please show you have tried to solve the question yourself first.
    What have you tried and with what result?

I like coding, but I don’t like interpreting other peoples code trying to figure out what they want.

When I use your field definition I get a totally different HTML layout. By default I mean, a fresh Grav 1.7.30, Quark and the Form plugin. Which theme are you using?

I use the Hola theme, overridden and heavily modificated, only certain parts of CSS has left.
In the default theme folder, there are no form folder or other overridden templates.
In my child theme folder I haven’t made any form template modifications.

Truly I’ve tried to override checkboxes.html.twig. I’ve copied the checkboxes.html.twig file into the child-theme\templates\forms\fields\checkboxes\checkboxes.html.twig but it seems that this template file is not responsible for displayed fields

I’ve used this .md code for a test to create checkboxes and check how they will be rendered:

  my_field:
  type: checkboxes
  label: false
default:
  - option1
  - option2
options:
  option1: Option 1
  option2: Option 2		
classes: custom-checkboxes

what you are trying to achieve in simple goals

I have a html based website with a contact form and I’m trying to transfer it to Grav CMS.
The part of the contact form consists of checkboxes, in plain html file it looks like I have demonstrated earlier:

<form action="#" method="post" id="c-form" class="col-md-12" enctype="multipart/form-data">
<div class="fields-group clearfix">
...

<div class="fields-group-head">
	<h3>Pre-heading</h3>
</div>

<div class="fields-group-controls custom-checkboxes">

	<div class="type-selection type-selection form-group col-md-4 col-sm-12" data-delay="3">
		<input type="checkbox" name="planner_project_type_checkbox" id="bio" value="Text value ONE">
		<label for="web" class="icon-web">Web OPTION</label>
	</div>

	<div class="type-selection type-selection form-group col-md-4 col-sm-12" data-delay="4">
		<input type="checkbox" name="planner_project_type_checkbox" id="geo" value="Text value TWO">
		<label for="graphic" class="icon-graphic">graphic option</label>
	</div>

</div>

...
</div>
</form>

It’s a group which is wrapped into a div with CSS classes. data-delay could be omitted.

Each checkbox is wrapped into a div with CSS class names, input field have its name, custom id and text value.
Labels with custom for attribute, custom class and value.

If I have skipped something - please ask me.
Thanks!

@01K,

Truly I’ve tried to override checkboxes.html.twig . I’ve copied the checkboxes.html.twig file into the child-theme\templates\forms\fields\checkboxes\checkboxes.html.twig but it seems that this template file is not responsible for displayed fields

Based on which observation does this seem to be the case?

I’ve been trying to manipulate the code inside child-theme\templates\forms\fields\checkboxes\checkboxes.html.twig, changing HTML code, pasting a text values, but as a result nothing was changing in display results :confused:

@01K, You’re not really showing what changes you have made and what HTML has been generated. That means I cannot reproduce your case, and therefor I cannot see where anything might have gone wrong on your side.

Please help us helping you by giving precise and succinct information. Not only coding requires specificity and accuracy, questions do too.

I’ll have to resort to my own observations instead…

When I:

  • Create a child theme of Quark named ‘quark-child’
  • Copy user/plugins/form/templates/forms/fields/checkboxes/checkboxes.html.twig into user/themes/quark-child/templates/forms/fields/checkboxes/checkboxes.html.twig
  • Change line 25 in copied file into:
    <input xxx type="checkbox"
    
  • Then a page with a form with the following definition:
    form:
      name: myform
      fields:
        myfield:
          type: checkboxes
          options:
            option1: Option 1
            option2: Option 2
    
    generates the following HTML for the checkbox field:
    <input xxx="" type="checkbox" id="myfield-option1" value="option1" name="data[myfield][myfield-option1]" class="form-checkbox ">
    

According to my observation, it seems template user/themes/quark-child/templates/forms/fields/checkboxes/checkboxes.html.twig does generate the checkboxes…

I’ve made a step further. On a fresh Grav installation.
Firstly I’ve copied checkboxes.html.twig from Git repo. and placed it into

  • into user/themes/quark-child/templates/forms/fields/checkboxes/checkboxes.html.twig

Ran it on my contact form example, this did not give any results. Further, I’ve changed:

  fields:
    myfield:
      type: checkboxes
      options:
        option1: Option 1
        option2: Option 2

into:

    -
        name: myField
        type: checkboxes
        options:
          option1: Option 1
          option2: Option 2	

Now I’m able to override the template. Testing It further

@01K, Changing the form definition is irrelevant.

But the change probably caused a clearing of the cache which made the change to the template visible.

I’ve cleared the cache several times, but this hasn’t made any sense.
It seems, that in my case, mixing the form element definitions caused such problems :confused:

Well, I have made some changes in checkboxes.html.twig
The problem is that I don’t know how to pass a custom value to a attributes. Nor haven’t found such a possibility in docs.

Here is a part of mine html generated form with some real CSS names for an example purpose. I need to achieve this markup

<div class="fields-group-controls onyx-checkboxes">

	<div class="type-selection type-selection form-group col-md-4 col-sm-12">
		<input type="checkbox" name="planner_project_type_checkbox" id="bio" value="Text Value 1">
		<label for="web" class="icon-bio">Text Value 1</label>
	</div>

	<div class="type-selection type-selection form-group col-md-4 col-sm-12">
		<input type="checkbox" name="planner_project_type_checkbox" id="geo" value="Text Value 2">
		<label for="graphic" class="icon-geo">Text Value 2</label>
	</div>
	
     ...

</div>

Moded checkboxes.html.twig:

<div class="fields-group-controls {{ field.classes }}">
{% set originalValue = value %}
{% set value = (value is null ? field.default : value) %}
{% if field.use == 'keys' and field.default %}
    {% set value = field.default|merge(value) %}
{% endif %}


{% block input %}
    {% for key, text in field.options %}

        {% set id = field.id|default(field.name)|hyphenize ~ '-' ~ key %}
        {% set name = field.use == 'keys' ? key : id %}
        {% set val = field.use == 'keys' ? '1' : key %}
        {% set checked = (field.use == 'keys' ? value[key] : key in value) %}
        {% set help = (key in field.help_options|keys ? field.help_options[key] : false) %}

        <div class="type-selection type-selection form-group col-md-4 col-sm-12">
            <input type="checkbox"
                   id="{{ id|e }}"
                   value="{{ text|t|e }}"
                   name="{{ (scope ~ field.name)|fieldName ~ '[' ~ name ~ ']' }}"
                   {% if checked %}checked="checked"{% endif %}
                   {% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
            >
            <label for="{{ id|e }}">
                {% if help %}
                    <span class="hint--bottom" data-hint="{{ help|t|e('html_attr') }}">{{ text|t|e }}</span>
                {% else %}
                    {{ text|t|e }}
                {% endif %}
            </label>
        </div>
    {% endfor %}
{% endblock %}
</div>

checkbox code

-
	name: custom-checkbox-field
	type: checkboxes
	label: false
	options:
		option1: 'Text Value 1'
		option2: 'Text Value 2'
	outerclasses: 'fields-group-controls onyx-checkboxes'
	classes: onyx-checkboxes

And here is what I’m getting after checkboxes.html.twig modifications:

<div class="fields-group-controls onyx-checkboxes">
                                        
        <div class="type-selection type-selection form-group col-md-4 col-sm-12">
            <input type="checkbox" id="custom-checkbox-field-option1" value="Text Value 1" name="data[custom-checkbox-field][custom-checkbox-field-option1]">
            <label for="custom-checkbox-field-option1">Custom Label Value 1</label>
        </div>
    
                                        
        <div class="type-selection type-selection form-group col-md-4 col-sm-12">
            <input type="checkbox" id="custom-checkbox-field-option2" value="Text Value 2" name="data[custom-checkbox-field][custom-checkbox-field-option2]">
            <label for="custom-checkbox-field-option2">Custom Label Value 2</label>
        </div>
    
        ...
</div>

The main div wrapper is OK.
The div wrapper of checkbox is OK.

The input and label should somehow receive custom values for these attributes:
input name and id
Label: for, class and it’s value

@anon76427325 any thoughts/solutions for it?

@01K,

@anon76427325 any thoughts/solutions for it?

I don’t believe I’ve received an order confirmation yet…

@01K, Is there a compelling reason to put time and effort in custom id’s/names for input fields?

I suspect changing id/name attributes of input fields will probably break other parts of the Form plugin.

Well, on plain html custom id’s were made for sophisticated CSS rules.
While name's were processed in the mailing script to populate the email template with checked values.
You gave me an idea to try to completely rewrite CSS and check how the values will be processed after form submission. Maybe it will be a solution :slight_smile:

@01K, I’m afraid the reply you have marked as solution doesn’t provide much help to others… The purpose of the forum is not only to answer/fix someone’s issues, it also serves as a knowledge base.

I think it would be more informative if you could share:

  • what issues you have encountered during the customisation of checkboxes
  • and what the solution was for each of the issues
  1. I had mixed definitions of the form elements, for example all my elements had this definition:
        -
            name: email
            type: email
            validate:
                required: true

while checkboxes had this:

    myfield:
      type: checkboxes
      options:
        option1: Option 1
        option2: Option 2

Because of this the overrides placed in user/themes/child-theme/templates/forms/fields/checkboxes/checkboxes.html.twig were not working. Simply no matter what I did changes were not displayed.

  1. I’ve removed some unnecessary class definitions for my needs, changed name field to name="{{ ( field.name) }}"
<div class="fields-group-controls {{ field.classes }}">
{% set originalValue = value %}
{% set value = (value is null ? field.default : value) %}
{% if field.use == 'keys' and field.default %}
    {% set value = field.default|merge(value) %}
{% endif %}


{% block input %}
    {% for key, text in field.options %}

        {% set id = field.id|default(field.name)|hyphenize ~ '-' ~ key %}
        {% set name = field.use == 'keys' ? key : id %}
        {% set val = field.use == 'keys' ? '1' : key %}
        {% set checked = (field.use == 'keys' ? value[key] : key in value) %}
        {% set help = (key in field.help_options|keys ? field.help_options[key] : false) %}

        <div class="type-selection form-group col-md-4 col-sm-12">
            <input type="checkbox"
                   id="{{ id|e }}"
                   value="{{ text|t|e }}"
                   name="{{ ( field.name) }}"
                   {% if checked %}checked="checked"{% endif %}
                   {% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
            >
            <label for="{{ id|e }}">
                {% if help %}
                    <span class="hint--bottom" data-hint="{{ help|t|e('html_attr') }}">{{ text|t|e }}</span>
                {% else %}
                    {{ text|t|e }}
                {% endif %}
            </label>
        </div>
    {% endfor %}
{% endblock %}
</div>
  1. Haven’t tested the mailing functionality: how the selected checkbox values are transferred to mail template. It seems that it will be another question/problem
1 Like

Still need some help. It’s working but not till the end: the checked values are not transferred to the mail template, but it’s a question for another thread, but I think it’s related to next issue:

The checkbox values are selected/unselected with this JS:

	var checkedValues = [];

	
	$('input[name="planner_project_type_checkbox"]:checked').each(function( index  ) {		         
		$(this).val();		
		checkedValues.push($(this).val())
	});

	$('div.type-selection').each(function() {

		$(this).on("click", function(e) {

			e.preventDefault();

			if ( $(this).find('input[checked]').length ) {
				checkedValues.splice( $.inArray($(this).find('input[checked]').val(), checkedValues), 1 );
				$(this).find('input[checked]').removeAttr('checked');				

			} else {
				$(this).find('input[name="planner_project_type_checkbox"]').attr('checked', true);
				checkedValues.push($(this).find('input[name="planner_project_type_checkbox"]').val());
checkedValues));
			}

		});

	});

Without this code my checkboxes are not selected. JS code was transferred from html contact form.

In checkboxes.html.twig I’ve observed these lines of code:

{% set checked = (field.use == 'keys' ? value[key] : key in value) %}
and
{% if checked %}checked="checked"{% endif %}

So, as I understand the JS part could be removed but {% if checked %}checked="checked"{% endif %} is not working after my modifications.

In form.md I’ve text values:

        -
            name: planner_project_type_checkbox
            type: checkboxes
            options:
                option1: 'Text Value 1'
                option2: 'Text Value 2'

What could be the problem?

@01K, We are at reply 18 now and still no end in sight. I’m sorry to say, but I give up…

For two reasons:

  • It seems you are trying to force a custom HTML form and custom form handler into a Grav Form. Don’t try to make the new environment do exactly what the old did, but go with the philosophy and capabilities of the new environment. Or don’t convert at all…
  • Your question is (again) not clear to me.

Suggestion:

  • Use the out-of-the-box Form functionality with checkboxes and mail action. The Form plugin is very well capable of creating forms with checkboxes and sending emails containing the containing the result of the form.
  • Or use the original HTML form and server component.
    • Copy the HTML form straight into the page’s markdown, or custom Twig template.
    • If js is required, copy it into the page’s markdown or template too.
    • Copy the original PHP mail code into a new plugin and handle it when form is submitted to the server.
1 Like