HTML::FormHandler dynamically set default form value - perl

I'm using HTML::FormHandler and I'd like to be able to dynamically set default values for the form. Here would be a good example of what I would like to be able to do:
#this doesn't work
my $form = myapp::Form::Example->new(field1=>'default1',field2=>$default2);
In the example above, field1's value would hold "default1" and field2's value would hold whatever the scalar $default2 holds. However, the above example does not do this. Does anyone know of a way to do this? Thanks!

There are a lot of ways of setting default values. You can use an init_object:
my $form = MyApp::Form::Example->new;
$form->process( init_object => { field1 => 'default1', field2 => 'default2' }, ... );
You can also use the 'defaults' shortcut for updating fields dynamically:
$form->process( defaults => { field1 => 'default1', field2 => 'default2' }, ... );
The 'init_object' acts instead of a database row (item), so if you're also passing an 'item', you might also have to set the 'use_init_obj_over_item' flag. It uses the object/form 'value' format, which includes nested hashrefs and arrayrefs. The 'defaults' hashref requires a flattened hashref, such as you get from the 'fif' (fill-in-form) method.
See https://metacpan.org/module/HTML::FormHandler::Manual::Defaults

From the docs the code in the Q is good. Please try to debug thhe problem with the following. This will allow you peeek "inside" the object and see whats going on.
My guess: The default value gets overwritten with actual data or variable is empty.
use Data::Dumper;
print Dumper($default2);
my $form = myapp::Form::Example->new(field1=>'default1',field2=>$default2);
print Dumper($form);

Related

passing value to form

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!

How can I alter a DBIx::Class object value without updating the actual DB

I am checking for mismatch usernames in one of my applications.
If it finds a mismatch username, I wrap the value in <mark> tags.
I want to update my DBIx::Class object's username value before passing it back to my JS.
I currently have the below, which is almost what I want but not quite.
my $mismatch_username = check_for_mismatch_username($self, $id, 'AD');
if(defined $mismatch_username)
{
my $flagged_username = "<mark>".$info->accountname."</mark> <font color=\"red\">(Mismatch: $mismatch_username)</font>";
$info->update({accountname => $flagged_username});
}
$info = {$info->get_columns};
$self->render(json => {info => $info});
It is very important I don't update the DB value. I only want to update the variable's value. I am currently still looking through the DBIx::Class documentation.
Any direction is appreciated.
Don't modify the object if you don't want it to be modified.
(You could, of course, update the field without saving it using $info->accountname(…). But that would still leave the object in a modified state, where other code could potentially save it. It'd also potentially fail if the HTML markup was rejected by a validator on the field.)
If all you actually need is to change the username in the JSON, generate the data that'll go into the JSON first, then update the appropriate field in the data before rendering it:
my $data = { $info->get_columns };
if (defined $mismatch_username) {
$data->{accountname} = "<mark>…";
}
$self->render(json => { info => $data });

DBIx::Class Wrapping/overloading a column accessor

Using DBIx::Class I am trying to manipulate the data of a column whenever it is being updated or retrieved. For instance, before it goes into the database I would like to encrypt it, and whenever it is being accessed I would like to decrypt it. I am following this example in the DBIx::Class::Manual::Cookbook, however I can't seem to get it to work. I have placed the following in my User schema. For testing I am just using the name column, I know it doesn't make sense:
__PACKAGE__->add_columns("name" => { accessor => '_name' });
sub name {
my $self = shift;
# If there is an update to the column, we'll let the original accessor
# deal with it.
if(#_) {
return $self->_name('test 1');
}
# Fetch the column value.
my $name = $self->_name;
$name = 'test 2';
return $name;
}
I can't see what I'm doing any different than what the cookbook says. Can't anyone help me understand what I'm doing wrong? Thanks!
DBIx::Class has a component for that called FilterColumn.
There are various modules on CPAN using that component like DBIx::Class::EncodedColumn and PassphraseColumn.
If you tell us what you use case is we might give you more/better suggestions.

Passing variables to a viewScript Decorator

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.

Drupal select list only submitting first character

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.