Form with "dropdown of existing and add new entity" in one

I want to combine the basic Form->control('thing.id') and Form->control('thing_id',['options'=>$things]) in an add template.

Such that the user can select from the existing list of things through the foreign key thing_id, and can add a new thing.id into the database if the thing doesn’t exist yet.

Is this possible in one form layout?

I have looked at https://book.cakephp.org/4/en/views/helpers/form.html#control-specific-options and https://book.cakephp.org/4/en/views/helpers/form.html#create-select-picker, resulting in
echo $this->Form->control('country_id', ['options' => $countries, 'country.id']); which does not give a syntax error, but shows just like without the extra option ‘country.id’.
Using select, I get syntax errors:
#echo $this->Form->select('country_id', [$countries, 'Enter New'=>'country.id']);
#echo $this->Form->select('country_id', [[$countries], ['country.id']]);

You can do this with a little effort.

Make two controls in your form

echo $this->Form->control('new_thing');
echo $this->Form->control('thing', ['options' => $things];

In your Controller, just check the values of the two request data array nodes and process it as you see fit.

So it is not possible to combine them into one form input?
And what would be the variable of a particular control node or to distinguish between them, to say if Formcontrol1 is empty, insert value Formcontrol2?

If you have the two inputs with the same name attribute, the browser can’t know which one to return to the server as the current value of the input

This code:

    echo $this->Form->create();
    echo $this->Form->control('input', ['type' => 'text']);
    echo $this->Form->control('input', ['options' => $inputs, 'empty' => 'choose one']);
    echo $this->Form->submit();
    echo $this->Form->end();

Would make this html:

and result in this data back to your program:

[
	'input' => ''
]

You could do something with javascript to coordinate the overlapping inputs. But I’m not seeing the gain in this approach.

This code:

    echo $this->Form->create();
    echo $this->Form->control('input_new', ['type' => 'text', 'placeholder' => 'new one']);
    echo $this->Form->control('input', ['options' => $inputs, 'empty' => 'choose one']);
    echo $this->Form->submit();
    echo $this->Form->end();

This would make these inputs which you could format for clarity:

Would get you this data back to the program:

[
	'input_new' => '',
	'input' => ''
]

You could either make rule in your code that any ‘input_new’ data is used if present or use javascript to insure only one or the other input is populated.

1 Like

Thanks for the (visual) help! I have trouble with the display field of the foreign id keys.
I would be OK for now to have it like this:
adding an order:

echo $this->Form->control('product_id', ['options' => $products, 'empty'=>'select product']);
echo $this->Form->control('product.name', ['type' => 'text', 'placeholder' => 'If item is not yet in the list, add here']);

This order can’t probably be saved since only product_id is the foreign key and not the product_name. I have set name as the product display field such that ‘options’=>$products show the list of names instead of ids. How to add a new product entity by inputting a name while the foreign id has to be created and added to the order?

From https://book.cakephp.org/4/en/views/helpers/form.html#creating-inputs-for-associated-data I see

$this->Form->create($article);

// Article controls.
echo $this->Form->control(‘title’);

// Author controls (belongsTo)
echo $this->Form->control(‘author.id’);
echo $this->Form->control(‘author.first_name’);
echo $this->Form->control(‘author.last_name’);

What makes me wonder, if it is necessary to have author fist and last name as foreign keys in the articles DB.

I tried working around it, creating a custom Form field name in add.php:
echo $this->Form->control('new_product_name', ['type'=>'text','required' => false, 'placeholder' => 'If item is not yet in the list, add here']);

and programming the bridge between product.id and product.name in the OrderController.

public function add()
    {
        $order = $this->Orders->newEmptyEntity();
        if ($this->request->is('post')) {
            $order = $this->Orders->patchEntity($order, $this->request->getData());
				// Changed: Set the user_id from the current user.
			$order->user_id = $this->request->getAttribute('identity')->getIdentifier();
			
			if($this->request->getData('new_product_name')){
			$product = $this->Products->newEmptyEntity();
			$product->product_name=$this->request->getData('new_product_name');
			$this->Products->save($product);
			$order->product_id=$product->product_id;
			}

However, $product = $this->Products->newEmptyEntity(); gives the error newEmptyEntity can’t be called on null, even though the same is done correctly above with $order = $this->Orders->newEmptyEntity(); . Has this to do with the fact I am in the OrderController at that point?

If I am correct then your problem solution is here

e.g. select category A to B if user need add new category in the dropdown the he enter into a input box before dropdown. and it appears into your dropdown box as selection. if it is ok then

well 1. first form submit save categories in category table with id
2. Second form as per you requirement with your dropdown box and dropdown box show you category list as user enter values.

Note: first form submit by using JavaScript or ajax call form save the category so that it will give in category dropdown box value added.

Hope this solution help you.

I can come up with abstract solutions, but I have trouble with the explicit CakePHP coding to realize these logical reasonings.

select2 and alike usually can over such a functionality.
e.g. https://sandbox.dereuromark.de/sandbox/tags/select (tags here are either existing or new)
source code is open source.

using some select2 dropdown with the option of a manual string input should probably make this possible somehow also for your use case.

1 Like

Seems promising! Sorry for basic dev questions, but I am lost what code to look for and where to implement it.

In your sandbox depos I get told to look in /plugins/Sandbox/ : , but my best guest would be /src/View/Helper/ MediaEmbedBbcodeHelper.php / and it is not what I am looking for.

At the other hand I hoped for either app\vendor\cakephp\cakephp\src\Form.php or \tutorial_app\vendor\wyrihaximus\twig-view\templates\bake\element, where the former should be the last place to edit anything, I suppose :slight_smile: