0

I'm trying to get some data from javascript to php. It's a table where the number of rows is variable. So, I'm trying to get all the data with a loop in javascript then sending them to php. There, I will use another loop to save each row with another loop. So, there is the code:

JAVASCRIPT

//---- this is the important section ---- //
var data = new FormData();
var table = [];
for (var i = 1; i <= document.getElementById('nblines').value; i++) {
    var date = document.getElementById('date' + i).innerHTML;
    if (document.getElementById('l' + i).checked == true) { var type = 1;} else { var type = 2;}
    var paiement = document.getElementById('a' + i).innerHTML;
    var tps = document.getElementById('b' + i).innerHTML;
    var tvq = document.getElementById('c' + i).innerHTML;
    var total = document.getElementById('d' + i).innerHTML;
    var interet = document.getElementById('e' + i).innerHTML;
    var principal = document.getElementById('f' + i).innerHTML;
    var balance = document.getElementById('g' + i).innerHTML;
    var line = [i,date,type,type,paiement,tps,tvq,total,interet,principal,total];
    table.push(line);
};
console.log(table);
data.append('amortTable', table);


------------------------------------------------
|                                              |
| ---- this is the NOT important section ----  |
|                                              |
------------------------------------------------


var token = document.getElementById("csrf_token").content;
var request = new XMLHttpRequest();
request.onreadystatechange = function notify()
{
    if (request.readyState === XMLHttpRequest.DONE) {
        if (request.status === 200) {
            setTimeout(loadPage(page),500);
            $.niftyNoty({
                type: 'success',
                container : 'floating',
                html : 'Votre calcul s\'est enregistré avec succès!',
                timer : 5000
            });
        } else {
        }
    } else {
        // still not ready
    }
}
request.open( "POST", "savecalcul", true);
request.setRequestHeader("X-CSRF-TOKEN", token);
request.send(data);

PHP

foreach ($request->input('amortTable') as $i) {
    $line = new Amortissement;
    $line -> calcul()   -> associate($calcul->id);
    $line -> number = $i[0];
    $line -> date = $i[1];
    $line -> type = $i[2];
    $line -> paiement = $i[3];
    $line -> tps = $i[4];
    $line -> tvq = $i[5];
    $line -> total = $i[6];
    $line -> interet = $i[7];
    $line -> principal = $i[8];
    $line -> total = $i[9];
    $line -> save();
}

I am getting this error local.ERROR: exception 'ErrorException' with message 'Invalid argument supplied for foreach()' in ... the line is :

    foreach ($request->input('amortTable') as $i) {

So, am I on the right way and if yes, what am I doing wrong. If I am not on the right way, what should I do?

Elie Morin
  • 1,456
  • 3
  • 15
  • 35

2 Answers2

2

The problem is in this line:

for (var i = 1; i >= document.getElementById('nblines').value; i++) {

It should be:

for (var i = 1; i <= document.getElementById('nblines').value; i++) {

rationalboss
  • 5,330
  • 3
  • 30
  • 50
  • Yeah, just saw it. Thank you. Now I get something in the console.log, but I got an error in php : local.ERROR: exception 'ErrorException' with message 'Invalid argument supplied for foreach()' in ... – Elie Morin Aug 19 '16 at 02:47
  • Your PHP code above is incomplete. That error means that `$request->input('table')` is not an array. – rationalboss Aug 19 '16 at 02:49
  • 1
    You added the JS array to the `FormData` as `'amortTable'`. You probably need to change `->input('table')` to `->input('amortTable')` so that it matches what you are sending. (or change the JS to use `'table'`) –  Aug 19 '16 at 02:56
  • Ok, but javascript make an array with the data and the console.log show it as an array. So why php don't see it as an array? – Elie Morin Aug 19 '16 at 02:56
  • @Terminus Thank you, I guess am a bit tired right now... But I made the change and still same error... – Elie Morin Aug 19 '16 at 03:04
  • 1
    @ElieMorin i forgot formData is funny that way. See [this Q/A](http://stackoverflow.com/questions/16104078/appending-array-to-formdata-and-send-via-ajax). Be sure to scroll all the way down the page to see the highest-voted answer. –  Aug 19 '16 at 03:19
  • @Terminus Just did it in the Q/A, but it was part of the solution. I'll add an anwser to explain what I did. – Elie Morin Aug 19 '16 at 15:39
0

So, with the help of @Terminus who lead me to this Q/A , I found the solution to my problem.

There is the new javascript code, explaination will follow:

var data = new FormData();
data.append('nblines', document.getElementById('nblines').value);
for (var i = 1; i <= document.getElementById('nblines').value; i++) {
    var date = document.getElementById('date' + i).innerHTML;
    if (document.getElementById('l' + i).checked == true) { var type = 1;} else { var type = 2;}
    var paiement = document.getElementById('a' + i).innerHTML;
    var tps = document.getElementById('b' + i).innerHTML;
    var tvq = document.getElementById('c' + i).innerHTML;
    var total = document.getElementById('d' + i).innerHTML;
    var interet = document.getElementById('e' + i).innerHTML;
    var principal = document.getElementById('f' + i).innerHTML;
    var balance = document.getElementById('g' + i).innerHTML;
    var line = i + '|' + date + '|' + type + '|' + paiement + '|' + tps + '|' + tvq + '|' + total + '|' + interet + '|' + principal + '|' + balance;
    data.append('line' + i, line);
};

So, instead of trying to put everything on the same array, I add to "data" the first line wich contain usefull information. In this case, the total number of row I want to add to the database.

Then, I created a loop that add every row to the dataForm with the index line + i wich contain a string of every var seperate with a specific character. Don't use one you can find in the input. Since in this case I only add numeric characters, I choosed "|".

After this, come the php code, where you simply use the first data.append to find how many time you need to run the next loop.

    $nblines = $request->input('nblines');
    for ($i=1; $i <= $nblines ; $i++) { 
        $line = new Amortissement;
        $line -> calcul()   -> associate($calcul->id);
        $j = explode('|', $request->input('line'.$i));
        $line -> number = $j[0];
        $line -> date = $j[1];
        $line -> type = $j[2];
        $line -> paiement = $j[3];
        $line -> tps = $j[4];
        $line -> tvq = $j[5];
        $line -> total = $j[6];
        $line -> interet = $j[7];
        $line -> principal = $j[8];
        $line -> balance = $j[9];
        $line->save(['timestamps' => false]);
    }

Using $j = explode('|', $request->input('line'.$i)); will create the array based on each string I added into the dataForm.

Special thanks to Rationalboss and Terminus!

Community
  • 1
  • 1
Elie Morin
  • 1,456
  • 3
  • 15
  • 35