Select element into foreach Twig template - php

I'm on Symfony2 with Twig and i have 2 array in param :
My controller :
return $this->render('MyBundle:Default:index.html.twig',
array('checked' => $boxChecked,
'choices' => $choices));
Vars 'checked' and 'choices' are two arrays, I want to show the value of $checked[$choices[$i]] to compare with true ofr false to apply checked or not into input into twig tpl.
This is my code but does'nt work :
{% for choice in choices %}
{% if checked.{{choice}} == true %}
<div class="choice">{{ choice|capitalize }} <input type="checkbox" id="{{ choice }}" /></div>
{% else %}
<div class="choice">{{ choice|capitalize }} <input type="checkbox" id="{{ choice }}" checked="checked" /> </div>
{% endif %}
{% endfor %}
error is : Expected name or number in "MyBundle:Default:index.html.twig" at line 22 (500 Internal Server Error)
Line 22 is : {% if checked.{{choice}} == true %}
I don't know how have my checked.(MY VAR CHOICE into my foreach CHOICES) into twig tpl ?

You must use brackets syntax instead:
{% for choice in choices %}
{% if checked[choice] == true %}
<div class="choice">{{ choice|capitalize }} <input type="checkbox" id="{{ choice }}" /></div>
{% else %}
<div class="choice">{{ choice|capitalize }} <input type="checkbox" id="{{ choice }}" checked="checked" /> </div>
{% endif %}
{% endfor %}

Related

Twig show n keys of array or all

