How to change value in the select option of an array in the Yii2 view? - arrays

I use Yii2 Framework and I have this array filter for the 'Ordine' column:
[
'attribute' => 'Ordine',
'filterType' => GridView::FILTER_SELECT2,
'filter' => ArrayHelper::map($ordine_nome,'id','ordine'),
'filterWidgetOptions'=>['pluginOptions'=>['allowClear'=>true]],
'filterInputOptions'=>['placeholder'=>'Tutti...'],
'label' => "Ordine",
'width' => '2%',
],
Now, the array is built in this manner:
$ordini=Elenchi::find()->asArray()->orderby(['Ordine' => SORT_ASC])->all();
foreach($ordini as $l){
$ordine_nome[] = ['id'=>$l['Ordine'],'ordine'=>$l['Ordine']];
}
It's all ok. But now I want to change the value in the array select option. For example, if the value is 'OFMCap', in the array selection I want to show 'OFMCap - Ordo fratrum minorum capuccinorum'. At the moment the various selection shows only the acronim (for example OFMCap, etc....)
Anyone can help me to build this type of search?
Thank you very much, I hope to be clear.

You have mapped the same column for id and description
assuming your Elenchi models contains at least two column ordine and description
with values :
ordine description
----- -----------
OFMCap, Ordo fratrum minorum capuccinorum
so the find() return the collection of (at least) these two values
$ordini=Elenchi::find()->asArray()->orderby(['Ordine' => SORT_ASC])->all();
then you should prepare you array as
foreach($ordini as $l){
$ordine_nome[] = ['id'=>$l['ordine'],'description'=>$l['description']];
}
and you map as
'filter' => ArrayHelper::map($ordine_nome,'id','description'),
I have use lower case name for db attribure .. so manage/adapted teh case to your needs
But if you need map directly .you can wrok on array result for map()
$myMap = ArrayHelper::map($ordine_nome,'id','description'),
$myMap['OFMCap'] = 'OFMCap - Ordo fratrum minorum capuccinorum';
'filter' => $myMap,

Related

Laravel 5.5 - Updating a pivot table with a custom field given two input arrays

I have 2 input arrays, one for ingredients and one for the amount of the ingredient that is required for an associated recipe. My pivot table has four columns - id, recipe_id, ingredient_id and amount. I want to use the sync method to update the pivot table, however I can't work out how I would go about passing the second 'amounts' array values and ensuring they are synced with the correct record?
$ingredients = $request->ingredients;
$ingredientAmounts = $request->ingredients_amount;
$project->ingredients()->sync( $ingredients => ['amount' => $ingredientAmounts] );
The ingredient and its amount will both have the same key so I guess I could loop through them manually and update the pivot table, but I feel like there will be a simpler way which will make better use of eloquent.
The two input arrays need to be merged to be in the format required:
$user->roles()->sync([1 => ['expires' => true], 2, 3]);
From https://laravel.com/docs/5.5/eloquent-relationships#updating-many-to-many-relationships
$array = [];
foreach ($ingredients as $key => $ingredient) {
$array[$ingredient->id] = ['amount' => $ingredientAmounts[$key]];
}
$project->ingredients()->sync($array);

DropDown contents depending on multiple other DropDown values

