Passing Array From Form To Controller

Hi

I hope someone could please help me with the following

I have a form which dynamicaly generates any number of dropdown lists ranging from 1-100 depending on the users selection

The dropdowns are not directly part of my active model but the data I get back will be used for creating player records

I have extended my model to include the variable ‘position’ and also added it to safe as follows:

Model




class GameResults extends CActiveRecord

{

	// extend to add property into model

	public $position;	//	to be used as the array for player


....


Rules

array('position', 'safe'),


....



In my view I have a hidden dropdown list which has been generated so that I can clone and re-use its options

_form.php - Hidden Select With Options To Be Cloned




<?php echo $form->dropDownList($model, 'wibble', $model->getPlayerlist(), array('class' => 'hidden', 'id' => 'venue_player_list')); ?>

<?php echo $form->hiddenField($model,'played_count',array('id'=>'howmany')); ?>



_form.php - Select A Number




<?php

// This dropdown gets populated from the model by calling getPlayercount() and once selected it passes the value to the function 'myfunction'

echo $form->dropDownList($model, 'player_total_selector', $model->getPlayercount(),

	array(

		'class'=>'styled-select',

		'onchange'=>'myfunction(this.value)',

		'id'=>'played_count',

		));

?>



_form.php - Script create required number of dropdowns incrementing the array ID




<script type="text/javascript">

// function gets the value of players then loops & clones the hidden options

function myfunction(val) 

{

	str = '';

    $("#howmany").val(val);

	for (var i = 1; i <= val; i++) {

		str += '<div class="row"><select name="GameResults[position' + i + ']" id="position' + i + '"></select></div>';

	}


	// Outputs the required number of empty selects to the div with the id #container

	$('#container').html(str);


	// Clone hidden options and append to the new selects

	var $selectContents = $('#venue_player_list option').clone();

	$('.listme').append($selectContents);

}

</script>



Everything works as expected

I select a number

The dropdowns appear populated with the cloned content

And if for example I select 3, and make my selections I can see the following ID’s been passed in the browser

Now I am stuck :(

Was this the correct way to pass an array?

And How do I loop through it in my controller?

For an example how to loop and echo out passed results?

My Controller looks like this so far




public function actionCreate()

	{

		$transaction=Yii::app()->db->beginTransaction();

		$isok = true;	


		$model=new GameResults;


		if (isset($_POST['GameResults'])) {


		    try {

		        	$model->attributes=$_POST['GameResults'];

		        	

		        		        		        			        	

					$total = $model->played_count;		// get the total number of people played for use in the loop counter

				

										

					for ($i = 1; $i <= $total; $i++){	// initiate the loop 

				        $x = $model->position[$i];		// test output 

				      

				        echo '<pre>';		// TEST	

					    var_dump($x); 

					    echo '</pre>';

				    }

				




		        	if ($isok == true) {

			            $transaction->commit();

	                	$this->redirect(array('view', 'id' => $model->id));

			        } 

			        else {

			        $transaction->rollBack();

			           echo 'something wrong!';

			        }

		    }

		    catch(Exception $e) { 

		        $transaction->rollBack();

		    }

		}


		$this->render('create',array(

			'model'=>$model,

		));	


	}




I have looked at many examples and read the section on tabular input but I cannot see the simple way to manually craft an array and loop through it in my controller

Any help would be most appreciated

Many thanks

GPM

why do you do




GameResults[position' + i + ']



i mean, it’s already an array, just leave


GameResults[]

then just traverse in controller


foreach($_POST['GameResults'] as $v) {

$v - value of select

}

Many thanks for your help with this

I have taken your suggestion and slightly modified my code.

This image shows my controller, the var_dump results, and the console in my browser.

The 2 values I want to loop over and capture are highlighted by the arrows ‘position’ & ‘bounty’

How could I loop and capture:

foreach( … {

 &#036;y = position


 &#036;x = bounty

}

i hardly understand why you make simple things so complicated.

if you want to tie position and bounty, then make 2 dropdowns, and same index of array will tie them for you.

if you want to use one dropdown and pass 2 values on selection (or just want to be sure PHP didn’t make a joke on you), you can make ajax serialization using user data.

example


<select name="GameResults[]" bounty-data="YOUR_BOUNTY" value="YOUR_POSITION" />

but in this way, you will have to submit post via ajax like


$('yourform').on('submit',function(e){

  e.preventDefault();

  var sel = $('yourdropdown').find(":selected");

  $.post(URL, {bounty: sel.attr('bounty-data'), position: sel.val(), function(res){

      // res is ajax response

      //if success redirect

      window.location.href = 'new url';

  }}

});

do you want something like that?

p.s.

can you in 10 words explain what you want :lol:

:lol:

Sorry, I will try

1: Select number of players

2: Choose player from list matching finish position

3: Choose players bounty score

4: Loop and store results

[indent]1st Place = Player_id 17 + Bounty = 0

2nd Place = Player_id 8 + Bounty = 3

3rd Place = Player_id 26 + Bounty = 7[/indent]

Many Thanks

GPM

it looks more clear.

      • 1 - - -

if you trust DOM/PHP enough, you can simply leave indexing on DOM


<select name="GameResults_Players[]">

<option value="user-id">Smith</option>

</select>

<select name="GameResults_Bounties[]">

<opotion value="0"></option>

</select>

and then do as you did


$players = $_POST['GameResults_Players'];

$bounties = $_POST['GameResults_Bounties'];


for($i=0; $i< count($players); $i++) {

   $position = $i + 1; // you trust DOM here

   $user_id =  $playes[$i];

   $bounty = $bounties[$i];

}

      • 2 - -

but, if you don’t trust, you may want to go with serialization and json

as for me who prefer json… i would post via ajax as objects, maybe even close to active record model

in short, you want to send array of objects

{ players: [ players_objs ], total_players }

where players_obj = {user, position, bounty}

so, in html it will look next


<select position-data="1" name="GameResults_Positions[]">

<option value="user-id">Smith</option>

</select>

<select position-data="1" name="GameResults_Bounties[]">

<option value="0"></option>

</select>

and jquery js


var players = [];

$.each($('select[name="GameResults_Positions[]"]'), function() {

   var player = {};

   var player.position = this.attr('position-data');

   var player.user_id = this.find('option:selected').val();

   var b = $('select[name="GameResults_Bounties[]"]).find('[position-data="'+player.position+'"]').closest();

   var player.bounty = b.find('option:selected').val();

   players.push(player);

});


$.post(url, { players: players, ...}, function... );

and on server side


$players = json_decode($_POST['players'])


foreach($players as $p) {

$p->position / $p->bounty / $p->user_id

}

sorry for errors, it’s late here and i didn’t test it

Thank you for all of your help,

Your answers have helped me to solve this problem

Many thanks

GPM