Silverstripe 3.2: How to add and update Dataobjects in a frontend form dynamically?
Asked Answered
S

1

6

Example: I have Members (who can login and update their data) who have one or many qualifications. So I have a DataObject 'Members' and a DataObject 'Qualification' with a has_one/has_many relationship.

Something like this:

class Qualification extends DataObject {

    private static $db = array (
        'Title' => 'Text',
        'From' => 'Date',
        'Till' => 'Date'
    );

    private static $has_one = array (
        'Member' => 'Member',
    );

...

class Member extends DataObject {

   ...

   private static $has_many = array (
      'Qualifications' => 'Qualification',
  );

...

Now I want to build a form in the frontend which allows the member to add many qualifications at once and also update existing qualifications in the same form.

It could look like this

Qualifikation One

Title: xxx (textfield) From: xxx (datefield) Till: xxx (datefield)

Qualifikation Two

Title: xxx (textfield) From: xxx (datefield) Till: xxx (datefield)

+ add qualifications

What is the best way to do that?

I could use jQuery to add fields dynamically like this: http://jsfiddle.net/nzYAW/

But how can I handle to update and add them to the database. Everything I tried was really complicated and messy, so I think maybe somebody else has an idea I just don't see at the moment. Every help would be appreciated!

Smasher answered 25/1, 2016 at 18:11 Comment(5)
I have never done this before, but I would look at trying to use a GridField on the front end with the GridField extensions module GridFieldEditableColumns and GridFieldAddNewInlineButton components.Ejective
@iraia you just need an action that reads the post and change the input attribute name to a format that can be read as an array: #2434227 . Then just save the "keys" data to the dataobject. Of course you could have a hidden field that submits the count of the inputs you have, and then concatenate that and get a field, but this way you can just iterate the submitted data quite easily.Nd
Thank you guys. I will give both options a try and will report my results here. :)Smasher
Ok. I started with the GridField extension module and it was so easy and worked as expected that I just keep that way. Nevertheless thank you both of you!Smasher
@iraia could you submit your own solution as an answer. Or at least the important bits :)Nd
S
4

I solved my problem with the solution of 3dgoo. I use a GridField in my frontend form with the GridField extension module and the components GridFieldEditableColumns and GridFieldAddNewInlineButton. Here is an example:

public function MyForm() {

     $config = GridFieldConfig::create();
     $config->addComponent(new GridFieldButtonRow('before'));
     $config->addComponent(new GridFieldEditableColumns());
     $config->addComponent(new GridFieldAddNewInlineButton());
     $gridField = GridField::create('Qualifications', 'Qualifications', Qualification::get()->filter(array('MemberID' => Member::currentUserID()))),$config);

     $fields = new FieldList(

          .... here goes some other Fields like Textfields ...

          TextField::create('MyTextField'),
          CheckboxField::create('MyCheckboxField'),
          $gridField,
     );


     $actions = new FieldList(
          FormAction::create('myAction','save'),
          FormAction::create('myOtherAction','save and next')
     );

     $form = new Form($this, __FUNCTION__, $fields, $actions);
     $form->loadDataFrom(Member::get()->byID(Member::currentUserID()));
     return $form;

}

public function myAction($data, $form) {
      $member = Member::get()->byId(Member::currentUserID());
      $form->saveInto($member);
      $member->write();      
}

I also had to add the canView, canEdit, canCreate and canDelete function to the Qualification DataObject to allow to edit and show it.

Smasher answered 27/1, 2016 at 10:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.