I created a drop-down to select the category for search. When I search the product for example I search Shoes for MEN, when the view page loaded the item resets to default
I want the category to remain what I selected
<form action="<?php echo Yii::app()->baseUrl; ?>/search" method="GET" class="form-inline form-section-2 row fadeInDown animated">
<div class="col-sm-5 form-group">
<input type="text" name="loc" class="form-control" id="loc" value="<?php echo $locationdet ; ?>" placeholder="Enter Your Keyword">
</div>
<div class="col-sm-4 form-group" >
<select name="cat" class="form-control selectpicker">
<option>Select Category</option>
<option value = '0'>Men</option>
<option value = '1'>Women</option>
</select>
</div>
<div class="col-sm-3 form-group">
<button type="submit" class="btn btn-default btn-new">Search Products</button>
</div>
</form>
Try this:
<option value = '0' <?php if(isset($_GET['cat']) && $_GET['cat'] == '0') echo "selected" ?>>Men</option>
<option value = '1' <?php if(isset($_GET['cat']) && $_GET['cat'] == '1') echo "selected" ?>>Women</option>
use
echo CHtml::dropDownList('cat',isset( $_REQUEST['cat'] ) ? $_REQUEST['cat'] : NULL, array('0'=>'Men', '1'=>'Women'),
array('empty'=>'Select Category', 'class' => 'form-control selectpicker'));
to achieve yii style,
cheers
You will have to pass the selected option via the controller back to the view.
In the controller you will need something like this:
$this->render('viewName', array('name' => 'valueOfTheList'))
Then in the view you can use
<option value = '0' <?php if($name == '0') echo "selected" ?>>Men</option>
<option value = '1' <?php if($name == '1') echo "selected" ?>>Women</option>
However. Since you are using Yii. I would advise you to look at CHTML::dropDownList(). Then you could do something like
<?php echo CHtml::dropDownList('name', $select,
array('M' => 'Male', 'F' => 'Female'));
Which is really a more Yii way to approach these kind of things.
Yii way to implement this functionality.
You can keep the form state by setting the user input value to Model properties. For this, you can use CFormModel to implement, same like YII's default login page. Below is a sample example.
Create a form model for your search (SearchForm.php) and place this inside models folder.
class SearchForm extends CFormModel
{
public $search_key;
public $search_cat;
public function rules()
{
return array(
array('search_key,search_cat', 'required'),
);
}
}
Assume i am using SiteController. I want to show this search form in my index page. When i submit the form it will submitted to search action
class SiteController extends Controller
{
public function actionIndex()
{
$searchModel=new SearchForm();
$searchModel->search_key;
$searchModel->search_cat;
$this->render('index',array('searchModel'=>$searchModel));
}
public function actionSearch()
{
$searchModel=new SearchForm();
if($_POST['SearchForm'])
{
$searchModel->attributes=$_POST['SearchForm'];
}
$this->render('search',array('searchModel'=>$searchModel));
}
}
$searchModel->attributes=$_POST['SearchForm']; That is i am resetting the user inputs to model.So, in your view the form will appear with user input values.
Call this Form in views
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'search-form',
'enableClientValidation' => true,
'action'=>array('default/search'), //Submiting my form to Search action
));
?>
<?php echo $form->textField($searchModel, 'search_key'); ?>
<?php
$htmlOptions = array('size' => '1', 'prompt' => 'Select');
$list = array('0' => 'Men', '1' => 'Women'); // You can load your Categories from the Database table/Model.
echo $form->dropDownList($searchModel, 'search_cat', $list, $htmlOptions);
?>
<?php echo CHtml::submitButton('Search'); ?>
<?php $this->endWidget(); ?>
Hope, This will help you for your better practice.
Related
I want delete user and user role by using checkbox. first check then submit button click. After click, selected user and user_role should be deleted.
got php undefined offset 2 error on line 491
this is my model:
public function add_participation(){
$user = $this->input->post('user');
$role = $this->input->post('role');
$delete = $this->input->post('delete');
for($i=0;$i<count($user);$i++){
if($user[$i] !=""){
$this->db->where('workflow_activity_id',$this->input->post('batch'));
$this->db->where('role_id',$role[$i]);
$this->db->where('user_id',$user[$i]);
$exist = $this->db->get('workflow_participation');
$data = array(
'user_id' => $user[$i],
'role_id' => $role[$i],
'workflow_activity_id' => $this->input->post('batch'),
);
if($exist->num_rows() == 0){
$this->db->insert('workflow_participation',$data);
}else{
$this->db->where('workflow_activity_id',$this->input->post('batch'));
$this->db->where('role_id',$role[$i]);
$this->db->where('user_id',$user[$i]);
$this->db->update('workflow_participation',$data);
}
if($delete[$i] == '1'){ //**error on this line**
$this->db->where('workflow_activity_id',$this->input->post('batch'));
$this->db->where('role_id',$role[$i]);
$this->db->where('user_id',$user[$i]);
$this->db->delete('workflow_participation');
}
}
}
return true;
}
In this view page user and user_role show in drop-down.
This is my view page
<div class="form-group">
<label class="control-label col-md-3">User :</label>
<div class="col-md-8">
<select id="user" name="user[]" class="select form-control">
<option value="" selected="selected">-------</option>
<?php
if(!empty($user)){
foreach($user as $user_result){?>
<option value="<?=$user_result->id;?>" <?php if(!empty($participent) && !empty($participent[1]) && $participent[1]->user_id == $user_result->id){?>selected="selected"<?php }?>><?=$user_result->username;?></option>
<?php }}?>
</select>
</div>
<label class="control-label col-md-3">Role :</label>
<div class="col-md-8">
<select id="role" name="role[]" class="select form-control">
<option value="" selected="selected">-------</option>
<?php
if(!empty($role)){
foreach($role as $role_result){?>
<option value="<?=$role_result->id;?>" <?php if(!empty($participent) && !empty($participent[1]) && $participent[1]->role_id == $role_result->id){?>selected="selected"<?php }?>><?=$role_result->name;?></option>
<?php }}?>
</select>
</div>
<label class="control-label col-md-3">Delete :</label>
<div class="col-md-8">
<input type="checkbox" name="delete[]" value="1">
</div>
Since you are using delete[] as array, i hope your view is in a loop.
a checkbox value is submitted only when it is checked. So you will receive your input in wrong order.
ie, you selected first user and role and checked last delete, you may receive delete for first user. The second and third delete will be undefined. Please see this link for details and hidden field hack for this issue
So I suggest change the following 3 lines in your html as following. you can use $participent[1]->user_id ( or a counter) as index in view file.
<select id="user" name="user[<?php echo $participent[1]->user_id;?>]" class="select form-control">
...
<select id="role" name="role[<?php echo $participent[1]->user_id;?>]" class="select form-control">
...
<input type="checkbox" name="delete[<?php echo $participent[1]->user_id;?>]" value="1">
change the loop from this
for($i=0;$i<count($user);$i++){
to
foreach( $user as $i => $unused ) {
Then instead of equal checking
if($delete[$i] == '1'){ //**error on this line**
use
if( isset($delete[$i]) ){ //**error on this line**
// if( $delete[$i] == '1' ){ //uncomment if you need double confirmation
First check if the variable $role have the same amount of data as $user, if it's not so you have a problem.
Next for the line for($i=0;$i<count($user);$i++), create an outside variable for your count, here everytime you enter the for, the count() is called, bad optimisation.
I have select input in my form for manufacturers.
<div class="form-group">
<label for="manufacturer">Manufacturer</label>
<select id="manufacturerSelect" name="manufacturer" class="form-control">
<option disabled selected value> -- select an manufacturer -- </option>
<?php foreach ($manufacturers as $manufacturers_item): ?>
<option value="<?=$manufacturers_item['id'];?>" <?php echo set_select('manufacturer',$manufacturers_item['id'], ( !empty($manufacturer) && $manufacturer == $manufacturers_item['id'] ? TRUE : FALSE )); ?> ><?=$manufacturers_item['name'];?></option>
<?php endforeach; ?>
<option disabled>──────────</option>
<option value="24" <?php echo set_select('manufacturer','24', ( !empty($manufacturer) && $manufacturer == '24' ? TRUE : FALSE )); ?> >Other</option>
</select>
<?php echo form_error('manufacturer'); ?><br />
</div>
If "other" (value == 24) is checked additional input is asked:
$('body').on('change', '#manufacturerSelect', function() {
if ($(this).val() == 24) {
$("#otherManufacturerSelect").removeClass('hidden');
} else {
$("#otherManufacturerSelect").addClass('hidden')
}
});
And HTML:
<div id="otherManufacturerSelect" class="form-group">
<label for="otherManufacturer" >What is it then?</label>
<input type="text" name="otherManufacturer" class="form-control">
<?php echo form_error('otherManufacturer'); ?><br />
</div>
CSS:
.hidden {
display: hidden;
}
Now if user picks "other" as manufacturer addition input is displayed. Form validation rule for otherManufacturer is added in server side if manufacturer == 24. The problem is that the other manufacturer input is displayed every time user get response from server. I could add class="hidden" by default to other manufacturer div but if the form validation doesnt run other manufacturer field will not be displayed again to user.
What I need is PHP IF condition inside:
<div id="otherManufacturerSelect" <?php if(/*???*/):?>class="hidden"<?php endif; ?> class="form-group">
So that class="hidden" would be added only if manufacturer is not "other". but I cannt think of rigth condition.
Any help would be appreciated!
EDIT
Controller:
public function create()
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('manufacturer', 'Manufacturer', 'required');
if($this->input->post('manufacturer') == '24'){
$this->form_validation->set_rules('otherManufacturer', 'Other manufacturer', 'required');
}
$data['manufacturers'] = $this->puzzles_model->getManufacturers();
if ($this->form_validation->run() === FALSE)
{
$this->load->view('puzzles/create', $data);
}
else
{
/* do the upload, return upload errors or save in db*/
}
}
In your particular case this would fix the problem:
<div id="otherManufacturerSelect" class="form-group <?php if(isset($manufacturer) && $manufacturer !== '24') { echo 'hidden'; } ?> ">
<label for="otherManufacturer" >What is it then?</label>
<input type="text" name="otherManufacturer" class="form-control">
<?php echo form_error('otherManufacturer'); ?><br />
</div>
Then you can remove the JS snippet. The additional form will be hidden on server side (class="hidden" will be set).
I saw that you're using var $manufacturer in the same template. I can't see your controller and how you're passing variables but instead of $manufacturer you can also use $_GET['manufacturer'] or $_POST['manufacturer'] (depending on your form action method).
Notice: $_GET['manufacturer'], $_POST['manufacturer'] and $_REQUEST['manufacturer'] is NOT sanitized input. When using $manufacturer I assume that it's sanitized in your controller.
I'm trying to create a system of posts and custom fields. Ex: I create the post type "Product" and then I associate it some fields: "Name", "Image", "Price"...
When I create one of this fields I save into my db an input field, for example for Name I will insert something like this:
$data = array(
'name' => $field_key,
'id' => $field_key,
'class' => 'form-control '.$type->type_key,
'type' => $type->type_key,
'data-input-type' => $type->type_key
);
return form_input($data);
Then when I go to create my first post "Product" I want to populate a form with my custom fields.
<form method="post" action="<?php echo site_url('admin/posts/manage').'/'.$post_id; ?>">
<?php
foreach ($post_fields as $field) {
?>
<div class="form-group">
<label>
<?php
echo $field->name;
?>
</label>
<?php
// Here the field input
echo $field->meta_value;
?>
</div>
<?php
}
?>
<?php if(isset($post)){ echo $post->name;}else{echo set_value('name');} ?>
<div class="form-group">
<input type="submit" value="Save" name="save">
</div>
</form>
There's no problem since I have to create a new one. But when I have to edit my post I don't know how to load field's value for that single post, because in my form_input $data I can't put something like
$value = (isset($post)) ? $post->name : set_value($field_key);
and in the $data array
'value' => $value
Somebody have an idea on what I can do?
Thank you and sorry for my elementary english.
SOLVED. I create a model which load the correct input type. I pass post values by the controller to this model to populate input values correctly, if the action required is "edit".
I have defined a form using Zend\Form. In that, there is a radio button.
$this->add(array(
'name' => 'nationality_radio',
'type' => 'Radio',
'options' => array(
'value_options' => array(
'local' => 'Local',
'expatriate' => 'Expatriate',
),
)
));
Its value is not directly binded with database column. But it should populate correct value taken form DB and save user input back. (eg - if value of table column nationality is local it should select local in radio button)
When rendered it should display as..
On form load, it will a select option considering column nationality. It will contain value either local or expatriate
<?php
if ($candidate->nationality == 'local'){
$local = 'checked';
} else if ($candidate->nationality == 'local'){
$expatriate = 'checked';
}
?>
In plain HTML i can do it as below,
<div class="profile_item list-group-item">
<span class="item_title">Local: </span>
<span class="item_content"><input type="radio" name="nationality" value="local" <?php echo $local ?>></span><br>
<span class="item_title">Expatriate: </span>
<span class="item_content"><input type="radio" name="nationality" value="expatriate" <?php echo $expatriate ?>></span>
</div>
But since Zend form rendered using <?php echo $this->formRow($form->get('nationality_radio')); ?> I couldn't do it. It just displayed as below.
How can i achieve my requirement ?
For set the value, within controller method:
$form = new YourFormClass();
//are you using fieldsets? let's say no...
//if accepted value for $candidate->nationality could be only 'local' and 'expatriate',
//check the scope with your defined value_options or use an if
$form->get('nationality_radio')->setValue($candidate->nationality);
On your view use formRadio helper:
<?php echo $this->formRadio($form->get('nationality_radio'),\Zend\Form\View\Helper\FormRadio::LABEL_PREPEND);?>
Check out documentation at: http://framework.zend.com/manual/2.2/en/modules/zend.form.elements.html#radio
or check classes:
\Zend\Form\View\Helper\FormRadio
and
\Zend\Form\View\Helper\FormMultiCheckbox
Accepted values for $labelPosition are:
const LABEL_APPEND = 'append';
const LABEL_PREPEND = 'prepend';
Try this
<?php
if ($candidate->nationality == 'local'){
$LocalChecked="checked";
}
else {
$expatriateChecked ="checked";
}
?>
<div class="profile_item list-group-item">
<span class="item_title">Local: </span>
<span class="item_content"><input type="radio" name="nationality" value="local" <?php echo $LocalChecked ?>></span><br>
<span class="item_title">Expatriate: </span>
<span class="item_content"><input type="radio" name="nationality" value="expatriate" <?php echo $expatriateChecked ?>></span>
</div>
I want to force the Zend form into Twitter Bootstrap style. I currently iterate through the form fields and write the form info into my bootstrap div construction.
I saw in Zend Framework 1(!) that there is a way to do this within a decorator. But for some reason the doc for version 2 doesn't cover this point...
I'd like to do something like this:
protected $_format = '<label for="%s">%s</label>'
. '<input id="%s" name="%s" type="text" value="%s"/>';
public function render($content)
{
$element = $this->getElement();
$name = htmlentities($element->getFullyQualifiedName());
$label = htmlentities($element->getLabel());
$id = htmlentities($element->getId());
$value = htmlentities($element->getValue());
$markup = sprintf($this->_format, $name, $label, $id, $name, $value);
return $markup;
}
Any ideas?
I'm using partials now. I'm iterating over the attributes, build a few exceptions for eg CSRF and Submit... This works pretty smooth:
View
echo $this->partial('partial/form-partial', array(
'form' => $this->form,
'url' => $this->url('whatever', array('action' => 'add')))); ?>
Partial
<?php
$form = $this->form;
$form->setAttribute ( 'action', $this->url () );
$form->prepare ();
echo $this->form ()->openTag ( $form );
foreach ( $form as $element ) :
?>
<div
class="control-group <?php if($this->formElementErrors($element)) echo "error" ?>">
<label class="control-label"><?php echo $element->getLabel() ?></label>
<div class="controls">
<?php echo $this->formElement ( $element );
if ($this->formElementErrors ( $element ))
?>
<span class="help-inline"><?php echo $this->formElementErrors($element) ?></span>
</div>
</div>
<?php
endforeach;
echo $this->form ()->closeTag ( $form );
?>
The exceptions are left out for clearity's sake...
I did it the way #Rufinus mentioned. See this Tutorial on how to create View Helpers in ZF2 http://blog.evan.pro/creating-a-simple-view-helper-in-zend-framework-2
In my case I simply wanted to wrap form elements with list items so I extended the original ZF2 View Helpers and let them do the rendering of the elements. I Just wrapped what they return:
View Helper FormCollection.php
<?php
// ./src/Application/View/Helper/FormCollection.php
namespace Application\View\Helper;
use Zend\Form\ElementInterface;
use Zend\Form\View\Helper\FormCollection as BaseFormCollection;
class FormCollection extends BaseFormCollection {
public function render(ElementInterface $element) {
return '<ul>'.parent::render($element).'</ul>';
}
}
View Helper FormElement.php
<?php
// ./src/Application/View/Helper/FormElement.php
namespace Application\View\Helper;
use Zend\Form\ElementInterface;
use Zend\Form\View\Helper\FormElement as BaseFormElement;
class FormElement extends BaseFormElement {
public function render(ElementInterface $element) {
if ($element->getOption('required')) {
$req = 'required';
}
$type = $element->getAttribute('type');
$name = $element->getAttribute('name');
return sprintf('<li class="%s %s %s">%s</li>', $name, $req, $type, parent::render($element));
}
}
while my view looks like this and didn't need to be modified for the changes to take effect.
<?php
$form = $this->form;
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formCollection($form);
echo $this->form()->closeTag($form);
worked like a charm.
I tried Ron's Partial method, the result would like this which not Bootstrap 3 intended.
<form id="tea" name="tea" method="POST" action="/tea/add">
...
<div class="form-group">
<label class="control-label">Brand</label>
<div class="form-control">
<input type="text" value="" name="brand">
</div>
...
We know, in order to use bootstrap 3 predefined Form style, we need to define style to input element: form-control, rather than its wrapping element.
My Partial way is as following.
echo $this->form()->openTag($form);
foreach ($form as $element) :?>
<div class="form-group">
<?php
if ($element->getOption('required')) { $req = 'required'; }
$type = $element->getAttribute('type');
$name = $element->getAttribute('name');
$label = $element->getLabel();
?>
<?php if ($name == 'id') { ?>
<div class="hidden"><?php echo $this->formElement($element); ?></div>
<?php } else if ($name == 'submit') { ?>
<input class='btn' name='submit' type='submit' value='Add'>
<?php } else if ($label != '') { ?>
<label class="control-label"><?php echo $label ?></label>
<input class='form-control' name='<?php echo $name ?>' type='<?php echo $type ?>'>
<?php } ?>
</div>
<?php
endforeach;
echo $this->form()->closeTag();
Well, we could get the result.
<form id="tea" name="tea" method="POST" action="/tea/add">
...
<div class="form-group">
<label class="control-label">Brand</label>
<input class="form-control" type="text" name="brand">
</div>
...
How to attach custom styles into zf2 forms has mentioned : to add class attribute to the Form element.
class TeaForm extends Form
{
public function __construct($name = null)
{
// we want to ignore the name passed
parent::__construct('tea');
$this->add(array(
'name' => 'id',
'type' => 'Hidden',
));
$this->add(array(
'name' => 'brand',
'type' => 'Text',
'options' => array(
'label' => 'Brand',
),
/** **define class attribute** **/
'attributes' => array(
'class' => 'form-control',
),
));
....
It looks quite simple, but, the problem is the input element would be wrapped into the label element, which still not what Bootstrap 3 intended.
<form id="tea" role="form" name="tea" method="POST" action="/tea/add">
<input type="hidden" value="" name="id">
<label>
<span>Name</span>
<input class="form-control" type="text" value="" name="name">
</label>
...
In my opinion, the Partial method is still one flexible and light choice. Tea Box is one ZF2 practice, you could find all above mentioned code and description from Gibhub
This will make the code easier.
http://php.net/manual/en/function.echo.php
<?php
$form->prepare();
echo
$this->form()->openTag($form),
$this->formCollection($form),
$this->form()->closeTag($form);