How can I save dynamically created Gravity Form fields into entries content? - gravity-forms-plugin

The code below successfully creates a dynamic field and for a Gravity Form, and on submission the dynamic field data is included in the email content sent. However the dynamic field isn't saved in the "entries" data for that form submission, only the fields created manually using the plugin are. Anyone know how to include this data in the entries data saved?
add_filter('gform_pre_render_5', 'populate_wines');
add_filter('gform_pre_validation_5', 'populate_wines');
function populate_wines($form) {
// create dynamic select field
$props = array(
'id' => 51,
'type' => 'select',
'label' => 'Dynamic field label',
'choices' => array(
array(
'text' => '',
'value' => '',
),
array(
'text' => '1',
'value' => '1',
),
array(
'text' => '2',
'value' => '2',
),
array(
'text' => '3',
'value' => '3',
),
)
);
$new_field = GF_Fields::create( $props );
$form['fields'][] = $new_field;
return $form;
}
Edit: Dave's solution below works great for the above function (thanks!!), but adding to the function to include the looped wine list (code below), it doesn't work, any ideas?
function populate_wines($form) {
// options for select lists
$select_choices = array(
array(
'text' => '',
'value' => '',
),
array(
'text' => '1',
'value' => '1',
),
array(
'text' => '2',
'value' => '2',
),
array(
'text' => '3',
'value' => '3',
),
);
// loop through wine list
if( have_rows('wine_options') ):
$wine_count = 50;
while( have_rows('wine_options') ) : the_row();
$wine_ID = get_sub_field('wine_option');
$wine_name = get_the_title($wine_ID);
// create wine select field
$props = array(
'id' => $wine_count,
'type' => 'select',
'label' => $wine_name,
'choices' => $select_choices
);
$new_field = GF_Fields::create( $props );
$form['fields'][] = $new_field;
$wine_count++;
endwhile;
endif;
if ( GFForms::get_page() !== 'form_editor' ) {
return $form;
}
}

You'll need to call the same function on the gform_admin_pre_render filter. My recommendation would be to also add a check to exclude it from being output in the form editor but you may want that. If you don't, it'd look something like this:
if ( GFForms::get_page() !== 'form_editor' ) {
return $form;
}

Related

Radio button: input was not found in the haystack?

