Retrieving values of Form::select - forms

I have a select box with an array of data to populate it like this:
{!! Form::select('language',$languageArray,'null', ['id'=>'language','multiple',]) !!}
I am passing $languageArray with view , and is simply an array of values like ['A','B','C']...
Now while fetching the selected values i am getting numeric value of selected options. Is there a way to change the values from numeric indexes to Text written in option. i did it using an associative array as second argument like this:
['english' => 'English',
'french' => 'French',
'so on ...' => 'So On ..']
But it creates a long list and view seems to be overloaded with data is there a better way for achieving below output ???
<select name="language">
<option value="english" ">English</option>
<option value="french">French</option>
....

I suggest you to use Config values ,
Create a file like languages.php in config folder.
<?php
return ['english' => 'English',
'french' => 'French',
'so on ...' => 'So On ..'
'german' => Lang::get('languages.german')
];
View :
{!! Form::select('language',Config::get('languages'),'null', ['id'=>'language','multiple',]) !!}
As you can see, in this way you can use config values in another view too and support multi language(its important too.. look at 'german')
Last Option is creating your own Form macro for example,
Form::macro('slugiySelect', function($name , $list , $selected = null , $options = [])
{
$options = [];
foreach($list as $row)
$options[Str::slug($row)] = $row;
return Form::select($name , $options , $selected , $options);
});
In this macro your options array is slugify with Laravel string function and uses as a key , I kept value as yours. You can do it with your way.

Related

display radio buttons using FormHelper

I am using CakePHP3
I am unable to decipher the documentation on using radio buttons to create for a list of results.
There is create radio button.
Which I tried this way:
foreach ($userGroups as $group_id => $group) {
echo $this->Form->radio("UserGroup.$group_id.id", ['value' => $group_id, 'label' => $group]);
}
There is using select pickers.
Which says all you need to do is set the type to radio. But I checked the api and it looks like it will unset the type.
Anyway, I tried
echo $this->Form->select("user_circle_id", $userGroups, ['type' => 'radio']);
Nothing works.
Please advise.
UPDATE:
$userGroups = [1 => 'Group 1', 2 => 'Group 2']; // basically primary key is keys and the display fields are the values.
Use following syntax :
$selectedStatus = 1;
$attributes = array('legend'=>false,'value'=>$selectedStatus,'class'=>'sortByStatusCourse','name'=>'sortByStatusCourse');
$options = array("1"=>"Active","0"=>"Inactive");
echo $this->Form->radio('is_active', $options,$attributes);
Code explanation :
We are passing parameters to cakePHP core so that it will output Radio button in HTML.
echo $this->Form->radio :
Here 1st param is Name on field in Database. 2nd param is What are the options for radio buttons , its value and text .3rd param is what are its attributes like what should be its default value here I explicitely set it to 1 so it will already tick radio with Activetext.
According to your code : echo $this->Form->radio("UserGroup.$group_id.id", ['value' => $group_id, 'label' => $group]);
I think order of param is wrong as you pass VALUE in 2nd param which should be 3rd param.Check my code.

CakePHP - input select not taking select options from a variable

