Form Builder - Custom layout
Created 8 years ago by emergingdznsI'm trying to build a module that has a stream in it called "Customers". In that stream are the following fields:
'email' => [
'type' => 'anomaly.field_type.email'
],
'billing_first_name' => [
'type' => 'anomaly.field_type.text'
],
'billing_last_name' => [
'type' => 'anomaly.field_type.text'
],
'billing_phone' => [
'type' => 'anomaly.field_type.text'
],
'billing_address' => [
'type' => 'anomaly.field_type.textarea'
],
'billing_city' => [
'type' => 'anomaly.field_type.text'
],
'billing_state' => [
"type" => "anomaly.field_type.state",
"config" => [
"default_value" => null,
"top_options" => null,
"countries" => ['US','CA'],
"mode" => "text",
"handler" => "Anomaly\StateFieldType\Handler\DefaultHandler@handle"
]
],
'billing_zip' => [
'type' => 'anomaly.field_type.text'
],
"billing_country" => [
"type" => "anomaly.field_type.country",
"config" => [
"default_value" => 'US',
"top_options" => ["US", "CA", "MX"],
"mode" => "text",
"handler" => "Anomaly\CountryFieldType\Handler\DefaultHandler@handle"
]
],
'shipping_first_name' => [
'type' => 'anomaly.field_type.text'
],
'shipping_last_name' => [
'type' => 'anomaly.field_type.text'
],
'shipping_phone' => [
'type' => 'anomaly.field_type.text'
],
'shipping_address' => [
'type' => 'anomaly.field_type.textarea'
],
'shipping_city' => [
'type' => 'anomaly.field_type.text'
],
'shipping_state' => [
"type" => "anomaly.field_type.state",
"config" => [
"default_value" => null,
"top_options" => null,
"countries" => ['US','CA'],
"mode" => "text",
"handler" => "Anomaly\StateFieldType\Handler\DefaultHandler@handle"
]
],
'shipping_zip' => [
'type' => 'anomaly.field_type.text'
],
"billing_country" => [
"type" => "anomaly.field_type.country",
"config" => [
"default_value" => 'US',
"top_options" => ["US", "CA", "MX"],
"mode" => "text",
"handler" => "Anomaly\CountryFieldType\Handler\DefaultHandler@handle"
]
]
Now, if I use the CustomerFormBuilder out of the box, I end up with one seriously loooong form in a single column.
What I want is a two column layout, with the billing fields (email plus all billing_*
fields) in one column and then all of the shipping fields (shipping_*
fields) in the second column.
I also want to add a single checkbox field before the shipping fields that the customer can check to say that they are using the same info for shipping as for billing. But I didn't want that as a field in the stream.
So it should look something like this:
https://www.evernote.com/l/AE3_1czw02NKqpngVlMSuEgpJVTkyDNBtlY
I'm unclear as to how to make this work with the builder. I tried messing with sections before but coudn't make heads or tails of it at the time.
Thanks!
Ahhhhhh! That's rad. I had no idea we could define views inside of the sections. That's great!
Thanks!
You are quite welcome! Check this out: http://pyrocms.com/documentation/streams-platform/v1.1#ui/control-panel/the-section-definition
Er.. shit. It's not listed! Ill correct them.
Ok, so I've revised the code and added the form builder php as follows:
<?php namespace MyFolder\StoreModule\Customer\Form;
use Anomaly\Streams\Platform\Ui\Form\FormBuilder;
use MyFolder\StoreModule\Customer\CustomerModel;
class CustomerFormBuilder extends FormBuilder
{
protected $model = CustomerModel::class;
/**
* The form fields.
*
* @var array|string
*/
protected $fields = [
'email',
'billing_first_name',
'billing_last_name',
'billing_address',
'billing_city',
'billing_state',
'billing_zip',
'billing_country',
'billing_phone',
'shipping_first_name',
'shipping_last_name',
'shipping_address',
'shipping_city',
'shipping_state',
'shipping_zip',
'shipping_country',
'shipping_phone'
];
/**
* Fields to skip.
*
* @var array|string
*/
protected $skips = [];
/**
* The form actions.
*
* @var array|string
*/
protected $actions = [];
/**
* The form buttons.
*
* @var array|string
*/
protected $buttons = [];
/**
* The form options.
*
* @var array
*/
protected $options = [];
/**
* The form sections.
*
* @var array
*/
protected $sections = [
'billing' => [
'view' => 'myfolder.module.store::billing_columns',
],
'shipping' => [
'view' => 'myfolder.module.store::shipping_columns',
],
];
/**
* The form assets.
*
* @var array
*/
protected $assets = [];
}
In the view where I'm trying to load the form, I tried adding the following:
{{ form('myfolder.module.store:customer')|raw }}
{{ form('myfolder.module.store::customer')|raw }}
{{ form('customer')|raw }}
But in all cases, I get an error that the Class customer does not Exist
.
What does I need to do?
Thanks!!
Oh wait. I figured that part out. I was missing the binding in the service provider. Oops.
That being said, I'm getting a different error. I'll keep plugging away at it, but figured I'd mention it here now just in case you know right off what the issue is...
Where I put the form, it's now showing this:
Whoops, looks like something went wrong.
FatalErrorException in 8acf457473d34a610bd7984941106c9c5fad63ee7b39a0d809f5c4e40ab4956a.php line 0:
Method Anomaly\Streams\Platform\Ui\Form\FormCriteria::__toString() must not throw an exception, caught ErrorException: Undefined index: type
in 8acf457473d34a610bd7984941106c9c5fad63ee7b39a0d809f5c4e40ab4956a.php line 0
Not a lot of info to go on there...
I still haven't figured this out. I tried adding some debugging to the FormCriteria file to see if I can figure out where things are going wrong, but didn't get anywhere. Here's the breakdown of how things are put together.
In my module, I have a controller that is doing this in the checkout process:
return view('myfolder.module.store::checkout-step2');
Here is the view file mentioned above:
{% extends layout('default') %}
{% block content %}
<div class="row">
<div class="col-xs-12 col-sm-12">
{{ form('customer')|raw }}
</div>
</div>
{% endblock %}
The CustomerFormBuilder is above. The CustomerFormFields file is here:
<?php namespace MyFolder\StoreModule\Customer\Form;
use Illuminate\Contracts\Config\Repository;
/**
* Class CustomerFormFields
*
*/
class CustomerFormFields
{
/**
* Handle the fields.
*
* @param CustomerFormBuilder $builder
* @param Repository $config
*/
public function handle(CustomerFormBuilder $builder, Repository $config)
{
$builder->setFields(
[
'email',
'billing_phone',
'billing_first_name',
'billing_last_name',
'billing_address',
'billing_city',
'billing_state',
'billing_zip',
'billing_country',
'shipping_first_name',
'shipping_last_name',
'shipping_address',
'shipping_city',
'shipping_state',
'shipping_zip',
'shipping_country',
'shipping_phone'
]
);
}
}
Here is the CustomerFormHandler:
<?php namespace Clarityhealth\StoreModule\Customer\Form;
use Illuminate\Routing\Redirector;
use Symfony\Component\HttpFoundation\Response;
use Clarityhealth\StoreModule\Customer\CustomerModel;
use Input;
use Session;
use Request;
/**
* Class CustomerFormHandler
*
*/
class CustomerFormHandler
{
/**
* Handle the form.
*
* @param CustomerFormBuilder $builder
* @param UserAuthenticator $authenticator
* @param UserSecurity $security
* @param Redirector $redirect
*/
public function handle(CustomerFormBuilder $builder, Redirector $redirect) {
// I haven't built the action yet...
}
}
So now here are the billing and shipping column twigs:
<div class="row">
<div class="col-xs-12 col-sm-6"><h4>Billing Information</h4>
<div class="form-group">
{{ customer.fields.email|raw }}
</div>
<div class="form-group">
{{ customer.fields.billing_phone|raw }}
</div>
<div class="form-group">
{{ customer.fields.billing_first_name|raw }}
</div>
<div class="form-group">
{{ customer.fields.billing_last_name|raw }}
</div>
<div class="form-group">
{{ customer.fields.billing_address|raw }}
</div>
<div class="form-group">
{{ customer.fields.billing_city|raw }}
</div>
<div class="form-group">
{{ customer.fields.billing_state|raw }}
</div>
<div class="form-group">
{{ customer.fields.billing_zip|raw }}
</div>
<div class="form-group">
{{ customer.fields.billing_country|raw }}
</div>
</div>
<div class="col-xs-12 col-sm-6">
<h4>Shipping Information</h4>
<div class="form-group">
<label>Use the billing information for shipping?</label>
<div class="checkbox" style="margin-bottom: 4px;">
<label><input type="checkbox" name="use_billing" value="1"> Yes</label>
</div>
</div>
<div class="form-group">
{{ customer.fields.shipping_phone|raw }}
</div>
<div class="form-group">
{{ customer.fields.shipping_first_name|raw }}
</div>
<div class="form-group">
{{ customer.fields.shipping_last_name|raw }}
</div>
<div class="form-group">
{{ customer.fields.shipping_address|raw }}
</div>
<div class="form-group">
{{ customer.fields.shipping_city|raw }}
</div>
<div class="form-group">
{{ customer.fields.shipping_state|raw }}
</div>
<div class="form-group">
{{ customer.fields.shipping_zip|raw }}
</div>
<div class="form-group">
{{ customer.fields.shipping_country|raw }}
</div>
</div>
</div>
FYI, I tried "form.fields.xxxx" in the above as well just as suggested but still get the error. So I then removed all of the twig field lines so each view is straight up html and still get the same error.
Could really use some guidance here. Thanks!
Try using {{ form('customer').get().getContent()|raw }}
to get more output information about that error.
Thanks. That provided the following:
An exception has been thrown during the rendering of a template ("Undefined index: type")
Line 28 is the form line you suggested. I'm perplexed as to what "type" index it's referring to.
It just occurred to me that maybe I needed to add {% block content %}
and {% endblock %}
to the two column view files. I tried that and still no luck. However, I scrolled down and now see two additional messages:
1/3
ErrorException in FieldTypeBuilder.php line 95:
Undefined index: type
and
2/3
Twig_Error_Runtime in Template.php line 182:
An exception has been thrown during the rendering of a template ("Undefined index: type")
In the 1/3 above (FieldTypeBuilder.php), I'm seeing more info in the stacktrace:
in FieldTypeBuilder.php line 95
at HandleExceptions->handleError('8', 'Undefined index: type', '/path/to/site/vendor/anomaly/streams-platform/src/Addon/FieldType/FieldTypeBuilder.php', '95', array('parameters' => array('field' => 'shipping_country', 'prefix' => null, 'rules' => array('nullable'), 'translatable' => false), 'type' => null)) in FieldTypeBuilder.php line 95
at FieldTypeBuilder->build(array('field' => 'shipping_country', 'prefix' => null, 'rules' => array('nullable'), 'translatable' => false)) in FieldFactory.php line 87
at FieldFactory->make(array('field' => 'shipping_country', 'prefix' => null, 'rules' => array('nullable'), 'translatable' => false), object(StreamModel), object(CustomerModel)) in FieldBuilder.php line 86
at FieldBuilder->build(object(CustomerFormBuilder)) in BuildFields.php line 33
I tried removing the shipping_country and billing_country fields from the two twig columns but still get the error.
I'm going to keep looking for the problem.
ok so more progress. I discovered I had a field defined that I had forgotten to add to the stream! I removed that one. Now I'm getting a different error. I feel like I'm getting close but I just can't break through this.
FatalErrorException in Environment.php(403) : eval()'d code line 0:
Method Illuminate\View\View::__toString() must not throw an exception, caught ErrorException: An exception has been thrown during the rendering of a template ("An exception has been thrown during the rendering of a template ("An exception has been thrown during the rendering of a template ("View [text] not found.") in "/path/to/site/vendor/anomaly/streams-platform/src/View/Command/../../../resources/views/form/partials/wrapper.twig" at line 41.") in "/path/to/site/vendor/anomaly/streams-platform/src/View/Command/../../../resources/views/form/partials/fields.twig" at line 2.") in "/path/to/site/vendor/anomaly/streams-platform/src/View/Command/../../../resources/views/form/standard.twig" at line 11.
Ok that one means that there is a syntax error I believe. Double check your views / post them here if you like. Try the deletion of your section views and add them back to find the culprit.
Thought id add to this thread that Pyro does support this better now as well as columns:
Dengan modal yang kecil bisa menang taruhan yang https://pasarbola.io/ sangat besar bila mendapatkan promo bonus deposit slot member baru langsung dari pasarbola.
Cukup anda mendaftar di situs masterqq anda sudah bisa bermain dengan aman dan nyaman dengan winrate tertinggi saat ini masterqq telah mendapatkan https://masterqq.com sertifikat resmi dari pkv games untuk winrate tertinggi.
Since Pyro does not yet support columns / rows just yet the easiest way to do this is with sections and in particular sections using views.
You can define sections in your builder like
protected $sections = [];
Try something like this:
Now inside of those views just include your HTML markup and include the fields like
{{ form.fields.billing_first_name|raw }}
.