I'm again. I've seen many threads which asking, how to create Dropdowns with content depending of a other Dropdown value. These logic works also for me. But now I have the problem, that the content of a Dropdown depends of the selection/value of 2 other Dropdowns. The code for depending on one Dropdown would looks like this:
$form = $crud->form;
$dd1 = $form->addField('dropdown', 'color', 'Color');
$dd1->setValueList(array('1' => 'white', '2' => 'black'));
$dd1->setEmptyText('all');
$dd2 = $form->addField('dropdown', 'size', 'Size');
$dd2->setValueList(array('1' => 'small', '2' => 'normal', '3' => 'large'));
$dd2->setModel('Size');
$dd3 = $form->getElement('packaging_id');
if ($_GET['color']) {
$dd3->model->addCondition('color', $_GET['color']);
}
if ($_GET['size']) {
$dd3->model->addCondition('size', $_GET['size']);
}
$dd1->js('change',
$form->js()->atk4_form('reloadField', 'packaging_id',
array($this->api->url(), 'color' => $dd1->js()->val())
)
);
$dd2->js('change',
$form->js()->atk4_form('reloadField', 'packaging_id',
array($this->api->url(), 'size' => $dd2->js()->val())
)
);
With these code the Dropdown dd3 will be filled with the packages, which matching the 'size' OR the 'color' option. But I need, that the Dropdown dd3 will be filled with packages, which matching both, the 'size' AND the 'color' options (for example packages that are 'small' and 'black').
I think, I need a way to achieve the values from both Dropdowns dd1 and dd2 and put it into the 'reloadField' $_GET argument. Then extract it from the $_GET and apply 2 conditions. But I haven't found a way yet. Can anyone help me? Thanks.
ByE...
Description
Parameters for atk4_form are the following:
->atk4_form($js_method, $param1, $param2, $param3, ...)
As result JS method $js_method from ui.atk4_form.js will be called like this:
->$js_method($param1, $param2, $param3, ...)
If method you use is $js_method = 'reloadField', then you can have following parameters:
reloadField: function(field_name, url, fn, notrigger, arg)
So you can pass URL arguments in one (or both) of two ways - using url parameter or using arg parameter.
Solution
So one of these solutions should work for you.
Pass URL parameters already included in URL (using PHP, wrong approach):
->atk4_form(
'reloadField',
'packaging_id',
$this->api->url(null, array( /* base URL + additional parameters, formatted by PHP */
'color' => $dd1->js()->val(),
'size' => $dd2->js()->val(),
))
)
or generate URL dynamically using JS (this is correct way):
->atk4_form(
'reloadField',
'packaging_id',
$this->api->url(), /* base URL */
null,
null,
array( /* additional parameters formatted by JS */
'color' => $dd1->js()->val(),
'size' => $dd2->js()->val(),
)
)

what it the find list error

I tyed get with the method $this>model->find() an array with ids of my model that have this form:
Array ( [0] => 2, [1] => 3) (value are the IDs)
and I try $this->model->find('list') I thought that would work too but for some strange reason I have done:
$this->model->find('list',array('recursive' => -1 ,'fields' => array('model.type_id'),'conditions'=>$cond));
and the query result is:
SELECT `model`.`round_id`, `model`.`type_id` FROM `database`.`model` AS `X` WHERE `X`.`Round_id` = '1'
If I make this query to the database returns two values ​​but cakephp returns only one:
Array ( [1] => 2 )
i do not know that may be going
I would use
$ids = $this->Model->find('list', array('fields' => array('id')));
if you really need the 0 based integer keys, you can still do:
$ids = array_values($ids);
but that is not necessary IMO.
Update:
After your question update the whole meaning of your question itself changed:
If you specify only id, they keys and values will both be filled with it.
Using 'fields' => array('round_id', 'type_id') you have round_id filling the keys, and type_id filling the values for find(list).
find(list) returns always a list (key + value row). If you don't want that use find(all) then.

Unsetting elements of a cakephp generated array

