zend framework text fields with same name but with different belongings - php

I have a problem with zend form, where i need to built a form where field name are same but with different belongings. Here is the input fields that i wanted inside my form.
Currently i am getting with straight html but because of this i am missing validation.
<input type="text" name="travel_guide_tab[4][title]">
<input type="text" name="travel_guide_tab[4][description]">
<input type="text" name="travel_guide_tab[6][title]">
<input type="text" name="travel_guide_tab[6][description]">

In Zend Form the element names must be unique (in some way) or else they will overwrite. However you can continue using your html form and simply filter and validate in the controller using Zend_Filter_Input. The filter and validation classes are the same ones used by Zend_Form you just pass the data in a different way.
Simple example, partial:
public function someAction() {
//set filters and validators for Zend_Filter_Input
$filters = array(
'nameOfInput' => array('HtmlEntities', 'StripTags')
);
$validators = array(
'nameOfInput' => array('NotEmpty', 'Int')
);
//assign Input
$input = new Zend_Filter_Input($filters, $validators);//can also pass the data in constructor (optional)
$input->setData($this->getRequest()->getParams());
//check input is valid and is specifically posted as 'Delete Selected'
if ($input->isValid()) {
//do some stuff
}
Good Luck.

Related

Yii - cannot define a safe array of attributes for form submit

I have a PHP form that need to submit a array of numbers, what we have in view:
<input type="text" id="ProductForm_sizeobj_1" name="ProductForm[sizeobj[1]]" value="13">
<input type="text" id="ProductForm_sizeobj_2" name="ProductForm[sizeobj[2]]" value="13">
<input type="text" id="ProductForm_sizeobj_3" name="ProductForm[sizeobj[3]]" value="13">
And I define in form class:
public $sizeobj = array();
public function rules() {
return array(
array('/** other attributes **/, sizeobj', 'safe')
);
}
Since "Sizeobj" is a dynamic attribute and the size will growth more then 3, therefore I use array. However after form submitted the error throw as follow:
Failed to set unsafe attribute "sizeobj[1" of "ProductForm".
I believe I might using the wrong method to setup array attribute, or wrong rule, any advice? I'm new to Yii, any help is appreciated.
Use name="ProductForm[sizeobj][1]" instead of name="ProductForm[sizeobj[1]]"

Should I use set_value() to repopulate a form in CodeIgniter

My question is whether I should use set_value() at all to re-populate a form. It might seem odd to say that, however I am creating a shared controller function and view which can be used to either add a new record or edit an existing one. It seems to make sense to do this since the functionality is so incredibly alike.
As such, if we call up an existing record to edit I do this:
$data['fields'] = $this->customer_model->get_customer($id);
If the form is submitted to save the record, or if we're adding a record for the first time, the form has the potential to reload if the user makes a mistake so I populate $data['fields'] this way instead:
$data['fields'] = array(
'company' => $this->input->post('company') ?: '',
'website' => $this->input->post('website') ?: '',
'credit_limit' => $this->input->post('credit_limit') ?: ''
);
My form element looks like this:
<input type="text" name="company" value="<?php echo set_value('company', $fields['company']); ?>" />
But I'm thinking it may as well look like this:
<input type="text" name="company" value="<?php echo escape_html($fields['company']); ?>" />
Since the form data could come from either user input (when adding or saving) or from the database (when retrieving a record to edit) I cannot rely entirely on post() or set_value() without the 2nd parameter. Furthermore, the second parameter for set_value() will always exist ($fields['company'] in this example) because it's initialized from the start, which is why I am thinking of just using it directly.
Is there a problem with this approach?
If you want to populate form fields on FALSE return of Form Validation or insert data for editing operations, I suggest you to use following helper:
Usage
<input type="text" name="last_name" value="<?=vset_value('last_name','',$rs);?>">
Explanation
$rs here is the $db data for record (if you are sending it to view). To stay at the safe side please include $this->data['rs'] = false; at your controller. If $rs is set and true, helper take results from it and display it. Otherwise it displays if the key exist in $_POST. If both don't exists, it display default value.
Helper
/**
* vayes_helper::vset_value
*
* Retains state of INPUT text after Form Validation
*
* #access public
* #param string name of INPUT tag
* #param string default value for INPUT tag
* #param mixed DB Result (array or object)
* #return string
*/
if(!function_exists('vset_value')) {
function vset_value ($name_of_input,$default_state='',$db_result_array='') {
$CI = &get_instance();
$render_state = $default_state;
if($CI->input->post()) {
$render_state = $CI->input->post($name_of_input);
} else {
if(is_object($db_result_array) && isset($db_result_array->$name_of_input)) {
$render_state = (isset($db_result_array->$name_of_input)) ? $db_result_array->$name_of_input : $default_state;
} else if($db_result_array != '' && array_key_exists($name_of_input,$db_result_array)) {
$render_state = (isset($db_result_array[$name_of_input])) ? $db_result_array[$name_of_input] : $default_state;
}
}
return $render_state;
}
}
If you like the way, let me know. I can supply for more form input type like select, checkbox, etc.
The approach is correct, as mentioned in the CodeIgniter docs. In fact, you don't need to include the second parameter in set_value.
set_value definition:
string set_value(string $field = '', string $default = '')
//$field: If there is a submitted field with this name, its value is returned.
//$default: If there is no matching submitted field, this value is returned.
Yes,You should.
set_value() is used to re-populate a form has failed validation.
There is no additional filtering on it, so it faster.
But, I prefer some times to use $this->input->post() for the secure.

Insert DB Value into Form Field

The Question: How do I insert values from a database table (#__mytable) into form text fields (motitle and modescription) which have been rendered from an XML file within the Joomla 3.0 platform?
-
I've been trying for days to solve this "easy" Joomla! based undocumented challenge.
I have followed Joomla!'s guide for Developing an MVC, read most of their out-of-date documentation and torn apart the com_content component but have still no idea how to populate my fields.
I've been playing with $this->form->bind($this->item);.
Below I have included some of my code to show the structure I am using. Please feel free to point out any issues you spot along the way.
Models\Forms\item.xml
<?xml version="1.0" encoding="UTF-8"?>
<form>
<fields name="groupOPTIONS">
<fieldset name="Options">
<field
type="text"
name="motitle"
id="motitle"
label="Title"
description="MY TEXT FIELD DESCRIPTION"
maxLength="255" />
<field
type="textarea"
name="modescription"
id="modescription"
label="Description"
description="MY TEXT FIELD DESCRIPTION"
rows="15"
cols="5"
maxLength="255" />
</fieldset>
</fields>
</form>
Models\item.php
jimport('joomla.application.component.modelitem');
class MagicObjectsModelItem extends JModelForm {
public function getForm($data = array(), $loadData = true) {
// Get the form 'items'
$form = $this->loadForm('com_magicobjects.item', 'item',
array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)) {
return false;
}
return $form;
}
protected function loadFormData() {
// Check the session for previously entered form data.
$data = JFactory::getApplication()->getUserState('com_magicobjects.item.edit.data', array());
if (empty($data)) {
$data = $this->getDBItem(1);
}
return $data;
}
public function getDBItem($pk) {
//Obtain JDatabase static connection
$oDb = JFactory::getDbo();
$oQuery = $oDb->getQuery(true);
$sValueToMatch = $pk;
$oQuery
->select(array('mid', 'name', 'keyword', 'description'))
->from('#__mytable')
->where('mid = "' . $sValueToMatch . '"')
->order('mid ASC');
$oDb->setQuery($oQuery);
return $oDb->loadObjectList();
}
views\item\view.html.php
jimport('joomla.application.component.view');
function display($tpl = null) {
// Initialise variables.
$this->form = $this->get('Form');
$this->item = $this->get('Item');
//Display the view
parent::display($tpl);
}
Views\item\tmpl\default.php
foreach ($this->form->getFieldset('Options') as $field) {
echo $field->label;
echo $field->input;
}
By performing a print_r() on item I can see I have the data, but I need to insert the data into the fields shown.
In case this it's still a problem because the form definition is defining a <fields /> group.
This mean that the form fields will be output as follows:
input type="text" name="[groupOPTIONS][motitle]"
based on the example you give above. If you remove the fields grouping it will probably work. It's annoying though as certain JForm methods only work on groups...
You would probably need to change the way in which the data was being passed into the form if you wanted to keep the fields grouping (e.g. by overloading getItem).
Hope that makes sense...
In Joomla 3, the JForm::bind() method appears to accept either an object or associative array as a parameter. All of the object/array fields are then stored in a protected JRegistry type data member called JForm::$data.
When you're trying to display a form field (by calling JForm::getInput()), the call stack is as follows
JForm::getInput() -> JForm::getField() -> JForm::loadField() -> JForm::getValue()
JForm::getValue() returns a value from the (aforementioned JRegistry) JForm::$data data member. The JForm::loadField() method also passes the default value (defined by the form) to the JForm::getValue() method in case a value in the JForm::$data variable doesn't exist.
In terms of doing this inside a model, you might want to generate a object or assoc array from a database query or table (ensuring that the field names correspond with the field names defined in the form xml) and then pass it to JForm::bind() as a parameter. However, if you are using JModelForm, I think you should only override JModelForm::loadFormData() to pass the object/assoc array to the loaded form.
See : libraries/joomla/form/form.php
Hope that helps :)
Instead of $oDb->loadObjectList(); use $oDb->loadAssoc(); in your getDBItem() function.
Check this - http://docs.joomla.org/Accessing_the_database_using_JDatabase/1.5
Check this also - joomla loadformdata
Hope this will work.

explicitly set "required" in div class using custom FormHelper (cakephp 1.3)

I am using cakephp 1.3, and want to set form inputs as "required" explicitly instead of relying on model validation. A form input example:
<div class="input text required">
<label for="ClaimClaimantFirstName">First Name</label>
<input name="data[ClaimClaimant][first_name]" type="text" id="ClaimClaimantFirstName" />
</div>
I also want to maintain the FormHelper naming instead of using custom form helper names. Example:
$this->Form->input(...)
The solution I came up with is
implement MyFormHelper, extending from FormHelper and overriding the input method. Specifically, around line 804 of the FormHelper, replacing
if (
isset($this->fieldset[$modelKey])
&& in_array($fieldKey, $this->fieldset[$modelKey]['validates'])
) {
$divOptions = $this->addClass($divOptions, 'required');
}
with
if (isset($options['required'])) {
if ($options['required'] === true) {
$divOptions = $this->addClass($divOptions, 'required');
} elseif ($options['required'] === false) {
// do not add class 'required'
}
} elseif (
isset($this->fieldset[$modelKey])
&& in_array($fieldKey, $this->fieldset[$modelKey]['validates'])
) {
$divOptions = $this->addClass($divOptions, 'required');
}
This ensures the presence of $options['required'] takes precedence before we rely on the model validation.
use Joe Beeson's analogue plugin, to alias MyForm to Form:
public $helpers = array(
'Analogue.Analogue' => array(
array(
'helper' => 'MyForm',
'rename' => 'Form'
) ) )
then, specifying the form input as required looks like:
$this->Form->Input(
'SomeModel.SomeField',
array('required' => true)
)
Is there some other better approach than this, or potential issues with this solution?
The original question specifies 1.3, but here is an update for those looking for a way in 2.0
For Cake 2.0 or greater you can specify the 'required'=>true keypair value in your input options array to enable html5 browser validation on the element.
http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#creating-form-elements

Symfony - Several form on the same page -> ID issue

I have an issue while displaying several forms of the same model on the same page.
The problem is that with the NameFormat, the fields have the same ID :
$this->widgetSchema->setNameFormat('display[%s]');
Will display
<form class="update_display_form" id="update_display_0" action="/iperf/web/frontend_dev.php/update_display" method="post">
<input type="checkbox" name="display[displayed]" checked="checked" id="display_displayed" />
<label for="display_displayed">test</label>
</form>
<form class="update_display_form" id="update_display_1" action="/iperf/web/frontend_dev.php/update_display" method="post">
<input type="checkbox" name="display[displayed]" checked="checked" id="display_displayed" />
<label for="display_displayed">truc</label>
</form>
And if you click on the second label, it will activate the first checkbox
So I thought I could use the object id to make them unique :
$this->widgetSchema->setNameFormat('display'.$this->getObject()->getId().'[%s]');
But then I can not process the request, since I don't know the name of the parameters.
The best option I found was to set an ID :
$this->widgetSchema['displayed']->setAttributes(array("id" => "display".$this->getObject()->getId() ));
but then I totally loose the connections between the label and the checkbox.
The problem would be solved if I could change the "for" attribute of my label. Does somebody know how to do that ? Or any other option ?
Here's an idea... push a variable to the form class from your action for setting a different name format dynamically:
In your action:
$this->form_A = new displayForm(array(),array('form_id' = 'A')); // pass a form id
$this->form_B = new displayForm(array(),array('form_id' = 'B'));
$this->form_C = new displayForm(array(),array('form_id' = 'C'));
In your form class:
$form_id = $this->getOption('form_id'); // get the passed value
$this->widgetSchema->setNameFormat('display'.$form_id.'[%s]'); // stick it into the name
It's ugly but I'm sure you can come up with something cleaner...
Conflicting inter-form checkbox/label interactions is caused by tag's id/for attributes not by their name attributes.
So there is no need to modify form's widget name format and thus having problem reading submitted data from request object (either by passing request key as form url parameter/hidden input or by looping all form name combinations created in the layout for each form and finding a matching one).
sfForm class has sfWidgetFormSchema::setIdFormat() method for that.
// Creating form instances
$formA = new sfForm();
$formA->getWidgetSchema()->setIdFormat( '%s1' );
$formA->getWidgetSchema()->setNameFormat( 'display' );
... // configure the form
$formB = new sfForm();
$formB->getWidgetSchema()->setIdFormat( '%s2' );
$formB->getWidgetSchema()->setNameFormat( 'display' );
... // configure the form
$formC = new sfForm();
$formC->getWidgetSchema()->setIdFormat( '%s3' );
$formC->getWidgetSchema()->setNameFormat( 'display' );
... // configure the form
// Processing a request data
$form = new sfForm();
... // configure the form
$_formNameRequestKey = $form->getName();
if( $request->hasParameter( $_formNameRequestKey ) ) {
$form->bind( $request->getParameter( $_formNameRequestKey ) );
}
... or just ...
if( $request->hasParameter( 'display' ) ) {
$form->bind( $request->getParameter( 'display' ) );
}

Categories