Toggle items from between choice widgets - php

I'm using Symfony2.3.4 and jQuery, or at least trying to.
The thing is I have a form with two choice widgets(in each multiple=true and expanded=false) and two buttons. This form was generated with Doctrine's crud, so I'm currently getting familiar to the code it generated. After a while searching the web, a long while since I'm new to a lot about web programming, I managed to get a function to remove the selected options from one choice widget and append them to the other using the id of each widget:
//../custom_js.js
function move_option_among_choices(id_from, id_to) {
$('#' + id_to).append($('#' + id_from + ' option:selected'));
}
Here comes the problem:
I click an option from the first widget(id_from).
I press the button that executes the func above.
I see that the selected option is removed from the first widget and appears now in the second.
I submit the form...
only I can't do what I want to do with the moved options because they are not there.
when I try to access the second widget's options:
var_dump($form->get('selected_prof')->getConfig()->getOptions()['choices']);
I get an empty array although every time a press the button that executes the js func it moves the option from the first widget to the second.
It's like the function only moves the text, the actual component/option(idk how to call it) is internally still in the first widget.
Is there a way to fix this?
It doesn't matter if it's either a different way to access the options in the second widget or a different way of appending them to it.
Thanks.
{% extends 'AdminBundle:Default:administracion.html.twig' %}
{% block contenido -%}
<h1>Nuevo Comité Académico</h1>
{% if error %}
<div class="alert alert-error my_error">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ error }}
</div>
{% endif %}
<div class="row-fluid">
<form class="form-horizontal sf_admin_form_area"
action="{{ path('comiteacad_create') }}"
method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="icon-ok"></i> {{'Guardar' | trans}}</button>
<a class="btn" href="{{ path('comiteacad') }}">
<i class="icon-ban-circle"></i> {{'Cancelar' | trans }}</a>
</div>
</form>
</div>
{% endblock %}

Related

Display selected elements twig template

data= [{id:1, text:'abc'},{id:2, text:'cde'}]
In my template I want to do this:
<ul>
{{% for article in data %}}
<li><a href={{article.id}}>{{article.id}}</a></li>
</ul>
In click on li I would display only the property "text" of related id.
<div>{{selected article.text}}</div>
If clicked 1 I want to see "abc".
Is there a way to do it with twig?
If I understand correctly, you cant to show dynamically the text related to an id on click on the li containing the related id.
This cannot be achieved with only twig. You need some javascript here. Basically what you can do is the following:
<ul>
{% for article in data %}
<li>
<a href="#" data-content="{{ article.text|e('html_attr') }}" onclick="document.getElementById('dynamic-content').innerHTML = this.dataset.content; return false">
{{ article.id }}
</a>
</li>
{% endfor %}
</ul>
<div id="dynamic-content"></div>
|e('html') is some escaping for keeping it inside an html attribute, learn more here
onclick="" this contains pure javascript, it work like this but I recommand to do it another way (checkout this JSFiddle)

Symfony3 form builder form field in span instead of div

