I have the following field
->add('specialProduct' , 'entity', array(
'class' => 'BSSmartDistributionBundle:Product',
'expanded' => true,
'multiple' => true,
'required' => true,
'label' => false,
'mapped' => false,
'query_builder' => function(ProductRepository $er) {
return $er->createQueryBuilder('p')
->where('p.active = :active')
->andWhere('p.type = :type')
->setParameter('type', 1)
->setParameter('active', 1);
},
'data' => $this->specialProduct # not working
))
I get the data and store it in session
$specialProduct = $form->get('specialProduct')->getData();
$request->getSession()->set('specialProduct', $specialProduct);
data :
Doctrine\Common\Collections\ArrayCollection Object
(
[elements:Doctrine\Common\Collections\ArrayCollection:private] => Array
(
[0] => BS\SmartDistributionBundle\Entity\Product Object
(
[id:BS\SmartDistributionBundle\Entity\Product:private] => 6
[type:BS\SmartDistributionBundle\Entity\Product:private] => 1
[name:BS\SmartDistributionBundle\Entity\Product:private] => Starter Pack
[duration:BS\SmartDistributionBundle\Entity\Product:private] => 1
[description:BS\SmartDistributionBundle\Entity\Product:private] => Tout de suite
[full_description:BS\SmartDistributionBundle\Entity\Product:private] => blabla
[price:BS\SmartDistributionBundle\Entity\Product:private] => 39
[picture:BS\SmartDistributionBundle\Entity\Product:private] => /tmp/php6h3rXK
[active:BS\SmartDistributionBundle\Entity\Product:private] => 1
)
[1] => BS\SmartDistributionBundle\Entity\Product Object
(
[id:BS\SmartDistributionBundle\Entity\Product:private] => 15
[type:BS\SmartDistributionBundle\Entity\Product:private] => 1
[name:BS\SmartDistributionBundle\Entity\Product:private] => asdsd
[duration:BS\SmartDistributionBundle\Entity\Product:private] => 2
[description:BS\SmartDistributionBundle\Entity\Product:private] => asdasd
[full_description:BS\SmartDistributionBundle\Entity\Product:private] => adsd
[price:BS\SmartDistributionBundle\Entity\Product:private] => 12
[picture:BS\SmartDistributionBundle\Entity\Product:private] => uploads/product/d978b90215d06fbf569203e7cf2d5aef.png
[active:BS\SmartDistributionBundle\Entity\Product:private] => 1
)
)
)
now I'd like to check the corresponding checkboxes !?
Same field with multiple false I can set the value with
'data' => $this->value
I tried
'data' => $this->specialProduct # not working (contains $specialProduct above)
How can I set those values ?
Do I need to pass an array ?
Thanks !
Setting default values for a form is always done on an instance of FormInterface using setData and not as data in options array for each form field. The docs says:
The default values for form fields are taken directly from the underlying data structure (e.g. an entity or an array). The data option overrides this default value.
If you used data option than the form will always have preselected what's in data and not from the entity.
So if I understand your code correctly it'd be:
$form->setData([
specialProduct => $request->getSession()->get('specialProduct')
]);
Because the stored data in session is a collection of Products.
I ended doing it this way :
I was storing and passing to the form an arrayCollection
controller :
$specialProduct = $form->get('specialProduct')->getData();
$request->getSession()->set('specialProduct', $specialProduct);
form :
$this->specialProduct = $options['specialProduct'];
'data' => $this->specialProduct
instead I use an array with only the ids
foreach ($specialProduct as $product) {
$specialProductIds[] = $product->getId();
}
$request->getSession()->set('specialProductIds', $specialProductIds);
pass it to the form with entity manager
$this->specialProductIds = $options['specialProductIds'];
$this->em = $options['em'];
in the form
public function availablespcialProduct($ids) {
if ($this->em) {
return $this->em
->getRepository('BS\SmartDistributionBundle\Entity\Product')
->findById(
$ids
);
}
}
and finally
'data' => $this->availablespcialProduct($this->specialProductIds)
Still waiting for a cleaner solution !
Thanks !
Related
I am using agile toolkit code for developing an application , i do have dropdown that get values from database, I want to show selected value from field 1 to field 2 without submit any thing.
$form->addField('field1', ['caption' => 'Field 1', 'DropDown', 'values'=> $arra1,'isMultiple' => true ,'readonly' => false, ['dropdownOptions' => ['fullTextSearch' => true]]]);
$form->addField('field2', ['caption' => 'Select Specfic Values', 'DropDown','model' => new view_values($db),'dependency' => function (view_values $model, $data)
{isset($data['field1']) ? $model->addCondition($model->fieldName()->id, 'like', '%' . $data['field1'] . '%') : null;}
,'isMultiple' => true ,'readonly' => false, ['dropdownOptions' => ['fullTextSearch' => true]]]);
issue is Fatal Error atk4\ui\Exception: Unable to add form field (), object: atk4\ui\FormField\DropDown () property: "dependency" value: {}. Looking for Help. maybe my logic is wrong.
I have managed to find a solution for 2 field multi selection scenario:
$values = new view_table($db);
$values->addCondition($db->dsql()->orExpr()->where($db->dsql()->
andExpr()->where('field_status','<>','1')));
$Array = array();
reset($Array);
foreach($values as $row){
$Array[$row['id']] = $row['field_1'].": ".$row['field_2'];
}
$fieldvalue_1 = $form->addField('fieldvalue_1', ['caption' => 'fieldvalue_1', 'DropDown', 'values'=> $Array,'isMultiple' => true ,'readonly' => $readonly, ['dropdownOptions' => ['fullTextSearch' => true]]]);
$fieldvalue_2 = $form->addField('fieldvalue_2', ['caption' => 'fieldvalue_2', 'DropDown', 'values'=> $Array,'isMultiple' => true ,'readonly' => $readonly, ['dropdownOptions' => ['fullTextSearch' => true]]])->set($_GET['val'] ?? 'No value');
$fieldvalue_1->js('change' ,new \atk4\ui\JsReload($fieldvalue_2,['val' => $fieldvalue_1->jsInput()->val()]));
Hello I just migrated from CI to Fuel.... I am using Fieldset class to auto generate form in the view.... The problem i am facing is I have multiple types of form templates i.e some of my models use twitter bootstrap horizontal inline form where as few models use custom templates... I am able to set single type of form template in form.php which i copy from fuel/core/config/form.php to fuel/app/config/form.php
Here is the sample return array for form template
return array(
// regular form definitions
'prep_value' => true,
'auto_id' => true,
'auto_id_prefix' => 'form_',
'form_method' => 'post',
'form_template' => "\n\t\t{open}\n\t\t<table>\n{fields}\n\t\t</table>\n\t\t{close}\n",
'fieldset_template' => "\n\t\t<tr><td colspan=\"2\">{open}<table>\n{fields}</table></td></tr>\n\t\t{close}\n",
'field_template' => "\t\t<tr>\n\t\t\t<td class=\"{error_class}\">{label}{required}</td>\n\t\t\t<td class=\"{error_class}\">{field} <span>{description}</span> {error_msg}</td>\n\t\t</tr>\n",
'multi_field_template' => "\t\t<tr>\n\t\t\t<td class=\"{error_class}\">{group_label}{required}</td>\n\t\t\t<td class=\"{error_class}\">{fields}\n\t\t\t\t{field} {label}<br />\n{fields}<span>{description}</span>\t\t\t{error_msg}\n\t\t\t</td>\n\t\t</tr>\n",
'error_template' => '<span>{error_msg}</span>',
'group_label' => '<span>{label}</span>',
'required_mark' => '*',
'inline_errors' => false,
'error_class' => null,
'label_class' => null,
// tabular form definitions
'tabular_form_template' => "<table>{fields}</table>\n",
'tabular_field_template' => "{field}",
'tabular_row_template' => "<tr>{fields}</tr>\n",
'tabular_row_field_template' => "\t\t\t<td>{label}{required} {field} {error_msg}</td>\n",
'tabular_delete_label' => "Delete?",
);
I want multiple form templates like this so that i will be able to auto generate the form where it is needed using $fieldset->form()->build() function...
Is there any way to do this??
yes. try this:
forge($name = 'default', $config = array());
$article_form = Fieldset::forge('article',array(
// regular form definitions
'prep_value' => true,
'auto_id' => true,
'auto_id_prefix' => 'form_',
'form_method' => 'post',
'form_template' => "\n\t\t{open}\n\t\t<table>\n{fields}\n\t\t</table>\n\t\t{close}\n",
'fieldset_template' => "\n\t\t<tr><td colspan=\"2\">{open}<table>\n{fields}</table></td></tr>\n\t\t{close}\n",
'field_template' => "\t\t<tr>\n\t\t\t<td class=\"{error_class}\">{label}{required}</td>\n\t\t\t<td class=\"{error_class}\">{field} <span>{description}</span> {error_msg}</td>\n\t\t</tr>\n",
'multi_field_template' => "\t\t<tr>\n\t\t\t<td class=\"{error_class}\">{group_label}{required}</td>\n\t\t\t<td class=\"{error_class}\">{fields}\n\t\t\t\t{field} {label}<br />\n{fields}<span>{description}</span>\t\t\t{error_msg}\n\t\t\t</td>\n\t\t</tr>\n",
'error_template' => '<span>{error_msg}</span>',
'group_label' => '<span>{label}</span>',
'required_mark' => '*',
'inline_errors' => false,
'error_class' => null,
'label_class' => null,
// tabular form definitions
'tabular_form_template' => "<table>{fields}</table>\n",
'tabular_field_template' => "{field}",
'tabular_row_template' => "<tr>{fields}</tr>\n",
'tabular_row_field_template' => "\t\t\t<td>{label}{required} {field} {error_msg}</td>\n",
'tabular_delete_label' => "Delete?",
));
I'm trying to merge eloquent result and array because I need to add all possible filters that user can use for this model. If anyone have any other idea how to make it I really would be very thankful. Here is an example code:
<?php
class School extends Eloquent {
protected $table = 'schools';
public function listSchoolsEndUser()
{
$schools_data = new School;
$schools_data = $schools_data->paginate(12);
$filters = array(
'filters' => array(
'name' => 'Neshtoto'
)
);
$schools_data = (object) array_merge(get_object_vars($schools_data), $filters);
echo '<pre>';
print_r( $schools_data );
exit;
return $schools_data;
}
And the result is very interesting:
stdClass Object
(
[filters] => Array
(
[name] => Neshtoto
)
)
If you just want to send both, filters and the school_data back in a JSON response you can do it this way:
return Response::json(array(
'filters' => array(
'name' => 'Neshtoto'
),
'data' => $school_data->toArray()
));
Or if you want to use array_merge:
$school_data = array_merge($filters, array('data' => $school_data->toArray()));
return $school_data;
Edit
If you are just injecting the data into a view I see no reason at all to merge the data, just pass two variables!
return View::make('view', array('schools' => $school_data, 'filters' => $filters));
(Here $filters would obviously only be array('name' => 'Neshtoto') and not the full thing including 'filters' => ...)
I have to modify a Zend form where some of the fields can contain decimals. Currently you can only enter your decimals using a point: 34.75)
What I'd like the users to be able is to write their decimals both with a comma or a point. The fields can contain either numbers like 34.75 and 34,75 (In this case, both have the same value). I don't want to modify any configuration on the server, so I need to do this in the code.
Right now the value of some fields is calculated in function of other fields; so when you enter a comma, it messes up the calculations. It's done in javascript, and I'll need to fix those calculations - but for now, I want to fix this issue in the php code when I retrieve the form.
I tried to find a solution on the Zend website, but I didn't find anything I've already read elsewhere with more examples. As you'll see in the code, I need to add either a filter or a validator to a zend_form_element_text. I cannot use a str_replace, as the element is a zend_form_element_text.
I have found this other question for reference.
Here is my resulting code:
$tabBilanFrais = array( 'txtFraisSecretariat' => array( 'nom' => 'Frais secrétariat', 'disabled' => true, "class"=>"calcul"),
'txtFraisRegion' => array( 'nom' => 'Frais région', 'disabled' => false),
'txtFraisSalle' => array( 'nom' => 'Salle', 'disabled' => false, "class"=>"calcul"),
'txtFraisPause' => array( 'nom' => 'Pauses', 'disabled' => false, "class"=>"calcul"),
'txtDivers' => array( 'nom' => 'Divers', 'disabled' => false, "class"=>"calcul"),
'txtTotalRegion' => array( 'nom' => 'Total région', 'disabled' => true, "class"=>"total"),
'txtIndemnisationAdherent' => array( 'nom' => 'Comm. ADH', 'disabled' => true, "class"=>"calcul"),
'txtIndemnisationPAP' => array( 'nom' => 'Comm. PAP', 'disabled' => true, "class"=>"calcul"),
'txtIndemnisationForNext' => array( 'nom' => 'Comm. ForNext', 'disabled' => true, "class"=>"calcul"),
'txtIndemnisationPROStages' => array( 'nom' => 'Comm. PROStages', 'disabled' => true, "class"=>"calcul"),
'txtRecettes' => array( 'nom' => 'Recettes', 'disabled' => true, "class"=>"totalMontant"),
'txtDepenses' => array( 'nom' => 'Dépenses', 'disabled' => true, "class"=>"totalMontant"),
'txtRecettesH' => array( 'nom' => 'Recettes', 'disabled' => false, "class"=>"hiddenTxt"),
'txtDepensesH' => array( 'nom' => 'Dépenses', 'disabled' => false, "class"=>"hiddenTxt")
);
$tabFormulaire = array() ;
foreach($tabBilanFrais as $id => $tabElement)
{
if($tabElement['nom'] == 'Frais region' )
$element = new Zend_Form_Element_Hidden($id, array("label" => $tabElement['nom'], "required" => false, 'decorators' => array("ViewHelper", "Errors", "Label"))) ;
else{
$element = new Zend_Form_Element_Text($id, array("label" => $tabElement['nom'], "required" => false, 'decorators' => array("ViewHelper", "Errors", "Label"))) ;
//$element->addFilter('pregReplace', array('match' => '/,/', 'replace' => '.'));
$element->addFilter('LocalizedToNormalized');
$element->addValidator('float', true, array('locale' => 'fr_FR'));
if(isset($tabElement['class']) && $tabElement['class']){
$element->setAttrib('class', $tabElement['class']);
}
}
if( $tabElement['disabled'])
$element->setAttrib('disabled', 'disabled');
$tabFormulaire[] = $element ;
}
The pregReplace isn't working. The validator is (comma becomes a .). I get an error message about the number not being a float.
You can always write your own validator. In case of float I faced the same problem like you:
class Yourlib_Validate_Float extends Zend_Validate_Abstract
{
const INVALID = 'floatInvalid';
const NOT_FLOAT = 'notFloat';
/**
* #var array
*/
protected $_messageTemplates = array(
self::INVALID => "Invalid type given. String, integer or float expected",
self::NOT_FLOAT => "'%value%' does not appear to be a float",
);
public function isValid($value)
{
$this->_setValue($value);
$value = str_replace(',', '.', $value);
if (!is_string($value) && !is_int($value) && !is_numeric($value)) {
$this->_error(self::INVALID);
return false;
}
if (is_numeric($value)) {
return true;
}
$this->_error(self::NOT_FLOAT);
return false;
}
}
And to add the validator:
$element->addValidator(new Yourlib_Validate_Float());
Please rename Yourlib to whatever suits you. And you need to register your "namespace" in the application.ini like this:
autoloadernamespaces.Yourlib = "Yourlib_"
Strictly speaking this validator is a numeric validator. It accepts all numeric values like ints and floats thru the check with is_numeric. Feel free to modify that.
Alright, here is the modified part of the code:
foreach($tabBilanFrais as $id => $tabElement)
{
if($tabElement['nom'] == 'Frais region' )
$element = new Zend_Form_Element_Hidden($id, array("label" => $tabElement['nom'], "required" => false, 'decorators' => array("ViewHelper", "Errors", "Label"))) ;
else{
$element = new Zend_Form_Element_Text($id, array("label" => $tabElement['nom'], "required" => false, 'decorators' => array("ViewHelper", "Errors", "Label"))) ;
$element->addFilter('pregReplace', array('match' => '/,/', 'replace' => '.'));
$element->addFilter('LocalizedToNormalized');
$element->addValidator(new Anper_Validate_Float(), true, array('locale' => 'fr_FR'));
if(isset($tabElement['class']) && $tabElement['class']){
$element->setAttrib('class', $tabElement['class']);
}
}
if( $tabElement['disabled'])
$element->setAttrib('disabled', 'disabled');
$tabFormulaire[] = $element ;
}
But now I need the values of the fields in $element to have the comma replaced by a point before the element is added to $tabFormulaire. Currently numbers with a comma are truncated (124,5 becomes 124) when I validate the form and display the updated values.
The pregreplace doesn't seem to work.
Edit: it seems I don't need the pregReplace. I used two echo in my isValid function for the custom validator: one before the str_replace and one after. When I write in one of the field a value with a comma, both the echo displays the number with a point. I assume it's the result of the filter LocalizedToNormalized.
What I don't understand is why once the values are saved and displayed those with a comma are truncated despite the findings I just made.
Edit2: If I write for example 124 8, and use a pregReplace to do like there was no blank, the 8 isn't kept on save; despite the pregReplace working (tried with my previous echo).
Although #bitWorking's answer is 100% OK, from the view point of semantics, it's better to use a filter (since it's more of filtering rather than validating)
either NumberFormat filter or writing your own.
I have the multiCheckbox element on my form with the common callback validator.
Validator works ok, but error message contains duplicated strings, separated by semicolon instead of single message. If 2 checkboxes selected - the 2 error messages, if 4 - 4 error messages and so on.
Do you know how to modify the code in order to show only one single error message instead of duplicates?
$rolesElement = $form->getElement('role_ids');
$rolesElement->addValidator(new Zend_Validate_Callback(function ($value) use ($rolesElement, $administrator) {
if( *magicHere* ){
$rolesElement->clearErrorMessages();
$rolesElement->setErrorMessages(array('blablabla!'));
return false;
}
return true;
}));
You can always use setMessages() method of the Validator class you are using to set Custom Error Messages.
Here is my Code
$emailIdValidator->setMessages(array(
Zend_Validate_EmailAddress::DOT_ATOM => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_FORMAT => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_HOSTNAME => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_LOCAL_PART => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_MX_RECORD => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_SEGMENT => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::LENGTH_EXCEEDED => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::QUOTED_STRING => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
));
$form = new Zend_Form ();
$form->addElement ('MultiCheckbox', 'name', array (
'label' => 'test',
'multioptions' => array (
1 => 'fake',
65 => 'dsa',
165 => 'dsa22'
)
));
$form->name->addValidator ('Callback', true, array (
'callback' => array (
$this,
'val'
),
'messages' => array (
'callbackValue' => 'Error in here'
)
));
In this case, the validating function should not add any error messages. Just a boolean value.
function val ($value, $values)
{
return false;
}
The problem is solved by the creation of my own custom validator based on Zend_Validate.