Display Image next to HABTM checkboxes - cakephp

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
}

Related

drupal form field not loading correct data

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

CakePhp and Google Charts Plugin

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>

multiple checkboxes with cakephp 1.2

I have a page with a list of books, and every row has a checkbox. (I'm using cakephp 1.2).
I want to let the user to save multiple books.
For now I have this checkbox in my view (in a cycle, where I get the list of all books):
<?php echo $form->input('salva', array('value' => $cdBiblio['CdBiblio']['codiceBiblio'], 'label' => '', 'type' => 'checkbox')); ?>
This form:<?php echo $form->create('cd_biblios', array('action' => 'save')); ?>
And this button:
<?php echo $form->end('Add All');?>
In the controller, I have something like this for debugging:
debug($this->data);
foreach($this->data['cd_biblios']['salva'] as $item) {
debug($item);
}
But it's not working.
I noticed that it takes only the last book id of the list with debug($this->data); and if I check more than 1 book, it show 0 or the last book id, for example:
Array (
[cd_biblios] => Array
(
[salva] => 0
) )
SOLVED:
In the view I use Danial's code.
In the controller I use this code:
if(!empty($this->data)) {
$item=$this->data;
debug($item);
$dim=count($item['Model']['field']);
$i=0;
for ($i=0;$i<$dim;$i++)
if ($item['Model']['field'][$i]!=0)
{
$data = $this->Session->read('libri');
$data[] = $item['Model']['field'][$i];
$this->Session->write('libri', $data);
}
$this->Session->setFlash(__('I libri sono stati salvati', true));
$this->redirect($this->referer());
}
In View:
<?php
foreach($array as $each_elem) {
echo $form->checkbox(
'Model.field',
array(
'id'=>'abcd_'.$each_elem['Model']['id'],
'value' => $each_elem['Model']['id'],
'hiddenField' => false,
'name' => 'data[Model][field][]',
'label' => false,
'div' => false,
));
}
?>
On submit the form, you will get the checked values in controller in $this->request->data
You have a conception problem.
Your checkboxes must be inside a form, because they are input tags. So, to send those values to the controller you'll need to submit that form. In your code, i see that "Add All" is just a link. And a link won't submit the form.
Change your link to a button :)
Hope this helps

CakePHP Count in a Loop

I extended the CakePHP Blog Tutorial, and added Categories for my Posts. The Posts Model belongsTo the Category Model. In my Posts View I am looping threw my Categories table to list the Categories for a Menu in the View, which works fine:
/* gets the category names for the menu */
$this->set('category', $this->Post->Category->find('all'));
Now I am trying to add the Post count to each Menu (Category) Item. So far I got this:
/* gets the category count for category 2*/
$this->set('category_2_count', $this->Post->find('count', array(
'conditions' => array('Category.id =' => '2'))));
The Problem is that I obviously can't use the Loop in my View anymore. With this I have to get each Category + each Count, which seems very inelegant. Is there a way to query the Category Names and the Count and get one Array for the View?
Any Ideas? I am new to Cake and any help is greatly appreciated.
In your controller:
$this->set('category', $this->Post->Category->find('all', array(
'fields' => array(
'*',
'(SELECT COUNT(*) FROM posts WHERE category_id = Category.id) AS `post_count`'
)
)));
In your view:
foreach ($category as $c) {
echo $c['Category']['name']; // category name
echo $c[0]['post_count']; // post count
}
try this:
$stats = $this->Category->Post->find('all', array(
'fields' => array(
'Category.*',
'COUNT(Post.id) AS cnt'
),
'group' => 'Category.id'
));

Yii CGridView and Multiple Checkbox Per Row

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

Resources