Display value in View layer (Cakephp) - cakephp

How can I display Organisation value in view, I tried this , but it does not work
Code in Model :
function getOrganisationName($organisation_id){
return $orgaName = $this->find('list',array('conditions' => array('Organisation.id' => $organisation_id), //array of conditions
'fields' => array('Organisation.name')));
}
Code in Controller :
$orgName = $this->Organisation->getOrganisationName($organisation_id);
$this->set(compact('indicators', 'organisations', 'rejections', 'projects', 'organisation_id','orgName'));
code in view :
echo $orgName['organisation']['name'];

Firstly, Code in your view should be
echo $orgName['Organisation']['name'];
Also you can use cakephp findById($id) or find(‘first’) to retrieve your data.

Related

Detect change in date field suitecrm

I'm trying to detect when the date has changed inside a regular "date" field
Have seen a few forum posts about how this can be done with text fields and dropdown, but it doesn't work for date fields.
Also tried:
'displayParams' =>
array (
'javascript' => 'onchange="checkStatusOption(this)"',
),
In the editviewdefs.php, but it didn't work (works for text fields though)
The closest I've got it actually just tracking every click on on the screen and then checking the before and after state of the date field, but it's obviously not a very elegant solution
Here's the code from the extended editview
function display() {
parent::display();
$js = <<<EOT
<script type="text/javascript" language="JavaScript">
// Capture initial state
calendar_before = document.getElementById("contract_date_c").value;
// Wait for any click to take place anywhere on the screen
$(document).click(function() {
// Capture state after we clicked somewhere
calendar_after = document.getElementById("contract_date_c").value;
// Compare the before and after
if(calendar_before != calendar_after) {
// Change detected
alert("Something's changed eh?" + calendar_before +" "+ calendar_after);
}
// Set the new state of the before_calendar
calendar_before = document.getElementById("contract_date_c").value;
});
}
</script>
EOT;
// now I output the javascript
echo $js;
}
UPDATE:
I also tried the suggested solution
1) Created a file custom/modules/un_inventory/contract_date_c_change.js and put the following inside:
function yourCustomFunction(formElement){
console.log(formElement);
}
2) Included a reference to that file in the metadata file (made sure it loads it):
array (
'file' => 'custom/modules/un_inventory/contract_date_c_change.js',
),
3) Attached the updateCallback to the field:
array (
'name' => 'contract_date_c',
'label' => 'LBL_CONTRACT_DATE',
// Checks if this field got filled up and shows hidden form field
'displayParams' =>
array (
'updateCallback' => 'yourCustomFunction();',
),
),
But nothing happens when I change that date field
Check this out (just tested in SuiteCRM 7.11) for a datetime field, for other fields take a look at this answer to another SO question
First, include your custom JS in the editviewdefs.php (example for Accounts module)
'includes' =>
array (
0 =>
array (
'file' => 'modules/Accounts/Account.js',
'file' => 'custom/modules/Accounts/myCustomFile.js',
),
),
Create the custom JS file custom/modules/Accounts/myCustomFile.js .
function yourCustomFunction(formElement){
console.log(formElement);
}
Then update the field you want to monitor for changes (contractsigned_c in the example) using the following code in the editviewdefs.php:
array (
'name' => 'contractsigned_c',
'label' => 'LBL_CONTRACTSIGNED',
'displayParams' =>
array (
'updateCallback' => 'yourCustomFunction(this)',
),
),
Now do a Repair and Rebuild inside the Admin/Repair section and voilà it should work :)
You can add the JS function on the function display() if you want, its the samething, the function will be called right after native combo update. It will look like this combo_contractsigned_c.update(); yourCustomFunction(this)
use this . it is working
YAHOO.util.Event.addListener('your_field_name', 'change', function(){
// your code here
});

Cannot render submit button

