Additional attributes in select options - php

In createForm.php I have code:
$this->add([
'type' => Element\Select::class,
'name' => 'subcategory_id',
'options' =>[
'label' => 'Subcategory',
'empty_option' => 'Select...',
'value_options' => $subcategoriesTable->fetchAllSubcategories(),
],
'attributes' => [
'required' => false,
'class' => 'custom-select',
],
]);
In SubcategoriesTable.php
public function fetchAllSubcategories()
{
$sqlQuery = $this->sql->select()->order('sub_name ASC');
$sqlStmt = $this->sql->prepareStatementForSqlObject($sqlQuery);
$handler = $sqlStmt->execute();
$row = [];
foreach($handler as $tuple){
$row[$tuple['subcategory_id']] = $tuple['sub_name'];
}
return $row;
}
And generated records from my database to my form:
<option value="1">Name1</option>
How I can change my code for making additional attribute like this?
<option value="1" data-chained="parent_name">Name1</option>
parent name value is from another select. Also generated in the same way.

You'll have to make a few changes.
Inside SubcategoriesTable, you'll have to retrieve the parent's name (I used parent_name as key, since we don't know what the exact column's name..):
public function fetchAllSubcategories()
{
$sqlQuery = $this->sql->select()->order('sub_name ASC');
$sqlStmt = $this->sql->prepareStatementForSqlObject($sqlQuery);
$handler = $sqlStmt->execute();
$row = [];
foreach($handler as $tuple){
$row[$tuple['subcategory_id']] = [
'sub_name' => $tuple['sub_name'],
'parent_name' => $tuple['parent_name']
];
}
return $row;
}
Then, in CreateForm:
$valueOptions = [];
foreach($subcategoriesTable->fetchAllSubcategories() as $subcategoryId => $subcategory){
$valueOptions[] = [
'value' => $subcategoryId,
'label' => $subcategory['sub_name'],
'attributes' => [
'data-chained' => $subcategory['parent_name']
]
];
}
$this->add([
'type' => Element\Select::class,
'name' => 'subcategory_id',
'options' =>[
'label' => 'Subcategory',
'empty_option' => 'Select...',
'value_options' => $valueOptions,
],
'attributes' => [
'required' => false,
'class' => 'custom-select',
],
]);
Re-reading your question, I saw that you need this value for another select. I suggest you to add parent's ID instead of parent's name, it would be easier to handle thing.
As exemple:
public function formAction() {
$subcagetoryForm = new Form();
$subcagetoryForm->add([
'type' => Select::class,
'name' => 'subcategory_id',
'options' => [
'label' => 'Subcategory',
'empty_option' => 'Select...',
'value_options' => [
[
'value' => 1,
'label' => 'Name 1',
'attributes' => [
'data-chained' => 'parent 1'
]
],
[
'value' => 2,
'label' => 'Name 2',
'attributes' => [
'data-chained' => 'parent 2'
]
]
],
],
'attributes' => [
'required' => false,
'class' => 'custom-select',
],
]);
return [
'subcagetoryForm' => $subcagetoryForm
];
}
In the view:
<?= $this->formElement($this->subcagetoryForm->get('subcategory_id')); ?>
Result:
[]
However, I'll suggest you to create a custom element to remove all this logic from the form. The custom element will be helpful if you'll need it inside another form. You can take a look at this question

Related

How to create recursive hierarchy in webonyx/graphql?

I want to create hierarchy tree-like structure.
$fieldOptionsType = new ObjectType([
'name' => 'Options',
'fields' => [
'nested' => [
'type' => Type::listOf($fieldType), // $fieldType not initialized yet.
],
],
]);
$fieldType = new ObjectType([
'name' => 'Field',
'fields' => [
'options' => [
'type' => $fieldOptionsType,
],
],
]);
I have problem, that variable $fieldType used first isnt created yet. How to solve this?
Try with the below code, this will build a tree structure.
private ObjectType $fieldOptionsType;
private ObjectType $fieldType;
private array $objectTypes;
$this->fieldOptionsType = $this->objectTypes['Options'] ??= new ObjectType([
'name' => 'Options',
'fields' => [
'nested' => [
'type' => fn() => Type::listOf($this->fieldType),
],
],
]);
$this->fieldType = $this->objectTypes['Field'] ??= new ObjectType([
'name' => 'Field',
'fields' => [
'options' => [
'type' => fn() => $this->fieldOptionsType,
],
],
]);

