Laravel 4 Populate a Dropdown list with 2 Database Columns? - php

echo Form::select(
'campaign_user_id',
User::find(1)->profile->lists('first_name', 'id'),
Input::get('campaign_user_id', $campaign->user_id),
array(
"placeholder" => "US",
'class' => 'form-control',
'disabled' => 'disabled'
)
)
The code above is used to build a Dropdown selection list. It fetches a list of Users from the database. On line 3 you can see User::find(1)->profile->lists('first_name', 'id')
It is getting the first_name column, I need to somehow get first and last name columns though and combine them in this list. So that list value is still user ID and Full name is shown.
Any idea how to make this work with 2 DB columns first_name and last_name? Or another method to reach my end goal?

// In your model
class User extends Eloquent
{
public function getFullNameAttribute()
{
return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
}
}
then grab like so:
User::find(1)->profile->lists('full_name', 'id');
OR
User::find(1)->profile->select(DB::raw('concat (first_name," ",last_name) as full_name,id'))->lists('full_name', 'id');
I prefer the first one :)

Related

How to render a dynamic Select (ChoiceType)?

So I am trying to generate a dynamic select for Product Table form
instead of writing all the options like this: (code from productType)
->add('id_cat', ChoiceType::class, [
'choices' => [
'cosmetique' =>'1',
'vetement' => '2',
'parfums' => '3',
],
])
I want the choices to be generated from another table Category(id,cat_name) .
For example instead of 'cosmetique' it shows cat_name and instead of 1 it shows id
(and those are values generated from the database from table Category)
I wrote this function that return all the values from table Category in a table $tab
public function cat (CategoryRepository $categoryRepository)
{
$allcat=$categoryRepository->findAll();
$tab=[];
foreach($allcat as $cat)
{
$tab=$cat->getId();
$tab[$tab]=$cat->getCatname();
}
return $tab;
}
I dont know where exactly I should place it? and how to send that $tab to ProductType.php page
If you have relation between the two entities (and i guess you have) you can easily use the entity type from Symfony to avoid problem like this which will show all the content inside the category table and submit the chosen object to be saved depending on your association :
$builder->add('category', EntityType::class, [
'class' => Category::class,
'choice_label' => 'cat_name',
]);
Or if you want to keep your way you can pass the array as an option to your form but its not a good practice.
Why not just make tab[] something like having a field named 'choices' statically built into it before populating and then add every I'd and category to it and return the table and return results of array wherever?
tab['choices']=$cat->getID();
tab['choices'][tab['choices']]=$cat->getCatname();
And then
for each ($choices as $choice)
For each ($choice as $category)
Print_r( $category)

Yii2 search by foreign table field and total count

Im trying to search by a foreign table as follows:
2 tables:
people:
id
name
...
url:
id
peopleID
url
People.php model:
public function getUrls()
{
return $this->hasMany(Urls::className(), ['peopleID' => 'id'])->select(['url']);
}
PeopleSearch.php model:
...
$query->joinWith(['urls']);
...
$query
->andFilterWhere(['or',
['like', 'name', $this->name],
...
['like', 'url', $this->name]]
);
This works to search value entered in "name" field in several fields including foreign url one but in my view i enter a manual pagination by using something like:
$dataProvider->prepare();
if ($dataProvider->totalCount > 0)
echo Yii::t('app', 'Showing').": <b> ".($dataProvider->pagination->page*$dataProvider->pagination->pageSize+1)."-".($dataProvider->pagination->page*$dataProvider->pagination->pageSize+$dataProvider->count)."</b> ".Yii::t('app', 'of')." <b>".$dataProvider->totalCount."</b> ".Yii::t('app', 'items');
else echo Yii::t('app', 'No results found.');
echo LinkPager::widget(['pagination' => $dataProvider->pagination])
And $dataProvider->totalCount gives me the total amount of records from joined table but not the total records from people one. For instance if i have 2 records in people table and each one has 20 urls in "url" table index.php view shows "showing 1-2 of 40 items" instead of "showing 1-2 of 2 items"
Also LinkPager::widget shows a wrong number of total pages
Note that $dataProvider is passed from the controller to the view with
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
What could I do for pagination to perform the way i want?
Thank you in advance,
In People.php model my recommendation is to remove the ->select(['url']):
public function getUrls()
{
return $this->hasMany(Urls::className(), ['peopleID' => 'id']);
}
This way you can still manipulate those urls if needed.
In PeopleSearch.php model:
...
// $query->joinWith(['urls']);
// This line is the one that makes it so you get 20 results instead of 2, because you actually get one result for each url related to the people returned by the query.
$query->with(['urls']);
// This last line makes sure the model class populates the relation using only one query.
// Two queries will end up being executed to populate both the people and url models,
// however you will get the right amount for $dataProvider->totalCount.
...
if(strlen($this->url) > 0) {
$urlsPeopleIDs = \app\models\Url::find()
->select('peopleID')
->asArray()
->where(['like', 'url', $this->url])
->all();
$query->andWhere(['id' => $urlsPeopleIDs]);
}
// This way you will only filter by url when you receive a url string with lenght > 0.
// If you haven't already, you will need to create a public property called 'url' in your PeopleSearch.php model and add a 'string' or 'safe' rule so you can actually load it's value from post.

