I'm still trying to process my csv data as mentioned in a former question. But I'm struggling with another part of this right now.

I decided to implement a custom field type which should display the data from my csv in a table to make it further editable for editors. The problem is that I don't even get something shown in this table even without processing a csv file before.

I tried something really simple, at least I thought it was...

public function getInputHtml($name, $value)
    $id = 'test';
    $cols = array(
        'Sample' => array(
            'heading' => 'Heading',
            'type'    => 'singleline'

    return craft()->templates->render('csvImport/csvimport', array(
        'name'  => $name,
        'value' => $value,
        'id'    => $id,
        'cols'  => $cols,

This works until the point of saving the data. Craft stores everything into database as a string. No matter how many cols I use, it will always result in a string which looks like this:

"{"1":"Sample":"The entered string"}}"

This is what craft stores in the database, so at least the data is processed. But how the pencil do I get this stuff to show up in the table of my template?

If you have any other idea how I could solve my problem, please let me know!


<table id="{{ id }}" class="shadow-box editable">
        {% for col in cols %}
            <th scope="col" class="header">{{ col.heading ? col.heading : ' ' }}</th>
        {% endfor %}
        {% if not static %}
            <th class="header" colspan="2"></th>
        {% endif %}
    {% for rowId, row in rows %}
        <tr data-id="{{ rowId }}">
            {% for colId, col in cols %}
                {% set cellName = name~'['~rowId~']['~colId~']' %}
                {% set value = (row[colId] is defined ? row[colId] : null) %}
                {% set textual = (col.type in ['singleline','multiline','number']) %}
                <td class="{% if textual %}textual{% endif %} {% if col.class is defined %}{{ col.class }}{% endif %}"{% if col.width is defined %} width="{{ col.width }}"{% endif %}>
                    {%- if col.type == 'select' -%}
                        {% include "_includes/forms/select" with {
                            class:    'small',
                            name:     cellName,
                            options:  col.options,
                            value:    value,
                            disabled: static
                        } only %}
                    {%- elseif col.type == 'file' -%}
                        {% include "_includes/forms/file" with {
                            class:    'small',
                            name:     cellName,
                            value:    value
                        } only %}
                    {%- elseif col.type == 'checkbox' -%}
                        <input type="hidden" name="{{ cellName }}">
                        <input type="checkbox" name="{{ cellName }}" value="1"{% if value %} checked{% endif %}{% if static %} disabled{% endif %}>
                    {%- else -%}
                        <textarea name="{{ cellName }}" rows="1"{% if static %} disabled{% endif %}>{{ dump(value) }}</textarea>
                    {%- endif -%}
            {% endfor %}
            {% if not static %}
                <td class="thin action"><a class="move icon" title="{{ 'Reorder'|t }}"></a></td>
                <td class="thin action"><a class="delete icon" title="{{ 'Delete'|t }}"></a></td>
            {% endif %}
    {% endfor %}

I guess this is the relevant part for the ouput of my values.

  • How to set anchor link for delete button to a certain row?
    – Volatil3
    Oct 27 '15 at 13:50

That string that Craft stores is just JSON. When you try to save an array, Craft will automatically JSON-encode it, since MySQL doesn’t have an array-based data type.

To get that string to be automatically decoded back into an array for you, you need to give your field type a defineContentAttribute() method that returns AttributeType::Mixed:

public function defineContentAttribute()
    return AttributeType::Mixed;

To get the values to actually output, you will need to make sure you’re passing the old value with the correct name. Your csvimport.html template is looping through a variable called rows, which is meant to represent the existing value, but in getInputHtml() you are sending $value to the template as a variable called value.

So if you change this line in your template:

{% for rowId, row in rows %}


{% for rowId, row in value %}

the template will probably start outputting data.

If you’re not actually making any changes to the table HTML, you should probably just include the actual _includes/forms/editableTable.html template, though. Using your own HTML puts you at a little risk, if you also intend to keep using the Craft.EditableTable JavaScript class, since those two are very much tied together. We aren’t concerned about making breaking changes to the way the HTML is supposed to look, as long as we haven’t broken the way the actual editableTable.html template is supposed to be included.

So from csvimport.html, you should just replace your entire <table>...</table> HTML with this:

{% from "_includes/forms" import editableTable %}

{{ editableTable({
    id: id,
    name: name,
    cols: cols,
    rows: value
}) }}

(In this case I’m using the editableTable() macro in _includes/forms.html instead of including the actual _includes/forms/editableTable.html template, mainly because I think using the macro looks nicer.)

  • Great, thank you Brandon! Bad blunder I made here... But I still don't see how to solve my main problem. How do I get the Array values mapped to my table cols? Maybe I just lost the vision throughout my experiments of the last days but I just don't get it working.
    – LikeAJohny
    Oct 31 '14 at 8:40
  • @JohN Hard to say without seeing your csvimport.html template. Can you update your question with that (or at least the parts of it that are relevant to this question)? Oct 31 '14 at 12:00
  • I more or less just copied the template from editableTable.html for testing issues, but sure I'll do. I'm pretty sure that it's just a matter of my thinking about the twig logic. I guess I'm too blind to wrap the value arrays for loop arround the columns one ^^
    – LikeAJohny
    Oct 31 '14 at 12:11
  • @JohN Thanks - just updated the answer with more info for you. Oct 31 '14 at 12:28
  • Thank you very much. That was exactly the type of brain error I expected... So I hope I didn't steal too much of your time. Btw I just included the whole template for testing issues as I said above. I will ofc replace it if I don't have to do any changes to the actual template. Thanks again an keep up the great great work you're doing :) Greetz
    – LikeAJohny
    Oct 31 '14 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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