Populate Multi select drop drop down zend 3

Hello everyone i am getting really hard time populating my multi select drop down in my form.
what i have tried so far was adding factory for my form which is like this
class MovieFormFactory
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$entityManager = $container->get('doctrine.entitymanager.orm_default');
$actors = $entityManager->getRepository(Actor::class)->findAll();
$form = new MovieForm();
$form->setActors($data);
return $form;
}
}
my form
Class MovieForm extends Form
{
private $actors = [];
public function setActors($actorsData){
$this->actors = $actors
}
public function __construct()
{
parent::__construct('post-form');
$this->setAttribute('method', 'post');
$this->addElements();
$this->addInputFilter();
$this->add([
'type' => 'select',
'name' => 'actors',
'attributes' => [
'id' => 'actors',
'multiple' => true
],
'options' => [
'label' => 'Actors',
'value_options' => $this->actors,
],
]);
$this->add([
'type' => 'select',
'name' => 'directors',
'attributes' => [
'id' => 'directors',
],
'options' => [
'label' => 'Director',
'value_options' => $this->getOptionForSelect($directors),
],
]);
}
/**
* This method adds elements to form (input fields and submit button).
*/
protected function addElements()
{
// Add "title" field
$this->add([
'type' => 'text',
'name' => 'title',
'attributes' => [
'id' => 'title'
],
'options' => [
'label' => 'Title',
],
]);
// Add "description" field
$this->add([
'type' => 'textarea',
'name' => 'description',
'attributes' => [
'id' => 'description'
],
'options' => [
'label' => 'Description',
],
]);
// Add "tags" field
// $this->add([
// 'type' => 'text',
// 'name' => 'actors',
// 'attributes' => [
// 'id' => 'actors',
// 'multiple' => 'multiple'
// ],
// 'options' => [
// 'label' => 'Actors',
// 'value_options' => $this->getOptionForSelect(),
// ],
// ]);
// Add "status" field
$this->add([
'type' => 'select',
'name' => 'status',
'attributes' => [
'id' => 'status'
],
'options' => [
'label' => 'Status',
'value_options' => [
MovieStatusEnum::STATUS_DRAFT => MovieStatusEnum::STATUS_DRAFT,
MovieStatusEnum::STATUS_PUBLISHED => MovieStatusEnum::STATUS_PUBLISHED,
]
],
]);
// Add the submit button
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Create',
'id' => 'submitbutton',
],
]);
}
/**
* This method creates input filter (used for form filtering/validation).
*/
private function addInputFilter()
{
$inputFilter = new InputFilter();
$this->setInputFilter($inputFilter);
$inputFilter->add([
'name' => 'title',
'required' => true,
'filters' => [
['name' => 'StringTrim'],
['name' => 'StripTags'],
['name' => 'StripNewlines'],
],
'validators' => [
[
'name' => 'StringLength',
'options' => [
'min' => 1,
'max' => 1024
],
],
],
]);
$inputFilter->add([
'name' => 'description',
'required' => true,
'filters' => [
['name' => 'StripTags'],
],
'validators' => [
[
'name' => 'StringLength',
'options' => [
'min' => 1,
'max' => 4096
],
],
],
]);
$inputFilter->add([
'name' => 'actors',
'required' => true,
]);
}
private function getOptionForSelect($data)
{
foreach ($data as $person) {
$selectData[$person->getId()] = $person->getName();
}
return $selectData;
}
}
and this is my registered factory in module.config.php
'form_elements' => [
'factories' => [
Form\MovieForm::class => Form\Factory\MovieFormFactory::class
]
],
but nothing seems to work i am unable to show my actors while creating a movie and unable to show selected actors while editing a movie can some please guide me here i am new to zend.
In the constructor, the line value_options' => $this->actors is wrong because $this->actors is not set yet. In your factory you write :
$form = new MovieForm();
$form->setActors($data);
You must therefore declare the public method setActors() in the class MovieForm which will take care of setting up the options array.
public function setActors($array)
{
$this->get('actors')->setValueOptions($array);
}

Laravel backpack select_from_array