Cakephp 3.0 how to populate a select field with database values instead of numeric index

How to populate a select dropdown in cakephp3 from a database table.
Currently Cakephp produces an array (list of options) which is numeric indexed.
The option values should have id of database records (should not be the numeric keys generated by Cakephp)
Departments(table) is a taxonomy to classify events.
Events(table) which should store department based list of events.
A event may belongs to many departments. How do I achieve this?
EventsController.php
<?php $department_results = $connection->execute('SELECT departmentname FROM department')->fetchAll('assoc'); // list of departments
$this->set('departmentvalues', $department_results );
Events: add.ctp
<?php echo $this->Form->input('department', array('label' => false,
'div' => false,
'type' => 'select',
'multiple'=>'checkbox',
'legend' => 'false',
'options' => $departmentvalues,
'empty' => 'Please select a Department'
));
Objective:
A select dropdown with values from database, option values should be id of the database record
Expected result:
<select name="department"><option value="2">Maths</option><option value="4">Physics</option></select>
Issue:
cakephp generates numeric indexed array of options.
<select name="department"><option value="0">Maths</option><option value="1">Physics</option></select>
You should really use the CakePHP standard for querying your models, instead of raw SQL, especially in the case of a simple list.
Something like the below should do what you need:
$department_results = $this->Departments->find('list')
->hydrate(false)
->fields(['id','departmentname'])
->toArray();
$this->set('departmentvalues', $department_results);
Note that you will need to include the fields as you have named your column departmentname. By default, a find('list') should return id and name fields.
Another option is to set the displayField this way :
`class DepartmentsTable extends Table {
public function initialize(array $config) {
parent::initialize($config);
$this->displayField('departmentname');
}
}`
In the controller you may just call the method find('list') this way :
$departments= TableRegistry::get("Departments");
$departmentvalues=$departments->find('list')
->hydrate(false)
->toArray();
$this->set('departmentvalues', $department_results);

How to populate dropdownlist from database in Codeigniter?

I have two tables: 1. STUDENT- fields are- (studentid,studentname,batch)
2. BATCH- fields are- (batchid,batchname)
I want to populate a dropdown list from the field "batchname" ( from the table "BATCH") and have the batchname selected based on the field-"batch" (from the table "Student")
My controller -
function update($id){
$this->load->model('mod_studentprofile');
$data['query']= $this->mod_studentprofile->student_get($id); //to retrieve information from the table "STUDENT"
$data['query']= $this->mod_studentprofile->batch_get();
$data['main_content']='update_studentprofile';
$this->load->view('includes/template',$data);
}
My model -
function batch_get()
{
$query = $this->db->get('batch');
return $query->result();
}
Now, I cannot figure out how to populate the dropdown in the "View". Would you please kindly help me with this?
Thanks in Advance.
You need to put the options you want displayed in the drop down into an array, like so
$options = array(
'red' => 'Red',
'green' => 'Green',
'blue' => 'Blue',
);
// The params here are:
// 'color' => name of the drop down
// '$options' => options for the drop down
// 'red' => the selected value of the drop down
echo form_dropdown('color', $options, 'red');
What I would do is create a function in my model, say $model->dropdown_options() and use that to get the rows from the database and put them into an array.
See Jamie Rumbelow's 'MY_Model' class, he has a method that does exactly what you're describing.
https://github.com/jamierumbelow/codeigniter-base-model/blob/master/core/MY_Model.php

Using the CakeDC search plugin with associated models

