need some tips on Drupal $form value - php

I got dpm($form) working. Nice! This is much better way to view data. I am still trying to figure out where stuff is coming from eg: location longitude & latitude. The word 'longitude' is referenced in 20 different places. I thought this was a likely place to isolate text box for this input field. dpm($form['#field_info']['field_store_latitude']['location_settings']['form']['fields']);
Any tips on how to track down individual input elements?
** this is not an answer, but a supplement to my first question **
hi googletorp -
I am trying to modify existing forms using hook_form_alter.
After several hours of poking around, I can now turn off location (longitude/latitude) section of a form like this:
unset($form['field_store_latitude']);
However, turning off just the latitude like this, does not work:
unset($form['field_store_latitude']['0']['#location_settings']['form']['fields']['locpick']);
I cannot find a easy way to link id and names in html source with arrays produced by Krumo.
In this case id is called "edit-field-store-latitude-0-locpick-user-latitude".
I need a recipe or guidelines for identifying form elemets in Drupal form.
I think I nailed down a solution
<?php
// allows you to alter locations fields, which are tricky to access.
// this will require a patch in location module described here:
// http://drupal.org/node/381458#comment-1287362
/**
* Implementation of custom _element_alert() hook.
*/
function form_overrides_location_element_alter(&$element){
// change some location descriptions
$element['locpick']['user_latitude']['#description'] = ' ' . t('Use decimal notation.');
$element['locpick']['user_longitude']['#description'] = ' ' . t('See <a href=!url target=_blank>our help page</a> for more information.', array('!url' => url('latlon_help')));
// or make them disappear entirely
unset($element['locpick']['user_longitude']);
unset($element['locpick']['user_latitude']);
}
/**
* Implementation of form_alter hook.
*/
function form_overrides_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'user_profile_form':
// change titles in user profile form
$form['account']['name']['#title'] = t('Login Name');
$form['account']['mail']['#title'] = t('Email');
break;
case 'retailer_node_form':
// let's check what is supposed to be here...
print '<pre>';
//print_r($form);
dsm($form);
print '</pre>';
// this works to remove the city
unset($form['field_myvar_latitude']['0']['#location_settings']['form']['fields']['city']);
// let's try #after_build property
$form['#after_build'][]='mymodule_after_build_mynode';
break;
}
}
function mymodule_after_build_mynode($form, $form_values) {
// This will not work for locations fields
return $form;
}`enter code here`

So there is sneaky way to alter the location field, what you need to do is to use the #after_built callback:
/**
* Implements hook_form_alter().
*/
function mymodule_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'x_node_form') {
// alter the location field
if (isset($form['locations'])) {
$form['locations']['#after_build'][] = 'mymodule_alter_location_field';
}
}
}
/**
* Remove the delete checkbox from location element.
*/
function mymodule_alter_location_field($form_element, &$form_state) {
$location = $form_element[0]; // The location field which you can alter
return $form_element;
}

Related

How to properly display a calculated value of a non-db field in the ListView?

