I have tried adding a partial to my form using the Zend Form's viewScript decorator, however i seem unable to pass along variables to the partial. Here's my code:
In the controller i add the form:
$form = new Content_Form_ContentForm(array("categories" => $sortedCategories));
$form->submit_button->setLabel("Add content");
$this->view->form = $form;
Then inside the form i add the viewscript:
public function setCategories($categories) {
$this->setDecorators(array(array('ViewScript', array(
'viewScript' => 'partials/dtreePartial.phtml',
'List'=>"{$categories}",
))));
}
I have tried printing the options for the view script by using print_r($this->getDecorator('ViewScript')->getOptions()); wich results in Array ( [viewScript] => partials/dtreePartial.phtml [List] => Array )
However when i run it all, the script returns an error about the List not existing.
I have the feeling i am missing something but i am unsure as to what it is. Any advice or solutions will be appreciated! :)
The problem is with this line:
'List'=>"{$categories}",
Because you put the variable inside quotes, it gets cast to a string. In PHP, when you cast an array to a string, the result is always the word Array.
Simply change to:
'List'=> $categories,
and it should work as you expect.
Related
I'm not quite sure about the way of doing.
The challenge:
I call an addAction which shows a form. The point of calling the addAction gives two routing parameters, say value1 and value 2 separated by an "-".
I need value 1 and value 2 to search a pk in a table which will be saved as a foreignkey value by the addAction. I take both values give it to a method and get the key I need, that is tested and ok so far.
My problem.
In the first call of addAction I get the routing parameters and find the key. But afterwards of course it is forgotten. How can I remember the found value, so that I can use it for my saveModel method?
What would be the best way?
Idea 1:
Can I give it to the form and set it as value to the hidden keyfield?
For example:
class PadForm extends Form
{
public function __construct($name = null, $unitpartid)
{
parent::__construct('pad');
$this->add([
'name' => 'UnitPartPadID',
'type' => 'hidden',
'value' => $unitpartid,
]);
Would this be working? And would this be an accepted, proper way?
Idea 2:
Or would I try to use an instance variable in my controllerclass, like $this->smtg; ?
In both cases I get an understandable error
Trying to get property of non-object
Questions:
what would be the best way?
and
how to do it, perhaps somebody could give a short example.
EDIT:
I really would appreciate to learn about the best way. I now tried to give a variable to my form and then fill in some field, but that doesn't work.
Part of Controlleraction
(the action works if I set a constant value for the related field)
$parameter = $this->params()->fromRoute('id');
// echo $parameter;
$partnumber =substr($parameter,0,strpos($parameter,"-"));
// echo $partnumber;
$unitid=substr($parameter, strpos($parameter,"-")+1, strlen($parameter));
// echo $unitid;
$test=$this->unitparttable->getUnitPartID($unitid, $partnumber);
echo $test->UnitPartID;
$form = new PadForm(NULL, $test->UnitPartID);
Then in the Formclass:
public function __construct($name = null, $unitpartid)
{
// We will ignore the name provided to the constructor
parent::__construct('pad');
// $this->db=$db;
$this->add([
'name' => 'UnitPartPadID',
'type' => 'hidden', //hidden
]);
$this->add([
'name' => 'UnitPartID',
'type' => 'text', //hidden
'value' => $unitpartid,
]);
The question is now, how to fill the formfield UnitPartID with the value of $unitpartid given within the constructor.
I also tried $form->populate but it is unknown, I used it in ZEND1 before, but probably it doesn't exist anymore.
any help appreciated!
I have a form that triggers on event in __construct method to load some items from another modules . So far so good , a field set is loaded from the other module and added to the form and in the request->getPost() I have the data for the elements inside the fieldset , but the $form->getData() doesn't have the data for the fieldset.
I am calling $form->getInputFilter() before adding this fieldsets to the form and it seems that calling the $form->getInputFilter() dosn't creates the filters for the newly added elements . so how can i create inputfilters for the dynamic events without recreating the hole filters again ?
Or should i just delay calling $form->getInputFilter() untill all of the elemnts have been added to the form ?
I also added some elements to the form later what was ignored by the input filter.
My solution is most likely not exactly the best one, but as you haven't received any other answers yet, here's what I did:
I added
use Zend\InputFilter\Factory as InputFactory;
in the class where I'm validating the form data and then used
$factory = new InputFactory();
$form->getInputFilter()->add($factory->createInput(array(
'name' => 'title_str',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
)));
#Afterdark017 that works and also i think it is possible to reset the filters.
protected function resetFilters(){
$this->filter = null;
$this->hasAddedInputFilterDefaults = false;
}
but i have not tested this yet.
When using Zend_Form, if an element is not valid the form returns the errors by way of an unordered list. How do I change this to use paragraph tags instead?
I have attempted loading the Errors decorator for the elements and calling setOptions() to pass in a bunch of tags to replace the ul/li stuff being used by Zend_Form_Decorator_FormErrors, but that didn't work =/ Instead Zend_Form_Decorator_Errors just put the options as attribute/value pairs in the ul tag.
Instead of extending the Errors decorator I have extended the formErrors view helper, getting it to accept and process the options in the array. The formErrors view helper has setters to let me change the tags being used:
class My_View_Helper_FormErrors extends Zend_View_Helper_FormErrors
{
public function formErrors($errors, array $options = null)
{
if(key_exists('htmlElementStart', $options))
{
$this->setElementStart($options['htmlElementStart']);
unset($options['htmlElementStart']);
}
if(key_exists('htmlElementEnd', $options))
{
$this->setElementEnd($options['htmlElementEnd']);
unset($options['htmlElementEnd']);
}
if(key_exists('htmlElementSeparator', $options))
{
$this->setElementSeparator($options['htmlElementSeparator']);
unset($options['htmlElementSeparator']);
}
return parent::formErrors($errors, $options);
}
}
To pass options, I got the error decorator and setOptions() on it:
$element->getDecorator()->setOptions(
array(
'class' => 'error',
'htmlElementStart' => '<p%s>',
'htmlElementEnd' => '</p>',
'htmlElementSeparator' => '<br/>'
)
);
And tell the elements to load the helper path:
$element->getView()->addHelperPath('My/View/Helper', 'My_View_Helper');
Unfortunatelly, you cannot change the output format by just passing a bunch of options.
If you like to change this behaviour you have no choice but to write your own Errors decorator (most likely a derivative from the original Errors decorator). This new decorator has to have its render () method overwritten in order to be able to call your own view helper (instead of the formErrors helper which ZF uses by default).
I have a form, created with Zend_Form, with method = GET used for searching records with elements as below:
[form]
user name [input type="text" name="uname"]
[input type="submit" value="Search" name="search"]
[/form]
After form is submitted all the GET parameters along with submit button value are appearing in the url.
http://mysite.com/users/search?uname=abc&search=Search
How to avoid submit button value appearing in the url? is custom routing the solution ?
When you create your element, you can simply remove the name attribute that was automatically set at creation
$submit = new Zend_Form_Element_Submit('search')->setAttrib('name', '');
Or inside a Zend_Form
// Input element
$submit = $this->createElement('submit', 'search')->setAttrib('name', '');
// Or Button element
$submit = $this->createElement('button', 'search')->setAttribs(array
(
'name' => '', 'type' => 'submit',
);
When a form gets submitted, all of its elements with their names and values become a part of a GET / POST - query.
So, if you don't want an element to appear in your GET - query, all you need to do is to create this element without a name. That's probably not the best approach, but since we're talking about the 'submit' element, I guess it doesn't matter that much.
Looking at Zend_View_Helper_FormSubmit helper, you can see that it's creating the 'submit' element and setting its name. So, the possible solution would be to create your own view helper and use it for rendering the 'submit' element instead of the default helper.
You can set a custom helper with
$element->setAttribs( array('helper' => 'My_Helper_FormSubmit') );
Then build your own form element class and remove the name attribute from the element with preg_replace. The beauty of it is, it will not interfere with the other decorators.
So the something like this:
class My_Button extends Zend_Form_Element_Submit
{
public function render()
{
return preg_replace('/(<input.*?)( name="[^"]*")([^>]*>)/', "$1$3", parent::render(), 1);
}
}
You can remove name attribute for submit button in javascript.
jQuery example:
$('input[name="submit"]').removeAttr('name');
In the controller that represents the form's action, redirect to another (or the same controller) only including the relevant params.
Pseudocode:
$params = $this->getRequest()->getParams();
if isset($params['search'])
unset($params['search']);
return $this->_helper->Redirector->setGotoSimple('thisAction', null, null, $params);
handle form here
This is basically the same idea as Post/Redirect/Get except that you want to modify the request (by unsetting a parameter) in between the different stages, instead of doing something persistent (the images on that Wiki-page shows inserting data into a database).
If I were you, I would leave it in. IMO it's not worth an extra request to the webserver.
I have a select list I've created in a form alter, however, when I select an option and submit the value, only the first digit gets stored in the database. I know this has something to do with how the array is formatted, but I can't seem to get it to submit properly.
function addSR_form_service_request_node_form_alter(&$form, $form_state) {
$form['field_sr_account'] = array( '#weight' => '-50',
'#type' => 'select',
'#title' => 'Select which account',
'#options' => addSR_getMultiple());
//Custom submit handler
$form['#submit'][] = 'addSR_submit_function';
}
function addSR_submit_function{
$form_state['values']['field_sr_account'] = array('0' => array('value' => $form['#field_sr_account']));
Below is the function that returns the associative array. It is returning the proper options, as I can view the correct value/option in the HTML source when the page loads
//The values returned are not the problem, however, the format of the array could be..
function addSR_getMultiple(){
$return = array();
$return['one'] = 'Choice1'
$return['two'] = 'Choice2'
return $return;
}
Update:
Drupal 6: Only inserting first character of value to MySQL
I had a similar issue with the same field. However, in that case, I knew the value I wanted to submit, and I was able to assign the value to the field in the form alter, before the form was submitted. The difference with this issue, is that I don't know the value of the field until it is submitted, so I can't "assign" it in the form alter. How can I assign it the same way in the submit handler.
Edit after question update (and discovery of root problem within the linked separate question):
As you are trying to manipulate CCK fields, and those have pretty special handling mechanisms compared to 'standard' Drupal FAPI form elements, you should probably read up on CCK form handling in general, and hook_form_alter() and CCK fields and CCK hooks in particular. Glancing at those documentations (and the other CCK articles linked in the left sidebar), it looks like there should be a straight forward solution to your problem, but it might require some digging.
As a potential 'quick fix', you could try keeping your current approach, and adjust the submitted value on validation, somewhat like so:
function addSR_form_service_request_node_form_alter(&$form, $form_state) {
$form['field_sr_account'] = array(
'#weight' => '-50',
'#type' => 'select',
'#title' => 'Select which account',
'#options' => addSR_getMultiple()
);
// Add custom validation handler
$form['#validate'][] = 'addSR_validate_function';
}
function addSR_validate_function (&$form, &$form_state) {
// Assemble result array as expected by CCK submit handler
$result = array();
$result[0] = array();
$result[0]['value'] = $form_state['values']['field_sr_account'];
// Set this value in the form results
form_set_value($form['field_sr_account'], $result, $form_state);
}
NOTE: This is untested code, and I have no idea if it will work, given that CCK will do some stuff within the validation phase as well. The clean way would surely be to understand the CCK form processing workflow first, and manipulating it accordingly afterward.