Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Form to comment in DataObject, SilverStripe 3.1.12


Go to End


10 Posts   4608 Views

Avatar
Fmateo

Community Member, 5 Posts

1 April 2015 at 10:51pm

Edited: 01/04/2015 10:53pm

I have this structure...:

Products>mysite>code>Products>Product.php
I have my product like DataObject and ContentController to create form and handle on backend...

    class Product extends DataObject
    {
        //...
    }

    class Product_Controller extends ContentController
    {
        private static $allowed_actions = array(
            'CommentForm'
        );
    
        public function CommentForm()
        {
            $form = Form::create(
                this,
                __FUNCTION__,
                FieldList::create(
                    TextField::create('Name',''),
                    EmailField::create('Email',''),
                    TextareaField::create('Comment','')
                ),
                FieldList::create(
                    FormAction::create('handleComment', 'Post Comment')
                    ->setUseButtonTag(true)
                    ->addExtraClass('btn btn-default-color btn-lg')
                ),
                RequiredFields::create('Name','Email', 'Comment')
            )->addExtraClass('form-style');
    
            foreach($form->Fields() as $field){
                $field->addExtraClass('form-control')
                    ->setAttribute('placeholder', $field->getName(), '*');
            }
    
            $data = Session::get("FormData.{$form->getName()}.data");
    
            return $data ? $form->loadDataFrom($data) : $form;
        }
    
        public function handleComment($data, $form){
            Session::set("FormData.{$form->getName()}.data", $data);
            $existing = $this->CommentForm()->Comments()->filter(array(
                'Comment' => $data['Comment']
            ));
            if($existing->exists() && strlen('Comment') > 20){
                $form->sessionMessage('That comment already exists!', 'bad');
    
                return $this->redirectBack();
            }
    
            $comment = ProductComment::create();
            $comment->ProductID = $this->ID;
            $form->saveInto($comment);
            $comment->write();
    
            Session::clear("FormData.{$form->fetName()}.data");
            $form->sessionMessage('Thanks for your comment', 'good');
    
            return $this->redirectBack();
    
        }
    }

Products>mysite>code>Products>ProductsPage.php
Page with many Products...
    class ProductsPage extends Page
    {
    
        private static $has_many = array(
            'Products' => 'Product',
            'Categories' => 'Category'
        );
    //...
    }
    class ProductsPage_Controller extends Page_Controller
    {
        private static $allowed_actions = array (
        'show'
        );
    
        public function show(SS_HTTPRequest $request)
        {
            $product = Product::get()->byID($request->param('ID'));
    
            if (!$product) {
                return $this->httpError(404, 'That region could not be found');
            }
    
            return array(
                'Product' => $product,
                'Name' => $product->Name
            );
        }
    }

Products>mysite>code>extensions>ProductExtension>ProductComments.php
Is a DataExtension with many comments...
    class ProductComments extends DataExtension{
    
        private static $has_many = array(
            'Comments' => 'ProductComment'
        );
    }

Products>mysite>code>extensions>ProductExtension>ProductComment.php
A simple DataObject to comment...
    class ProductComment extends DataObject
    {
        private static $db = array(
            'Name' => 'Varchar',
            'Email' => 'Varchar',
            'Comment' => 'HTMLText'
        );
    
        private static $summary_fields = array(
            'Created' => 'Created',
            'Name' => 'Name',
            'Email' => 'Email',
            'Comment' => 'Text'
        );
        private static $has_one = array(
            'Product' => 'Product'
        );
        public function getCMSFields(){
            $fields = FieldList::create(
                TextField::create('Name'),
                TextField::create('Email'),
                HtmlEditorField::create('Comment')
            );
            return $fields;
        }
    }

My file config.yml to add extension comments...
Products>mysite>_config>config.yml
    Product:
      extensions:
        - ProductComments

SilverStripe files (.ss)... </p>

Products>themes>my_theme>templates>Layout>ProductsPage.ss
Little view to products...

     <% loop $Products %>
            <div class="item col-md-2"><!-- Set width to 4 columns for grid view mode only -->
                <div class="image">
                    <a href="$Link">
                        $Main_image.CroppedImage(175,150)
                    </a>
                </div>
                <div class="item">
                    <h3>
                        <a href="$Link">$Name</a>
                    </h3>
                    $Short_description
                </div>
            </div>
            <% end_loop %>

Products>themes>my_theme>templates>Layout>ProductsPage_show.ss
View to see info and comment product.
    <% with $Product %>
        <%--...--%>
        <h1>Comments</h1>
            <% loop $Comments %>
                <div class="comment">
                    <h3>$Name <small>$Created.Format('j F,Y')</small></h3>
                        <p>$Comment</p>
                </div>
            <% end_loop %>
    
            <div class="comments-form">
                <h3>Leave a Reply</h3>
                    <p>Your email address wlill no be published. Required fields are marked*</p>
    
                $CommentForm
            </div>
    <% end_with %>