I have an array called $all_countries following this structure:
Array
(
[0] => Array
(
[countries] => Array
(
[id] => 1
[countryName] => Afghanistan
)
)
[1] => Array
(
[countries] => Array
(
[id] => 2
[countryName] => Andorra
)
)
)
I want to loop through an array called prohibited_countries and unset the entire [countries] element that has a countryName matching.
foreach($prohibited_countries as $country){
//search the $all_countries array for the prohibited country and remove it...
}
Basically I've tried using an array_search() but I can't get my head around it, and I'm pretty sure I could simplify this array beforehand using Set::extract or something?
I'd be really grateful if someone could suggest the best way of doing this, thanks.
Here's an example using array_filter:
$all_countries = ...
$prohibited_countries = array('USA', 'England'); // As an example
$new_countries = array_filter($all_countries, create_function('$record', 'global $prohibited_countries; return !in_array($record["countries"]["countryName"], $prohibited_countries);'));
$new_countries now contains the filtered array
Well first of all id e teh array in the format:
Array(
'Andorra' => 2,
'Afghanistan' => 1
);
Or if you need to have the named keys then i would do:
Array(
'Andorra' => array('countryName'=> 'Andorra', 'id'=>2),
'Afghanistan' => array('countryName'=> 'Afghanistan', 'id'=>1)
);
then i would jsut use an array_diff_keys:
// assuming the restricted and full list are in the same
// array format as outlined above:
$allowedCountries = array_diff_keys($allCountries, $restrictedCountries);
If your restricted countries are just an array of names or ids then you can use array_flip, array_keys, and/or array_fill as necessary to get the values to be the keys for the array_diff_keys operation.
You could also use array_map to do it.
Try something like this (it's probably not the most efficient way, but it should work):
for ($i = count($all_countries) - 1; $i >= 0; $i--) {
if (in_array($all_countries[$i]['countries']['countryName'], $prohibited_countries) {
unset($all_countries[$i]);
}
}
If you wanted to use the Set class included in CakePHP, you could definitely reduce the simplicity of your country array with Set::combine( array(), key, value ). This will reduce the dimensionality (however, you could do this differently as well. It looks like your country array is being created by a Cake model; you could use Model::find( 'list' ) if you don't want the multiple-dimension resultant array... but YMMV).
Anyway, to solve your core problem you should use PHP's built-in array_filter(...) function. Manual page: http://us3.php.net/manual/en/function.array-filter.php
Iterates over each value in the input
array passing them to the callback
function. If the callback function
returns true, the current value from
input is returned into the result
array. Array keys are preserved.
Basically, pass it your country array. Define a callback function that will return true if the argument passed to the callback is not on the list of banned countries.
Note: array_filter will iterate over your array, and is going to be much faster (execution time-wise) than using a for loop, as array_filter is a wrapper to an underlying C function. Most of the time in PHP, you can find a built-in to massage arrays for what you need; and it's usually a good idea to use them, just because of the speed boost.
HTH,
Travis

How do I get the last inserted 'id' from the forms table and add it to the 'form_id' in the attributes table?

I have two tables,Forms and Attributes. I'm tring to retrieve the last inserted id from the Forms table and insert it to the form_id column of the Attributes table, along with the other field columns.
Earlier I retrieved the form Id from the Forms table and used it to update the value of the Form name column. It worked fine.The code for that is given below:
function saveFormName($data)
{
$this->data['Form']['formname']=$data['Form']['formname'];
$this->data['Form']['id']=$this->find('all', array(
'fields' => array('Form.id'),
'order' => 'Form.id DESC'
));
$this->id=$this->data['Form']['id'][0];
$this->saveField('name',$this->data['Form']['formname']);
}
But When I tried to do it in a similar way for updating the attributes table,the row is not saved in the database,since the value of $this->data['Form']['id'][0] is an 'Array'.
Even in the saveFormName function, the value of $this->data['Form']['id'][0] is an 'Array',but the form name gets updated correctly. Someone explain me the concept.
function saveFieldEntries($data)
{
$this->data['Form']['id']=$this->find('all', array(
'fields' => array('Form.id'),
'order' => 'Form.id DESC'
));
$this->data['Attribute']['form_id'] = $this->data['Form']['id'][0];
$this->data['Attribute']['label']= 'Label';
$this->data['Attribute']['size']='20';
$this->data['Attribute']['type']=$data['Attribute']['type'];
$this->data['Attribute']['sequence_no'] = $data['Attribute']['sequence_no'];
$this->Attribute->save($this->data);
}
EDIT:
Ok, here is the corresponding code in the controller.
function insertFormName()
{
$this->data['Form']['formname']=$this->params['form']['formname'];
$this->Form->saveFormName($this->data);
}
function insertFieldEntry()
{
$this->data['Attribute']['type']=$this->params['form']['type'];
$this->data['Attribute']['sequence_no'] = $this->params['form']['sequence_no'];
$this->Form->saveFieldEntries($this->data);
}
The parameters form name,type and sequence no are passed to the controller from the corresponding view file.
$this->data['Form']['id'][0] holds an array because find('all') returns an array.
So if you need first ID from this array, you need to pick it properly in function saveFieldEntries:
...
$this->data['Attribute']['form_id'] = $this->data['Form']['id'][0]['Form']['id'];
...

Resources