0

I am using cakePHP and Jquery UI for a small project.

I have an 'Add Item' link on my index.ctp of Item.

I want to show a jQuery UI dialog with the forum in for adding an Item when the 'Add Item' link is clicked.

So that I can make use of cakePHP's awesome FormHelper I want the controller's add() method to return the html the FormHelper creates if($this->request->is('ajax')) but this is giving me Internal Server Errors (when I Inspect Element in Chrome).

I know this isn't very MVC but my reasoning is that I want my app to work if the user has Js enabled or not, therefore the 'Add Item' link shows the add.ctp View if they don't have jQuery but if they do I've got preventDefault() in my jQuery script.

The jQuery click handler then sets up the dialog box's properties (jQueryUI Dialog Box) and then makes an ajax request to add() for the form.

I copied and pasted the FormHelper code I used on add.ctp but instead of echoing, added each line to $htmlString. I then called echo $htmlString; exit(); but here I get the 500 Internal Server Error.

If I comment out all the FormHelper lines in the add() function everything works ($htmlString is just "") so there is something going wrong here.

As I said I know this isn't very MVC-y but I can't think of another way to do it. Could I potentially get add.ctp returned rather than the copy and pasted code? That would keep the MVC model right and also if $this->layout = 'ajax' then I will only get the exact add.ctp file code right?

Thanks for your time and help in advance.

Edit - Added jQuery ajax request and cakephp Controller add() function

Jquery ajax request:

$('.add_project').click(function(event) {
        //Kill default
        event.preventDefault();

        $.ajax({
            url : $(this).attr('href'),
            type : 'post',
            data : 'ajax=1',
            dataType: 'html',
            success: function(response) {
                alert(response);

                //Check jquery loaded
                if(jQuery.ui) {
                    //Fill dialog with form
                    $("#dialog").html(response).show();

                    //Show dialog
                    $("#dialog").dialog("open");
                }
            }
        });
    });

CakePHP Controller code:

public function add()
{
    //If this has been requested with ajax then give the form that we create on add.ctp
    if($this->request->is('ajax'))
    {
        App::import('Helper', 'Form');

        $this->loadModel('Project');
        $html = '';

        $html += $this->Form->create('Project');
         $html += $this->Form->input('name');
         $html += $this->Form->input('colour', array(
             'options' => array('blue' => 'Blue', 'green' => 'Green', 'red' => 'Red', 'orange' => 'Orange', 'yellow' => 'Yellow')
         ));
        $html += $this->Form->end('Create Project');
        echo html;
        exit();
    } 

I'm pretty positive it's nothing to do with the ajax request it's more of a problem in cakephp that it doesn't like to use the FormHelper in the controller. I know this is bad MVC practice but I can't think of another way to do this dynamically (as in the fact that cakephp builds the html tags based on the Model).

Thanks again.

4
  • lets see what the add function looks like and your jquery ajax request Commented Nov 27, 2012 at 20:44
  • I am sure you are expecting this but, you definitely need to put your html code in your view. I don't even know that the Form helper is accessible from the controller. It will all get back to your jquery request just the same if you put the form in your view file add.ctp Commented Nov 27, 2012 at 21:56
  • I'm not sure I understand. My add.ctp is made up of many echo calls (just like the cakephp blog tutorial), will all of these get to the jquery or just the first 'echo'? Commented Nov 27, 2012 at 21:58
  • It will send a completely rendered page to the jquery ajax request. PHP is server side, jquery has no idea the php exists, only that there is an html page that is rendered and it needs to retrieve. Commented Nov 27, 2012 at 22:07

2 Answers 2

1

The 500 Internal Server error you are receiving is because you are using a Helper within a Controller.

However! you can pass a view back through your ajax request. Create the method in your controller. Create the view with the form helper

ajaxForm.ctp

$this->Form->create('Project');
$this->Form->input('name');
$this->Form->input('colour', array(
       'options' => array('blue' => 'Blue', 'green' => 'Green', 'red' => 'Red', 'orange' => 'Orange', 'yellow' => 'Yellow')
));
$this->Form->end('Create Project');

controller

public function ajaxForm(){

if($this->request->is('ajax')){
    $this->layout = 'ajax';   // to avoid returning your full layout
    $this->render('ajaxForm');

}

}

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks I now understand cakePHP a bit better, thanks for the help!
0

Separate your html and frontend code from the php backend code your add function can be empty if you aren't passing any data to the view and you won't need to check for ajax if the add function is not being called by non ajax requests. It will be dedicated to your ajax request in your view.

//controller file
App::import('Helper', 'Form');
public function add()
{

} 


//App/Views/Projects/add.ctp file
        echo $this->Form->create('Project');
        echo $this->Form->input('name');
        echo $this->Form->input('colour', array(
             'options' => array('blue' => 'Blue', 'green' => 'Green', 'red' => 'Red', 'orange' => 'Orange', 'yellow' => 'Yellow')
         ));
        echo $this->Form->end('Create Project');

1 Comment

Thanks for the help Tim, I put @Mark B. as the answer as his was the way I tried first but thanks for all the help! I tried upvoting but I don't have enough rep yet :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.