I can´t extend ContentController from DataObject, it´s wrong... What would be the best way to posting a product that is DataObject? I'm new, sorry if it is misplaced this topic.

Avatar
Pyromanik

Community Member, 419 Posts

2 April 2015 at 3:18am

What do you mean by 'posting a product'?
Updating one via REST?
Posting a comment?
??

Avatar
Fmateo

Community Member, 5 Posts

2 April 2015 at 6:56am

'Posting a product' I mean put a comment about the product.

Avatar
Fmateo

Community Member, 5 Posts

9 April 2015 at 7:47pm

Edited: 09/04/2015 7:51pm

Hi again... I got part of solution my problem:

In ProductPage i controll the form getting ID product with a param...

Products>mysite>code>Products>ProductsPage.php

 
class ProductsPage_Controller extends Page_Controller
{

    private static $allowed_actions = array (
    'show', 'CommentForm'
    );

    public function show(SS_HTTPRequest $request)
    {
         $product = Product::get()->byID($request->param('ID'));

        if (!$product) {
            return $this->httpError(404, 'That region could not be found');
        }

        return array(
            'Product' => $product,
            'Name' => $product->Name
        );
    }

    public function CommentForm($id)
    {
        $form = Form::create(
            $this,
            __FUNCTION__,
            FieldList::create(
                TextField::create('Name',''),
                EmailField::create('Email',''),
                TextareaField::create('Comment',''),
                HiddenField::create('id','', $id)
            ),
            FieldList::create(
                FormAction::create('handleComment', 'Post Comment')
                    //->setUseButtonTag(true)
                    ->addExtraClass('btn btn-default-color btn-lg')


            ),
            RequiredFields::create('Name','Email', 'Comment')
        )->addExtraClass('form-style');

        foreach($form->Fields() as $field){
            $field->addExtraClass('form-control')
                ->setAttribute('placeholder', $field->getName(), '*');
        }

        $data = Session::get("FormData.{$form->getName()}.data");

        return $data ? $form->loadDataFrom($data) : $form;
    }

    public function handleComment($data, $form){

        Session::set("FormData.{$form->getName()}.data", $data);

        $comment = ProductComment::create();
        $comment->ProductID = $data['id'];
        $form->saveInto($comment);
        $comment->write();


        Session::clear("FormData.{$form->fetName()}.data");
        $form->sessionMessage('Thanks for your comment', 'good');


        return $this->redirectBack();
    }
}

Now the problem is that this when i post the comment, uri change to "Products/home/CommentForm" with a handle error "Sorry, there was a problem handling your request.", the coment posted good but redirection page not working. This because "__Function__" form launch the action form "HandleCommen" but change the url...

Result...

              
<form id="Form_CommentForm" action="/Products/home/CommentForm" method="post" enctype="application/x-www-form-urlencoded" class="form-style">
	<p id="Form_CommentForm_error" class="message " style="display: none"></p>
	<fieldset>	
			<div id="Name" class="field text form-control nolabel">
	<div class="middleColumn">
		<input name="Name" class="text form-control nolabel" id="Form_CommentForm_Name" required="required" aria-required="true" placeholder="Name" type="text">
	</div>
</div>
			<div id="Email" class="field email text form-control nolabel">
	<div class="middleColumn">
		<input name="Email" class="email text form-control nolabel" id="Form_CommentForm_Email" required="required" aria-required="true" placeholder="Email" type="email">
	</div>
</div>	
			<div id="Comment" class="field textarea form-control nolabel">
	<div class="middleColumn">
		<textarea name="Comment" class="textarea form-control nolabel" id="Form_CommentForm_Comment" required="required" aria-required="true" placeholder="Comment" rows="5" cols="20"></textarea>
	</div>
</div>	
			<input name="id" value="1" class="hidden form-control nolabel" id="Form_CommentForm_id" placeholder="id" type="hidden">	
			<input name="SecurityID" value="22a40220fd5e2b641a5b316c37e7159e7056c1a7" class="hidden form-control" id="Form_CommentForm_SecurityID" placeholder="SecurityID" type="hidden">	
		<div class="clear"><!-- --></div>
	</fieldset>
	<div class="Actions">		
	<input name="action_handleComment" value="Post Comment" class="action btn btn-default-color btn-lg" id="Form_CommentForm_action_handleComment" type="submit">	
	</div>
</form>

I´m near to find the solution, but i don´t know what can i do...

Avatar
Fmateo

Community Member, 5 Posts

9 April 2015 at 10:41pm

Edited: 09/04/2015 10:54pm

Solution
Well I got solution for my problem... With this way i can post comments in DataObject...

Products>mysite>code>Products>ProductsPage.php
The most important file, with this, we must control form comment whith PageController.

class ProductsPage extends Page
{
        //...
}

class ProductsPage_Controller extends Page_Controller
{