I have an editor with a set of buttons, and I want to display only a set of buttons based on twig::render variables.
If I include all I want it to display are buttons available, if I include individual button keys I want to display only that ones.
echo TwigLoader::render('#ui/editor.html.twig'['toolbar'=>['all']]);
echo TwigLoader::render('#ui/editor.html.twig'['toolbar'=>['font','size']]);
For the template I'm using the following code:
{% set toolbar_tools = [
{'font':'<select class="ql-font"></select>'},
{'size':'<select class="ql-size"></select>'}]
%}
<div id="button-container">
<span class="ql-formats">
{% for tool, key in toolbar_tools %}
{{ tool.key|raw}}
{% endfor %}
</span>
</div>
I'm getting an empty container.
Is this a good strategy or there are better ways?
Seems you`re looking for something like this:
{% set toolbar_tools = {
'font':'<select class="ql-font"></select>',
'size':'<select class="ql-size"></select>'
}
%}
<div id="button-container">
<span class="ql-formats">
{% if toolbar|length > 0 %}
{% for t in toolbar %}
{% if t == 'all' %}
{# show all options #}
{% for tool in toolbar_tools %}
{{ tool|raw }}
{% endfor %}
{% else %}
{# show defined options #}
{{ attribute(toolbar_tools, t)|raw }}
{% endif %}
<br />
{% endfor %}
{% endif %}
</span>
</div>
Hope you will be fine with that.

Twig Setting Select Option on a dropdown

I am currently writing a php mvc from scratch and using twig as my template engine and need some assistance setting the selected option on a drop down list. Currently in my model I have an sql query that pull all list of supervisors and drops them in my drop down list using the twig for loop but I need to some how select a user’s supervisor if it matches up.
I apologize now as I am new to twig
View:
<select class="form-control" id="supervisor">
{% for supervisor in supervisor %}
<option value="{{supervisor.fname}} {{supervisor.lname}}" >{{supervisor.fname}} {{supervisor.lname}}</option>
{% endfor %}
</select>
Tried:
<select class="form-control" id="supervisor">
{% for supervisor in supervisor %}
{% if {{supervisor.fname}} {{supervisor.lname}} == {{ user.supervisor }} %}
<option value=”{{supervisor.fname}} {{supervisor.lname}}” selected>{{supervisor.fname}} {{supervisor.lname}}</option>
{% else %}
<option value=”{{supervisor.fname}} {{supervisor.lname}}”>{{supervisor.fname}} {{supervisor.lname}}</option>
{% endif %}
{% endfor %}
</select>
May be you can try something like this:
Replace supervisor variable name by oneSupervisor in the loop and test oneSupervisor with user.supervisor.
<select class="form-control" id="supervisor">
{% for oneSupervisor in supervisor %}
{% set selected = '' %}
{% if (oneSupervisor.fname ~ ' ' ~ oneSupervisor.lname) == user.supervisor %}
{% set selected = 'selected' %}
{% endif %}
<option value="{{oneSupervisor.fname}} {{oneSupervisor.lname}}" {{ selected }}>{{oneSupervisor.fname}} {{oneSupervisor.lname}}</option>
{% endfor %}
</select>
Assuming you have a form called form and therein a select field called field, You could simply do the following:
{% do form.field.setRendered %}
<select id="{{ form.field.vars.id }}"
name="{{ form.field.vars.name }}">
{% for option in form.field.vars.choices %}
<option {{ form.field.vars.value == option.value ? 'selected' : '' }}
value="{{ option.value }}">
{{ option.label }}
</option>
{% endfor %}
</select>

Possible memory leak in PHP script

I'm developing a web app using OctoberCMS where a user can select an item and see a list of material needed to craft it. Some materials can also be crafted and the user can see a "+" sign near the craftable material, that could be clicked to show an other list with the material needed to create the material.
See example
The problem is that while there is only one nested submaterial (like in the example image) there are no problem, but when there are more than one nested submaterial (for example a craftable submaterial that has craftable submaterials) the server returns me an "Internal server error" and the error_log reports:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65536 bytes) in /home/federico/federicoxella.com/vendor/composer/ClassLoader.php on line 412
This is the script i'm using to extract data from database (The database is on the same machine of the server)
public function onExpand()
{
$itemID = post('item_id');
$this->page['subitemMaterials'] =
Item::select('federicoxella_lootbot_items.id', 'name', 'craftable')
->join('federicoxella_lootbot_crafts', function($join) use ($itemID)
{
$join->on('federicoxella_lootbot_crafts.material_1', '=', 'federicoxella_lootbot_items.id')
->orOn('federicoxella_lootbot_crafts.material_2', '=', 'federicoxella_lootbot_items.id')
->orOn('federicoxella_lootbot_crafts.material_3', '=', 'federicoxella_lootbot_items.id');
})
->where('federicoxella_lootbot_crafts.material_result', '=', $itemID)
->get();
}
This function should take the ID of an item, extract all needed material from database and insert them in a page variable (subitemMaterial) that looks like this [{"id":3,"name":"Colla","craftable":0},{"id":4,"name":"Accendino","craftable":0},{"id":23,"name":"Metallo","craftable":0}]
If an item has "craftable":1 a new partial is created to host the material needed to create the item.
And this is the partial in where I use the variable
<ul class="no-bullet-list">
{% for i in 0..2 %}
<li>
{% if subitemMaterials[i].craftable == 1 %}
<b>{{ itemMaterial[i].name }}</b>
<form style="display:inline;">
<input type="hidden" name="item_id" value="{{ subitemMaterials[i].id }}" />
<a data-request="{{ __SELF__ }}::onExpand"
data-request-update="'{{ __SELF__ }}::subItems': '#{{ subitemMaterials[i].id }}_materials'">+</a>
</form>
<div id="{{ subitemMaterials[i].id }}_materials">
{% partial __SELF__~'::subItems' %}
</div>
{% else %}
{{ subitemMaterials[i].name }}
{% endif %}
</li>
{% endfor %}
</ul>
And the partial in where I declare the previous partial
<div class="callout">
<h3>{{ itemToCraft.name }}</h3>
<ul class="no-bullet-list">
{% for i in 0..2 %}
<li>
{% if itemMaterial[i].craftable == 1 %}
<b>{{ itemMaterial[i].name }}</b>
<form style="display:inline;">
<input type="hidden" name="item_id" value="{{ itemMaterial[i].id }}" />
<a data-request="{{ __SELF__ }}::onExpand"
data-request-update="'{{ __SELF__ }}::subItems': '#{{ itemMaterial[i].id }}_materials'">+</a>
</form>
<div id="{{ itemMaterial[i].id }}_materials">
{% partial __SELF__~'::subItems' %}
</div>
{% else %}
{{ itemMaterial[i].name }}
{% endif %}
</li>
{% endfor %}
</ul>
</div>
Can you guys help me understand why server returns this error code?
Found the problem (that not is exactly a problem):
Pratically I'm recursively adding partials that print the value of the variable injected in the page.
<ul class="no-bullet-list">
{% for i in 0..2 %}
<li>
{% if subitemMaterials[i].craftable == 1 %}
<b>{{ itemMaterial[i].name }}</b>
<form style="display:inline;">
<input type="hidden" name="item_id" value="{{ subitemMaterials[i].id }}" />
<a data-request="{{ __SELF__ }}::onExpand"
data-request-update="'{{ __SELF__ }}::subItems': '#{{ subitemMaterials[i].id }}_materials'">+</a>
</form>
<div id="{{ subitemMaterials[i].id }}_materials">
{% partial __SELF__~'::subItems' %} <--- Incriminate line of code.
</div>
{% else %}
{{ subitemMaterials[i].name }}
{% endif %}
</li>
{% endfor %}
</ul>

Twig - How to render an HTML rating element

What I am trying to achieve is to render a simple 5-star rating HTML element based on a number ( 0-5 )
Example :
{{ user.rating }} // returns integer 4
Output should be:
<div class="rating">
<i class="star voted"></i>
<i class="star voted"></i>
<i class="star voted"></i>
<i class="star voted"></i>
<i class="star-empty"></i>
</div>
// 4 lighted stars out of 5
Thanks
You can archive your problem with this code:
<div class="rating">
{% for i in 1..5 %}
{% set starClass = (user.rating >= i ? "star voted" : "star-empty") %}
<i class="{{ starClass }}"></i>
{% endfor %}
</div>
See the working solution on this twigfiddle
Explanation:
From the doc:
If you do need to iterate over a sequence of numbers, you can use the
.. operator:
{% for i in 0..10 %}
* {{ i }}
{% endfor %}
The Twig built-in .. operator is just syntactic sugar for the range function.
Simple way :
{% set stars, count,starsResult = 4 , 1 , "" %}
{% for i in range(1, 5) %}
{% if stars >= count %}
{% set starsResult = starsResult ~ "<i "star active">" %}
{% else %}
{% set starsResult = starsResult ~ "<i class="star disable">" %}
{% endif %}
{% set count = count + 1 %}
{% endfor %}
{{ starsResult }}

Is it possible to design the html from form builder

I made select form in buildForm()
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('icon','entity',
array(
'class' => 'UserBundle:IconPics',
'property' => 'label',
'expanded' => true,
'data' => $defaultIcon,
'multiple' => false,
'label' => 'form.icon',
'query_builder' => function ($repository) {
return $repository->createQueryBuilder('i')
->add('where', 'i.enabled = true');
},
));
in twig.
{{ form_widget(form.icon) }}
it shows the radiobutton selector html like this.
<div id="fos_user_registration_form_icon">
<input type="radio" id="fos_user_registration_form_icon_3" name="fos_user_registration_form[icon]" required="required" value="3" checked="checked" />
<label for="fos_user_registration_form_icon_3" class="required">male</label>
<input type="radio" id="fos_user_registration_form_icon_4" name="fos_user_registration_form[icon]" required="required" value="4" />
<label for="fos_user_registration_form_icon_4" class="required">female</label>
<input type="radio" id="fos_user_registration_form_icon_5" name="fos_user_registration_form[icon]" required="required" value="5" />
<label for="fos_user_registration_form_icon_5" class="required">old male</label>
<input type="radio" id="fos_user_registration_form_icon_6" name="fos_user_registration_form[icon]" required="required" value="6" />
</div>
However,this html is not cool,just align the radio button.
I would like to design this html.
such as using table or something
<table><tr>
<td>Button1</td>
<td>label</td>
</tr></table>
Is it possible?
Thanks for your reply
I have read the link and choose the most simple way.
put this at the top of twig and made some progress.
But I am facing two problems
{% form_theme form _self %}
{% block radio_widget %}
<td>
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}/>
</td>
{% endblock radio_widget %}
it shows the html like this
<td style="border-style:none;">
<input type="radio" id="fos_user_registration_form_icon_3" name="fos_user_registration_form[icon]" required="required" value="3"/></td>
<label for="fos_user_registration_form_icon_3" class="required">male</label>
1.problem
radio button is inside the td tag (good!!),but label is out side the
where does this label appears?????
how can I delete or control this???
I understood this label is defferent from the 'label' that I can choose at the formBuilder.
2) problem
when I use 'checked' as sample says
{% if checked %} checked="checked"{% endif %}
it says like this checked property is used in even normal
form_div_layout.html.twig
I have no clue about this.
Please help me . thanks
Variable "checked" does not exist in FOSUserBundle:Registration:register_content.html.twig at line 7
500 Internal Server Error - Twig_Error_Runtime
You can override the form theme in twig by using your new form layout like
{% form_theme formObject 'NamespaceYourBundle:Form:form_div_layout.html.twig' %}
and in form_div_layout.html.twig redefine your field blocks like for radio button you can customize it
{% block radio_widget %}
{% spaceless %}
<td>
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
</td>
{% endspaceless %}
{% endblock radio_widget %}
For label block you can use it like
{% block form_label %}
{% spaceless %}
{% if label is not sameas(false) %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %} /* you can skip this part for td */
{% endif %}
{% if required %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{% endif %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
<td {% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</td>
{% endif %}
{% endspaceless %}
{% endblock form_label %}
And now finally override the expanded widget
{% block choice_widget_expanded %}
{% spaceless %}
<table {{ block('widget_container_attributes') }}>
{% for child in form %}
<tr>
{{ form_widget(child) }}
{{ form_label(child) }}
</tr>
{% endfor %}
</table>
{% endspaceless %}
{% endblock choice_widget_expanded %}
Edit to override label block for choice_widget_expanded you can define your block and use it like in below
{% block choice_widget_expanded %}
{% spaceless %}
<table {{ block('widget_container_attributes') }}>
{% for child in form %}
<tr>
{{ form_widget(child) }}
{{ form_label_custom(child) }}
</tr>
{% endfor %}
</table>
{% endspaceless %}
{% endblock choice_widget_expanded %}
And for the custom label too form_label_custom now for every choice field with expanded property (not all fields) your new label will be in action
{% block form_label_custom %}
{% spaceless %}
{% if label is not sameas(false) %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %} /* you can skip this part for td */
{% endif %}
{% if required %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{% endif %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
<td {% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</td>
{% endif %}
{% endspaceless %}
{% endblock form_label_custom %}
How to customize Form Rendering
Check out Form theming.
You have to create fields.html.twig and include into yout twig file like:
{% form_theme form with 'AcmeTaskBundle:Form:fields.html.twig' %}
In fileds.html.twig add radio widget (check out). Here you can now add tables, divs etc. Inside {% block radio_widget %}.
{% block radio_widget %}
{% spaceless %}
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{% endspaceless %}
{% endblock radio_widget %}

Categories