weerd's avatar

Dynamic Forms

Howdy,

Does anyone know if any of the Laracasts lessons cover how to plan and create dynamic forms in Laravel? For example if you have an admin area for an app, and on a edit form for a specific page you want to allow the admin to add another field to the form to enter additional data.

I'd imagine it's an advanced topic, but was wondering if any of the lessons mention something related to this or if anyone knows of a good resource to learn how to plan and allow for such a feature.

Any help would be appreciated, thanks!

0 likes
19 replies
jostrander's avatar

+1 I've been waiting for this as well. I have an entire back end I'm waiting to code up until I learn how to do this.

tkjaergaard's avatar

Could a simple way to accomplish this not be a fields table and a pivot table to link the record on the fields table to the page record?


Schema::create('fields', function(Blueprint $table) { $table->increments('id'); $table->string('name'); $table->text('value'); $table->timestamps(): }); Schema::create('field_page', function(Blueprint $table) { $table->increments('id'); $table->integer('field_id')->unsigned()->index(); $table->foreign('field_id')->references('id')->on('fields')->onDelete('cascade'); $table->integer('page_id')->unsigned()->index(); $table->foreign('page_id')->references('id')->on('pages')->onDelete('cascade'); $table->timestamps(); });

This would mimic the Wordpress way of custom fields. It might not be the prettiest, but it should work in most cases.

jostrander's avatar

I can't speak for @weerd but what I had interpreted it as is say you have a product with multiple sizes or attributes, etc. On the front end you would end up with something like a plus sign on your form to have Javascript add another element to the form. How do you handle this with Laravel?

Edit: In a more specific scenario, the product would have it's own table, and the attributes would have their own table with a product id.

tkjaergaard's avatar

@jostrander that ain't Laravel, thats more of a frontend question. You could accomplish this with jQuery or preferably Angular.

Laravel is the server layer, it handles the request and servers the response the browser, the UI specific resists in your frontend code.

Again, my approach described above, should still work with the use-case you are describing in terms of saving the data.

1 like
phaberest's avatar

It's just about adding HTML with js. Using .append() of jQuery, for example. ;)

Take a look on this fiddle

If you use a name like name[] for the form fields, in laravel side you treat them like an array.

jostrander's avatar

@tkjaergaard I understand that, but in the server side you have to be able to handle the fields that were added by the javascript (jQuery or Angular like you said). The Schema is already established I would assume, it's more of the validation and using the Input class to handle the dynamic form that I'm less educated about.

Edit: I now realize my first reply was worded wrong. My Apologies.

Devon's avatar

You can store the validation rules in another column with the custom field...

tkjaergaard's avatar
Level 5

You could use a Command bus also covered widely here on Laracasts or you could use a Service class, You've should know the fields available on the model (table), you've properly already defined those fields in the $fillable property on you model.

You could therefore setup a class or method to filter all input and sort out which are not listed on the model, and send them off to the fields table.

Alternatively you could wrap you custom fields in an array in the frontend like:

<input type="text" name="[custom][]" value=""/>

Now you know when you parse the Input::all() that custom contains all of the fields that should be added to the fields.

Hope it makes sense?

I would properly go with the last approach..

1 like
wells's avatar

If you're thinking in terms of a products-esque table, you could also store the item information for said item as either HTML, Markdown, or JSON in a single column of your table.

phaberest's avatar

@jostrander I edited my answer to suit your needing :)

PS: Dont use ids for those fields, obviously.

You can also collect multidimensional data if you name them something like name[][input1] and name[][input2], then you use a foreach to read data from them.

wells's avatar

Ah yes, in the case of searchable... Definitely would separate in a manner similar to what @tkjaergaard has shared. And yes, your UI can be rendered either server side for initial load (optional step) or on the frontend using javascript.

tkjaergaard's avatar

@phaberest again, i wouldn't call either json or a serialized array in the db searchable and not through Eloquent at all.

But, again it comes down to preference, but i wouldn't do it.

weerd's avatar

@tkjaergaard Yeah, that's a good call (using a pivot and fields table) to handle it. I was considering something similar. It's worth a shot!

@jostrander to help clarify, I definitely meant more on the server side of things. So say I have a user facing form, and it has 5 questions that need to be filled out. Well, an Admin on the site decides that they would like to add an additional 2 questions, so they would edit the admin view of the form and add the 2 questions along with the custom labels for what the question asks. Then on the user facing side, the user would now see 7 questions with their respective fields to enter answers. Does this help clarify? :)

weerd's avatar

@tkjaergaard I also like that additional approach you added. Figured the CommandBus could come into play. I like both of these options as well. Need to see which will work best. Thanks for all the suggestions!

weerd's avatar

Thank for the suggestions everyone. Appreciate the input. I'll post in this discussion once I figure out which direction we end up going with once we get it all working!

bdschr's avatar

Use MongoDB to accomplish what you want. Then use a foreach in the controller to save all input to the MongoDB database. It's easier that way, and besides MongoDB is made to process functionalities like this.

sriracha's avatar

@weerd did you ever get this working? I'm looking to do exactly the same...

Please or to participate in this conversation.