4

I want to set up a form on the front-end of a site to allow logged in users to choose items from a list which represent entries in a channel using checkboxes, then save those entries as relations to an entry that the user is editing.

Using the docs and various questions here I have got setting a relationship to one entry working. However, I want to allow up to 5 relationships to be set and I can't figure out how to add further relationships.

The entry field containing the related choices is called choices.

Here's the template code I've got at the moment (simplified):

{# Get current list of choices to pre-set checkboxes #}
{% set choices = entry.choices %}
{% set choiceList = '' %}

{% for choice in choices %}
    {% set choiceList = choiceList ~ choice.id ~ "," %}
{% endfor %}

<form id="entry-edit-form" method="post" accept-charset="UTF-8">
    {{ getCsrfInput() }}
    <input type="hidden" name="action" value="entries/saveEntry">
    <input type="hidden" name="redirect" value="choices-saved">
    <input type="hidden" name="sectionId" value="8">
    <input type="hidden" name="enabled" value="1">
    <input type="hidden" name="entryId" value="{{ entry.id }}">
    <input type="hidden" id="choicesList" name="fields[choices][]" value="">

    {% for choice in choices %}
        <div>
            <input class="choice-checkbox" type="checkbox" id="choice{{ loop.index }}" data-id="{{ choice.id }}" {% if choice.id in (choiceList|split(',')) %}checked="checked"{% endif %} />
            <label for="choice{{ loop.index }}">{{ choice.title }}</label>
        </div>
    {% endfor %}

    <input type="submit" class="button" value="Save choices">
</form>

Then I've got some javascript that runs on form submit to loop through the checkboxes and grab the ids of the checked boxes. What format do these need to be saved in as a value to the hidden choicesList field so that an array of related ids is saved to the correct field in the edited entry?

Or is there another, simpler, way of doing this?

2
  • Have you tried making the variable array inside the fields variable "fields[choice[]]"? Mar 17, 2015 at 5:37
  • Tried that. It causes the values to not be saved at all as the field name gets interpreted by Craft as choices[ so the values are ignored and not saved. Mar 18, 2015 at 10:40

2 Answers 2

3

I'm pretty sure you can do this much simpler and without javascript. I've setup a front-end form using the doc's example and added checkboxes to choose entries that will be stored in a relational field simply by using name="fields[fieldName][]" in the input type="checkbox". For example:

<input id="" class="" type="checkbox" name="fields[kitIcons][]" value="{{ entry.id }}" checked>{{ entry.title }}<br/>

In the above example, "kitIcons" is the name of my relationship field, and I have this going through a loop to populate the entry.id and entry.title. Seems to be working without any glitches in my system.

1
  • I need to limit the number of relationships people can set up to no more than 5 out of around 60, so I'm using JavaScript to enforce that limit before the form is submitted. I do like your idea of setting the value of the checkbox directly to {{ entry.id }} though, good idea! Oct 6, 2015 at 18:39
2

OK, so I've come up with a working solution to this. It may not be the most elegant, but it works!

I allow up to 5 choices to be made, so in the form I make sure that there are 5 hidden form fields with the name fields[choices][]. To output the existing choices so that people can edit them, I loop through the choices they have made, the output any blank value hidden fields to make the total 5.

Here's my revised template code:

<form id="entry-edit-form" method="post" accept-charset="UTF-8">
    {{ getCsrfInput() }}
    <input type="hidden" name="action" value="entries/saveEntry">
    <input type="hidden" name="redirect" value="choices-saved">
    <input type="hidden" name="sectionId" value="{{ entry.sectionId }}">
    <input type="hidden" name="enabled" value="1">
    <input type="hidden" name="entryId" value="{{ entry.id }}">

    {# Get current list of choices to pre-set checkboxes #}
    {% set choices = entry.choices %}
    {% set choiceList = '' %}
    {% set numberOfChoicesMade = 0 %}

    {# Fill out existing values to hidden fields #}
    {% for choice in choices %}
        {% set choiceList = choiceList ~ choice.id ~ "," %}
        {% set numberOfChoicesMade = numberOfChoicesMade + 1 %}
        <input type="hidden" class="choicesList" name="fields[choices][]" value="{{ choice.id }}">
    {% endfor %}

    {# Add as many blank fields as we need #}
    {% if numberOfChoicesMade < 5 %}
        {% for i in (numberOfChoicesMade + 1)..5 %}
            <input type="hidden" class="choicesList" name="fields[choices][]" value="">
        {% endfor %}
    {% endif %}

    {% for choice in choices %}
        <div>
            <input class="choice-checkbox" type="checkbox" id="choice{{ loop.index }}" data-id="{{ choice.id }}" {% if choice.id in (choiceList|split(',')) %}checked="checked"{% endif %} />
            <label for="choice{{ loop.index }}">{{ choice.title }}</label>
        </div>
    {% endfor %}

    <input type="submit" class="button" value="Save choices">
</form>

Now in my javascript on form submission, I loop through the checkboxes to grab the ids of the checked boxes (from the data-id attribute).

I then loop through these values, writing them to the values of the hidden choicesList fields and deleting any remaining hidden choicesList fields whose value is blank, before finally submitting the form.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.