Get choices from select in twig - symfony

I'm new in Symfony2 and Twig, really I only markup the views of some forms. I have created a generic forms.twig.html with some macros for render type of input.
Then I pass to the select type the options list for selects options, but I cant get this options in the vars array from symfony2. ¿Is this possible?
Macro
{% macro select(name, options, selected) %}
<div class="innerB">
<select class="form-control" name="{{name}}">
{% for option in options %}
{% if option.value == selected %}
<option value="{{option.value}}" selected>{{ option.value }}</option>
{% else %}
<option value="{{option.value}}">{{ option.value }}</option>
{% endif %}
{% endfor %}
</select>
</div>
{% endmacro %}
And this is the twig:
<!-- Print selects -->
{% if type == 'choice' %}
{{ macroforms.label(item.vars.name, item.vars.label) }}
{{ macroforms.select(item.vars.name, item.vars.choices, item.vars.selected?) }}
{% endif %}
Updated: This works... The problem was type of element, "choice" and not "collection", but now, I want to access each element for the collection, which are choices... Any idea?

Related

Variable does not exist within Symfony Form Theme block override

I am building a form which contains a series of categories used to search some content, defined as a ChoiceType within my Symfony FormType.
I pass the category list along with some other data (per-category count) (defined as the variable "aggs" in my controller) into a Twig template and create a form theme, overriding the choice_widget_options block for my categories drop-down so that I can display the extra data at render time, thus:
{% form_theme form.categories _self %}
{% block choice_widget_options %}
{% if choices is defined %}
{% for choice in choices %}
<option value="{{ choice.value }}">{{ choice.label }} {{ aggs }}</option>
{% endfor %}
{% endif %}
{% endblock choice_widget_options %}
Why is it that my block here cannot access the top-level variables defined in my controller? It can see the "app" global variable, but not the controller-defined ones.
Thanks!
More elegant solution is to override the buildView method of AbstractType class.
Just add:
$view->vars[‘aggs’] = YOUR AGGS VAR;
And the use it in your form as:
<option value="{{ choice.value }}">{{ choice.label }} {{ form.vars.aggs }}</option>
Basically you pass the variable to your form and then you use it in twig. The way you pass it to the form type is up to you. It can be a dependency injection or via the form options from the controller.

Twig template set select control to database value

I have a class called Offices which contains id and officeName among other attributes.
I'm trying to fill a select control with all possible values for that class and then set the select control to the value for the current record (stored as customer.officeName)
{% for office in offices %}
<option value="{{ office.Id}}">{{ office.officeName}} </option>
{% if %}
(office.id== customer.officeName) ? ' selected ' : ''
{% endif %}
{% endfor %}
</select>
Any suggestions on how I can update the above syntax to work?
Figured it out
this works
{% for office in offices %}
<option value="{{ office.Id}}"
{% if (office.Id== customer.managingOffice) %}
{{ 'selected'}}
{% endif %}
>{{ office.officeName}}</option>

Is it possible to override default # products in a row in custom Shopify collections template?

I have created an alternate collection.liquid template for a shopify site I'm working on. My struggle is with not being able to control the number of products that appear in a row in the grid. I developed the custom template so that I wouldn't affect the number of products/row that appear on the other collections.
The code that displays the grid in my liquid template is this:
<div class="four columns section_select {% unless settings.collection_sort %}offset-by-four omega{% endunless %}">
{% for tag in collection.all_tags %}
{% if forloop.first %}
<label for="tag_filter" class="inline">
{{ 'collections.sorting.filter' | t }}: </label>
<select name="tag_filter" id="tag_filter">
<option {% unless current_tags %}selected="selected"{% endunless %} value="{% if collection.handle == "all" %}/collections/all{% else %}{{ collection.url }}{% endif %}">{{ 'collections.general.all_collection_title' | t: title: collection.title }}</option>
{% endif %}
{% unless tag contains 'meta-related-collection-' %}
<option {% if current_tags contains tag %}selected="selected"{% endif %} value="/collections/{% if collection.handle != blank %}{{ collection.handle }}{% else %}all{% endif %}/{{ tag | handleize }}">{{ tag }}</option>
{% endunless %}
{% if forloop.last %}
</select>
{% endif %}
{% endfor %}
</div>
Even when I change the class class="four columns" to something else, it is not reflected on my collection.
The problem could be in my code that assigns how many products are pulled in this collection but I can't seem to make a difference.
{% case products_per_row %}
{% when '1' %}
{% assign grid_item_width = 'medium--one-third large--one-whole' %}
{% when '2' %}
{% assign grid_item_width = 'medium-down--one-half large--one-half' %}
{% when '3' %}
{% assign grid_item_width = 'medium--one-third large--one-third' %}
{% when '4' %}
{% assign grid_item_width = 'medium-down--one-half large--one-quarter' %}
{% when '5' %}
{% assign grid_item_width = 'medium-down--one-half large--one-fifth' %}
{% endcase %}
Any help would be great!
It looks like your theme is using Timber grid.
You will find grid structure and classes to use in documentation here: https://shopify.github.io/Timber/
HTH

Access to an array field

I have a real strange problem with twig, I iterate over an array and when I try to 'print' value with {{value}} I get the exception "Array to string conversion" and when I try with {{value.first()}} I get the error "Impossible to invoke a method ("first") on a string variable ("false")"
Can someone help me out ?
<select name="select">
{% for key,value in array %}
{% if (key != 'id') and (key != 'type') %}
<option value={{key}}>{{ key }}: {{ value }}</option>
{% endif %}
{% endfor %}
</select>
I think the best way to handle this would be to pass the data already flatten to Twig, so it would only need to loop through the data always in the same way.
If that's not possible and you need to use Twig to handle this, you can make use of iterable. This is not pretty, but here we go:
<select name="select">
{% for key,value in array %}
{% if (key != 'id') and (key != 'type') %}
{% if value is iterable %}
{% for item in value %}
<option value={{item}}>{{ key }}: {{ item }}</option>
{% endfor %}
{% else %}
<option value={{key}}>{{ key }}: {{ value }}</option>
{% endif %}
{% endif %}
{% endfor %}
</select>

Symfony2 - form theming based on field name

I want to create a choice_widget_collapsed theme, but only for one type of field, it can be checked by name, or by class name (it's entity field). Other choice field should be rendered by standard widget.
I've tried FIELDNAME_widget, CLASSNAME_widget, and I've searched in Google, but with no results.
EDIT
This is code of choice_widget_colapsed:
{% block choice_widget_collapsed -%}
{% if required and empty_value is none and not empty_value_in_choices and not multiple %}
{% set required = false %}
{% endif %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{% if empty_value is not none -%}
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
{%- endif %}
{%- if preferred_choices|length > 0 -%}
{% set options = preferred_choices %}
{{- block('choice_widget_options') -}}
{% if choices|length > 0 and separator is not none -%}
<option disabled="disabled">{{ separator }}</option>
{%- endif %}
{%- endif -%}
{% set options = choices -%}
{{- block('choice_widget_options') -}}
</select>
{%- endblock choice_widget_collapsed %}
I want to modify HTML of this widget, only for fields named color.
Problem solved.
When you want to change html of widget, based by field name, you have to overwrite block:
{% block _FORMNAME_FIELDNAME_widget -%}
{# your html #}
{%- endblock %}

Resources