In Suitecrm/SugarCRM 6.5
I need to modify the ListView. Showing the value of a field based on a certain condition.
In the Account module, the name field may be empty based on certain conditions, I require that when this occurs show the value of a custom field. To do this, first I tryied using 'customCode' + smarty as usual in Edit/Detail vies, but in several posts mention that this is not possible in the ListView. The concession is to use logic hooks + a non-db field to store the calculated field. Following this SO answer I have written the following:
Custom field at custom/Extension/modules/Accounts/Ext/Vardefs/custom_field_name_c.php
<?php
$dictionary['Account']['fields']['name_c']['name'] = 'account_name_c';
$dictionary['Account']['fields']['name_c']['vname'] = 'LBL_ACCOUNT_NAME_C';
$dictionary['Account']['fields']['name_c']['type'] = 'varchar';
$dictionary['Account']['fields']['name_c']['len'] = '255';
$dictionary['Account']['fields']['name_c']['source'] = 'non-db';
$dictionary['Account']['fields']['name_c']['dbType'] = 'non-db';
$dictionary['Account']['fields']['name_c']['studio'] = 'visible';
Label at suitecrm/custom/Extension/modules/Accounts/Ext/Language/es_ES.account_name_c.php
<?php
$mod_strings['LBL_ACCOUNT_NAME_C'] = 'Nombre de cuenta';
Logic hook entry at custom/modules/Accounts/logic_hooks.php
$hook_array['process_record'] = Array();
$hook_array['process_record'][] = Array(
2,
'Get proper name',
'custom/modules/Accounts/hooks/ListViewLogicHook.php',
'ListViewLogicHook',
'getProperName'
);
Logic hook at custom/modules/Accounts/hooks/ListViewLogicHook.php
<?php
class ListViewLogicHook
{
public function getProperName(&$bean, $event, $arguments)
{
if (empty($bean->fetched_row['name'])) {
$bean->account_name_c = $bean->fetched_row['person_name_c'];
} else {
$bean->account_name_c = $bean->fetched_row['name'];
}
// Here I also tried, but same result
// $bean->account_name_c = empty($bean->name) ? $bean->person_name_c : $bean->name;
}
}
listviewdefs.php at custom/modules/Accounts/metadata/listviewdefs.php
I added the field
'NAME_C' =>
array (
'width' => '20%',
'label' => 'LBL_ACCOUNT_NAME_C',
'default' => true,
),
After these modifications and repair I hope to see the field full with the right value. But it appears empty. I have verified that the logic hook is properly called, but the name andperson_name_c fields are always empty. In case it is relevant I have verified in Studio that the name fields in Account is typename I do not know what this means when it comes to obtaining its value.
I appreciate your comments
The problem is in the logic hook is due to first that the $bean does not have access to the custom fields, so I have to invoke them using $bean->custom_fields->retrieve(); Also the name field is always empty, I had to use DBManager to get only the name field.
The logic of the final logic hook is the following:
<?php
class ListViewLogicHook
{
public function getProperName($bean, $event, $arguments)
{
// Get access to custom fields from $bean
$bean->custom_fields->retrieve();
// Get access to name property using DBManager because $bean->name return null
$sql = "SELECT name FROM accounts WHERE id = '{$bean->id}'";
$name = $GLOBALS['db']->getOne($sql);
// Assign a value to non-db field
$bean->name_c = empty($name) ? $bean->nombre_persona_c : $name;
}
}
I was not familiar with the method $bean->custom_fields->retrieve() and at the moment I do not know why is empty the name field and I understand others fields remain empty.
I hope this is useful
We achieved that doing an after_retrieve hook, very fast and simple - This is taken from a working example.
public function RemoveCost(&$bean, $event, $arguments)
{
global $current_user;
include_once(‘modules/ACLRoles/ACLRole.php’);
$roles = ACLRole::getUserRoleNames($current_user->id);
if(!array_search("CanSeeCostRoleName",$roles)){
$bean->cost = 0;
$bean->cost_usdollar = 0;
}
}
All you need is to define and add this function to the module logic_hooks.php
You can even tailor down to specific calls:
if (isset($_REQUEST['module'],$_REQUEST['action']) && $_REQUEST['module'] == 'Opportunities' && $_REQUEST['action'] == 'DetailView')
As some times there are views you do want to show the field, for example quicksearch popup.

Zend_Form set and validate field value manually

