CakePHP, Google Charts Plugin and JsHelper - cakephp

i wish select an element of dropdownlist (choose a Project) and with JSHELPER (ajax) update the GRAPH that show statistics of this Project.
I can choose the Project and through the 'POST' I can generate the array graph, but i cannot show the GRAPH. I tested without JSHELPER and show my Graph.
MY VIEW CODE:
<b>ESCOLHA O PROJETO: </b>
<?php
echo $this->Form->select('projects', array($projects), array('multiple' => false,
'class' => 'span2',
'id' => 'projectsTest'));
?>
</br>
<div id="chart_div" >
</div>
<?php
$this->Js->get('#projectsTest')->event('change', $this->Js->request(array(
'controller' => 'Registos',
'action' => 'timePerProjectIssueTypeChart'
), array(
'update' => '#chart_div',
'async' => true,
'method' => 'post',
'dataExpression' => true,
'data' => $this->Js->serializeForm(array(
'isForm' => true,
'inline' => true
))
)));
?>
MY VIEW TIME_PER_PROJECT_ISSUE_TYPE_CHART
<div id="chart_div" >
<?php
echo $this->GoogleChart->createJsChart($timePerProjectIssueTypeChart);
?>
</div>
CONTROLLER
function timePerProjectIssueTypeChart() {
if (!empty($this->request->data['projects'])) {
$id_project = $this->request->data['projects'];
$totalProject = $this->timeSpentPerProjectSpecific(10001, 'Registo.issuetype');
$timeSpent = $this->totalTimeSpentPerProject(10001);
//Setup data for chart
$timePerProjectIssueTypeChart = new GoogleChart();
$timePerProjectIssueTypeChart->type("PieChart");
$timePerProjectIssueTypeChart->options(array('title' => "Percentagem de Tempo (horas) investido em cada Tarefa",
'height' => 300, 'width' => 500));
$timePerProjectIssueTypeChart->columns(array(
//Each column key should correspond to a field in your data array
'issuetype' => array(
'type' => 'string',
'label' => 'Tipo Tarefa'
),
'tempoGasto' => array(
'type' => 'time',
'label' => '% horas'
)
));
//You can also use this way to loop through data and creates data rows:
foreach ($totalProject as $row) {
if ($timeSpent[0][0]['tempogasto'] != 0) {
$percentagemTempoGasto = ($this->timeToHour($row[0]['tempogasto']) / $timeSpent[0][0]['tempogasto']) * 100;
} else {
$percentagemTempoGasto = 0;
}
if (!empty($row['IssueType'])) {
$timePerProjectIssueTypeChart->addRow(array('tempoGasto' => $percentagemTempoGasto, 'issuetype' => $row['IssueType']['pname']));
} else {
$timePerProjectIssueTypeChart->addRow(array('tempoGasto' => $percentagemTempoGasto, 'issuetype' => 'Sem tarefa'));
}
}
//Set the chart for your view
$this->set('totalProject', $totalProject);
$this->set('timeSpent', $timeSpent);
$this->set(compact('timePerProjectIssueTypeChart'));
}
}
I do not put the code of the controllers, because individually tested and are working.
Thanks

Teste com ajax, sem o JS helper:
$(document).ready(function() {
$("#projectsTest").change(function(){
$.ajax({
type: 'POST',
data: { projects: $('#projectsTest').val()},
url: 'timePerProjectIssueTypeChart',
success: funcion() {
$("chart_div").load('timePerProjectIssueTypeChart');
}
})
})
});
E não esqueça de colocar $this->layout = false no controller

Related

Yii2 Kartik file input multiple file delete button