I'm using CakePHP 1.3.8, and I've installed the CakeDC Search plugin. I have a Tutorial model, which is in a HABTM relationship with a LearningGoal model.
I have a search action & view in the Tutorials controller with which I can successfully search fields in the Tutorial model. I'd also like to filter my tutorial search results using LearningGoal checkboxes on the same form. I've tried adding various parameters to Tutorial's $filterArgs and TutorialsController's $presetVars. I've also tried moving the relevant $filterArgs to the LearningGoal model. I have not yet been able to successfully trigger the entry for learning goals in $filterArgs.
I think I must be missing something obvious. Or maybe the Search plugin doesn't support what I'm trying to do. Does anyone know how to use this plugin to search on associated models?
So here's what I've figured out. You can combine what's below with the Search plugin directions to search on related models.
The $filterArgs piece in the Tutorial model must look like this:
var $filterArgs = array(
array('name' => 'LearningGoal', 'type' => 'subquery', 'method' => 'findByLearningGoals', 'field' => 'Tutorial.id'),
);
Here's the supporting function in the Tutorial model:
function findByLearningGoals($data = array()) {
$ids = explode('|', $data['LearningGoal']);
$ids = join(',', $ids);
$this->LearningGoalsTutorial->Behaviors->attach('Containable', array('autoFields' => false));
$this->LearningGoalsTutorial->Behaviors->attach('Search.Searchable');
$query = $this->LearningGoalsTutorial->getQuery('all',
array(
'conditions' => array('LearningGoalsTutorial.learning_goal_id IN (' . $ids . ')'),
'fields' => array('tutorial_id'),
)
);
return $query;
}
In TutorialsController, $presetVars should look like this:
public $presetVars = array(
array('field' => 'LearningGoal', 'type' => 'checkbox', 'model' => 'Tutorial'),
);
And in my search action in TutorialsController, I did this:
$this->LearningGoal = $this->Tutorial->LearningGoal;
The Prg component seems to need that.
I am using CakePHP version 2.X
Every time I come to do this in a project I always spend hours figuring out how to do it using CakeDC search behavior so I wrote this to try and remind myself with simple language what I need to do. I've also noticed that although Michael is generally correct there is no explanation which makes it more difficult to modify it to one's own project.
When you have a "has and belongs to many" relationship and you are wanting to search the joining table i.e. the table that has the two fields in it that joins the tables on either side of it together in a many-to-many relationship you want to create a subquery with a list of IDs from one of the tables in the relationship. The IDs from the table on the other side of the relationship are going to be checked to see if they are in that record and if they are then the record in the main table is going to be selected.
In this following example
SELECT Handover.id, Handover.title, Handover.description
FROM handovers AS Handover
WHERE Handover.id in
(SELECT ArosHandover.handover_id
FROM aros_handovers AS ArosHandover
WHERE ArosHandover.aro_id IN (3) AND ArosHandover.deleted != '1')
LIMIT 20
all the records from ArosHandover will be selected if they have an aro_id of 3 then the Handover.id is used to decide which Handover records to select.
On to how to do this with the CakeDC search behaviour.
Firstly, place the field into the search form:
echo $this->Form->create('Handover', array('class' => 'form-horizontal'));?>
echo $this->Form->input('aro_id', array('options' => $roles, 'multiple' => true, 'label' => __('For', true), 'div' => false, true));
etc...
notice that I have not placed the form element in the ArosHandover data space; another way of saying this is that when the form request is sent the field aro_id will be placed under the array called Handover.
In the model under the variable $filterArgs:
'aro_id' => array('name' => 'aro_id', 'type' => 'subquery', 'method' => 'findByAros', 'field' => 'Handover.id')
notice that the type is 'subquery' as I mentioned above you need to create a subquery in order to be able to find the appropriate records and by setting the type to subquery you are telling CakeDC to create a subquery snippet of SQL. The method is the function name that are going to write the code under. The field element is the name of the field which is going to appear in this part of the example query above
WHERE Handover.id in
Then you write the function that will return the subquery:
function findByAros($data = array())
{
$ids = ''; //you need to make a comma separated list of the aro_ids that are going to be checked
foreach($data['aro_id'] as $k => $v)
{
$ids .= $v . ', ';
}
if($ids != '')
{
$ids = rtrim($ids, ', ');
}
//you only need to have these two lines in if you have not already attached the behaviours in the ArosHandover model file
$this->ArosHandover->Behaviors->attach('Containable', array('autoFields' => false));
$this->ArosHandover->Behaviors->attach('Search.Searchable');
$query = $this->ArosHandover->getQuery('all',
array(
'conditions' => array('ArosHandover.aro_id IN (' . $ids . ')'),
'fields' => array('handover_id'), //the other field that you need to check against, it's the other side of the many-to-many relationship
'contain' => false //place this in if you just want to have the ArosHandover table data included
)
);
return $query;
}
In the Handovers controller:
public $components = array('Search.Prg', 'Paginator'); //you can also place this into AppController
public $presetVars = true; //using $filterArgs in the model configuration
public $paginate = array(); //declare this so that you can change it
// this is the snippet of the search form processing
public function admin_find()
{
$this->set('title_for_layout','Find handovers');
$this->Prg->commonProcess();
if(isset($this->passedArgs) && !empty($this->passedArgs))
{//the following line passes the conditions into the Paginator component
$this->Paginator->settings = array('conditions' => $this->Handover->parseCriteria($this->passedArgs));
$handovers = $this->Paginator->paginate(); // this gets the data
$this->set('handovers', $handovers); // this passes it to the template
If you want any further explanation as to why I have done something, ask and if I get an email to tell me that you have asked I will give an answer if I am able to.

Categories