I am totally confused with select_from_array field in laravel backpack.
in my controller i am using a select_from_array field where in options i call a function,but when i run the code error is displayed. please help me with this.
Error : FatalErrorException in EventController.php line 106: syntax error, unexpected '$this' (T_VARIABLE)
controller.php
public $crud = array(
"model" => "App\Larapen\Models\Event",
"entity_name" => "event",
"entity_name_plural" => "events",
"route" => "admin/event",
"reorder" => true,
"reorder_label" => "name",
"reorder_max_level" => 2,
"details_row" => true,
// *****
// COLUMNS
// *****
"columns" => [
[
'name' => "id",
'label' => "ID"
],
],
"fields" => [
[
'name' => "event_name",
'label' => "Event name",
'type' => "text",
'placeholder' => "Event Name",
],
[
'name' => "event_topic",
'label' => "Event Topic",
'type' => "text",
'placeholder' => "Event Topic",
],
[
'name' => "event_type_id",
'label' => "Event Type",
'model' => "App\Larapen\Models\EventType",
'entity' => "eventType",
'attribute' => "name",
'type' => "select",
],
[
'name' => "about_event",
'label' => "About event",
'type' => "ckeditor",
'placeholder' => "About the Event",
],
[
'name' => "country_code",
'label' => "Country",
'type' => 'select_from_array',
'options' => $this->countries(),
'allows_null' => false,
],
],
);
public function countries()
{
..................
}
Please help me with this , why this happens? how to solve this issue?
Waiting for a response................
You can not use the pseudo-variable $this out of class method.
http://php.net/manual/en/language.oop5.properties.php
The pseudo-variable $this is available inside any class method when that method is called from within an object context. $this is a reference to the calling object
So if you want to set the attribute of crud's with $this, you can set it in the __construct function
public function __construct()
{
$this->crud['fields'][4] = $this->countries();
}
Or initialize it the __construct function
public $crud;
public function __construct()
{
$this->crud = array(
'model' => 'App\Larapen\Models\Event',
'entity_name' => 'event',
'entity_name_plural' => 'events',
'route' => 'admin/event',
'reorder' => true,
'reorder_label' => 'name',
'reorder_max_level' => 2,
'details_row' => true,
// *****
// COLUMNS
// *****
'columns' => [
[
'name' => 'id',
'label' => 'ID'
],
],
'fields' => [
[
'name' => 'event_name',
'label' => 'Event name',
'type' => 'text',
'placeholder' => 'Event Name',
],
[
'name' => 'event_topic',
'label' => 'Event Topic',
'type' => 'text',
'placeholder' => 'Event Topic',
],
[
'name' => 'event_type_id',
'label' => 'Event Type',
'model' => 'App\Larapen\Models\EventType',
'entity' => 'eventType',
'attribute' => 'name',
'type' => 'select',
],
[
'name' => 'about_event',
'label' => 'About event',
'type' => 'ckeditor',
'placeholder' => 'About the Event',
],
[
'name' => 'country_code',
'label' => 'Country',
'type' => 'select_from_array',
'options' => $this->countries(),
'allows_null' => false,
],
],
);
}

Adding a conditional statement to an array of fields?

I need to include a conditional statement into the following array called $fields.
$fields = [
'program_id' => [
'type' => 'select',
'label' => 'Program',
'opts' => ["One", "Two", "Three"],
],
'name' => [
'label' => 'Job Name'
],
'start_date' => [
'class' => 'date-picker',
'label' => 'Job Starts' . $req,
'val' => $job->start_date ? dateToPicker($job->start_date) : null
],
'end_date' => [
'class' => 'date-picker',
'label' => 'Job Ends' . $req,
'val' => $job->end_date ? dateToPicker($job->end_date) : null
],
'section' => [
'type' => 'hidden',
'val' => 'details'
],
];
if (!$job->id && $program)
{
$fields['job_copy'] = [
'label' => 'Copy Job From',
'type' => 'select',
'textAsValue' => false,
'_comment' => 'Selecting a job here will copy all job information except the name.',
'opts' => array_replace([0 => '-- Select Job --'], $program->jobs()->lists('name', 'id')->all())
];
}
$fields[] = [
'type' => 'submit',
'label' => "Save",
'class' => 'btn btn-primary !important'
];
}
I need to move the conditional statement to the top so that it is the first thing displayed on the form. However, when I move it to the top it disappears. How can I integrate the conditional check into the top of the form as opposed to at the bottom where it currently displays?
$fields = [];
if (!$job->id && $program)
{
$fields['job_copy'] = [
'label' => 'Copy Job From',
'type' => 'select',
'textAsValue' => false,
'_comment' => 'Selecting a job here will copy all job information except the name.',
'opts' => array_replace([0 => '-- Select Job --'], $program->jobs()->lists('name', 'id')->all())
];
}
$fields2 = [
'program_id' => [
'type' => 'select',
'label' => 'Program',
'opts' => ["One", "Two", "Three"],
],
'name' => [
'label' => 'Job Name'
],
'start_date' => [
'class' => 'date-picker',
'label' => 'Job Starts' . $req,
'val' => $job->start_date ? dateToPicker($job->start_date) : null
],
'end_date' => [
'class' => 'date-picker',
'label' => 'Job Ends' . $req,
'val' => $job->end_date ? dateToPicker($job->end_date) : null
],
'section' => [
'type' => 'hidden',
'val' => 'details'
],
];
$fields = array_merge($fields,$fields2);
$fields[] = [
'type' => 'submit',
'label' => "Save",
'class' => 'btn btn-primary !important'
];