I have a problem with kartik file-input and the delete button... i have it working when i use one file. But for the multi files - i can't make the trash button working.. Here is my form and my controller action (delete-files).
As my function deleteFiles is the same for another form/controller and works, i think i have a problem with the form here, more than the action...
Any help would be very much appreciated 🙂
Here is my form code
<?php
$allfiles = [];
$initialPreviewConfigAward = [];
if (!$model->isNewRecord)
{
$filesData = ArrayHelper::map(MakerFiles::find()->where(['maker_id' => $model->id,'type'=>$model->gs_type])->all(),'id','file_url');
foreach($filesData as $iKey=>$iVal)
{
$allfiles[] = '/backend/web/'.$iVal;
$initialPreviewConfigAward = [
'caption' => '/backend/web/'.$iVal,
'url' => Url::to(['greensocial/delete-files','id' => $iKey])];
];
}
}
?>
<?= $form->field($upload, 'file_url[]')->widget(FileInput::classname(),
['options' => ['id'=>'award-file','multiple' => true],
'pluginOptions'=>[
'previewFileType' => 'any',
'overwriteInitial'=>false,
'initialPreview'=>$allfiles,
'initialPreviewAsData'=> true,
'initialPreviewConfig' => $initialPreviewConfigAward,
//'showPreview' => true,
// 'deleteUrl'=> Url::to(['maker/delete-files', 'id' => $initialPreviewConfigAward->id]),
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
],
])->label(false); ?>
Here is my function (in my controller)
public function actionDeleteFiles($id){
$file = MakerFiles::find()->where(['id'=>$id])->one();
$filetodelete = Url::to('#backend/web/').$file->file_url;
if( file_exists ( $filetodelete )) {
unlink( $filetodelete );
if($file->save(false)){
echo json_encode('Fichier supprimé');
};
//return 'fichier supprimé';
}
else { echo json_encode('Unable to delete'); }
}
So, Thank you very much #MichalHynčica, it was the missing [] i forgot... i can now move on the next problem haha
i post the code modified here:
<?php
$allfiles = [];
$initialPreviewConfigAward = [];
if (!$model->isNewRecord)
{
$filesData = ArrayHelper::map(MakerFiles::find()->where(['maker_id' => $model->id,'type'=>$model->gs_type])->all(),'id','file_url');
foreach($filesData as $iKey=>$iVal)
{
$allfiles[] = '/backend/web/'.$iVal;
$initialPreviewConfigAward = [
'caption' => '/backend/web/'.$iVal,
'url' => Url::to(['greensocial/delete-files','id' => $iKey])];
];
}
}
?>
<?= $form->field($upload, 'file_url[]')->widget(FileInput::classname(),
['options' => ['id'=>'award-file','multiple' => true],
'pluginOptions'=>[
'previewFileType' => 'any',
'overwriteInitial'=>false,
'initialPreview'=>$allfiles,
'initialPreviewAsData'=> true,
'initialPreviewConfig' => $initialPreviewConfigAward,
//'showPreview' => true,
// 'deleteUrl'=> Url::to(['maker/delete-files', 'id' => $initialPreviewConfigAward->id]),
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
],
])->label(false); ?>

Duplicate entry with cakePhp

I am trying to apply data by adding _copy to the name and of course a new ID but I am not at all expert cakePHP and I do not know where to start. Here is my view:
I add the button "duplicate" with a route in the controller
<td>
<?php echo $this->Html->link(
'Dupliquer',
array(
'controller' => 'contracts',
'action' => 'duplicate',
$contract['Contract']['id']
),
array(
'class' => 'btn btn-default btn-sm'
)
); ?>
</td>
The function I call in my controller:
public function duplicate($id = null) {
if (!$id)
{
throw new NotFoundException(__('Identifiant invalide'));
}
$contract = $this->Contract->find('first', [
'conditions' => [
'Contract.id' => $id
]
]);
if (!$this->Contract->HasAny(['Contract.id' => $id])) {
throw new NotFoundException(__('Le contrat n\'a pas pu être trouvé'));
}
$data = [
'name' => $contract['Contract']['name']. '_copy',
];
return $this->redirect('edit');
}
In my function I retrieve the information to duplicate and it is here that I stuck at the level of the recording. Do you have an idea how to do it to make it clean?
Thank you.
Change:
$contract = $this->Contract->findById($id);
to:
$contract = $this->Contract->find()->where(['id' => $id])->first();
then:
$data = [
'name' => $contract->name. '_copy',
// other fields ...
];
$entity = $this->Contracts->newEntity($data);
$this->Contracts->save($entity);
// ...
// $this->redirect($this->referer());

rawurlencode() expects parameter 1 to be string, array given [CORE\Cake\Routing\Route\CakeRoute.php, line 506]

