susanBuck / e2-fall23

0 stars 0 forks source link

Submit array as hidden form field help #40

Open alilienfeld opened 10 months ago

alilienfeld commented 10 months ago

For P3 one aspect of the game is that cards are being drawn. I am trying to persist a deck of cards from index.php to process.php. I did get feedback from P2 here https://github.com/susanBuck/e2-fall23/issues/20 that I am trying to implement. Therefore I put all game processing in process and index only displays form and results. I have a line of code that redirects from index to process if an initial card has not been drawn to start the game:

if(!$this->app->old('original')) {
    return $this->app->redirect('/process');
}

From process I draw the first card out of the deck:

$deck = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13];
shuffle($deck);
$original_card = array_pop($deck);

    return $this->app->redirect('/', [
        'original' => $original_card,
        'deck' => $deck,
    ]);

Now I have initialized the game so the next time I end up on process it will be due to form submission guessing next card being high or low. The only way I can think of to get the current value of deck back to process is via hidden form submission. Index is returning a variable for deck in blade:

       $first_card = $this->app->old('original');   
       $deck = $this->app->old('deck');
        //dd($deck);

        return $this->app->view('index', [
            'original' => $first_card,
            'deck' => $deck
        ]);
<form method='POST' action='/process'>
    <input type='hidden' name='original' value='{{$original}}'>
    <input type='hidden' name='deck' value='{{$deck}}'>
    <input type='radio' name='guess' value='high' id='high'><label for='high'>High</label>
    <input type='radio' name='guess' value='low' id='low'><label for='low'>Low</label>
    <input type='radio' name='guess' value='tie' id='tie'><label for='tie'>Tie</label>
    <button type='submit' class='btn btn-primary'>Guess!</button>
</form>

When I load the page with deck as a variable I get an error that I cannot submit an array to a string. I did try to make a foreach loop from steps in https://stackoverflow.com/questions/6547209/passing-an-array-using-an-html-form-hidden-element but this only submits one value

<form method='POST' action='/process'>
    <input type='hidden' name='original' value='{{$original}}'>
@foreach($deck as $card)
    <input type='hidden' name='deck' value='{{$card}}'>
@end foreach
    <input type='radio' name='guess' value='high' id='high'><label for='high'>High</label>
    <input type='radio' name='guess' value='low' id='low'><label for='low'>Low</label>
    <input type='radio' name='guess' value='tie' id='tie'><label for='tie'>Tie</label>
    <button type='submit' class='btn btn-primary'>Guess!</button>
</form>

The end goal here is to submit a variable that is an array to the form as a hidden value so that I can access what remains to the deck to draw the next card in process once a guess has been submitted via logic. I will add logic to restart the deck as it runs out of cards.

$guess = $this->app->input('guess');
$deck = $this->app->input('deck');
$next_card = array_pop($deck);

//Logic for  correct answer
//Logic to compare guess from input to correct answer

I have a link to functioning code here but it does not persist the deck across process and index: https://github.com/alilienfeld/e2/blob/main/p3/app/Controllers/AppController.php Thanks!

susanBuck commented 10 months ago

For passing array-type data back and forth as part of a form submission I suggest using the built in methods _jsonencode and _jsondecode to serialize the array data into a JSON string that can be transferred in the hidden input.

So instead of something like this:

@foreach($deck as $card)
    <input type='hidden' name='deck' value='{{$card}}'>
@end foreach

Try this:

<input type='hidden' name='deck' value='{{ json_encode($deck)}} '>

With that code in place, do a "View Source" on the page and observe how it converts the array into a JSON string object.

Then, when processing the form you'll want to translate that JSON string object back into an array:

$deck =  json_decode($this->app->old('deck'));

Give that a shot and let me know if you have any follow-up questions or issues implementing it.