Whenever I submit the form I get this message:
The input was not found in the haystack.
This is for the shipping-method element (radio button). Can't figure out what it means, the POST data for that element is not null.
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
// Some other basic filters
$inputFilter->add(array(
'name' => 'shipping-method',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim')
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'max' => 20,
),
),
array(
'name' => 'Db\RecordExists',
'options' => array(
'table' => 'shipping',
'field' => 'shipping_method',
'adapter' => $this->dbAdapter
)
),
),
));
$inputFilter->get('shipping-address-2')->setRequired(false);
$inputFilter->get('shipping-address-3')->setRequired(false);
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
I only keep finding solutions for <select>.
Here's the sample POST data:
object(Zend\Stdlib\Parameters)#143 (1) {
["storage":"ArrayObject":private] => array(9) {
["shipping-name"] => string(4) "TEST"
["shipping-address-1"] => string(4) "test"
["shipping-address-2"] => string(0) ""
["shipping-address-3"] => string(0) ""
["shipping-city"] => string(4) "TEST"
["shipping-state"] => string(4) "TEST"
["shipping-country"] => string(4) "TEST"
["shipping-method"] => string(6) "Ground"
["submit-cart-shipping"] => string(0) ""
}
}
UPDATE:
form.phtml
<div class="form-group">
<?= $this->formRow($form->get('shipping-method')); ?>
<?= $this->formRadio($form->get('shipping-method')
->setValueOptions(array(
'Ground' => 'Ground',
'Expedited' => 'Expedited'))
->setDisableInArrayValidator(true)); ?>
</div>
ShippingForm.php
$this->add(array(
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Shipping Method',
'label_attributes' => array(
'class' => 'lbl-shipping-method'
),
)
));
The problem lies with when you use the setValueOptions() and the setDisableInArrayValidator(). You should do this earlier within your code as it is never set before validating your form and so the inputfilter still contain the defaults as the InArray validator. As after validation, which checks the inputfilter, you set different options for the shipping_methods.
You should move the setValueOptions() and the setDisableInArrayValidator() before the $form->isValid(). Either by setting the right options within the form itsself or doing this in the controller. Best way is to keep all of the options in one place and doing it inside the form class.
$this->add([
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => [
'value_options' => [
'Ground' => 'Ground',
'Expedited' => 'Expedited'
],
'disable_inarray_validator' => true,
'label' => 'Shipping Method',
'label_attributes' => [
'class' => 'lbl-shipping-method',
],
],
]);
Another small detail you might want to change is setting the value options. They are now hardcoded but your inputfilter is checking against database records whether they exist or not. Populate the value options with the database records. If the code still contains old methods but the database has a few new ones, they are not in sync.
class ShippingForm extends Form
{
private $dbAdapter;
public function __construct(AdapterInterface $dbAdapter, $name = 'shipping-form', $options = [])
{
parent::__construct($name, $options)
// inject the databaseAdapter into your form
$this->dbAdapter = $dbAdapter;
}
public function init()
{
// adding form elements to the form
// we use the init method to add form elements as from this point
// we also have access to custom form elements which the constructor doesn't
$this->add([
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => [
'value_options' => $this->getDbValueOptions(),
'disable_inarray_validator' => true,
'label' => 'Shipping Method',
'label_attributes' => [
'class' => 'lbl-shipping-method',
],
],
]);
}
private function getDbValueOptions()
{
$statement = $this->dbAdapter->query('SELECT shipping_method FROM shipping');
$rows = $statement->execute();
$valueOptions = [];
foreach ($rows as $row) {
$valueOptions[$row['shipping_method']] = $row['shipping_method'];
}
return $valueOptions;
}
}
Just had this happen yesterday.
The select and multi select ZF2+ elements have a built in in_array validator.
Remember filters occur before validators.
You may be doing too much here -- it is very rare to need to filter or add validators ot select and multi select form elements in ZF2 forms. The built in element validator is robust, ZF does a lot of work for us.
Try removing both filter and validator for the element, such as:
$inputFilter->add(array(
'name' => 'shipping-method',
'required' => true,
));
There is another edge case that I have seen: changing the select element's valueOptions somewhere in the controller (or view) resulting in different valueOptions used in view vs form validation (in our case it was replacing the element with a new one before validation).
I think your problem lies in the fact you are adding your value options after the InArray validator has been set, hence the validator has no haystack.
Try this
$this->add(array(
'name' => 'shipping-method',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Shipping Method',
'label_attributes' => array(
'class' => 'lbl-shipping-method'
),
'value_options' => array(
'Ground' => 'Ground',
'Expedited' => 'Expedited'
),
'disable_inarray_validator' => TRUE,
)
));
and remove setValueOptions and setDisableInArrayValidator from your view.
Hope this works.

Expand tx_news TCA

