Anyone? Sorry for such a school boy question, but just having a massive mental block
Arrays, saving multiple
I have the following, and I want to save then as individual rows as they will be related to a block
array:5 [▼
"name_of_blocks" => array:4 [▼
0 => null
1 => "test1"
2 => "test2"
3 => "test3"
]
"no_units" => array:4 [▶]
"no_of_floors" => array:4 [▼
0 => null
1 => "2"
2 => "2"
3 => "3"
]
"lift" => array:4 [▼
0 => "Please Select"
1 => "no"
2 => "no"
3 => "yes"
]
"facilities" => array:1 [▼
0 => "visitor_parking"
]
]
How does one save these again I'm forgot and having a major meltdown about it lol
I have tried the following but this fails:
$data = $request->except('_token');
for($i = 0; $i < count($data); $i++){
$block = new Blocks;
$block->name_of_blocks = $name[$i];
$block->no_units = $units[$i];
$block->no_of_floors = $floors[$i];
$block->lift = $lift[$i];
$block->facilities = $facilities[$i];
$block->save();
}
You left off the array keys when accessing the array in the loop to get the values. You also aren't accessing the $data array where all of your data is. There aren't individual $name, $units, $floors, $lift or $facilities variables. It's an array.
It's also not efficient to use count($data) in the loop, becuase it has to calculate it on each iteration. It's better to assign the count to a variable and use that.
$count = count($data);
for ($i = 0; $i < $count; $i++) {
$block = new Block;
// access name_of_blocks key
$block->name_of_blocks = $data['name_of_blocks'][$i];
}
Then do the same for the others like I did with
$block->name_of_blocks = $data['name_of_blocks'][$i];
You will run into one problem though. You only have 1 facilities and 4 of everything else. So it will error out after the first loop because of that. Not sure how you want to solve that, but it depends on what you're doing and how.
Thanks @cronix I'll give that a go.
I'm basically showing another form from a previous form, this form will have a certain amount of duplicated inputs based on user's previous selection. I use jQuery to clone the inputs based on their inputs. Then I want to save each one as a row within the db, hope this make sense.
Yes it makes sense, except for why there is only 1 facility showing in your original array and 4 of everything else. There needs to be 4 of everything for my solution to work (as is). If there will always only be one facility and multiple everything else, then you could hardcode that key instead of using $i, so it uses the same facility for all.
for ($i = 0; $i < $count; $i++) {
$block = new Block;
// access name_of_blocks key
$block->name_of_blocks = $data['name_of_blocks'][$i];
// other fields here
// hardcode first element of facilities key
$block->facilities = $data['facilities'][0];
}
There was only 1 as I only entered one at the time, as some inputs will have data and some won't but the new db rows should be entered still the same just with null values.
Then you will also have to check to make sure whether each thing you are iterating over actually exists in the array before trying to use it, and assign null if it doesn't. Otherwise you will get errors about indexes not existing.
For instance, if there is only 1 facilities in the array, and you try to access index 1 to get the value (index 0 is first element in array), it will error because it doesn't exist. You'll have a lot of extra code here to do all of that checking.
Is there an easy way to achieve this in that case?
Here's the form in question:
<div class="clone">
<div class="row">
<div class="col">
<div class="form-group">
<label>Block Name</label>
<input type="text" name="name_of_blocks[]" class="form-control">
</div>
</div>
<div class="col">
<label>No of units in the block</label>
<input type="number" name="no_units[]" class="form-control" id="blockNo">
</div>
<div class="col">
<label>Number of floors</label>
<input type="number" class="form-control" name="no_of_floors[]">
</div>
<div class="col">
<label>Does this block have a lift?</label>
<select class="form-control" name="lift[]">
<option>Please Select</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
</div>
<div class="row">
<div class="col">
<label>What facilities does this block have?</label>
<div class="row">
<div class="col">
<ul class="list-unstyled">
<li><input type="checkbox" name="facilities[]" value="fob"> Fob Entry</li>
<li><input type="checkbox" name="facilities[]" value="gate_entry"> Gate Entry</li>
<li><input type="checkbox" name="facilities[]" value="key"> Key Entry</li>
<li><input type="checkbox" name="facilities[]" value="finger"> Fingerprint Entry</li>
<li><input type="checkbox" name="facilities[]" value="Code Entry"> Code Entry</li>
<li><input type="checkbox" name="facilities[]" value="mailbox"> Mailbox Area</li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li><input type="checkbox" name="facilities[]" value="bar"> Bar</li>
<li><input type="checkbox" name="facilities[]" value="bike_storage"> Bike Storage</li>
<li><input type="checkbox" name="facilities[]" value="car_park"> Secure Car Parking</li>
<li><input type="checkbox" name="facilities[]" value="off_road"> Off-road Parking</li>
<li><input type="checkbox" name="facilities[]" value="visitor_parking"> Visitor Parking</li>
<li><input type="checkbox" name="facilities[]" value="concierge"> Concierge</li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li><input type="checkbox" name="facilities[]" value="gym"> Gym</li>
<li><input type="checkbox" name="facilities[]" value="pool"> Swimming Pool </li>
<li><input type="checkbox" name="facilities[]" value="snooker"> Snooker/Pool Table</li>
<li><input type="checkbox" name="facilities[]" value="cafe"> Cafe</li>
<li><input type="checkbox" name="facilities[]" value="maintenance"> Maintenance Service</li>
<li><input type="checkbox" name="facilities[]" value="various"> Various businesses/commercial outlets</li>
</ul>
</div>
</div>
</div>
</div>
<br />
<hr />
<br />
</div>
some inputs will have data and some won't but the new db rows should be entered still the same just with null values.
It doesn't have to do with the form, it has to do when saving. You have to check to see if the array_key_exists() before trying to use it. I'm not going to write it all out.
for ($i = 0; $i < $count; $i++) {
$block = new Block;
// check if this index exists in array. If so, use that value. If not, use null
$nameOfBlocks = array_key_exists($i, $data['name_of_blocks']) ? $data['name_of_blocks'][$i] : null;
// do same as above for all other fields
// now assign the values
$block->name_of_blocks = $nameOfBlocks;
$block->save();
}
@CRONIX - Cool, thanks I'll give that a try. Presume that will work also based on the form I posted regardless?
yes
0
Unable to save arrays with the correct key based on how many inputs the user selects.
I'm sure it the jQuery clone script, but not sure how to put this right as jQuery not my strongest point.
Here's the html:
<div class="row">
<div class="col">
<div class="form-group">
<label>Block Name</label>
<input type="text" name="name_of_blocks[]" class="form-control">
</div>
</div>
<div class="col">
<label>No of units in the block</label>
<input type="number" name="no_units[]" class="form-control" id="blockNo">
</div>
<div class="col">
<label>Number of floors</label>
<input type="number" class="form-control" name="no_of_floors[]">
</div>
<div class="col">
<label>Does this block have a lift?</label>
<select class="form-control" name="lift[]">
<option>Please Select</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
</div>
<div class="row">
<div class="col">
<label>What facilities does this block have?</label>
<div class="row">
<div class="col">
<ul class="list-unstyled">
<li><input type="checkbox" name="facilities[]" value="fob"> Fob Entry</li>
<li><input type="checkbox" name="facilities[]" value="gate_entry"> Gate Entry</li>
<li><input type="checkbox" name="facilities[]" value="key"> Key Entry</li>
<li><input type="checkbox" name="facilities[]" value="finger"> Fingerprint Entry</li>
<li><input type="checkbox" name="facilities[]" value="Code Entry"> Code Entry</li>
<li><input type="checkbox" name="facilities[]" value="mailbox"> Mailbox Area</li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li><input type="checkbox" name="facilities[]" value="bar"> Bar</li>
<li><input type="checkbox" name="facilities[]" value="bike_storage"> Bike Storage</li>
<li><input type="checkbox" name="facilities[]" value="car_park"> Secure Car Parking</li>
<li><input type="checkbox" name="facilities[]" value="off_road"> Off-road Parking</li>
<li><input type="checkbox" name="facilities[]" value="visitor_parking"> Visitor Parking</li>
<li><input type="checkbox" name="facilities[]" value="concierge"> Concierge</li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li><input type="checkbox" name="facilities[]" value="gym"> Gym</li>
<li><input type="checkbox" name="facilities[]" value="pool"> Swimming Pool </li>
<li><input type="checkbox" name="facilities[]" value="snooker"> Snooker/Pool Table</li>
<li><input type="checkbox" name="facilities[]" value="cafe"> Cafe</li>
<li><input type="checkbox" name="facilities[]" value="maintenance"> Maintenance Service</li>
<li><input type="checkbox" name="facilities[]" value="various"> Various businesses/commercial outlets</li>
</ul>
</div>
Heres what I have in my controller, but this either doesn't save correctly or saves one row if there's two and doesn't save the correct info:
$data = $request->all();
$count = $data['number_of_blocks'];
for ($i = 0; $i < $count; $i++) {
$blok = new Blocks;
$blok->block_id = $block->id;
$blok->name_of_blocks = array_key_exists($i, $data['name_of_blocks']) ? $data['name_of_blocks'][$i] : null;
$blok->no_units = array_key_exists($i, $data['no_units']) ? $data['no_units'][$i] : null;
$blok->no_of_floors = array_key_exists($i, $data['no_of_floors']) ? $data['no_of_floors'][$i] : null;
$blok->lift = array_key_exists($i, $data['lift']) ? $data['lift'][$i] : null;
$blok->facilities = array_key_exists($i, $data['facilities']) ? $data['facilities'][$i] : null;
$blok->save();
}
I do have some clone script to clone the amount of form fields based on how many the user wants, so this could also be a problem, but I'm not sure what or where:
$("#continue").click(function () {
$("#first").hide();
$("#second").show();
var blocks = $("#noBlocks").val();
var name = $("#blockName").val();
$(".clone").hide();
var select = parseInt(blocks, 10);
var $clone = $('.clone').html();
var html = '';
while (select > 0) {
html += $clone;
select--;
}
$("#area").empty().html(html);
$("#bno").html(blocks);
$("#bn").html(name);
});
Basically if the user selects 2 then I want the code to save two rows and the facilities to be json encoded for each row, and match what the user selects. Any help advice greatly appreciated.
Anyone willing to help me on this one, and please be gentle, it's been on of those weeks :(
Please or to participate in this conversation.