I have came across with one problem i need to show different form elements
Based on different condition to the user i know it will be easy in core php but want to do in zend environment
EXAMPLE:
If person is disabled we will show two radio buttons
$disable = new Shaadi_Form_Element_radio('disablitiy');
$disableArr = array(""=>" Doesn't Matter","Y"=>" show disabled");
IF he is not disabled
$disable = new Shaadi_Form_Element_radio('disablitiy');
$disableArr = array(""=>" Doesn't Matter","N"=>" do not show disabled");
I want this code to be done in form how can I optimize this please help me
Whenever a form - or any object, for that matter - is dependent upon some information external to the form, I usually pass that information in the form's constructor. Then I inspect it later in init() when I am building the form.
Example:
class My_Form extends Zend_Form
{
protected $hasDisability;
public function __construct($hasDisability)
{
$this->hasDisability = (bool) $hasDisability;
parent::__construct();
}
public function init()
{
// Add all your other elements
// Blah, blah
// Add the element that is dependent upon the $hasDisability value
$disable = new Shaadi_Form_Element_radio('disablitiy');
$disableArr = $this->hasDisability
? array(""=>" Doesn't Matter","Y"=>" show disabled")
: array(""=>" Doesn't Matter","N"=>" do not show disabled");
// Add the $disableArr into the radio element
$disable->setMultiOptions($disableArr);
}
}
Usage - perhaps in a controller - is then something like:
$form = new My_Form(true); // for a disabled used
$form = new My_Form(false); // for a non-disabled user
To implement the element in form, based on some condition, you need to pass the user disability option in form constructor through controller.
You can perform below steps to display radio button in view:
Form code:
class Application_Form_User extends Zend_Form {
public function init() {
$formAttribs = $this->getAttribs();
$isDisable = $formAttribs['disable'];
if (!$disabled) {
$disableArr = array(""=>" Doesn't Matter","Y"=>" show disabled");
} else {
$disableArr = array(""=>" Doesn't Matter","N"=>" do not show disabled");
}
$this->addElement('radio', 'disability', array(
'label' => 'Disability',
'required' => true,
'multiOptions' => $disableArr,
));
}
}
In controller:
public function addAction() {
$disable = ($user->disable) ? true : false;
$form = new Application_Form_User(array('disable' => $disable));
$this->view->form = $form;
}
In view you can get 'disability' element as below :
<?php echo $this->form->getelement('disability'); ?>
In your form, define your radio element:
$disable = new Shaadi_Form_Element_radio('disablitiy');
In your Controller, call this element and add the good options:
if ($disable)
$disableArr = array(""=>" Doesn't Matter","Y"=>" show disabled");
else
$disableArr = array(""=>" Doesn't Matter","N"=>" do not show disabled");
$form->getElement('disablitiy')->setMultiOptions($disableArr);
Related
I am currently trying to add a Clone action to my EmployeeCrudController.
The action should redirect to the Action::NEW view and have some prefilled values.
However I can't figure out how to prefill this form.
Here is where how I define my action within the EmployeeCrudController:
public function configureActions(Actions $actions): Actions
{
$cloneAction = Action::new('Clone', '')
->setIcon('fas fa-clone')
->linkToCrudAction('cloneAction');
return $actions->add(Crud::PAGE_INDEX, $cloneAction);
}
And this is how my cloneAction looks like, which currently redirects to the Action::NEW as expected but without prefilled values:
public function cloneAction(AdminContext $context): RedirectResponse
{
$id = $context->getRequest()->query->get('entityId');
$entity = $this->getDoctrine()->getRepository(Employee::class)->find($id);
$clone = new Employee();
$entity->copyProperties($clone);
$clone->setFirstname('');
$clone->setLastname('');
$clone->setEmail('');
$routeBuilder = $this->get(CrudUrlGenerator::class);
$url = $routeBuilder->build([
'Employee_lastname' => 'test',
'Employee[teamMembershipts][]' => $clone->getTeamMemberships(),
])
->setController(EmployeeCrudController::class)
->setAction(Action::NEW)
->generateUrl()
;
return $this->redirect($url);
}
You can set the value of a field in easyAdmin using the option data.
$builder->add('Employee_lastname', null, ['data' => $clone->getTeamMemberships()]);
If your field has multiple options, you can use the choices and choices_value.
I have form, created by ActiveForm widget. User enters polish postal code there. In appropriate controller I put entered data in DB, for example:
$company_profile_data->postal_code = $_POST['CompanyProfiles']['postal_code'];
$company_profile_data->update();
I decided to use standalone validator for postal code validation. Rules for this attribute in model:
public function rules() {
return [
//...some other rules...
['postal_code', 'string', 'length' => [6,6]],
['postal_code', PostalValidator::className()], //standalone validator
];
}
app/components/validators/PostalValidator class code:
namespace app\components\validators;
use yii\validators\Validator;
use app\models\CompanyProfiles;
use app\models\Users;
class PostalValidator extends Validator {
public function init() {
parent::init();
}
public function validateAttribute($model, $attribute) {
if (!preg_match('/^[0-9]{2}-[0-9]{3}$/', $model->$attribute))
$model->addError($attribute, 'Wrong postal code format.');
}
public function clientValidateAttribute($model, $attribute, $view) { //want js-validation too
$message = 'Invalid status input.';
return <<<JS
if (!/^[0-9]{2}-[0-9]{3}$/.test("{$model->$attribute}")) {
messages.push("$message");
}
JS;
}
}
So, an example of correct code is 00-202.
When I (in user role) enter incorrect value, page reloads and I see Wrong postal code format. message, although I redefined clientValidateAttribute method and wrote JS-validation, which, as I suggested, will not allow page to reload. Then I press submit button again: this time page doesn't reload and I see Invalid status input. message (so, the second press time JS triggers). But I when enter correct code after that, I still see Invalid status input. message and nothing happens.
So, what's wrong with my clientValidateAttribute() method? validateAttribute() works great.
UPDATE
Snippet from controller
public function actionProfile(){ //can't use massive assignment here, cause info from 2 (not 1) user models is needed
if (\Yii::$app->user->isGuest) {
return $this->redirect('/site/index/');
}
$is_user_admin = Users::findOne(['is_admin' => 1]);
if ($is_user_admin->id == \Yii::$app->user->id)
return $this->redirect('/admin/login/');
$is_user_blocked = Users::find()->where(['is_blocked' => 1, 'id' => \Yii::$app->user->id])->one();
if($is_user_blocked)
return $this->actionLogout();
//3 model instances to retrieve data from users && company_profiles && logo
$user_data = Users::find()->where(['id'=>\Yii::$app->user->id])->one();
$user_data->scenario = 'update';
$company_profile_data = CompanyProfiles::find()->where(['user_id'=>Yii::$app->user->id])->one();
$logo = LogoData::findOne(['user_id' => \Yii::$app->user->id]);
$logo_name = $logo->logo_name; //will be NULL, if user have never uploaded logo. In this case placeholder will be used
$upload_logo = new UploadLogo();
if (Yii::$app->request->isPost) {
$upload_logo->imageFile = UploadedFile::getInstance($upload_logo, 'imageFile');
if ($upload_logo->imageFile) { //1st part ($logo_data->imageFile) - whether user have uploaded logo
$logo_file_name = md5($user_data->id);
$is_uploaded = $upload_logo->upload($logo_file_name);
if ($is_uploaded) { //this cond is needed, cause validation for image fails (?)
//create record in 'logo_data' tbl, deleting previous
if ($logo_name) {
$logo->delete();
} else { //if upload logo first time, set val to $logo_name. Otherwise NULL val will pass to 'profile' view, and user wont see his new logo at once
$logo_name = $logo_file_name.'.'.$upload_logo->imageFile->extension;
}
$logo_data = new LogoData;
$logo_data->user_id = \Yii::$app->user->id;
$logo_data->logo_name = $logo_name;
$logo_data->save();
}
}
}
if (isset($_POST['CompanyProfiles'])){
$company_profile_data->firm_data = $_POST['CompanyProfiles']['firm_data'];
$company_profile_data->company_name = $_POST['CompanyProfiles']['company_name'];
$company_profile_data->regon = $_POST['CompanyProfiles']['regon'];
$company_profile_data->pesel = $_POST['CompanyProfiles']['pesel'];
$company_profile_data->postal_code = $_POST['CompanyProfiles']['postal_code'];
$company_profile_data->nip = $_POST['CompanyProfiles']['nip'];
$company_profile_data->country = $_POST['CompanyProfiles']['country'];
$company_profile_data->city = $_POST['CompanyProfiles']['city'];
$company_profile_data->address = $_POST['CompanyProfiles']['address'];
$company_profile_data->telephone_num = $_POST['CompanyProfiles']['telephone_num'];
$company_profile_data->email = $_POST['CompanyProfiles']['email'];
$company_profile_data->update();
}
if (isset($_POST['personal-data-button'])) {
$user_data->username = $_POST['Users']['username'];
$user_data->password_repeat = $user_data->password = md5($_POST['Users']['password']);
$user_data->update();
}
return $this->render('profile', ['user_data' => $user_data, 'company_profile_data' => $company_profile_data, 'upload_logo' => $upload_logo, 'logo_name' => $logo_name]);
}
My inaccuracy was in clientValidateAttribute() method. Instead of $model->$attribute in code snippet:
if (!/^[0-9]{2}-[0-9]{3}$/.test("{$model->$attribute}")) {
...I had to use predefined JS-var value, cause this var changes with entered value change. So, my new code is:
public function clientValidateAttribute($model, $attribute, $view) {
return <<<JS
if (!/^[0-9]{2}-[0-9]{3}$/.test(value)) {
messages.push("Wrong postal code format.");
}
JS;
}
Model does not load rules and behaviors until not called any function from model. When you call $company_profile_data->update(); model call update and validate functions.
Try add after $company_profile_data = CompanyProfiles::find() this code:
$company_profile_data->validate();
Or just use load function. I think it will help.
I'm trying to create simple form with Zend, I need to use this form in most part, so I create the default form then in controller i modify it for the occurrence with private function. But I have two problems:
the form getValues() doesn't take the value of text element.
I put render at the end of the form action, but it doesn't render to the right page.
The form consists of a text field and the sumbit button
Here is the code of my controller:
That is for customize the form
private function getSearchForm($action = '', $name, $type, $placeholder)
{
$urlHelper = $this->_helper->getHelper('url');
$this->_searchForm = new Application_Form_Admin_Search_Search();
$this->_searchForm->setName($name);
$text = $this->_searchForm->getElement('ricerca');
$text->setLabel('Ricerca '.$type);
$text->setName($type);
$text->setAttrib('placeholder', $placeholder);
$this->_searchForm->setAction($urlHelper->url(array(
'controller' => 'admin',
'action' => $action),
'default'
));
return $this->_searchForm;
}
there are the actions:
public function pneumaticoAction()
{
$this->_searchForm = $this->getSearchForm('pneumaticosearch', 'search', 'pneumatico', 'Ricerca per: modello, marchio o codice');
$this->view->searchForm = $this->_searchForm;
}
public function pneumaticosearchAction()
{
if (!$this->getRequest()->isPost()) {
$this->_helper->redirector('index', 'public');
}
$form=$this->_searchForm;
if (!$form->isValid($this->getRequest()->getPost())) {
$this->render('pneumatico');
}
$values = $form->getValues();
$this->view->assign(array(
"pneumatici" => $this->_modelAdmin->searchPneumatici($values['pneumatico'])
));
$this->render('pneumatico');
}
First question, whenever you get routed to pneumaticosearch action, you do not set $this->_searchForm but you have it as:
$form=$this->_searchForm;
Should be something like this:
$form = $this->getSearchForm('pneumaticosearch', 'search', 'pneumatico', 'Ricerca per: modello, marchio o codice');
And the second question. When you run render, it is similar to pass $this->view parameters to .phtml. I don't see your view files, but I guess you need to set view first:
$this->view->searchForm = $form
I need a help..
I have a unique form with multiples fieldsets, and i need separate some fieldsets in tabs..
So, i tried in the view (form is my variable with the whole form):
$form = $this->form;
$customFieldset = $form->get('customFieldset');
$form->remove('customFieldset');
It works, my fieldset form is in $customFieldset.. but, i can't render this!
When a try:
echo $this->form($customFieldset);
//OR
echo $this->formInput($customFieldset);
//OR
$this->formCollection($customFieldset);
None of that works..
I'm doing right? How i can do it?
Thank very much.
To achieve the result you want (using the form across several tabs, it is better to construct the form differently, based on the tab's number. For example, your form constructor method would look like below:
<?php
namespace Application\Form;
use Zend\Form\Form;
// A form model
class YourForm extends Form
{
// Constructor.
public function __construct($tabNum)
{
// Define form name
parent::__construct('contact-form');
// Set POST method for this form
$this->setAttribute('method', 'post');
// Create the form fields here ...
if($tabNum==1) {
// Add fields for the first tab
} else if($tabNum==2) {
// Add fields for the second tab
}
}
}
In the example above, you pass the $tabNum parameter to form model's constructor, and the constructor method creates a different set of fields based on its value.
In your controller's action, you use the form model as below:
<?php
namespace Application\Controller;
use Application\Form\ContactForm;
// ...
class IndexController extends AbstractActionController {
// This action displays the form
public function someAction() {
// Get tab number from POST
$tabNum = $this->params()->fromPost('tab_num', 1);
// Create the form
$form = new YourForm($tabNum);
// Check if user has submitted the form
if($this->getRequest()->isPost()) {
// Fill in the form with POST data
$data = $this->params()->fromPost();
$form->setData($data);
// Validate form
if($form->isValid()) {
// Get filtered and validated data
$data = $form->getData();
// ... Do something with the validated data ...
// If all tabs were shown, redirect the user to Thank You page
if($tabNum==2) {
// Redirect to "Thank You" page
return $this->redirect()->toRoute('application/default',
array('controller'=>'index', 'action'=>'thankYou'));
}
}
}
// Pass form variable to view
return new ViewModel(array(
'form' => $form,
'tabNum' => $tabNum
));
}
}
In your view template, you use the following code:
<form action="">
<hidden name="tab_num" value="<?php echo $this->tabNum++; ?>" />
<!-- add other form fields here -->
</form>
I am using a Yii hiddenField in a CActiveForm widget. I have saved this hidden field value in database. There is no issue with storing in DB with Controller action at all. after saving this the hidden field should display the value. And how can I populate the form with the database stored value. Or how to refer some other field in the form to contain value from DB after save is processed.
<?php echo $form->hiddenField($model,'ad_form_id',array('value'=>$base)); ?>
My controller action
public function actionBCFormFields()
{
$model=new BCFormField();
if(isset($_POST['BCFormField']))
{
$model->ad_form_id = $_POST['BCFormField']['ad_form_id'];
$model->attributes=$_POST['BCFormField'];
if ($model->save()){
echo'saved';
}
$this->redirect(array('create',
'crm_base_form_field_id'=>$model->crm_base_form_field_id));
}
Based on the very litle code you have given us i would suggest something like this in your controller, but if you edit your question and elaborate , i will edit my question:
public $ad_form_id
public function actionCreate()
{
$model = new User;
$this->ad_form_id = $this->base;
if (isset($_POST['User'])) {
$model->attributes = $_POST['User'];
$this->base = $this->ad_form_id;
if ($model->validate() && $model->save()) {
$this->redirect(array('view'));
}
}
$this->render('create',array('model' => $model,));
}