I want to add a field in the backend of the new news module. For that I created a new extension with 3 files in it:
ext_emconf.php
<?php
$EM_CONF[$_EXTKEY] = array(
'title' => 'Expand news',
'description' => 'Expand news',
'category' => 'fe',
'author' => 'SOG',
'author_email' => '-',
'shy' => '',
'dependencies' => '',
'conflicts' => '',
'priority' => '',
'module' => '',
'state' => 'stable',
'internal' => '',
'uploadfolder' => 0,
'createDirs' => '',
'modify_tables' => '',
'clearCacheOnLoad' => 0,
'lockType' => '',
'author_company' => '',
'version' => '0.1.0',
'constraints' => array(
'depends' => array(
),
'conflicts' => array(
),
'suggests' => array(
),
),
'_md5_values_when_last_written' => '',
'suggests' => array(
),
);
?>
ext_tables.php
<?php
/*if (!defined('TYPO3_MODE')) {
die ('Access denied.');
}*/
$tempColumns = array(
'tx_sogexpandnews_test' => array(
'exclude' => 0,
'label' => 'test',
'config' => array(
'type' => 'text',
'cols' => '30',
'rows' => '5',
)
),
);
t3lib_div::loadTCA('tx_news_domain_model_news');
t3lib_extMgm::addTCAcolumns('tx_news_domain_model_news',$tempColumns,1);
t3lib_extMgm::addToAllTCAtypes('tx_news_domain_model_news','tx_sogexpandnews_test', '', 'after:title'));
?>
ext_tables.sql
#
# Table structure for table 'news'
#
CREATE TABLE tx_news_domain_model_news (
tx_sogexpandnews_test text
);
The field is in the database but I dont see the field in the backend when I wanna create a new news item.
I also checked LocalConfiguation.php and made sure that my extension is under the news extension.
Any idea what I miss?
I can't tell why but I deactived news, updated it and installed it again and now I see the field.
cache - cache - cache ... always cache.
If you need to be sure, always delete everything in typo3temp and flush all cf_* tables in your db.
(deactivating and reinstalling almost does the same)

Prestashop Module : Add multi select dropdown

I'm working on a module and I would like to know how to add multiple dropdown with fields_options.
$this->fields_options = array(
'Test' => array(
'title' => $this->l('Test'),
'icon' => 'delivery',
'fields' => array(
'IXY_GALLERY_CREATION_OCCASION' => array(
'title' => $this->l('DropdownList'),
'type' => 'select',
'multiple' => true , // not working
'identifier' => 'value',
'list' => array(
1 => array('value' => 1, 'name' => $this->l('Test 1 ')),
2 => array('value' => 2, 'name' => $this->l('Test 2)'))
)
),
),
'description' =>'',
'submit' => array('title' => $this->l('Save'))
)
);
This is how I'm doin if you're meaning that :
$combo = $this->getAddFieldsValues();
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Title'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'select',
'lang' => true,
'label' => $this->l('Nom'),
'name' => 'nom_matiere',
'options' => array(
'query' => $combo[0],
'id' => 'id_option',
'name' => 'name'
)
),
array(
'type' => 'select',
'lang' => true,
'label' => $this->l('Nom'),
'name' => 'name',
'options' => array(
'query' => $combo[1],
'id' => 'id_option',
'name' => 'name'
)
),
),
),
'submit' => array(
'title' => $this->l('Save'),
'name' => $this->l('updateData'),
)
),
);
the answer are not correctly .. due its not only dfined the field in the database, also must capture and stored in special way the values, in this example i demostrate to store as "1,2,3,6,8" using a single field
THE COMPLETE CODE AND ALL THE STEPS ARE AT: https://groups.google.com/forum/m/?hl=es#!topic/venenuxsarisari/z8vfPsvFFjk
here i put only the most important parts..
as mentioned int he previous link, added a new fiel in the model definition, class and the table sql
this method permits to stored in the db as "1,2,3" so you can use only a single field to relation that multiple selected values, a better could be using groupbox but its quite difficult, take a look to the AdminCustomers controller class in the controllers directory of the prestachop, this has a multiselect group that used a relational table event stored in single field
then in the helper form list array of inputs define a select as:
at the begining dont foget to added that line:
// aqui el truco de guardar el multiselect como una secuencia separada por comas, mejor es serializada pero bueh
$this->fields_value['id_employee[]'] = explode(',',$obj->id_employee);
this $obj are the representation of the loaded previous stored value when go to edit ... from that object, get the stored value of the field of your multiselect, stored as "1,3,4,6"
and the in the field form helper list of inputs define the select multiple as:
array(
'type' => 'select',
'label' => $this->l('Select and employee'),
'name' => 'id_employee_tech',
'required' => false,
'col' => '6',
'default_value' => (int)Tools::getValue('id_employee_tech'),
'options' => array(
'query' => Employee::getEmployees(true), // el true es que solo los que estan activos
'id' => 'id_employee',
'name' => 'firstname',
'default' => array(
'value' => '',
'label' => $this->l('ninguno')
)
)
),
an then override the post process too
public function postProcess()
{
if (Tools::isSubmit('submitTallerOrden'))
{
$_POST['id_employee'] = implode(',', Tools::getValue('id_employee'));
}
parent::postProcess();
}
this make stored in the db as "1,2,3"