I have Symfony3 app and I am making a simple form the code in the twig is as follows
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="Edit" />
{{ form_end(edit_form) }}
Pretty simple. What this code creates is a form and each form field is within it's own <div> which is fine, but if the type is date here is what the generated html looks like
<div>
<label class="required">Term</label>
<div id="appbundle_project_term">
<select id="appbundle_project_term_year" name="appbundle_project[term][year]"></select>
<select id="appbundle_project_term_year" name="appbundle_project[term][month]"></select>
<select id="appbundle_project_term_year" name="appbundle_project[term][day]"></select>
</div>
</div>
What bugs me is the inner div created for the date type field. Is there a way in the FormBuilder to keep the type date but remove this inner div without using javascript to handle it or in the twig template. Simply to say - "inner tag => span".
This is pretty generic question as I am looking for a way to usually change the auto generated tags, but if needed here is how this form field is created in form builder
add('term',DateType::class, array(
'widget' => 'choice',
'label'=>"Term",
'data'=>$project->getTerm()
))
You can override form rendering, there are few ways.
The simplest one is overriding form theme widget block (in this case date_widget) and setting form_theme to _self.
Basic example:
{% form_theme form _self %}
{% block date_widget %}
<span>
{% if widget == 'single_text' %}
{{ block('form_widget_simple') }}
{% else %}
{# rendering 3 fields for year, month and day #}
{{ form_widget(form.year) }}
{{ form_widget(form.month) }}
{{ form_widget(form.day) }}
{% endif %}
</span>
{% endblock %}
{% block content %}
{# ... form rendering #}
{{ form_row(form.someDateField) }}
{% endblock %}

In October CMS, How to redirect from a plugin to a page with data

I'm creating a plugin for October CMS that has a frontend form (component) with
{{ form_open({ request: 'onSubmitForm' }) }}
In the plugin there is a function onSubmitForm() with a validator.
If the validator fails I want to redirect to the page the form input came from ($this->page->url) but send the validator messages ($validator->messages()) and the original input of the form (post()) with it.
I've tried:
if ($validator->fails()) {
return Redirect::to($this->page->url)->withErrors($validator->messages())->withInput(post());
}
and if I put {{ errors }} on the page i do get a message
Object of class Illuminate\Support\ViewErrorBag could not be converted
to string
which I then fixed by using:
{% for error in errors.all() %}
<li>{{ error }}</li>
{% endfor %}
and {{ errors.first('name') }}
but the {{ input }} doesn't even return an error.
Am I doing the redirecting wrong? Or does it have to do with how Twig and Blade are so completely different? Is there a way to prefill old input values and error messages?
You can output the old input value with this twig
{{form_value('my_input_name')}}
october cms form doc
As you can read in the very top you can "translate" php exemple to twig by changing "method name" to lower case and "::" to _
exemple:
// PHP
<?= Form::open(..) ?>
// Twig
{{ form_open(...) }}
hope it will help.
this is my regular code for blade
#if (count($errors) > 0)
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<strong>{{trans('messages.sorry')}}</strong>
<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Instead of redirecting to the same page where the form was submitted from, just use Ajax! You can do in couple ways.
instead of form_open, use form_ajax.
Here is an example:
form_ajax('onSubmitForm', { model: user, class: 'whateverclass', id: 'idoftheform', success:'doSomethingInJS(textStatus, data)'})
in PHP, you can return your error message as
return ["ErrorMsg" => 'this is some error']
Then in JS you can display it:
function whateverClass (textStatus, data){
alert (data.ErrorMsg);
$('#alertHolderDiv').html(data.ErrorMsg);
}
another way would be to use a partial! And once you throw an error you can use "update" in ajax command to update the partial. The partial will be overwritten with the new message.

How to get text before and after specific string

I have content stored in variables and I have a string that users enter in search fields.
My question is how can I chop the text before and after the searched string?
-SearchString has a the value which user has entered.
-Wholetext has the whole data from database.
Now, I want to show the Wholetext as the excerpt like user search for "test" and then I will show the result like:
"text before search string" : "test"
"text after search string" : "_"
Here's my code:
{% block field %}
<div>
{% set SearchString=admin.datagrid.filters.data.value.value %}
<div class="less_resume_container">
{% if SearchString is defined and SearchString in object.data %}
{% set Wholetext= object.data|replace({ (SearchString): '<span style="background-color: #FFFF00;font-size:15px;font-weight:bold">' ~SearchString~'</span>'}) %}
{{ Wholetext|striptags()|truncate(50) }} <a href="javascript:void(0)" class="show_full_resume">Show
more</a>
{% else %}
{% set Wholetext= object.data %}
{{ Wholetext|truncate(50) }} Show more
{% endif %}
</div>
<div class="full_resume_container" style="display: none;">{{ Wholetext|raw() }}
View less
</div>
<br/>
</div>
{% endblock %}
Currently it is showing 50 characters from the text.
This is not what I want. By the way I am using sonata admin with symfony 2.
You can use a combination of substr and strlen.
substr(WHOLETEXT, 0, (strlen(WHOLETEXT) - strlen(SEARCHTERM)))
Alternatively, you could explode the whole text on the search term, which would leave you with a two part array(assuming your search term only appeared once). The first part would be everything before the search term. The second part would be everything after.
$array = explode(SEARCHTERM, WHOLETEXT);
$before = $array[0];
$after = $array[1];

Overriding symfony radio widget

Default radio widget creates a following structure:
<label>...</label>
<div id="...">
<div class="clearfix prettyradio labelright blue">
<input type="radio" id="..._0" name="..." value="..." style="display: none;">
...
</div>
I found the radio_widget block, but it contains only an input itself. So I can customize there only this part:
<input type="radio" id="..._0" name="..." value="1" style="display: none;">
But I can't understand how to change whole the structure of radio choice field?
Also, does anybody knows, why symfony adds display:none to the input?
Thanks.
if you're using Radio Field Type, you can customize only the input part of the radio_widget block by calling form_widget(form.yourField), all it displays is,
{% 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 %}
But if you're using Choice Field Type to display Radio Fields (expanded => true and multiple => false). You'll then have to override the choice_widget block, which call for each child element the radio_widget block surrounded by a global div
How did you get the "display:none"? because there's no style such this in the default block.
If you specifically want to override the way an individual radio field is rendered - i.e. how each input field in the group is rendered - use this formula for the block name:
_<form name>_<field name>_entry_widget
Note this bit: _entry
If you're using an expanded choice field ..._entry_row and ..._entry_label won't work because they aren't used for the individual choices - well for radio buttons at least.
More generally you can find out a lot about which block Symfony intends to use during the next call to {{ form_widget(form) }} function call using this code:
{% for b in form.vars.block_prefixes %}
{{ dump(b) }}
{% endfor %}
or you might want to look at child in some situations:
{% for b in child.vars.block_prefixes %}
{{ dump(b) }}
{% endfor %}

Categories