SilverStripe submit HTML form through Ajax

旧时模样 提交于 2020-05-15 08:35:05

问题


I want to pass data from a simple HTML form to a controller through Ajax, then process the data and return a response back.

At the moment I have the following:

HomePage.ss

<form method="POST" class="form-horizontal submit-form" onsubmit="return checkform(this);">

    <!-- Text input-->
    <div class="form-group">
        <label class="col-md-4 control-label" for="name">Name</label>  
        <div class="col-md-8">
            <input id="name" name="name" type="text" placeholder="insert full Name" class="form-control input-md" required="" />
        </div>
    </div>

    <!-- Button -->
    <div class="form-group">
        <label class="col-md-4 control-label" for="send-btn"></label>
        <div class="col-md-8">
            <button id="send-btn" name="send-btn" class="btn btn-primary">Submit</button>
        </div>
    </div>
</form>

JavaScript

$('form.submit-form').submit(function() {
    $.ajax({
        type: 'POST',
        url: 'processForm',
        data: $(this).serialize(),
        success: function(data) {
            alert('data received');
        }
    });
});

HomePage.php

class HomePage_Controller extends Page_Controller {
    public function events() {
        $events = CalendarEvent::get();
        return $events;
    }

    public function processForm() {
        if (Director::is_ajax()) {
            echo 'ajax received';
        } else {
            //return $this->httpError(404);
            return 'not ajax';
        }
    }
}

In developer tools I can see that I got the xhr processForm with a 404 not found error.

How do I get this Ajax form working correctly with the SilverStripe controller?


回答1:


Spider,

I've done something similar to below. This is a quick and dirty demo and hasn't been tested, but it may get you going in the right path. If you're unfamiliar with how forms work within SilverStripe there is a lesson for front end forms in SilverStripe. I've found the lessons useful personally and provide the code for the lesson as well: http://www.silverstripe.org/learn/lessons/introduction-to-frontend-forms?ref=hub

Page.php

<?php

class Page extends SiteTree
{



}

class Page_Controller extends Content_Controller
{

    private static $allowed_actions = array(
        'MyForm',
    );

    public function MyForm()
    {
        Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.min.js');
        Requirements::javascript(THIRDPARTY_DIR . '/jquery-validate/jquery.validate.min.js');
        Requirements::javascript('/path/to/your/validation/script.js');

        $fields = FieldList::create(
            TextField::create('name')
                ->setTitle('Name')
        );

        $actions = FieldList::create(
            FormAction::create('doSubmit')
                ->setTitle('Submit')
        );

        $requiredFields = RequiredFields::create(
            'name'
        );

        $form = Form::create($this, 'MyForm', $fields, $actions, $requiredFields);

        return $form;
    }

    public function doSubmit($data, $form)
    {
        //process $data or create your new object and simpley $form->saveInto($yourObject); then $yourObject->write()
        //then deal with ajax stuff
        if ($this->request->isAjax()) {
            return $this->customise(array(
                'YourTemplateVar' => 'Your Value'
            ))->renderWith('YourIncludeFile');
        } else {
            //this would be if it wasn't an ajax request, generally a redirect to success/failure page
        }
    }

}

YourValidationScript.js

(function ($) {
    $(function () {
        $('#MyForm_Form').validate({
            submitHandler: function (form) {
                $.ajax({
                        type: $(form).attr('method'),
                        url: $(form).attr('action') + "?isAjax=1",
                        data: $(form).serialize()
                    })
                    .done(function (response) {
                        $('.content').html(response);
                    })
                    .fail(function (xhr) {
                        alert('Error: ' + xhr.responseText);
                    });
            },
            rules: {
                name: "required"
            }
        });
    })
})(jQuery);



回答2:


You need to understand how HTTP request routing is handled in SilverStripe.

When you send request POST /processForm, it is treated as page and managed by ModelAsController. That is why you get 404 error - there is no SiteTree record with URLSegment = processForm.

Solution 1

Use Form object. It creates all routing configuration automatically during runtime. Read more https://docs.silverstripe.org/en/3.3/tutorials/forms/ https://docs.silverstripe.org/en/3.3/developer_guides/forms/

Solution 2

Use this approach, when you really want to go down to the simple one method request handler. Register custom controller and routing.

  1. You specify your route in mysite/_config/routing.yml

    ---
    Name: siteroutes
    ---
    Director:
      rules:
        processCustomForm: CustomFormController
    
  2. Handle your request

    class CustomFormController extends Controller
    {
        public function handleRequest( SS_HTTPRequest $request, DataModel $model ) {
            if (!$request->isPost()) {
              // handle invalid request
            }
    
            $name = $request->postVar('name')
            // process your form
        }
    }
    


来源:https://stackoverflow.com/questions/35895427/silverstripe-submit-html-form-through-ajax

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!