Form submit with AJAX

Permalink
Hi, i am struggeling to make an AJAX call when a form is submitted. I've checked the AJAX lessons:http://www.concrete5.org/documentation/how-tos/developers/ajax-less... but with no luck.

Questions are;
- What should there be written in the action attribute inside the form tag?
- Where should the controller.php (that handles the AJAX request) reside? Inside a seperate controller folder? Should this have the same name as the file that holds the form itself and the ajax request?
- Could anyone provide me with an example on how this should be done if one exists?

Relevant code:

ajaxcall.php
<form id="ajaxcall" action="<?php echo $this>action('submit')?>"method="post">
<input type="text" name="page_name" placeholder="" required/>
<input id="submit" type="submit" name="submit" value=""/>
</form>
<script type="text/javascript">
$(function(){
  $('#submit').click(function(e){
    e.preventDefault();  
    $form = $(this).closest('form');
    $.ajax({
   url: $form.attr('action'),
   type: $form.attr('method'),
   dataType: 'json',
        succes: //handle succes and error
    });


controller.php
public function action_submit() {
//handle the ajax request
}

GreyhorseDesign
 
JohntheFish replied on at Permalink Reply
JohntheFish
If it is a single page, you can put the submit action in the single page controller.

If it is a block, you can put the submit action in the block controller.

Be careful about naming - they have different conventions for the 'action' prefix. You can see that in ajax lessons.

In both cases, you can also create a separate tools file to handle the action. Just which works best depends on your application and whether the action needs access to controller data.

In your code you have
$this>action(...

(it will probably compile, but not do what you want)

It should be
$this->action(...


For the actual form submission, $.ajax is the lowest level and hence most complex to use jquery method. In many cases, $().post(), $().load() or even $().ajaxForm() provide increasingly higher levels of abstraction and hence easier use if they do what you want.

The latter is in the jquery forms package and already built into ccm.app.js.
http://malsup.com/jquery/form/#getting-started...
GreyhorseDesign replied on at Permalink Reply
GreyhorseDesign
@JohntheFish. Thank you for your reply and explanation. Very much appreciate it! I got one more question though. I managed to use the Jquery form plugin that's already built into ccm.app.js like you suggested for handeling the ajax request.
But I actually want to programmatically add a page using this ajax request (the form allows the users to set attributes like the title and description).

I'm following the instructions here:http://www.concrete5.org/documentation/developers/pages/overview...
to programmaticaly create a new page.

$parentPage = Page::getByPath("/sample");
$data = array(
        'name' => "sample2",
        'cHandle' => "sample2handle",
    'cDescription' => "Add page test."           
);
$pt = CollectionType::getByHandle("page_type_handle");
$newPage = $parentPage->add($pt,$data);


So I'm not using any form input in the above example just for the sake of testing if it will actually work without. Unfortunately my ajax call returns the error function.
So I guess I need to load some helpers inside the forms action php file or anything? Dit that but didn't work out.
A bit lost here...hope you could help me out.

FYI: The whole thing is actually a package, it creates a new button in the c5 edit bar to allow people to directly create a page of a certain page type under a specific path.
The stuff that contains the form and form handler are in the ../tools folder of this package. So the form is a pop-up window when clicking the button in the c5 edit bar.

Thank you in advance.
JohntheFish replied on at Permalink Reply
JohntheFish
At a guess, its failing because the parent page is not set before you start trying to use it as an object.

For debugging stuff like this, you can dump anything to a log or to the page with:

http://www.concrete5.org/documentation/how-tos/developers/concrete5...
GreyhorseDesign replied on at Permalink Reply
GreyhorseDesign
Thank you again. Well actually I should formulate my question a little differently.

In short the package will add a button to the c5 edit bar. Clicking this button results in opening a dialog which contains a form. This form is used to create a new page with a certain page type at a specific location.

Package folder structure:
/addpage
   /elements
       /header_menu
          /addpage
                 contains: controller.php, view.css and view.js
   /tools
                 contains: addpage.php


addpage contains the form and ajax calls. So what should I place inside the action attribute of the form and where should I place the files that are being called?

Calling this
$action_ajax_data = $this->action('controller_addpage');


results in
Fatal error: Using $this when not in object context in...
JohntheFish replied on at Permalink Best Answer Reply
JohntheFish
The way you are using it, you are expecting $this to refer to the controller. However, the controller object does not exist in a tool.

You can either:

a) Explicitly load the controller from your tool and use that object.

or

b) Use a controller action rather than a separate tool, so you already have $this as the controller object.
GreyhorseDesign replied on at Permalink Reply
GreyhorseDesign
So going for option 1 I should;

- Place a folder /controllers at the root of the package folder.
- Place a controlleraddpage.php there with; (echo test, for testing purposes)

<?php 
defined('C5_EXECUTE') or die("Access Denied.");
class ControlleraddpageController extends Controller {
public function controller_addpage() {
echo "test";
}
}
?>


In the tools file:

$c = Page::getByPath('/controllers/controlleraddpage.php');
$cnt = Loader::controller($c);
$action = $cnt->controller_addpage();
<form id="create_page" action="<?php echo $action?> method="post">
....


This doesn't work. Guess I'm doing something wrong here..
JohntheFish replied on at Permalink Reply
JohntheFish
You are creating a path to the page, not an instance of the controller.
GreyhorseDesign replied on at Permalink Reply
GreyhorseDesign
I see, think I got it now...
Again thank you very much for taking the time to reply to these posts!