I've customized the edit profile view using template.php and user-profile-form.php
All shows up correctly but the Submit (and Delete) button..
I'm using Adaptive Theme and I've modified like this :
template.php
function adaptivetheme_theme(&$existing, $type, $theme, $path) {
return array(
'user_profile_form' => array(
'template' => 'templates/user-profile-form',
'render element' => 'form',
),
);
}
function adaptivetheme_preprocess_user_profile_form(&$vars) {
$vars['form']['account']['name']['#description'] = t('blabla');
$vars['form']['submit']['#value'] = t('Save profile');
$vars['form']['delete']['#value'] = t('Delete account');
$vars['account'] = drupal_render($vars['form']['account']);
$vars['theme_select'] = drupal_render($vars['form']['theme_select']);
$vars['picture'] = drupal_render($vars['form']['picture']);
$vars['signature_settings'] = drupal_render($vars['form']['signature_settings']);
$vars['contact'] = drupal_render($vars['form']['contact']);
$vars['timezone'] = drupal_render($vars['form']['timezone']);
$vars['submit'] = drupal_render($vars['form']['submit']);
$vars['delete'] = drupal_render($vars['form']['delete']);
}
then in the user-profile-form.tpl.php :
<div id="user-profile-form">
<?php echo $account; ?>
<?php echo $timezone; ?>
<?php echo $submit; ?>
<?php echo $delete; ?>
</div>
The edit form of the account shows correctly. I've tried adding/removing variables successfully (ie the $timezone) but the submit/delete are missing.
I don't know what's wrong..
I've tried to change the name of the variables 'submit' and 'delete' but still no button shows up. Of course I've cleared the cache every times needed (and not).
I have no JS hiding the buttons neither..
I render this form through a custom block in a Panel :
<?
module_load_include('inc', 'user', 'user.pages');
global $user;
print drupal_render(drupal_get_form('user_profile_form', $user));
?>
Maybe a problem with Panels ???
Any idea is appreciated :)
Thx for reading
Erwan
I forgot the "[action]".. :
$vars['submit'] = drupal_render($vars['form']['actions']['submit']);
$vars['cancel'] = drupal_render($vars['form']['actions']['cancel']);
And 'Delete' button didn't show up at first because it's called "cancel", and its #access param was sent to FALSE. Thx DPM ;)
Now, the problem is that when I trigger the submit button, the form is not sent, it justs reload he page. I will update if I manage to solve that too.
The page is only reloading because you forget to render the hidden form elements. To do so in your template preprocess you can use something like that :
function THEME_preprocess_user_profile_form(&$variables) {
$hidden = array();
foreach(element_children($variables['form']) as $key)
{
$type = $variables['form'][$key]['#type'];
if($type == "hidden" || $type == "token"){
$hidden[] = $variables['form'][$key];
}
}
$variables['hidden'] = $hidden;
//Dont forget to report your variables like you already did ...
}
Then when it s done render the $hidden variable in your template file
<?php print render($hidden);?>
And there you go !

cakephp string field used to create checkboxes

