Showing all choice option at once in one Sonata Admin Form's Select - sonata-admin

Inside $formMapper variable in sonata's src/Admin/TareaspendientesAdmin.php file I have:
->add('subcategoria', ChoiceType::class, [
'placeholder' => 'Select Subcategory',
'choices' => [
// Categoría: Coche
'Recambios' => '21',
'ITV' => '22',
// Categoría: Compras
'Alimentacion' => '91',
'Limpieza' => '92',
'LeroyMerlin-Bricodepo' => '93',
'Libros-Cultura' => '94',
'Otros-compras' => '95',
// Categoría: Doméstica
'Limpieza-casa' => '11',
'Ordenar-casa' => '12',
// Categoría: Eguzkilore
'Instalaciones' => '51',
'Hacienda' => '52',
'Facturas' => '53',
'Otros-eguzkilore' => '54',
// Categoría: Viajes
'Mapas-GPS' => '61',
'Alojamiento' => '62',
'Vuelos' => '63',
'Otros-viajes' => '64',
],
In the html file that originates, when you select 'Select Subcategory' the options are displayed, but it only show us the first 6, and you must use the scroll to see the others.
Question: How can I show all of them at once (suppose they are 11) without using the scroll?
I have tried the following. I have located the file that draws the form:
vendor/sonata-project/admin-bundle/src/Resources/views/Form/form_admin_fields.html.twig
I add size="11" in the next row:
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %} size="11">
but it doesn't work.

I have found a solution: I found it in the following css file:
public/bundles/sonatacore/vendor/select2/select2.css
you have to modify the max-height property (set by default to 200px) in the class .select2-results:
.select2-results {
max-height: 800px;

Related

Cannot get CakePHP 3.8 multiple file upload to work

I'm working on this project and at first it has a single file upload that works perfectly fine, but had to change to multiple file upload and now I just can't make it work!
Getting an "Headers aready sent" error:
Deprecated (16384): Accessing `here` as a property will be removed in 4.0.0. Use request->getAttribute("here") instead. - /home1/thecyb80/seibo.the-cyberpunk.com/src/Controller/AppController.php, line: 92
You can disable deprecation warnings by setting `Error.errorLevel` to `E_ALL & ~E_USER_DEPRECATED` in your config/app.php. [CORE/src/Core/functions.php, line 311]
Warning (512): Unable to emit headers. Headers sent in file=/home1/thecyb80/seibo.the-cyberpunk.com/vendor/cakephp/cakephp/src/Error/Debugger.php line=856 [CORE/src/Http/ResponseEmitter.php, line 51]
Warning (2): Cannot modify header information - headers already sent by (output started at /home1/thecyb80/seibo.the-cyberpunk.com/vendor/cakephp/cakephp/src/Error/Debugger.php:856) [CORE/src/Http/ResponseEmitter.php, line 152]
Warning (2): Cannot modify header information - headers already sent by (output started at /home1/thecyb80/seibo.the-cyberpunk.com/vendor/cakephp/cakephp/src/Error/Debugger.php:856) [CORE/src/Http/ResponseEmitter.php, line 185]
Warning (2): Cannot modify header information - headers already sent by (output started at /home1/thecyb80/seibo.the-cyberpunk.com/vendor/cakephp/cakephp/src/Error/Debugger.php:856) [CORE/src/Http/ResponseEmitter.php, line 185]
Here's my code: add.ctp
<?= $this->Form->create($atividade, ['type' => 'file']) ?>
[...]
<div class="form-group m-0">
<label class="btn btn-light p-3 rounded border d-flex align-items-center justify-content-center flex-column" style="cursor: pointer; min-height: 350px;">
<strong class="d-block">Selecione o(s) arquivo(s) da atividade. Você pode enviar até 10 arquivos.</strong>
<span class="exercicio-nome d-flex aling-items-center justify-content-center w-100 mt-3"></span>
<?= $this->Form->file('arquivos[]', [ 'class' => 'exercicio-item', 'multiple' => 'multiple', 'style' => 'display: none;', 'label' => [ 'class' => 'd-none' ] ]) ?>
</label>
</div>
Validation founded in AtividadesTable.php (that's the only occurrence of the field):
$validator
->scalar('arquivos')
->maxLength('arquivos', 255)
->allowEmptyString('arquivos')
->allowEmptyFile('arquivos');
I've tried several solutions, that I've found over the internet, but none helped me. I'm using CakePHP 3.8.11 over PHP 7.2.31.
Here'se my composer.json modules installed (don't know if it can help):
"require": {
"php": ">=5.6",
"cakephp/cakephp": "3.8.*",
"cakephp/migrations": "^2.0.0",
"cakephp/plugin-installer": "^1.0",
"mobiledetect/mobiledetectlib": "2.*"
}
Since I can't go over this step, I'm assuming that for now, my Controller is irrelevant. What can I do?
Edit: 06/04 (asked by Salines)
Multiple file upload (uploaded 4 files)
Using
<?= $this->Form->file('arquivos[]', [ 'class' => 'exercicio-item', 'multiple' => 'multiple', 'style' => 'display: none;', 'label' => [ 'class' => 'd-none' ] ]) ?>
Output
(Page just refreshs)
Single file upload
Using
<?= $this->Form->file('arquivos[]', [ 'class' => 'exercicio-item', 'multiple' => 'multiple', 'style' => 'display: none;', 'label' => [ 'class' => 'd-none' ] ]) ?>
Output
(Page just refreshs)
Multiple file upload (uploaded 4 files)
Using
<?= $this->Form->file('arquivos', [ 'class' => 'exercicio-item', 'multiple' => 'multiple', 'style' => 'display: none;', 'label' => [ 'class' => 'd-none' ] ]) ?>
Output
/src/Controller/AtividadesController.php (line 159)
[
'nome' => 'Atividade teste',
'status' => '1',
'users' => [
'_ids' => [
(int) 0 => '306'
]
],
'turmas' => [
'_ids' => [
(int) 0 => '17'
]
],
'materias' => [
'_ids' => [
(int) 0 => '45'
]
],
'descricao' => '<p>Teste</p>
',
'comeca_dia' => [
'year' => '2020',
'month' => '06',
'day' => '04'
],
'termina_dia' => [
'year' => '2020',
'month' => '06',
'day' => '04'
],
'video' => '',
'aviso_do_professor' => 'Teste',
'arquivos' => [
'tmp_name' => '/tmp/phpafKkWr',
'error' => (int) 0,
'name' => 'imagem_sobre.png',
'type' => 'image/png',
'size' => (int) 600995
]
]
Multiple file upload (uploaded 4 files)
Using
<?= $this->Form->file('arquivos. ', [ 'class' => 'exercicio-item', 'multiple' => 'multiple', 'style' => 'display: none;', 'label' => [ 'class' => 'd-none' ] ]) ?>
Output
(Page just refreshs)
AtividadesController
I'll show my AtividadesController.php (add method):
/**
* Add method
*
* #return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
*/
public function add($nivelId = null)
{
$atividade = $this->Atividades->newEntity();
if ($this->request->is('post')) {
// Edit - StackOverflow
debug($this->getRequest()->getData()); exit;
$atividade = $this->Atividades->patchEntity($atividade, $this->request->getData());
die(debug($_FILES));
// Salvando os arquivos
if (!empty($_FILES['arquivos']['name'])) {
$file = $_FILES['arquivos'];
$arquivoName = $file['name'];
$userId = $this->Auth->user('id');
$ext = substr(strtolower(strrchr($arquivoName, '.')), 1);
$arr_ext = array('zip', 'rar', 'pdf', 'doc', 'docx', 'ppt', 'pptx');
if (in_array($ext, $arr_ext)) {
$imgHashed = md5($arquivoName) . time() . '.' . $ext;
$fileDir = WWW_ROOT . 'files/' . $userId;
if (!is_dir($fileDir)) {
mkdir($fileDir);
}
#move_uploaded_file($file['tmp_name'], $fileDir . '/' . $imgHashed);
$atividade['arquivos'] = $imgHashed;
$atividade['arquivo_nome'] = $arquivoName;
} else {
$this->Flash->error(__("Só aceitamos imagens dos tipos 'zip', 'rar', 'pdf', 'doc', 'docx', 'ppt' ou 'pptx'."));
return $this->redirect(['action' => 'add']);
}
}
if ($this->Atividades->save($atividade)) {
$this->Flash->success(__('A atividade foi salva.'));
return $this->redirect(['action' => 'index', $this->Auth->user('id')]);
}
$this->Flash->error(__('A atividade não pode ser salva. Por favor, tente novamente.'));
}
$arquivos = $this->Atividades->Arquivos->find('list');
$materias = $this->Atividades->Materias->find('list');
if ($nivelId) {
$turmas = $this->Atividades->Turmas->find('list')->matching('Nivels', function($q) use ($nivelId) {
return $q
->select()
->where(['Nivels.id' => $nivelId]);
});
} else {
$turmas = $this->Atividades->Turmas->find('list');
}
$users = $this->Atividades->Users->find('list')->where(['tipo' => 'professor']);
$this->set(compact('atividade', 'arquivos', 'materias', 'turmas', 'users'));
}
Am I missing something? Some CakePHP component, maybe? Some PHP extension?

sonata_type_model - Set value to empty

Is there a way to allow to set an empty value in the sonata_type_model?
This is my current configuration:
->add('location', 'sonata_type_model', [
'class' => Location::class,
'property' => 'name',
'label' => 'Herkunft',
])
Simply add 'empty_value' => '' to the array.
Same problem here. I solved it with the help of Saving Hooks: preUpdate()
public function preUpdate($object)
{
if (!$this->getRequest()->request->get($this->getForm()->getName())['location']) {
$object->setLocation(null);
}
}
// Changed sonata_type_model to symfony entity type field
// Then add placeholder option witch recognized as empty value option in select box.
...
->add('location', null, [
'class' => Location::class,
'property' => 'name',
'label' => 'Herkunft',
'placeholder' => 'Your empty option label',
])

Adding a default option "Please Select" in cakephp dropdown

I am new to cakephp. I need to add a default
<option value="0">--Please Select--</option>
in my following select field :
$attributes = array("empty"=>false,"Selected" => 'Select City',"id" => "location");
echo $form->select("gal_location_id", $gal_locations,null,$attributes);
I tried to add
$gal_locations[0] = "--Select City--";
$attributes = array("empty"=>false,"default" => 0,"id" => "location");
but the option coming at the bottom of the list. What is the proper way to add the default option ?
You're looking for the "empty" attribute:
$this->Form->input('gal_location_id', array(
'type' => 'select',
'options' => $gal_locations,
'empty' => 'Select City', // <-- Shows as the first item and has no value
'id' => 'location'
));
See the equivalent in CakePHP3 from this post
CakePHP3
With the following option you dont get a notification to choose a dropdown item.
So if you're just looking for a default value and force the user to pick another, just replace the assign a string to 'empty'.
echo $this->Form->input('db_field', [
'label' => 'My Drop Down',
'empty' => [$default => $default], //Your default options
'options' => $my_options //Your array /list'
]);
echo $this->Form->input('country_id',[
`enter code here`'options' =>$country,
'label' => false,
'class'=>'form-control select2',
'empty'=> 'Select...',
'value' => ''
]);

Cakephp edit.ctp not populating input boxes despite existing in $this->data

I'm struggling to find the answer to this. I have only been using CakePHP for a month and I've hit a problem. It's something I can fix by manually inserting the values but I expected my data to pre-populate. Here is what is happening:
The Model is Product which hasMany 'Dynamicprice'
I'm testing a product with the id of 7 (/products/edit/7).
the first part of my edit function is:
public function edit($id = null) {
$this->Product->id = $id;
if (!$this->Product->exists()) {
throw new NotFoundException('Invalid Product');
}
if ($this->request->is('get')){
$this->request->data = $this->Product->read();
}
debug($this->request->data);
//other stuff setting vars for drop-down lists
}
the
debug($this->request->data);
gives me the following:
array(
'Product' => array(
'id' => '7',
'category_id' => '70',
'name' => 'Full Test',
'description' => 'This is to test all features',
'price' => '0.00',
'aesthetic' => true,
'image' => '',
'price_structure' => '2',
'suggest_for' => '',
'created' => '2012-06-28 12:49:06',
'modified' => '2012-06-28 12:49:06'
),
'Dynamicprice' => array(
(int) 0 => array(
'id' => '15',
'product_id' => '7',
'drop' => '600',
'prices' => '6000:9.99, 12000:18.99 '
),
(int) 1 => array(
'id' => '16',
'product_id' => '7',
'drop' => '1200',
'prices' => '6000:19.99, 12000:28.99 '
),
(int) 2 => array(
'id' => '17',
'product_id' => '7',
'drop' => '2400',
'prices' => '6000:29.99, 12000:38.99 '
)
)
)
However, whilst everything in ['Product'] pre-populates the ['Dynamicprice'] array does not pre-populate the following:
<?php
echo $this->Form->input('Dynamicprices.0.id');
echo $this->Form->input('Dynamicprices.0.drop', array('label' => 'Drop 1 (mm). Enter "0" for "Any Drop"'));
echo $this->Form->input('Dynamicprices.0.prices', array('label' => 'Prices 1', 'type' => 'textarea', 'rel' => 'dynamic'));
?><hr><?php
echo $this->Form->input('Dynamicprices.1.id');
echo $this->Form->input('Dynamicprices.1.drop', array('label' => 'Drop 2 (mm).'));
echo $this->Form->input('Dynamicprices.1.prices', array('label' => 'Prices 2', 'type' => 'textarea', 'rel' => 'dynamic'));
?><hr><?php
echo $this->Form->input('Dynamicprices.1.id');
echo $this->Form->input('Dynamicprices.2.drop', array('label' => 'Drop 3 (mm).'));
echo $this->Form->input('Dynamicprices.2.prices', array('label' => 'Prices 3', 'type' => 'textarea', 'rel' => 'dynamic'));
?>
Am I right to expect them to populate automatically and if so what have I done wrong?
I have created /Model/Dynamicprice.php with the following just to make sure:
class Dynamicprice extends AppModel {
public $name = 'Dynamicprice';
public $belongsTo = 'Product';
But as I expected it didn't change anything.
This is the second time I've done this this week; ask a stupid question. Yes I was right to expect them to pre-populate. The problem is I got my naming conventions mixed up. "Dynamicprices.1.drop" shouldn't have the 's' at the end. Silly me!

Second taxonomy autocomplet depend on first taxonomy autocomplet

Drupal-7
Second taxonomy autocomplet depend on first taxonomy autocomplet.
Add offer:
step 1) Country with autocomplet , City is empty
Country: U
------------USA
City:
step 2) when we select USA then we can use City with autocomplet
Country: USA
City: Be
-------Berkeley
Step 3) but we just insert new item Bexxx
Country: USA
City: Bexxx
Search offer:
Step 1) Country - select USA from the list, City is empty
Country: USA
-----------Germany
City:
Step 2) when we select USA then we have 3 items on the list
Country: USA
City: Berkeley
-------Berlin
-------Bexxxxx
I use Drupal 6, module Hierarchical select and Views. Then in Views I used field with exposed filter.
This is a simple example of dependent fields. Make a simple module named "myajx" and placed this code as it is. Now access through url ie "http://localhost/mypage". Now select a value from first field and you will see only its dependent values are listed in below field.
<?php
/**
* Implementation of hook_menu().
* Registers a form-based page that you can access at "http://localhost/mypage"
*/
function myajx_menu(){
return array(
'mypage' => array(
'title' => 'A page to test ajax',
'page callback' => 'drupal_get_form',
'page arguments' => array('myajx_page'),
'access arguments' => array('access content'),
)
);
}
/**
* A form with a dropdown whose options are dependent on a
* choice made in a previous dropdown.
*
* On changing the first dropdown, the options in the second are updated.
*/
function myajx_page($form, &$form_state) {
// Get the list of options to populate the first dropdown.
$options_first = myajx_first_dropdown_options();
$value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);
$form['dropdown_first'] = array(
'#type' => 'select',
'#title' => 'First Dropdown',
'#options' => $options_first,
'#default_value' => $value_dropdown_first,
// Bind an ajax callback to the change event (which is the default for the
// select form type) of the first dropdown. It will replace the second
// dropdown when rebuilt
'#ajax' => array(
// When 'event' occurs, Drupal will perform an ajax request in the
// background. Usually the default value is sufficient (eg. change for
// select elements), but valid values include any jQuery event,
// most notably 'mousedown', 'blur', and 'submit'.
'event' => 'change',
'callback' => 'myajx_ajax_callback',
'wrapper' => 'dropdown_second_replace',
),
);
$form['dropdown_second'] = array(
'#type' => 'select',
'#title' => 'Second Dropdown',
'#prefix' => '<div id="dropdown_second_replace">',
'#suffix' => '</div>',
'#options' => myajx_second_dropdown_options($value_dropdown_first),
'#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
);
return $form;
}
/**
* Selects just the second dropdown to be returned for re-rendering
*
* Since the controlling logic for populating the form is in the form builder
* function, all we do here is select the element and return it to be updated.
*
* #return renderable array (the second dropdown)
*/
function myajx_ajax_callback($form, $form_state) {
return $form['dropdown_second'];
}
/**
* Helper function to populate the first dropdown. This would normally be
* pulling data from the database.
*
* #return array of options
*/
function myajx_first_dropdown_options() {
return array(
'colors' => 'Names of colors',
'cities' => 'Names of cities',
'animals' => 'Names of animals',
);
}
function myajx_second_dropdown_options($key = '') {
$options = array(
'colors' => array(
'red' => 'Red',
'green' => 'Green',
'blue' => 'Blue'
),
'cities' => array(
'paris' => 'Paris, France',
'tokyo' => 'Tokyo, Japan',
'newyork' => 'New York, US'
),
'animals' => array(
'dog' => 'Dog',
'cat' => 'Cat',
'bird' => 'Bird'
),
);
if (isset($options[$key])) {
return $options[$key];
}
else {
return array();
}
}

Resources