jQuery Form Doesn't Post

I changed the target URL to
var targetUrl = "<?php echo $this->Url->build(["controller" => "Mealplans", "action" => "edit", $mealplan->id]); ?>";

To my ajax call, I added
headers : {
‘X-CSRF-Token’: $(’[name="_csrfToken"]’).val()
},

Now I get the error:

2021-04-12 15:04:45 Error: [ArgumentCountError] Too few arguments to function App\Controller\MealplansController::edit(), 0 passed in C:\xampp\htdocs\momp\vendor\cakephp\cakephp\src\Controller\Controller.php on line 531 and exactly 1 expected in C:\xampp\htdocs\momp\src\Controller\MealplansController.php on line 174

Request URL: /mealplans/edit?total_calories=%22625%22
Referer URL: http://localhost/mealplans/add

I changed the target URL to include a query string like this:
var targetUrl = "<?php echo $this->Url->build(["controller" => "Mealplans", "action" => "edit", $mealplan->id, "?" => ["foo" => "bar"],]); ?>";

but the page submitted to the edit template without any query string added. My ajax function doesn’t seem to be using the target URL at all.

Have you actually used this targetUrl variable anywhere in your $.ajax call? You make it very hard to help you, because it seems you’re just sort of randomly adding bits of code here and there but without any understanding of how it’s all supposed to go together. Or, if you are understanding that, you’re not demonstrating that understanding by showing us all the relevant edits.

It’s being used in the second line of the ajax call:

$.ajax({
type : 'GET',
url : targetUrl,
dataType: "text",
data: querystring,
headers : {
      'X-CSRF-Token': $('[name="_csrfToken"]').val()
	},
success : function(data) {
alert(querystring);
    },
error: function(jqXHR, textStatus, errorThrown) {
var errorMessage = jqXHR.responseText;
if (errorMessage.length > 0) {
alert(errorMessage);
        }
    }
});

When I do a hard reload of my page with SHIFT + CTRL + R and look at the view source, I see that it’s:

var targetUrl = "/mealplans/edit";

even though I coded it as:

var targetUrl = "<?php echo $this->Url->build(["controller" => "Mealplans", "action" => "edit", $mealplan->id]); ?>";

When I hardcode the id into my target URL like this:
var targetUrl = "<?php echo $this->Url->build(["controller" => "Mealplans", "action" => "edit", 449]); ?>";

The view source shows this:
var targetUrl = "/mealplans/edit/449";

The ajax uses the success function but the query string isn’t appended to the URL.

So then, it would seem that $mealplan is not set to what you think it is, when you are building that URL.

I did debug($mealplan); in my template and saw in the results that the id was 0
The results of the debug:
object(App\Model\Entity\Mealplan) id:0 {
‘[new]’ => true
‘[accessible]’ => [ ]
‘[dirty]’ => [ ]
‘[original]’ => [ ]
‘[virtual]’ => [ ]
‘[hasErrors]’ => false
‘[errors]’ => [ ]
‘[invalid]’ => [ ]
‘[repository]’ => ‘Mealplans’
protected _accessible => [ ]
protected _fields => [ ]
protected _original => [ ]
protected _hidden => [ ]
protected _virtual => [ ]
protected _dirty => [ ]
protected _accessors => [ ]
protected _new => true
protected _errors => [ ]
protected _invalid => [ ]
protected _registryAlias => ‘Mealplans’
}

This appears to be a brand-new entity, not something that’s had any data at all patched into it. Is this form on an “edit” page, or “add”?

I tried putting the following before my page was saved:

$id=$mealplan->id;
$this->set('int', intval($id));

and using the new variable here:

var targetUrl = "<?php echo $this->Url->build(["controller" => "Mealplans", "action" => "edit", $int]); ?>";

but this resulted in:

var targetUrl = "/mealplans/edit/0";

because $mealplan is an empty entity before the save.

$mealplan = $this->Mealplans->newEmptyEntity();

I tried putting it after the save but of course that didn’t work

This form is on the add page.

On the add page, you do not yet have an ID. This is by design, and very much on purpose. You should be posting that form to the add URL, which could then redirect to the edit page if that’s what you want. But you can’t just use the edit and add actions interchangeably.

Honestly still don’t understand why you’re hung up on using Ajax to post this instead of using the normal flow of things. You’re trying to run before learning to walk.

@Zuluru I need ajax to post this because the total gets updated every time a tile is dragged to the droppable box. Draggable and droppable capabilities are enabled with jQuery so I can’t find the total with PHP.

There are multiple ways to deal with that without Ajax. The most reliable way is to not even try to include the total in the form, because as I’ve said before it’s susceptible to tampering by the user. By all means, display the total on the page somehow, but then recalculate it on the server side in PHP by using the details of the tiles that have been selected. Alternately (but still unreliable in terms of data integrity), have a hidden input that you update the value of with JS, and then submit as normal.

I don’t know how to detect that a tile has been dragged to the right side of the page. I looked at the view source after dragging and dropping a tile but it didn’t show that it was in the droppable box on the right side of the page.

“View source” typically won’t show any such thing, as it doesn’t update with changes made by JS. “Inspect element”, on the other hand, will show the current structure.

Thanks, Zuluru. I can see the dragged tile in the click and mousedown event listeners in inspect element. I don’t know yet how I’m going to tag them but I’m taking a Udacity front end Web developer course and my project due date is coming soon so I have to work on that and put this project on hold.

In the meantime, if anyone could suggest how to detect that the tile has been dragged to the droppable box in PHP it would be greatly appreciated.

php will not detect this event. php is serverside based and the drag and drop happens on the clientside.