I'm using cakephp 2.1 and let me tell you: I just love it.
In my form I have a field that can have multiple answers (checkboxes).
I don't want to create a database field for each option, nor use an HABTM.
Update:
Since I needed several sets of flags, I went the $hasAndBelongsToMany way. (allos to add new flags without fixing the code but editing a table (eg. via phpmyadmin).
1.- Made a table/model for each set of flags I need:
2.- In my main model, declared the relation to each:
var $hasAndBelongsToMany = array('Sample','Format','Report','Openend','Dataproce','Prefield');
3.- In my main Controller, populated an array per table to use:
$openends = $this->Project->Openend->find('list', array(
//'order' => 'name'
));
4.- And use the arrays in the view:
echo $this->Form->input('Dataproce', array('label' => false, 'type' => 'select', 'multiple' => 'checkbox', 'size' => 2));
=== Old question starts here; correct answer worked for only one set of flags ===
I'd like to save a string and use it to to magically create a group of checkboxes that belong to a single data field.
I'm in the middle of it already.
my view:
echo $this->Form->input('pr_reports', array('type' => 'select',
'multiple' => 'checkbox',
'options' => array('0' => 'Interrnal',
'1' => 'Disposition',
'2' => 'Web Disposition',
'3' => 'Marginal',
'4' => 'Custom')))
my controller add method, before saving
// Used serialize() to convert the array to string
$dataString = serialize($this->request->data['Project']['pr_reports']);
$this->request->data['Project']['pr_reports'] = $dataString;
The string is being saved allright (encoded it seems but is ok: a:5:{i:0;s)
My question is how would I go when editing the record in order for the checkboxes to check themselves accordingly? That is, where do I unserialize() the string field and handle this on the edit view?
Is there a better way for this?
Thank you very much for any help.
Carlos García
==== After solution, troubles to have more than one field with a different set of flags
data is only saved for one field, ignoring the other ====
Hello;
For one field on the table it works just fine as noted;
I'm having a hard time using another field (separate set of flags).
It seems only one behaviour is attached; I was wondering if I should attach them differently.
my fields:
pr_data_format` tinyint(3) unsigned NOT NULL,
pr_report_format` tinyint(3) unsigned NOT NULL,
my controller
$this->Project->Behaviors->attach('Bitmasked', array('mappedField'=>'pr_data_formats', 'bits'=>'Project::pr_data_formats'));
$this->Project->Behaviors->attach('Bitmasked', array('mappedField'=>'pr_report_formats', 'bits'=>'Project::pr_report_formats'));
my model
const STATUS_ASCII = 1;
const STATUS_SPSS = 2;
const STATUS_EXCEL = 4;
const STATUS_CUSTOM = 8;
public static function pr_data_formats($value = null) {
$options = array(
self::STATUS_ASCII => __('ASCIId'),
self::STATUS_SPSS => __('SPSSBd'),
self::STATUS_EXCEL => __('Exceld'),
self::STATUS_CUSTOM => __('Customd'),
);
return parent::enum($value, $options);
}
const REP_ASCII = 1;
const REP_SPSS = 2;
const REP_EXCEL = 4;
const REP_CUSTOM = 8;
public static function pr_report_formats($value = null) {
$options = array(
self::REP_ASCII => __('ASCIIr'),
self::REP_SPSS => __('SPSSBr'),
self::REP_EXCEL => __('Excelr'),
self::REP_CUSTOM => __('Customr'),
);
return parent::enum($value, $options);
}
my view
echo $this->Form->input('pr_data_formats', array('options' => Project::pr_data_formats(), 'multiple' => 'checkbox'));
echo $this->Form->input('pr_report_formats', array('options' => Project::pr_report_formats(), 'multiple' => 'checkbox'));
Just can't figure it out, tried:
$this->Project->Behaviors->attach('Bitmasked', array('mappedField'=>'pr_report_formats', 'bits'=>'Project::pr_report_formats'), array('mappedField'=>'pr_data_formats', 'bits'=>'Project::pr_data_formats'));
but no use, only one field is updated.
Can you help? We'll use some 4 or 5 flagsets.
Thank you so much.
Carlos
a proper way to do this is using a behavior. this keeps your model clean and can be applied to several models simply by putting this in your model:
public $actsAs = array('MyBehavior');
now, for serializing I use my Jsonable Behavior:
http://www.dereuromark.de/2011/07/05/introducing-two-cakephp-behaviors/
it basically makes your input array a storable string on save and the string back to an array on read. you could easily adjust this to your needs.
BUT for what you want to do with multiple checkboxes there is even a better thing - bitmasks. I developed a so called Bitmasked behavior - you would need to use 1,2,4,8,... but other than that its the same thing:
http://www.dereuromark.de/2012/02/26/bitmasked-using-bitmasks-in-cakephp/
I use it exactly for the same thing.

cakephp undefined index when definitely defined

For reference, please visit this page here. When trying to get a view display on one particular model, I am getting an undefined index error. Specifically, any data from my Coupon model. Here is my controller code:
public function seafood() {
$this->paginate['Restaurant']=array(
'limit'=>9,
'order' => 'RAND()',
'contain'=>array(
'User'=>array(
'id', 'user_name'),
'Coupon'=>array(
'id','description','expires','end_date','promo_code','restaurant_id')
),
'conditions'=>array(
'Restaurant.active'=>1,
'Restaurant.seafood'=>'Seafood'
)
);
$data = $this->paginate('Restaurant');
$this->set('seafood', $data);
when I debug($seafood) in my view, all data for Coupon shows, so I know it is correctly pulling data and associating it with my Restaurant model. However, when I create a foreach loop with my $seafood array, I get nothing but undefined index errors for anything Coupon-related. What's weird is that I also have my controller pulling from the User model and anything I call up from that model in the view gets rendered. Here is my view code:
<?php foreach ($seafood as $res) { ?>
.....irrelevant code.....
<p><?php if($res['Coupon']['description'] !=''){
echo $this->Text->truncate($res['Coupon']['description'], 200, array('ending'=>'...', 'exact'=>false) );
}
else echo 'Sorry, a description of this restaurant\'s promotion is not available. <br><br><br>';
?><em> (read more -->)</em></p>
<br />
<div>
<span style="margin-left:36px;">Promo Code: <span style="font-style:bold; color:#FF0000;"><?php echo $res['User']['user_name']; ?></span></span>
<span style="margin-left:24px;">Print</span>
<?php } ?>
......more irrelevant code.....
I have tried removing the containable behavior from the array but the results are the same. I should point out that when the debug array prints, it goes in order: Restaurant, User, Coupon. Is cake somehow losing the Coupon array because it is 3rd? Or is my view code just screwy?
Looks like Restaurant hasMany Coupon so Coupon is an indexed array. You'll need a nested for loop.
foreach ($seafood as $res) {
//irrelevant
foreach ($res['Coupon'] as $coupon) {
if($coupon['description'] !=''){
//do stuff
}
}
}

Populate Webform hidden field with title of referring node

Drupal 7
I'm having a similar problem to one that's been presented previously but so far I've not been able to make any of the suggestions work.
I have 'Product' pages of content type 'Software Products'. I want to place a link on the product pages pointing to a Webform 'Request Information' I want to populate a (hidden) field on the form with the product name which is also the title of the referring product page.
I have tried the following but this just results in the title of the form being shown - not the referring page.
<?php
/**
* Implementation of hook_form_alter().
*/
function AddNodeInfoToForm_form_alter(&$form, $form_state, $form_id) {
switch($form_id) {
case 'webform_client_form_10': // the id of the form
{$current_object = menu_get_object();
$product_title = $current_object->title;
$form['submitted']['product']['#default_value'] = $product_title; }
return $form;
}
}
I would appreciate any pointers - I'm new to Drupal
That's quite a messy way round of doing what you need to, you should just put the product nid in the URL as part of the query string in the link from your product page and then load it up from the webform.
In your node template/preprocess:
$webform_path = 'node/10'; // Or whatever the webform's nid is
$link = l('Request Information', $webform_path, array(
'query' => array(
'product_nid' => $product_node->nid
)
));
echo $link;
Then in your form alter:
function AddNodeInfoToForm_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'webform_client_form_10' && isset($_GET['product_nid']) && is_numeric($_GET['product_nid'])) {
$product_node = node_load($_GET['product_nid']);
if ($product_node) {
$product_title = $product_node->title;
$form['submitted']['product']['#default_value'] = $product_title;
}
}
}
Note that you don't return the form from the hook_form_alter function, the $form variable is passed in by reference so changes are stored that way.

Resources