I am new in CakePHP. I wanted to create menu in cakePHP 2.3.9 but when I run the application it gives following warning "rawurlencode() expects parameter 1 to be string, array given [CORE\Cake\Routing\Route\CakeRoute.php, line 506]"
I am giving the complete code here. I can not understand how to eliminate the warning message above.
At first I have created this file at /app/Model/menu.php. Which looks like this
<?php
class Menu extends AppModel {
var $name = 'Menu';
var $useTable = false;
function main ($selected = 'home') {
return array(
'divClass' => 'menu',
'ulClass' => 'menu',
'tabs' => array(
array(
'controller' => 'pages',
'action' => '',
'params' => '',
'aClass' => $selected == 'home' ? 'selected' : '',
'liClass' => '',
'text' => 'Home'
),
array(
'controller' => 'pages/service',
'action' => '',
'params' => '',
'aClass' => $selected == 'Service' ? 'selected' : '',
'liClass' => '',
'text' => 'Service'
),
array(
'controller' => 'pages/user',
'action' => '',
'params' => '',
'aClass' => $selected == 'users' ? 'selected' : '',
'liClass' => '',
'text' => 'Users'
),
)
); // end return
} // end Main
} // end class Menu
?>
Then I have created this file at /app/Controller/MenusController.php. Which looks like this
<?php
class MenusController extends AppController {
var $name = 'Menus';
private $menus;
function beforeFilter () {
parent::beforeFilter();
$this->menus[] = array(
'name' => 'main',
'selected' => 'users'
);
// $this->set('menuList', $this->menus);
}
function index() {
$this->menus[] = array(
'name' => 'users',
'selected' => 'users'
);
$this->set('menuList', $this->menus);
}
function menus($menus) {
$output = array();
foreach ($menus as $menu):
$output[] = $this->Menu->{$menu['name']}($menu['selected']);
endforeach;
return $output;
}
}
?>
Then, this file I have created at /app/View/Elements/menu.ctp, which looks like this
<?php
if (empty($menuList)):
$menuList = array(
array(
'name' => 'main',
'selected' => 'home'
)
);
endif;
$menus = $this->requestAction(
array(
'controller' => 'menus',
'action' => 'menus'
),
array('pass' => array( $menuList))
);
if (! empty($menus)):
foreach ($menus as $menu):
$tabs = '';
foreach ($menu['tabs'] as $tab):
$url = array(
'controller' => $tab['controller'],
'action' => $tab['action']
);
if (! empty($tab['params'])):
$url[] = $tab['params'];
endif;
$tabs .= $this->html->tag(
'li',
$this->html->link(
$tab['text'],
$url,
array('class' => $tab['aClass'])),
array('class' => $tab['liClass'])
);
endforeach;
echo '<div class="' . $menu['divClass'] . '">
<div class="container_12">
<div class="grid_12">' . $this->html->tag('ul', $tabs, array('class' =>
$menu['ulClass'])) . '</div></div></div>';
endforeach;
endif;
?>
accept my advance gratitude for help
Your framework might have a default helper function which uses php's rawurlencode() function by default too. You might want to check the parameters you should pass for $this->html->link() since php's rawurlencode() function accepts only a string as a parameter.
Although the documentation says requestAction now supports 'array based cake style URLs' which 'bypass the usage of Router::url()', try passing a string as the first parameter to request action.
For example where you currently have:
array(
'controller' => 'menus',
'action' => 'menus'
),
Try:
'menus/menus',

CakePHP re-populate list box

