This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.
Hi. I'm working on a custom real estate plugin, and I wanted to create a simple button "preview" in the form create controller, to load the frontend page with the form data to preview the offer in a real situation.
I've succeed to pass my form data with a basic cookie which lives one minute and redirecting on request success to the front end view secured with a middleware to redirect all unlogged user to a 404.
But I'm having a headache about how to access the file: in my ajax handler, I've spent about 5 hours reading the docs, forum posts and trying to understand how to access the files:
Input::file()
> null, post('photos')
> null, Input::get('photos')
> null, (new File)->fromPost()
> null, read and tried with deferred binding but can't achieve what I want... I've tried with photos and Land.photos (all my form field are "namespaced" with the model name)
In my .yaml file I have this:
photos:
label: Photos
mode: image
imageWidth: '200'
imageHeight: '200'
useCaption: true
type: fileupload
And my form button is there:
<?= Form::open(['class' => 'layout', 'files' => true]) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<button
type="submit"
data-request="onPreview"
data-request-success="window.open(`/preview/land`, '_blank')"
data-hotkey="ctrl+p, cmd+p"
data-load-indicator="<?= e(trans('backend::lang.relation.preview')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.relation.preview')) ?>
</button>
<!-- I also tried with data-request-file attributes on form and button tag -->
And here is the ajax handler where I'm trying to access the files:
public function create_onPreview()
{
// How to get the file here?
$land = new Land(Input::get('Land'));
return response(null, 200)->withCookie('previewCookie', $land, 1);
}
What I'm afraid of is the fact that maybe the ajax just can't pass the fileupload files on custom ajax handler...
Last updated
I'm having my full form value, the session key, but no mention of the photos field. I'm not on my laptop my laptop for now. Will edit this message to show you in 3 hours.
Already tried, as said in the comment on my view file.
I also tried to reproduce the full form tag manually in plain html with the data-request-file.
Does the file field should appear in input::all() dump? I'm guessing it should appear at least the class name as I've already seen elsewhere in my plugins.
When I'm performing the create action, the file is correctly performed, I don't have "two form imbricated" actually. Here is my full create.htm, I've just change the "Save" button to a Preview one :
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('romainmazb/realestate/lands') ?>">Lands</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout', 'files' => true]) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onPreview"
data-request-success="window.open(`/preview/land`, '_blank')"
data-hotkey="ctrl+p, cmd+p"
data-load-indicator="<?= e(trans('backend::lang.relation.preview')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.relation.preview')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
data-request-confirm="Confirmer la création et diffusion?"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create_and_close')) ?>
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('romainmazb/realestate/lands') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('romainmazb/realestate/lands') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>
Here is the dump:
array:4 [
"_session_key" => "lq5cT3KzeNDu2epWGNJ8JBSgYRViXLnUptD3XHSw"
"_token" => "gSK8lGfiivwjz40GqTqi0fVZiIBUgeV7FHfVZJT0"
"Land" => array:21 [
"town" => "Taverny"
"price" => "150000"
"price_prefix" => ""
"price_suffix" => ""
"type" => "0"
"postal_code" => "95150"
"situation" => "1"
"surface" => "300"
"facade" => "16"
"utilities" => "1"
"cos" => "0.12"
"sanitation" => "2"
"level_diff" => "2"
"zone" => array:2 [
0 => "Calme"
1 => "Centre ville"
]
"conveniences" => array:2 [
0 => "Écoles"
1 => "Commerces"
]
"export" => "1"
"description" => "Some huge long text I've truncated"
"tile_front" => "Terrain de [surface] à [ville] ([département])\r\n"
"tile_back" => "[prix]€ pour ce superbe terrain à [ville]\r\n"
"selected_mixable_house_models" => "0"
"_activate_refresh_description" => "0"
]
"formExtraFields_loaded" => "1"
]
Try changing your:
<?= Form::open(['class' => 'layout', 'files' => true]) ?>
to:
<?= Form::ajax('onPreview', ['class' => 'layout', 'files' => true]) ?>
I've seen cases with file uploads where using Form::ajax instead of regular Form::open made a difference.
Same result, I've just also tried to generate the file field directly with the Form helper:
<?= Form::ajax('onPreview', ['class' => 'layout', 'files' => true]) ?>
<?= Form::file('image') ?>
And no mention of the image
field in the Input::all()
dump
I'm currently trying to reproduce the onSave
native behavior in my onPreview
ajax handler, at least the way this handler retrieve the formData but with no success:
"Undefined class constant 'CONTEXT_CREATE'" on line 165 of /home/maz/websites/me/plugins/romainmazb/realestate/controllers/Lands.php
And if I just pass the context to 'create', I'm facing the next line issue, and so on... Don't know why:
"Cannot access protected property Backend\Behaviors\FormController::$context" on line 382 of /home/maz/websites/me/vendor/october/rain/src/Extension/ExtendableTrait.php
Also a weird things, all the FormController "helper", such as formGetContext
, formGetModel
, formGetWidget
and so on, return me 'null' ???
Can't understand why since I'm providing the FormController
class in $implement
:
class Lands extends Controller
{
public $implement = [
'Backend\Behaviors\ListController',
'Backend\Behaviors\FormController',
];
Last updated
You might want to try a simple FRONT-END form with AJAX to see if you get the same problems... maybe this is a problem on the backend.
Maz, I tried with this very simple front-end form in a CMS page and it's working as expected:
url=/form
layout=default
==
function onPreview()
{
debug(Input::all());
}
==
{{ form_ajax('onPreview', {'class':'layout', 'files':true}) }}
{{ form_file('image') }}
{{ form_submit('Submit') }}
{{ form_close }}
Note: I use the debug bar plugin
Last updated
debug
array:3 [▼
"_session_key" => "AMo86tVwcLnuzXe7ju57HUIGpkrDZSuhEhrwoOau"
"_token" => "bI336LMJ705GeLx8eVUuveX1qHlStzfbOgZ77d4O"
"image" => UploadedFile {#1168 ▼
-test: false
-originalName: "Capture d’écran 2020-04-22 à 15.30.23.png"
-mimeType: "image/png"
-size: 131790
-error: 0
#hashName: null
path: "/tmp"
filename: "phpSn7aja"
basename: "phpSn7aja"
pathname: "/tmp/phpSn7aja"
extension: ""
realPath: "/tmp/phpSn7aja"
aTime: 2020-05-02 13:09:58
mTime: 2020-05-02 13:09:58
cTime: 2020-05-02 13:09:58
inode: 147460
size: 131790
perms: 0100600
owner: 1194
group: 1196
type: "file"
writable: true
readable: true
executable: false
file: true
dir: false
link: false
}
]
I ran some tests with a backend controller form with file attachments and it looks like they are not being sent to the AJAX handler.
So there seems to be a different behavior between frontend/backend
Yes, I'm using the last version of firefox.
I was making a frontend/backend test before writing the response. Yep, the front end works for me too... That's not a good news ;/
Any idea about how to access it? I've spent all of mine
Last updated
The fact that all the controller's getters doesn't work makes me feel like something else is happening here too.
I should be able to access the formGetWidget()->getSaveData()
but I'm not.
[EDIT] I've tried in an other really basic FormController, I'm note able to access the getters too:
class Styles extends Controller
{
public $implement = [
'Backend\Behaviors\ListController',
'Backend\Behaviors\FormController',
];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $requiredPermissions = [
'manage_styles',
];
public function __construct()
{
parent::__construct();
BackendMenu::setContext('RomainMazB.RealEstate', 'settings-menu', 'styles-menu');
}
public function onPreview($context = null)
{
debug($this->formGetWidget()); // Return null
}
}
Feeling like onSave native handler is magic :o
Last updated
Maz said:
The fact that all the controller's getters doesn't work makes me feel like something else is happening here too.
I should be able to access the
formGetWidget()->getSaveData()
but I'm not
This is a different issue. You'd need to run some form initialization code to get the form content in this way from the AJAX handler.
On another note, if the file upload field is defined DIRECTLY in the html markup (not in the model form fields definition file) and you add "data-request-files" to the BUTTON markup, that works...
We need to figure out why it doesn't get the file upload from the formRender()
To use the FormController methods and properties, you'd need to emulate this in your ajax handler:
public function preview($recordId = null, $context = null)
{
try {
$this->context = strlen($context) ? $context : $this->getConfig('preview[context]', self::CONTEXT_PREVIEW);
$this->controller->pageTitle = $this->controller->pageTitle ?: $this->getLang(
"{$this->context}[title]",
'backend::lang.form.preview_title'
);
$model = $this->controller->formFindModelObject($recordId);
$this->initForm($model);
}
catch (Exception $ex) {
$this->controller->handleError($ex);
}
}
This [old] forum post [may] address the file upload issue for a form controller:
https://octobercms.com/forum/post/batch-upload-and-create
Last updated