Rudiger
Rudiger

Reputation: 6769

Upload field with custom form requiring a custom implementation of Field()

I have some custom routes in my system:

---
Name: mysiteroutes
---
Director:
  rules:
    'create//$Action': 'CreateController'

Which has a custom controller to create a form:

class CreateController extends Page_Controller{

    private static $allowed_actions = array(
        'submit'
    );

    public function link($action = null) {
        return $this->join_links('create/', $action);
    }

    public function index() {
        $form = Form::create(
            $this,
            '',
            FieldList::create(
                TextField::create('Name', 'Name'),
                $upload = new UploadField('Upload', 'Upload')
            ),
            FieldList::create(
                FormAction::create('submit', 'Submit')->setAttribute('class', 'btn btn-success')
            ),
            RequiredFields::create('Name')
        );
        if($this->request->isPost()) return $form;
        return $this->customise(array('Form'=>$form))->renderWith(array("Create", "Page"));     
    }

    public function submit($data, $form = null) {
        $params = $this->getRequest()->params();
        var_dump($params);
    }
}

When I try and upload something it calls Field() on my controller and then fails as it's not there. I can add it and it calls it correctly however I have no idea what to put in it. I've looked through the Field() function in UploadField.php however there is a lot of code there which I probably shouldn't just copy.

How should I manage the upload of the file in my custom controller or can I forward it to the core framework somehow?

Upvotes: 3

Views: 68

Answers (1)

Fatal Error
Fatal Error

Reputation: 1024

UploadField expects to have a route based on the Form name, in your case ''. If you would change the name of the form to form it would call form/field/Upload/upload. What this does is get the form, then get the field with the name Upload and call the method upload on that class.

Unfortunately, the way you are using the form (which I showed you in an earlier answer :( ) does not support this.

We could solve it like this;

CreateController

class CreateController extends Page_Controller
{
    private static $allowed_actions = [
        'form'
    ];

    public function link($action = null) 
    {
        return $this->join_links('create', $action);
    }

    public function index()
    {
        return $this->renderWith(array("Create", "Page"));     
    }

    public function form()
    {
        return UploadForm::create($this, 'form', 'submit');
    }

    public function submit($data, $form = null)
    {
        $params = $this->getRequest()->params();
        var_dump($params);
    }
}

Form

// create an extra class for the form to keep your controller clean
class UploadForm extends Form
{
    public function __construct($controller, $name, $action)
    {
        $fields = FieldList::create(
            TextField::create('Name', 'Name'),
            UploadField::create('Upload', 'Upload')
        );

        $actions = FieldList::create(
            FormAction::create($action, 'Submit')
                ->setAttribute('class', 'btn btn-success')
        );

        $validator = RequiredFields::create('Name');

        parent::__construct($controller, $name, $fields, $actions, $validator);
    }
}

Upvotes: 1

Related Questions