I have a question about cakePHP. I create two drop down lists in my view. When the user changes the value in one list, I want the second to change. Currently, I have this working like this: An on click event fires when the user selects from list box one. This fires a jQuery ajax function that calls a function from my controller. This is all working fine, but how do I re-render my control, asynchronously (or, view)? I i know I could just serialize the array to json and then recreate the control in javascript, but there seems like there should be a more "CakePHP" way. Isn't that what render is for? Any help would be great. Here's the code I have so far:
jQuery:
function changeRole(getId){
$.ajax({
type: 'POST',
url: 'ResponsibilitiesRoles/getCurrentResp',
data: { roleId: getId },
cache: false,
dataType: 'HTML',
beforeSend: function(){
},
success: function (html){
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
}
});
View:
<?php
echo 'Roles:';
echo'<select name="myOptions" multiple="multiple">';
foreach ($rolesResponsibility as $role) {
echo' <option onclick="changeRole(this.value);" value="'; echo $role["ResponsibilitiesRole"]["role_id"]; echo '">'; echo $role["r"]["role_name"]; echo '</option>';
}
echo '</select>';
echo 'Responsbility:';
echo'<select name="myOptionsResp" multiple="multiple">';
foreach ($respResponsibility as $responsibility) {
echo' <option value="'; echo $responsibility["responsibility"]["id"]; echo '">'; echo $responsibility["responsibility"]["responsibility_name"]; echo '</option>';
}
echo '</select>';
?>
Controller function:
public function getCurrentResp(){
$getId = $this->request->data['roleId'];
$responsibilityResp = $this->ResponsibilitiesRole->find('all',
array("fields" => array('role.role_name','ResponsibilitiesRole.role_id','responsibility.*'),'joins' => array(
array(
'table' => 'responsibilities',
'alias' => 'responsibility',
'type' => 'left',
'foreignKey' => false,
'conditions'=> array('ResponsibilitiesRole.responsibility_id = responsibility.id')
),
array(
'table' => 'roles',
'alias' => 'role',
'type' => 'left',
'foreignKey' => false,
'conditions'=> array('ResponsibilitiesRole.role_id = role.id')
)
),
'conditions' => array ('ResponsibilitiesRole.role_id' => $getId),
));
$this->set('respResponsibility', $responsibilityResp);
//do something here to cause the control to be rendered, without have to refresh the whole page
}
The js event is change fired on the select tag and NOT click
You can use the Form Helper to build your form.
Pay attention Naming things following the cakephp way.
Because your code is a bit confused i will make other simple example:
Country hasMany City
User belongsTo Country
User belongsTo City
ModelName/TableName (fields)
Country/countries (id, name, ....)
City/cities (id, country_id, name, ....)
User/users (id, country_id, city_id, name, ....)
View/Users/add.ctp
<?php
echo $this->Form->create('User');
echo $this->Form->input('country_id');
echo $this->Form->input('city_id');
echo $this->Form->input('name');
echo $this->Form->end('Submit');
$this->Js->get('#UserCountryId')->event('change',
$this->Js->request(
array('controller' => 'countries', 'action' => 'get_cities'),
array(
'update' => '#UserCityId',
'async' => true,
'type' => 'json',
'dataExpression' => true,
'evalScripts' => true,
'data' => $this->Js->serializeForm(array('isForm' => false, 'inline' => true)),
)
)
);
echo $this->Js->writeBuffer();
?>
UsersController.php / add:
public function add(){
...
...
// populate selects with options
$this->set('countries', $this->User->Country->find('list'));
$this->set('cities', $this->User->City->find('list'));
}
CountriesController.php / get_cities:
public function get_cities(){
Configure::write('debug', 0);
$cities = array();
if(isset($this->request->query['data']['User']['country_id'])){
$cities = $this->Country->City->find('list', array(
'conditions' => array('City.country_id' => $this->request->query['data']['User']['country_id'])
));
}
$this->set('cities', $cities);
}
View/Cities/get_cities.ctp :
<?php
if(!empty($cities)){
foreach ($cities as $id => $name) {
?>
<option value="<?php echo $id; ?>"><?php echo $name; ?></option>
<?php
}
}
?>

Cakephp isPut() Save Logic

help me to fix isPut or isPost for save logic, in the following code i can view the data in the from, but when i am trying to save it its not working, i have tried ispost and isput logic both are not working. i think problem is with controller sections not with view
here is view of my form,
<?php
echo $this->Form->create('Role',array('url'=>array('controller'=>'Organisations','action' => 'edit_profile'),'id' => 'role'));
echo $this->Form->input('RoleLanguage.rolename',array('label'=>'Profile Name:','id'=>'rolename'));
$options = array('A' => 'Approve', 'P' => 'Pending', 'D' => 'Delete');
echo $this->Form->input('Role.status', array(
'options'=>$options,
'empty' => false,
'label'=>'Status',
'style'=>'width:100px',
'id'=>'status'
));
$id= array('value' => $id);
//print_r($id);die();
echo $this->Form->hidden('rle_id', $id);
echo "<br>";
$options = array('R' => 'Role', 'P' => 'Position', 'T' => 'Team','C'=>'Core Strategic Profile');
echo $this->Form->input('Role.type', array(
'options'=>$options,
'empty' => false,
'label'=>'Type of Job Profile:',
'style'=>'width:100px',
'id'=>'type'
));
echo "<br>";
echo $this->Form->input('RoleLanguage.external_document_URL',array('label'=>'External Document URL:','id'=>'external_document_URL','type'=>'text'));
echo "<br>";
echo $this->Form->input('RoleLanguage.description', array('style'=>'width:420px','rows' => '5', 'cols' => '5','label'=>'Description','id'=>'description'));
?>
here is controller logic
function edit_profile($id=NULL)
{
$this->layout='Ajax';
//print_r($id);die();
$this->set('id',$id);
$this->Role->recursive = 0;
$this->Role->id = $id;
$language = $this->getLanguage('content');
$this->Role->unBindModel(array("hasMany" => array('RoleLanguage')));
$this->Role->bindModel(array("hasOne" => array('RoleLanguage'=> array('foreignKey' => 'rle_id', 'className' => 'RoleLanguage', 'type' => 'INNER', 'conditions' => array('RoleLanguage.language' => $language)))));
$this->data = $this->Role->read();
//print_r($this->data);die();
if ($this->RequestHandler->isPut())
{
$this->data=array(null);
$this->autoRender = false;
$acc_id = $this->activeUser['User']['acc_id'];
$this->data['Role']['acc_id'] = $acc_id;
unset($this->Role->RoleLanguage->validate['rle_id']);
print_r($this->data);die();
$this->Role->saveAll($this->data);
}
}
i am serializing data in another view from where i am calling the qbove view code for that is
$.ajax({
type: 'Put',
url: $('#role').attr('action'),
data: $('#role').serialize()
It could be that the data is failing the model validation test that occurs when you call saveAll.
Have you tried printing $this->Role->invalidFields() to see if there is anything there?

Resources