How to put a picture instead of text in radio element in ZF2?

Subject: How to put a picture instead of text in radio element in ZF2?
code:
Options field:
array(
'spec' => array(
'type' => 'radio',
'name' => 'fcaptcha',
'options' => array(
'label' => 'Капча',
'label_attributes' => array(
'class' => 'control-label',
),
),
'attributes' => array(
'required' => 'required',
),
),
)
Controller:
$temp[0] = 'Here you need to put a picture instead of text';
$temp[1] = 'Here you need to put a picture instead of text';
$form->get('fcaptcha')->setValueOptions($temp);
You can do that just with some CSS. Here's a simple example that you can adapt for your purpose :
Let say you have this Zend\Form\Element\Radio element :
array(
'type' => 'Zend\Form\Element\Radio',
'name' => 'fcaptcha',
'options' => array(
'value_options' => array(
'0' => 'something1',
'1' => 'something2',
),
),
'attributes' => array(
'id'=>"fcaptcha-id"
)
)
CSS :
radio-option1 {background-image:url(option1.png);}
radio-option2 {background-image:url(option2.png);}
Some JS :
$(document).ready(function(){
$(':radio[value="0"]').addClass('radio-option1');
$(':radio[value="1"]').addClass('radio-option2');
});

CakePHP Form Dropdown

I've got this table in my database that outputs this:
array(
(int) 0 => array(
'Price' => array(
'id' => '1',
'amount' => '20',
'price' => '180.00',
'type_id' => '1',
'active' => 'a'
)
),
(int) 1 => array(
'Price' => array(
'id' => '2',
'amount' => '30',
'price' => '232.50',
'type_id' => '1',
'active' => 'a'
)
),
...And so on.
I need a drop down in my form that displays the amount and price together (ie. "20 # 180.00"), but when selected, gets the "id" field.
I reworked a new array called $prices so it outputs like so...
array(
(int) 0 => array(
'id' => '1',
'amount' => '20',
'price' => '180.00',
'type_id' => '1',
'active' => 'a',
'display' => '20 # 180.00'
),
(int) 1 => array(
'id' => '2',
'amount' => '30',
'price' => '232.50',
'type_id' => '1',
'active' => 'a',
'display' => '30 # 232.50'
However, I'm not sure if that array is necessary.
But the main problem is that I don't know what to put in the Form options to make it select the "display" field.
echo $this->Form->input('Project.quantity', array(
'options' => $prices[?????]['display']
));
Simply adding the
'options' => $prices
displays a lot of stuff in the drop down (http://f.cl.ly/items/1e0X0m0D1f1c2o3K1n3h/Screen%20Shot%202013-05-08%20at%201.13.48%20PM.png).
Is there a better way of doing this?
You can use virtual fields.
In your model:
public $virtualFields = array(
'display' => 'CONCAT(amount, " # ", price)'
);
In the controller:
$prices = $this->Price->find('list', array(
'fields' => array('id', 'display')
));
Two ways to do this.
You said you reworked you array to $prices. Then, change that rework so the $prices array looks like this
array('1' => '4 # 6',
/*id*/ => /*price*/
/*etc*/);
and then pass it to the form
echo $this->Form->input('Project.quantity', array(
'options' => $prices
));
For a simple dropdown, retrieve the data with a find('list'). That will give you an array like the one you need to make a dropdown. To change the display field, create a virtual field like this in the model
public $virtualFields = array("display_price"=>"CONCAT(amount, ' # ' ,price)");
public $displayField = 'display_price';
And that way you don't have to rework your array.
If you have other drowpdowns of the same model in other forms, note that those will also change. That's the advantage of doing that in the model... Or disadvantage, if you only want to do it in one part... Like almost everything, it depends on what your need are :)