I have a Zend_Form with a dropdown field.
When the user sets a value in the url this one should be selected as default value in this dropdown.
So what i do at the moment is this:
$parlang = $this->getRequest()->getParam('lang');
if($parlang){
$this->view->filterForm->getElement('ddLanguage')->setValue($parlang);
}
if ($this->getRequest()->isPost()) {
if($this->view->filterForm->isValid($_POST)){
...
...
...
No i want to check if the value of the variable is even a valid value for the dropdown? How can i check this in coorporation with the form validation. Yes i can check the variable against a array or so but this seems to be "fighting against the framework".
So what is the Zend way to do such a thing?
Edit:
My final solution for all who are interested, is:
$parlang = $this->getRequest()->getParam('lang');
if($parlang){
$ddLanguage = $this->view->filterForm->ddLanguage;
if($ddLanguage->isValid($parlang)){
$ddLanguage->setValue($parlang);
$language = $parlang;
}
}
I ran a quick test and it looks like one method you can use is Zend_Form_Element_Select::getMultiOption() to check if the language exists in the select values.
<?php
$parlang = $this->getRequest()->getParam('lang');
if ($parlang) {
$el = $this->view->filterForm->getElement('ddLanguage');
// attempt to get the option
// Returns null if no such option exists, otherwise returns a
// string with the display value for the option
if ($el->getMultiOption($parlang) !== null) {
$el->setValue($parlang);
}
}
If your Multiselect element contains a list of country, I would just populate a default in your element value according to the one in the URL.
In order to do so, you could create a custom Zend_Form_Element as follow:
class My_Form_Element_SelectCountry extends Zend_Form_Element_Select
{
protected $_translatorDisabled = true;
public function init()
{
$locale = Zend_Registry::get('Zend_Locale');
if (!$locale) {
throw new Exception('No locale set in registry');
}
$countries = Zend_Locale::getTranslationList('territory', $locale, 2);
unset($countries['ZZ']);
// fetch lang parameter and set US if there is no param
$request = Zend_Controller_Front::getInstance()->getRequest();
$lang = $request->getParam('lang', 'US');
// sort your country list
$oldLocale = setlocale(LC_COLLATE, '0');
setlocale(LC_COLLATE, 'en_US');
asort($countries, SORT_LOCALE_STRING);
setlocale(LC_COLLATE, $oldLocale);
// check weither the lang parameter is valid or not and add it to the list
if (isset($countries[$lang])) {
$paramLang = array($lang => $countries[$lang]);
$countries = array_merge($paramLang, $countries);
}
$this->setMultiOptions($countries);
}
}
You get the idea from this custom form.
If what you're trying to do isn't a Multiselect field filled by a country list but a list of language instead, then the logic is the same, you just need to change the call to the static method Zend_Locale::getTranslationList()and grab whatever information you need.
One more thing, if you just want a single element in your Multiselect element, then go for a Zend_Form_Element_Hidden.
It's a lot of "if" but I can't understand how looks like your Multiselect element exactly from your question.
Now let's take a look on the validation side, when you're using a Multiselect element, Zend_Framework automatically adds an InArray validator, which means that you don't have anything to do to check weither the data sent are correct or not. isValid is going to do it for you.
Weither a user let the default parameter and everything will be fine, or he modifies/deletes this parameter and the default parameter (en_US in this case, see code above) is going to be set as a default value for the Multiselect field.
To answer your last question, no it's not against the framework to check a variable set by a user and compare it with an array (from getTranslationList()for example). I would say it's even the recommended way to do things.

Yii framework - Different validation rules depending on selected options

Is it possible to create model rules that are dependent from selection?
I have a model "Deposit" which is used to enter the money transfer details..I have drop down list with two possible choices "Cash Transfer","Cheque Transfer", and i have fields cash_deposit_date,bank_name.. which is required only for cash transfer and cheque_date, cheque_no and in_favour_of.. which is required only at the time of cheque transfer.. how can i do that..?
I know i can use scenarios like this,
$model=new Deposit("cash_transfer");
or
$model=new Deposit("cheque_transfer");
but how can I change scenario depending on the value selected in dropdown list?
Couldn't you just do this:
Generated HTML:
<form>
....
<select name="scenario">
<option value="cash_transfer">Cash Transfer</option>
<option value="cheque_transfer">Checque Transfer</option>
</select>
....
</form>
Code:
// allow only lowercase letters and underscore
$scenario = preg_replace('/[^a-z_]/', '', $_POST['scenario']);
if (!empty($scenario)) {
$model = new Deposit($scenario);
} else {
die('Missing scenario!');
}
Extending from jupaju answer,
That dropdown list also a model field(transfer_type), so I have done something like this..
After checking POST values are set, I use $model->scenario = $model->transfer_type==1 ? 'cash_transfer':'cheque_transfer' to change the scenario.
My code is
$model=new Deposit;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Deposit']))
{
$model->attributes=$_POST['Deposit'];
$model->scenario = $model->transfer_type==1 ? 'cash_transfer':'cheque_transfer';
if($model->save())
$this->redirect(array('admin'));
}
$this->render('create',array('model'=>$model));
Now it is working..
I think the best way would be to use a personalized validation rule in your model and then check if the model's "scenario" property is set to one or other option.
You can read more about custom validation rules in here
Hope this helps. Good luck!
This is more simple form me
In your model put:
public $pay_type;
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
...
array('pay_type', 'required'),
array('cash_deposit_date', 'validationTransfer'),
...
);
}
public function validationTransfer($attribute,$params)
{
// this a sample, put all your need
if($this->pay_type=='cash_transfer' and $this->cash_deposit_date==='')
$this->addError('cash_deposit_date','If you will pay to Cash Transfer, enter your cahs deposit date');
// this a sample, put all your need
if($this->pay_type=='cheque_transfer' and $this->cheque_date==='')
$this->addError('cheque_date','If you will pay to Cheque Transfer, enter your cheque date');
// this a sample, put all your need
if($this->pay_type=='cheque_transfer' and $this->cheque_no==='')
$this->addError('cheque_no','If you will pay to Cheque Transfer, enter your Cheque No');
}
In the view into your widget form
<?php echo $form->labelEx($model,'pay_type',array('class'=>'control-label')); ?>
<?php echo $form->dropDownList($model,'pay_type',array("cash_transfer"=>"Cash Transfer","cheque_transfer"=>"Cheque Transfer"),array('class'=>'form-control','empty'=>'Pay Type...')); ?>
<?php echo $form->error($model,'pay_type',array('class'=>'help-block')); ?>
Note: css class like "help-block", "control-label", "form-control" on witget form are optionals, maybe you use Bootstrap 3 and it will looks good

