Background
I have a CGridView that contains multiple checkbox columns. I have created the checkbox columns using code like this:
$columns[] = array(
'header'=>'Health',
'value' => 'CHtml::checkBox("hsid[]", $data->healthService, array("value"=>$data->wc_client_id,"id"=>"hsid_".$data->wc_client_id))',
'type'=>'raw',
'htmlOptions'=>array('style'=>'text-align:center'),
);
$columns[] = array(
'header'=>'Education',
'value' => 'CHtml::checkBox("esid[]", $data->educationService, array("value"=>$data->wc_client_id,"id"=>"esid_".$data->wc_client_id))',
'type'=>'raw',
'htmlOptions'=>array('style'=>'text-align:center'),
);
The $data->healthService and $data->educationService are used to set the initial checked state of the checkbox, based on data from the database.
Question
How can I capture changes to each of the different checkbox in a row, and send those changes back to my controller? The controller would then update the database based on checkbox changes.
Here is how I finally got it to work:
View Code
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'service-grid',
'dataProvider'=>$clients->search(),
'columns'=>array(
'first_name',
'last_name',
array(
'header'=>'Education',
'class'=>'CDataColumn',
'type'=>'raw',
'htmlOptions'=>array('style'=>'text-align:center'),
'value' => 'CHtml::checkBox("esid[]", $data->education, array("value"=>$data->wc_client_id,"id"=>"esid_".$data->wc_client_id))',
),
array(
'header'=>'Health',
'class'=>'CDataColumn',
'type'=>'raw',
'htmlOptions'=>array('style'=>'text-align:center'),
'value' => 'CHtml::checkBox("hsid[]", $data->health, array("value"=>$data->wc_client_id,"id"=>"hsid_".$data->wc_client_id))',
)
),
));
Controller Code To Retrieve Selected IDs
$healthClientId = array();
if(isset($_POST['hsid']) && is_array($_POST['hsid']))
{
$healthClientId = $_POST['hsid'];
}
$educationClientId = array();
if(isset($_POST['esid']) && is_array($_POST['esid']))
{
$educationClientId = $_POST['esid'];
}
May be a better choice is a CCheckBoxColumn ?
See http://www.yiiframework.com/doc/api/1.1/CCheckBoxColumn
Related
I am building my first Drupal 7 module and am having trouble with the screen to edit a fieldable entity. I am using field_attach_form and it is working great for all accept one field which is displaying the field default rather than the current content of that field for that entity.
I have a text field, a number field, a number of Boolean fields and the one list_text field which is failing.
Any ideas what I a doing incorrectly? Code below is what I think is needed but please do let me know if you need more.
Code to create the field in hook_enable:
if (!field_info_field('field_available')) {
$field = array (
'field_name' => 'field_available',
'type' => 'list_text',
'settings' => array(
'allowed_values' => array('No', 'Provisionally', 'Yes'),
),
);
field_create_field($field);
Code to create the instance, also in hook_enable:
if (!field_info_instance('appointments_status', 'field_available', 'appointments_status')) {
$instance = array(
'field_name' => 'field_available',
'entity_type' => 'appointments_status',
'bundle' => 'appointments_status',
'label' => t('Available?'),
'required' => TRUE,
'default_value' => array(array('value' => 'No')),
'description' => t('Set to No if appointments with this status make this slot unavailable, Provisionally means that it will only reserve a space temporarily'),
);
field_create_instance($instance);
This entity has only the one bundle with the same name as the entity.
The code to create the URL in hook_menu:
$items['admin/appointments/appointments_statii/%/edit'] = array(
'title' => 'Edit appointment status',
'description' => 'Edit the parameters of the selected status code',
'page callback' => 'drupal_get_form',
'page arguments' => array('appointments_status_edit_form',3),
'access arguments' => array('access administration pages'),
'type' => MENU_CALLBACK,
);
The form function is:
function appointments_status_edit_form($form, &$form_state) {
// Get the status id from the form_state args
$status_id = $form_state['build_info']['args'][0];
// Load the chosen status entity
$status = entity_load_single('appointments_status', $status_id);
// Set up the fields for the form
field_attach_form('appointments_status', $status, $form, $form_state);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Save changes',
'#weight' => 99,
);
return $form;
}
I have used the Devel module's dpm to check that the data is loaded correctly by entity_load_single and it is.
Thanks
Rory
I have answered my own question!
I was also programmatically loading some entities and was not loading this field with the numbers that a list_text field stores, instead I was loading the visual text.
I used a metadata wrapper and the code looked like this:
$w_appointments_status->$appointments_availability= 'Yes';
I changed it to:
$w_appointments_status->$appointments_availability = 2;
In this example 'Yes' was the third allowed value - hence 2.
So the code in my question was in fact correct although I have since added 'widget' and 'formatter' parameters to the instance.
I am sorry if this got some of you scratching your heads thinking ' but that code is correct'!!
Regards
Rory
Cane Somebody give me an ideas on this Please!
I Generate multiple checkboxes from a table that is related with another table with HABTM relationship association.
I would like to generate multiple checkboxes with an image along with the text in the label.
My two tables are items and items_characteristics. So an Item HasAndBelongToMany characteristics, and an ItemCharacteristic HasAndBelongToMany Items.
echo $this->Form->input('Item.ItemCharacteristic',array(
'label' =>false,
'type'=>'select',
'multiple'=>'checkbox',
'options' => $itemCharacteristics ,
'selected' => $this->Html->value('ItemCharacteristic.ItemCharacteristic')
));
This code generate the list of the checkboxes properly and works perfect:
This is what i have:
Which is generated from DB from the table items_characteristics.
And this is what i wanna have:
Does Anyone have any Idea how i can achieve this Please?
I assume that in your controller you did something like:
$this->request->data = $this->Item->find('first', ... );
so that $data contains the information about selected characteristics in form of a subarray,
edit: I also assume that Item habtm ItemCharacteristic
then in your view
$checked_characteristics = Hash::extract($this->data, 'ItemCharacteristic.{n}.id');
foreach($itemCharacteristics as $id => $itemCharacteristic )
{
$checked = in_array($id, $checked_characteristics );
$img = $this->Html->image('cake.icon.png'); // put here the name
// of the icon you want to show
// based on the charateristic
// you are displayng
echo $this->Form->input(
'ItemCharacteristic.ItemCharacteristic.',
array(
'between' => $img,
'label' => $itemCharacteristic,
'value' => $id,
'type' => 'checkbox',
'checked' => $checked
)
);
}
edit: from your comment I understand that $itemCharacteristics come from a find('list') statement.
change it into a find('all', array('recursive' => -1));
now your code becomes
foreach($itemCharacteristics as $itemCharacteristic )
{
$id = $itemCharacteristic['ItemCharacteristic']['id'];
$icon_name = $itemCharacteristic['ItemCharacteristic']['icon_name']; //or wherever you get your icon path
$img = $this->Html->image($icon_name);
$itemCharacteristicName = $itemCharacteristic['ItemCharacteristic']['name'];
// same as above
}
Hello i'm using Google Charts Plugin to my CakePHP application.
In my Controller i do:
There are two functions that return two graphs.
function statistics() {
$this->timePerClient();
$this->timePerProjectChart();
}
FUNCTION timePerProject
function timePerProjectChart() {
$totalProjeto = $this->timePerProject();
$tempoTotalGasto = $this->tempoTotalInvestido();
//Setup data for chart
$timePerProjectChart = new GoogleChart();
$timePerProjectChart->type("PieChart");
$timePerProjectChart->options(array('title' => "Percentagem de Tempo (horas) investido por Projeto"));
$timePerProjectChart->columns(array(
//Each column key should correspond to a field in your data array
'projects' => array(
'type' => 'string',
'label' => 'Projeto'
),
'tempoGasto' => array(
'type' => 'time',
'label' => '% horas'
)
));
//You can also use this way to loop through data and creates data rows:
foreach ($totalProjeto as $row) {
$percentagemTempoGasto = ($this->timeToHour($row[0]['tempogasto']) / $tempoTotalGasto[0][0]['tempogasto']) * 100;
$timePerProjectChart->addRow(array('tempoGasto' => $percentagemTempoGasto, 'projects' => $row['Project']['pname']));
}
//Set the chart for your view
$this->set('timePerProjectChart', $timePerProjectChart);
}
In my view (statistics) i do :
<div id="chart_div" ><?php $this->GoogleChart->createJsChart($timePerProjectChart);
$this->GoogleChart->createJsChart($timePerClientChart);
?></div>
but I just can not see a single graph. I tested (individually) each and are functioning.
I'll wish to put multiple charts on the same view.
Is it possible?
thanks
What is happening in your statistics action in your controller? $this is an object.
There are a couple steps required to use the plugin: '
Get data. Use a find or other model method to get the data you want.
Set up the chart:
$chart->type("LineChart");
$chart->options(array('title' => "Recent Scores"));
$chart->columns(array(
//Each column key should correspond to a field in your data array
'event_date' => array(
//Tells the chart what type of data this is
'type' => 'string',
//The chart label for this column
'label' => 'Date'
),
'score' => array(
'type' => 'number',
'label' => 'Score'
)
));
Add rows to your chart by looping through data, an example is given below
foreach($model as $round){
$chart->addRow($round['Round']);
}
Set the chart for your view- this is the same name that must be then called in <div id="chart_div"><?php $this->GoogleChart->createJsChart($chart);?></div> in the view.
$this->set(compact('chart'));
To display more than one chart in a single view, you need to not just use the default chart_div as the id of your div. You need to set two different divs and update the objects accordingly:
set
<?php $timePerProjectChart->div('projectChart');?>
<?php $timePerClientChart->div('clientChart');?>
<div id="projectChart"><?php $this->GoogleChart->createJsChart($timePerProjectChart);?></div>
<div id="clientChart"><?php $this->GoogleChart->createJsChart($timePerClientChart);?></div>
I am still new to PHP, and even newer to Drupal's Form API. I'm simply trying to populate a drop down select from the database. I think the issue stems from my lack of a deep understanding of how to work with multidimensional arrays. Any help is sincerely appreciated.
My code is currently:
//Query DB for Rows
$query = db_select('hp_education_years');
$query->fields('hp_education_years', array('id', 'years',));
$query->orderBy('years', 'ASC');
$results = $query->execute();
//define rows
$options = array();
foreach ($results as $result) {
$options[$result->id] = array(
$result->years,
);
}
$form['education']['year'] = array(
'#type' => 'select',
'#title' => t('Year'),
'#options' => $options,
'#states' => array(
'visible' => array(
':input[name="data_set"]' => array('value' => 'education'),
),
),
);
This returned a populated list, but displays the year's ID in bold as well as the year (2008 for example).
How can I get the dropdown just to display the year, not the year ID in bold, and then the year. It seems like $option is just a level higher than I want it to be? if that makes sense?
Many thanks in advance.
Try changing
//define rows
$options = array();
foreach ($results as $result) {
$options[$result->id] = array(
$result->years,
);
}
to
//define rows
$options = array();
foreach ($results as $result) {
$options[$result->id] = $result->years;
}
If you look at the example from Drupal's Form API, you'll see that the Options values should be just the string value and not an array.
I have built a cake model that, when searched, needs to return paginated results that exclude some items based on data in another model.
I have a model called Box and a model called Item.
Each box can have 0 or more items, but I only want the boxes with 1 or more items with the category of Fruit to appear in a pagination result.
The Box model has a 'hasMany' association with the Item model.
The Item model has a field called 'is_friut'.
take care,
lee
This will make an inner join between the tables, only when the item is_fruit.
public $paginate = array(
'joins' => array(
array(
'table' => 'items',
'alias' => 'ItemJoin',
'type' => 'INNER',
'conditions' => array(
'ItemJoin.is_fruit' => 1
)
)
)
);