I am developing an application with CakePHP 2.3.2 and I am having some trouble with an input select on a form. I am creating an array, in my Controller, which contains a list of states. In my View I find that when I use this variable in the 'options' field of the input I do not get any select options. If I do a print_r on the variable, in the view, I see exactly what I think I should be seeing for the 'options' field. I have even tried copying this print_r output and putting it in the 'options' field and then the input select works fine.
Here is what I have
In Controller
$options = 'array(1 => \'NSW\',2 => \'ACT\',3 => \'NT\');
$this->set('all_states, $options);
In View
<?php
$options = $all_states;
echo $this->Form->create('Refine', array('url => '/ServiceDirectoryResults/view/refine'));
echo $this->Form->input('field' ,array(
'type' => 'select',
'label' => false,
'options' => $options
));
echo $this->Form->end('Refine Search');
?>
When I run this I see a select with no select options
If I add print_r($options) after the echo $this->Form->end('Refine Search'); I see
array(1 => 'NSW',2 => 'ACT,3 => 'NT')
Which is what I would expect as it is the content of the $options variable which was the $all_states variable passed from the controller. If I take this output from the print_r and replace the $option with it in the input select the select drop down works fine and I see the three options. For some reason I can't work out the select is working fine if I hard code the select options but it will not work if I pass a variable containing the array to the input select.
I would really appreciate if if someone could give me a clue what I am doing wrong here.
Kind Regards
Richard
you might try it like below:
echo $this->Form->input('field', array('type'=>'select','label' => false,
'options' => $options,'default'=>'2'));
to the following HTML being generated:
<option value="2" selected="selected">ACT</option>
option two is shown instead any other one.
Likely issue:
Arrays should not be made as strings like you have:
$options = 'array(1 => \'NSW\',2 => \'ACT\',3 => \'NT\');
Instead, just make an array:
$options = array(1 => 'NSW', 2 => 'ACT', 3 => 'NT');
Other notes:
Why are you setting $options to $all_states only to set it back?
Missing quotes all over - make sure if you start quotes, that you also end them
not good practice to hard-code your URLs (like in your Form->create)

Yii CJuiAutoComplete for Multiple values

I am a Yii Beginner and I am currently working on a Tagging system where I have 3 tables:
Issue (id,content,create_d,...etc)
Tag (id,tag)
Issue_tag_map (id,tag_id_fk,issue_id_fk)
In my /Views/Issue/_form I have added a MultiComplete Extension to retrieve multiple tag ids and labels,
I have used an afterSave function in order to directly store the Issue_id and the autocompleted Tag_ids in the Issue_tag_map table, where it is a HAS_MANY relation.
Unfortunately Nothing is being returned.
I wondered if there might be a way to store the autocompleted Tag_ids in a temporary attribute and then pass it to the model's afterSave() function.
I have been searching for a while, and this has been driving me crazy because I feel I have missed a very simple step!
Any Help or advices of any kind are deeply appreciated!
MultiComplete in Views/Issue/_form:
<?php
echo $form->labelEx($model, 'Tag');
$this->widget('application.extension.MultiComplete', array(
'model' => $model,
'attribute' => '', //Was thinking of creating a temporary here
'name' => 'tag_autocomplete',
'splitter' => ',',
'sourceUrl' => $this->createUrl('Issue/tagAutoComplete'),
// Controller/Action path for action we created in step 4.
// additional javascript options for the autocomplete plugin
'options' => array(
'minLength' => '2',
),
'htmlOptions' => array(
'style' => 'height:20px;',
),
));
echo $form->error($model, 'issue_comment_id_fk');
?>
AfterSave in /model/Issue:
protected function afterSave() {
parent::afterSave();
$issue_id = Yii::app()->db->getLastInsertID();
$tag; //here I would explode the attribute retrieved by the view form
// an SQL with two placeholders ":issue_id" and ":tag_id"
if (is_array($tag))
foreach ($tag as $tag_id) {
$sql = "INSERT INTO issue_tag_map (issue_id_fk, tag_id_fk)VALUES(:issue_id,:tag_id)";
$command = Yii::app()->db->createCommand($sql);
// replace the placeholder ":issue_id" with the actual issue value
$command->bindValue(":issue_id", $issue_id, PDO::PARAM_STR);
// replace the placeholder ":tag_id" with the actual tag_id value
$command->bindValue(":tag_id", $tag_id, PDO::PARAM_STR);
$command->execute();
}
}
And this is the Auto Complete sourceUrl in the Issue model for populating the tags:
public static function tagAutoComplete($name = '') {
$sql = 'SELECT id ,tag AS label FROM tag WHERE tag LIKE :tag';
$name = $name . '%';
return Yii::app()->db->createCommand($sql)->queryAll(true, array(':tag' => $name));
actionTagAutoComplete in /controllers/IssueController:
// This function will echo a JSON object
// of this format:
// [{id:id, name: 'name'}]
function actionTagAutocomplete() {
$term = trim($_GET['term']);
if ($term != '') {
$tags = issue::tagAutoComplete($term);
echo CJSON::encode($tags);
Yii::app()->end();
}
}
EDIT
Widget in form:
<div class="row" id="checks" >
<?php
echo $form->labelEx($model, 'company',array('title'=>'File Company Distrubution; Companies can be edited by Admins'));
?>
<?php
$this->widget('application.extension.MultiComplete', array(
'model' => $model,
'attribute' => 'company',
'splitter' => ',',
'name' => 'company_autocomplete',
'sourceUrl' => $this->createUrl('becomEn/CompanyAutocomplete'),
'options' => array(
'minLength' => '1',
),
'htmlOptions' => array(
'style' => 'height:20px;',
'size' => '45',
),
));
echo $form->error($model, 'company');
?>
</div>
Update function:
$model = $this->loadModel($id);
.....
if (isset($_POST['News'])) {
$model->attributes = $_POST['News'];
$model->companies = $this->getRecordsFromAutocompleteString($_POST['News']
['company']);
......
......
getRecordsFromAutocompleteString():
public static cordsFromAutocompleteString($string) {
$string = trim($string);
$stringArray = explode(", ", $string);
$stringArray[count($stringArray) - 1] = str_replace(",", "", $stringArray[count($stringArray) - 1]);
$criteria = new CDbCriteria();
$criteria->select = 'id';
$criteria->condition = 'company =:company';
$companies = array();
foreach ($stringArray as $company) {
$criteria->params = array(':company' => $company);
$companies[] = Company::model()->find($criteria);
}
return $companies;
}
UPDATE
since the "value" porperty is not implemented properly in this extension I referred to extending this function to the model:
public function afterFind() {
//tag is the attribute used in form
$this->tag = $this->getAllTagNames();
parent::afterFind();
}
You should have a relation between Issue and Tags defined in both Issue and Tag models ( should be a many_many relation).
So in IssueController when you send the data to create or update the model Issue, you'll get the related tags (in my case I get a string like 'bug, problem, ...').
Then you need to parse this string in your controller, get the corresponding models and assigned them to the related tags.
Here's a generic example:
//In the controller's method where you add/update the record
$issue->tags = getRecordsFromAutocompleteString($_POST['autocompleteAttribute'], 'Tag', 'tag');
Here the method I'm calling:
//parse your string ang fetch the related models
public static function getRecordsFromAutocompleteString($string, $model, $field)
{
$string = trim($string);
$stringArray = explode(", ", $string);
$stringArray[count($stringArray) - 1] = str_replace(",", "", $stringArray[count($stringArray) - 1]);
return CActiveRecord::model($model)->findAllByAttributes(array($field => $stringArray));
}
So now your $issue->tags is an array containing all the related Tags object.
In your afterSave method you'll be able to do:
protected function afterSave() {
parent::afterSave();
//$issue_id = Yii::app()->db->getLastInsertID(); Don't need it, yii is already doing it
foreach ($this->tags as $tag) {
$sql = "INSERT INTO issue_tag_map (issue_id_fk, tag_id_fk)VALUES(:issue_id,:tag_id)";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":issue_id", $this->id, PDO::PARAM_INT);
$command->bindValue(":tag_id", $tag->id, PDO::PARAM_INT);
$command->execute();
}
}
Now the above code is a basic solution. I encourage you to use activerecord-relation-behavior's extension to save the related model.
Using this extension you won't have to define anything in the afterSave method, you'll simply have to do:
$issue->tags = getRecordsFromAutocompleteString($_POST['autocompleteAttribute'], 'Tag', 'tag');
$issue->save(); // all the related models are saved by the extension, no afterSave defined!
Then you can optimize the script by fetching the id along with the tag in your autocomplete and store the selected id's in a Json array. This way you won't have to perform the sql query getRecordsFromAutocompleteString to obtain the ids. With the extension mentioned above you'll be able to do:
$issue->tags = CJSON::Decode($_POST['idTags']);//will obtain array(1, 13, ...)
$issue->save(); // all the related models are saved by the extension, the extension is handling both models and array for the relation!
Edit:
If you want to fill the autocomplete field you could define the following function:
public static function appendModelstoString($models, $fieldName)
{
$list = array();
foreach($models as $model)
{
$list[] = $model->$fieldName;
}
return implode(', ', $list);
}
You give the name of the field (in your case tag) and the list of related models and it will generate the appropriate string. Then you pass the string to the view and put it as the default value of your autocomplete field.
Answer to your edit:
In your controller you say that the companies of this model are the one that you added from the Autocomplete form:
$model->companies = $this->getRecordsFromAutocompleteString($_POST['News']
['company']);
So if the related company is not in the form it won't be saved as a related model.
You have 2 solutions:
Each time you put the already existing related model in you autocomplete field in the form before displaying it so they will be saved again as a related model and it won't disapear from the related models
$this->widget('application.extensions.multicomplete.MultiComplete', array(
'name' => 'people',
'value' => (isset($people))?$people:'',
'sourceUrl' => array('searchAutocompletePeople'),
));
In your controller before calling the getRecordsFromAutocompleteString you add the already existing models of the model.
$model->companies = array_merge(
$model->companies,
$this->getRecordsFromAutocompleteString($_POST['News']['company'])
);

sfWidgetFormDoctrineChoice adding extra choice field

I'm using sfWidgetFormDoctrineChoice and I'm reading options from table. Is it easy way to add one option and place as first which is not in this table?
By option I mean html option:
<select>
<option val="new"></option>
</select>
You could always localize the choices, then prepend the resulting array with the value you would like to use:
$choice = new sfWidgetFormDoctrineChoice(array('model' => 'MODEL', 'order_by' => array('name', 'asc')));
$choices = $choice->getChoices();
array_unshift($choices, array('key' => 'My Custom Value'));
$this->widgetSchema['widget_name'] = new sfWidgetFormChoice(array('choices' => $choices));
$this->validatorSchema['widget_name'] = new sfValidatorChoice(array('choices' => array_keys($choices));

Populate date in MultiOptions element of Zend Form

Hello I have an array like this :
Array (
[id] => 1
[code] => Dep98
[description] => Hello World
[facility] => Array (
[0] => FacName1
[1] => FacName2
)
)
But when I populate this array to Zend_Form it only show data in textboxes elements having same id as defined in array index not in multiselect dropdown element. for example:
'code' id is also define in form's first textbox element,
'description' id is also define in form's second textbox element,
'facility' id is also define in form's third MultiOptions element
But in MultiOptions it does not show any record.
I agree with Travis, you should pass an array with following values to populate:
$vals = array('code'=>5,
'description' => 'testing',
'facility' => array(1=>'FacName2'));
$form->populate($vals);
But note this - options must be filled in the facility form element before attempting to populate or validate, dont expect facility value to be set if there is an empty list of options in the facility element.
What exactly do you want in the drop down box?
The array you pass to multiOptions must be in the form of value => title.
You may want to loop through your results and generate an options array.
For example
$options = array();
foreach ( $data as $value ) {
$options[$value['id']] = $value['description'];
}
$select = Zend_From_Element_Select("select_field");
$select->multiOptions($options);
Try this:
Array (
[id] => 1
[code] => Dep98
[description] => Hello World
[facility] => Array (
FacName1 => [0]
FacName2 => [1]
)
)