Showing blank rows for filters in Yii2.0 with GridView

I have set up GridView to crfeate my table in Yii2.0 as follows:
<?= \yii\grid\GridView::widget([
'dataProvider' => $model->dataProvider,
'filterModel' => $model->searchModel,
'columns' => [
[
'label' => Yii::t( $cat, 'Id' ),
'value' => 'id',
],
[
'label' => Yii::t( $cat, 'Title' ),
'format' => 'raw',
'value' => function ( $data ) {
if ( $data['status_code'] != 5 )
{
return Html::a( $data['title'], '/signer/view/' . $data['id'] );
}
else
{
return $data['title'];
}
},
],
[
'label' => Yii::t( $cat, 'Description' ),
'value' => 'description',
],
[
'label' => Yii::t( $cat, 'Filename' ),
'value' => 'filename',
],
[
'label' => Yii::t( $cat, 'Status' ),
'value' => 'status',
'contentOptions' => function ( $data ) {
$statuses = [
1 => 'text-primary', # New
2 => 'text-warning', # Unsigned
3 => 'text-warning', # Partially signed
4 => 'text-success', # Signed
5 => 'text-danger', # Deleted
];
return [ 'class' => $statuses[$data['status_code']] ];
}
],
[
'label' => Yii::t( $cat, 'Created' ),
'value' => 'created',
],
//[ 'class' => 'yii\grid\ActionColumn' ],
],
]);
?>
I get all the correct data, but instead of filter inputs, I get empty rows.
Why is that? What am I missing?
PS: The search model itself works fine, meaning, when I add to the url ?title=asd it actually get the search results!
According to the documentation of the $filterModel property:
Note that in order to show an input field for filtering, a column must have its yii\grid\DataColumn::$attribute property set or have yii\grid\DataColumn::$filter set as the HTML code for the input field.
So you need to set yii\grid\DataColumn::$attribute property on your columns and in most of the cases this makes the value unnecessary:
<?= \yii\grid\GridView::widget([
'dataProvider' => $model->dataProvider,
'filterModel' => $model->searchModel,
'columns' => [
[
'label' => Yii::t( $cat, 'Id' ),
'attribute' => 'id',
],
[
'label' => Yii::t( $cat, 'Title' ),
'format' => 'raw',
'attribute' => 'title',
'value' => function ( $data ) {
if ( $data['status_code'] != 5 )
{
return Html::a( $data['title'], '/signer/view/' . $data['id'] );
}
else
{
return $data['title'];
}
},
],
[
'label' => Yii::t( $cat, 'Description' ),
'attribute' => 'description',
],
[
'label' => Yii::t( $cat, 'Filename' ),
'attribute' => 'filename',
],
[
'label' => Yii::t( $cat, 'Status' ),
'attribute' => 'status',
'contentOptions' => function ( $data ) {
$statuses = [
1 => 'text-primary', # New
2 => 'text-warning', # Unsigned
3 => 'text-warning', # Partially signed
4 => 'text-success', # Signed
5 => 'text-danger', # Deleted
];
return [ 'class' => $statuses[$data['status_code']] ];
}
],
[
'label' => Yii::t( $cat, 'Created' ),
'attribute' => 'created',
],
//[ 'class' => 'yii\grid\ActionColumn' ],
],
]);
?>
Another possible reason for the blank line: (not in posters exact case)
Missing/incorrect declaration of the public function rules() in the search model. In Yii 1 you could concatenate the string, in Yii2 they need to be actual array elements.
return [
[['authorId, title, publishFrom'], 'safe'], //WRONG
[['authorId', 'title', 'publishFrom'], 'safe'], //CORRECT
];

Categories