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>
Related
Currently working with Bitrix CMS and need to make vote for users from specific group. With knowing id of group i made a form with bunch of radio buttons inside. When someone vote, result shoud be writen in file (or database) and page with "Thank you for voting!" should be displayed.
My question is what is the best way to do it?
I tried a few different ways:
1) this tutorial, not working
2) two another web tutorials, can link if you ask me
3) Voting form from bitrix, but for that module of the system should be change, and that not advised.
Below is page with vote itself, but "poll.php" makes me confused because of not knowing right way to do it. So good advice would be really appreciated.
p.s. you can ignore 'Bitrix' part, most important is php
/*get users from group in array*/
<?$arUsers = CGroup::GetGroupUser(20);
$iCountUsers = 0;
$arUsersbyGroupID = array();
foreach($arUsers as $arUser) {
$arUserbyID = CUser::GetByID($arUser);
$rsUserbyID = $arUserbyID -> Fetch();
$arUsersbyGroupID[] = $rsUserbyID; }
$iCountUsers++;?>
<div class="wrapper">
<div id="poll-container">
<form class="grid" action="poll.php" method="post" accept-charset="utf-8">
/*for each create element with radio button*/
<?$iVoteCount = 0;
$allopt = array();
foreach($arUsersbyGroupID as $Vote) {
$photo = $Vote["PERSONAL_PHOTO"];
if (!empty($photo)) {
$name = "{$Vote["NAME"]} {$Vote["LAST_NAME"]}";?>
<div class="cell">
<div class="cell_img"><?echo CFile::ShowImage($photo)?></div>
<div class="cell_caption">
<input type="radio" value="<?=$iVoteCount?>" name="vote" onclick="getVote(this.value)" />
<label for='opt<?=$iVoteCount?>'><?echo $name?></label>
</div>
</div>
$iVoteCount++;
}
} ?>
<div id="sub"><input type="submit" value="Vote" /></div>
</form>
</div>
</div>
You shouldn't write your fully custom solution for creating polls. In Bitrix Framework we have a module called - vote
With supply of this module you can create standard polls or if they are not fit to your tasks - you can customize them, but you should not be writing all these code from scratch.
For basic polls configuration you can read official online courses (in Russian) - http://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=41&LESSON_ID=2859
Use bitrix api to transfer your array data using $_POST or $_REQUEST global varibles binding them to your custom form name[] . Just add bitrix api code on after submit event. Voting results may be pasted into the custom lead fields that should be previously created in BX manually. Check out this example. It was fully workable and tested.
<?php
$queryUrl ='';
$_SERVER['REMOTE_ADDR'] = $ip;
$queryData = http_build_query($basebitrix24 = array(
'fields' => array(
"TITLE" =>'one',
"NAME" => 'two',
"LAST_NAME" => $leadData['question_one'],
"STATUS_ID" => "NEW",
"OPENED" => "Y",
"UF_CRM_1491235024" => $leadData['question_second'],
"UF_CRM_1491235124" => $leadDataQ1[$answer],
"UF_CRM_1491235376" => $leadData['question_third'],
"ASSIGNED_BY_ID" => 16,
'SOURCE_ID' => $i,
"PHONE" => array(array("VALUE" => $_REQUEST['phone'], "VALUE_TYPE" => "WORK" )),
"EMAIL" => array(array("VALUE" => $_REQUEST['email'], "VALUE_TYPE" => "WORK" )),
),
'params' => array("REGISTER_SONET_EVENT" => "Y")
));
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $queryUrl,
CURLOPT_POSTFIELDS => $queryData,
));
$result = curl_exec($curl);
curl_close($curl);
$result = json_decode($result, 1);
?>
The requests are not about voting but there is no very much trouble to use same method for any custom form too. Form code in example purposes.
if (isset($_POST['s_submit'])) {
#$email = strtolower(trim($_POST['email']));
#$name = trim($_POST['name']);
if (isset($_POST) && count($_POST) != 0) {
if (#isset($email) && #$email != '') {
$line = check_record_exist($removelist, $email, $form_type);
if ($line) {
$line--;
delete_line_from_file($removelist, $line);
}
if (!check_record_exist($addlist, $email, $form_type)) {
add_record($addlist, $email, $name);
$sm_res = 1;
} else {
$sm_res = 3;
}
} else
echo '<font color="#FF0000">Please enter e-mail address</font>';
}
}
if (isset($sm_res)) {
switch ($sm_res) {
case '1': echo '<b>You have successfully subscribed</b>';
break;
case '2': echo '<b>You have successfully unsubscribed</b>';
break;
case '3': echo '<b>You are already subscribed</b>';
break;
case '4': echo '<b>You are already unsubscribed</b>';
break;
}
unset($sm_res);
} else {
<form name="contactform" id="sky-form" method="post" action="">
<fieldset>
<div class="row">
<div class="sky-form epochta">
<section class="col col-6" >
<label class="input"><i class="icon-append icon-envelope-alt"></i> <h3>EMAIL </h3><input type="email" name="email" value="<?$_REQUEST['email']?>"> </label>
</section>
<?php if ($form_type != 1) { ?>
<section class="col col-6">
<label class="input"> <i class="icon-append icon-user"></i><h3>NAME<h3> <input type="text" name="name" size="15" value="<?php echo #trim(strip_tags($_REQUEST['name'])); ?>">
</label>
</section>
<?php } ?>
<section class="col col-12" >
<input type="hidden" name="saved" value="yes">
<input type="submit" class="subbutton" name="submit" value="">
<td align="center" colspan="2"><font face="Verdana" size="-2">ePochta Subscription Manager</font>
</section>
</div>
</div>
</fieldset>
</form>
?>
I'm really struggling getting my layout into Yii2. To be as close as possible to the state-of-the-art, I read about styling the ActiveField and ActiveForm, which kinda works, but not to 100%. Maybe you see whats wrong.
Let me start of with my HTML, which I want to have:
// normal state without any validations
<p>
<label for="signup_name">Name, Surname:<span class="required">*</span></label>
<input type="text" name="signup_name" id="signup_name" value="" />
</p>
// input field after validation fails (ajax + reload)
<p>
<label for="signup_email">E-mail:<span class="required">*</span></label>
<input class="error-input" type="text" name="signup_email" id="signup_email" value="" />
<span class="error-msg">E-mail must be filled !</span>
</p>
This is the current state, in which the layout is in:
<p>
<label class="control-label" for="signupform-username">Username</label>
<input id="signupform-username" class="form-control" type="text" name="SignupForm[username]">
<span class="error-msg">Username may not be empty</span>
</p>
This is my PHP / Yii2-part
<?php
$form = ActiveForm::begin([
'id' => 'form-signup',
'fieldConfig' => [
'template' => "<p>{label}{input}{error}</p>",
'errorOptions' => [
'tag' => 'span',
'class' => 'error-msg',
],
],
]);
echo $form->field($model, 'username', [
'inputTemplate' => '{input}',
])->textInput(['autofocus' => false])
?>
The Problems:
The <span class="error-msg"> is always rendered, even though there is no error yet. To clarify: The span has no content and is rendered like this:
<span class="error-msg"></span> (I want it to be there if there IS actually an error, not as a placeholder before
I can't figure out on how to apply an error-class to the input, which works for the ajax-validation, as well as the not JS-way.
Any help is appreciated,
thanks
you can add class for each field if you want
<?= $form->field($model, 'title')->textInput(['class'=>'form-control'])->label('Your Label',['class'=>'label-class']) ?>
Try to disable ajax validation of input field.
echo $form->field($model, 'username', ['enableAjaxValidation' => false]);
or
echo $form->field($model, 'username', ['enableClientValidation' => false]);
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 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.
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);