Using Hook_form_alter on webform submitted values

Drupal 7. Webforms 3.x.
I am trying to modify a webform component value on submit. I made a custom module called 'mos' and added this code to it.
function mos_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'webform_client_form_43') {
dsm($form['#node']->{'webform'}['components']['1']);
$form['#submit'][] = 'mos_contact_us_submit';
}
}
function mos_contact_us_submit($form, &$form_state) {
$form['#node']->{'webform'}['components']['1'] = 'working#mos.com';
}
However when I look at the results in the database the regular, non-overridden value is stored. Can you help let me know what I am doing wrong?
Eventually I want to take the input value and output an email address based on what was provided (for example. 24 turns into bob#somewhere.com) But I think I can figure this part out myself.
You should to place your submit first.
array_unshift(
$form['actions']['submit']['#submit'],
'mos_contact_us_submit'
);
However, if you want to change some variables in form_state, you should to using custom _valadate function.
I got it! BIG Thanks to #dobeerman for pointing me in the right direction. Here is the code that ended up working:
function mos_form_alter(&$form, &$form_state, $form_id) {
if ('webform_client_form_43' == $form_id) {
//dsm($form);
$form['#validate'][] = 'mos_check_email';
}
}
function mos_check_email(&$form, &$form_state, $form_id) {
$emailVal = $form_state['values']['submitted']['to'];
switch($emailVal) {
case 1: $emailVal = 'email#test.com'; break;
case 2: $emailVal = 'email2#test.com'; break;
case 3: $emailVal = 'email3#test.com'; break;
......
}
$form_state['values']['submitted']['to']=$emailVal;
//dpm($form_state);
}
This way I can keep email address private, but still pass variables to the form with _GET. Kind of a weird situation... but we are trying to keep some existing code intact, so it seemed like the best route.
I accidentally messed up my account creation, so I can't give you the credit dobeerman but I emailed the admins and hopefully I will get it straightened out to get you some rep!

Drupal - CCK field - make required

I've installed the following module - http://drupal.org/project/og_reg_keys This module adds an additional field to your Organic Group Node types, to allow auser to specify a registration key for users to use to join the group.
The problem is that field is not required to be entered by the user.How can one make this field a required field ?
I found the below code, which makes the CCK field mandatory for users of a specific role, but being a non PHP person I have no idea how to change this to:
Make the Group registration key a required field (not sure what the $form element would be called or where to find this)
To remove the section on the code where it applies to users of a specific role, so that it always applies.
Code:
function mymodule_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'profile_node_form':
global $user;
if(in_array('targetrole', $user->roles)) {
$form['field_profile_pic'][0]['#required'] = 'TRUE';
$form['#field_info']['field_profile_pic']['required'] = '1';
break
Any help would be greatly appreciated. Sorry for the code being so messy, I couldn't seem to paster it correctly, it kept getting cut off.
This should make it required for all users:
function mymodule_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'profile_node_form':
$form['field_profile_pic'][0]['#required'] = 'TRUE';
$form['#field_info']['field_profile_pic']['required'] = '1';
break ;
}
}

Categories