    private static $allowed_actions = array (
    'show', 'CommentForm'
    );

    public function show(SS_HTTPRequest $request)
    {
         $product = Product::get()->byID($request->param('ID'));

        if (!$product) {
            return $this->httpError(404, 'That region could not be found');
        }

        return array(
            'Product' => $product,
            'Name' => $product->Name
        );
    }

    public function CommentForm($id)
    {
        $form = Form::create(
            $this,
            __FUNCTION__,
            FieldList::create(
                TextField::create('Name',''),
                EmailField::create('Email',''),
                TextareaField::create('Comment',''),
                HiddenField::create('id','', $id)
            ),
            FieldList::create(
                FormAction::create('handleComment', 'Post Comment')
                    //->setUseButtonTag(true)
                    ->addExtraClass('btn btn-default-color btn-lg')
            ),
            RequiredFields::create('Name','Email', 'Comment')
        )->addExtraClass('form-style');

        foreach($form->Fields() as $field){
            $field->addExtraClass('form-control')
                ->setAttribute('placeholder', $field->getName(), '*');
        }
        $data = Session::get("FormData.{$form->getName()}.data");

        return $data ? $form->loadDataFrom($data) : $form;
    }

    public function handleComment($data, $form){

        Session::set("FormData.{$form->getName()}.data", $data);

        $comment = ProductComment::create();
        $comment->ProductID = $data['id'];
        $form->saveInto($comment);
        $comment->write();

        Session::clear("FormData.{$form->getName()}.data");
        $form->sessionMessage('Thanks for your comment', 'good');

        return $this->redirectBack();
    }
}
show(SS_HTTPRequest $request): Allow display product from PageHolder.
CommentForm($id): Create the form comment and save product ID in a HiddenField for handle comment by product.
handleComment($data, $form): Save the comment on database and reload the page with clean form.

Products>mysite>code>Products>ProductsPage.php

class Product extends DataObject
{
    //Product basic data...
    private static $db = array(
        'Name' => 'varchar',
        'Short_description' => 'text',
        'Content' => 'HTMLText'
    );
}
A simple DataObject where we want comment...

Products>mysite>code>extensions>ProductExtension>ProductComments.php
Is a DataExtension with many comments...

 class ProductComments extends DataExtension{
    
        private static $has_many = array(
            'Comments' => 'ProductComment'
        );
    }

Products>mysite>code>extensions>ProductExtension>ProductComment.php

class ProductComment extends DataObject
    {
        private static $db = array(
            'Name' => 'Varchar',
            'Email' => 'Varchar',
            'Comment' => 'HTMLText'
        );
    
        private static $summary_fields = array(
            'Created' => 'Created',
            'Name' => 'Name',
            'Email' => 'Email',
            'Comment' => 'Text'
        );
        private static $has_one = array(
            'Product' => 'Product'
        );
        public function getCMSFields(){
            $fields = FieldList::create(
                TextField::create('Name'),
                TextField::create('Email'),
                HtmlEditorField::create('Comment')
            );
            return $fields;
        }
    }

Products>mysite>_config>config.yml

Product:
      extensions:
        - ProductComments

Products>themes>my_theme>templates>Layout>ProductsPage_show.ss

<% with $Product %>
    <%--...--%>
    <h1>Comments</h1>
        <% loop $Comments %>
            <div class="comment">
                <h3>$Name <small>$Created.Format('j F,Y')</small></h3>
                    <p>$Comment</p>
            </div>
        <% end_loop %>

        <div class="comments-form">
            <h3>Leave a Reply</h3>
                <p>Your email address wlill no be published. Required fields are marked*</p>
         </div>

<% end_with %>
    <div class="col-sm-12">
        $CommentForm($Product.ID)
    </div>

Avatar
mi32dogs

Community Member, 75 Posts

6 June 2015 at 4:02pm

Question: is it also saving the relation to the $has_many table(something like Product_ProductComment) in the database for you?

I have built something very similar, and it is saving to the ProductComment table fine but it is not recording it in the relation table, so if you go to the product page in the CMS you will get a gridfield with all the comments.

Avatar
Pyromanik

Community Member, 419 Posts

9 June 2015 at 9:23am

You need to use GridFieldConfig_RelationEditor.

Avatar
mi32dogs

Community Member, 75 Posts

10 June 2015 at 8:59am

Edited: 10/06/2015 3:44pm

Thanks Pyromanik,
I’m using the GridFieldConfig_RelationEditor that was not the problem.
I made a big mistake instead of a $has_many I typed $many_many and this messed the whole thing up, now it is all working as expected

One question, so I have a datagrid with all the $has_many items and I like to export them, so I have added the GridFieldExportButton what works and it is exporting the $summary_fields list from the dataobject, now is it possible to have a different export field list than the summeryfield list? I tried the getExportFields function in the dataobject but that is not working.

Go to Top