Laravel edit blade checkbox array issue - arrays

My Problem I can't get my dynamic checkboxes to save properly in from my edit.blade, they only work if the values are 1, if an unchecked checkbox is submitted via hidden field it will overwrite the next set of checkbox checked values.
My Code
I have a crud resource that takes orders, the form in the create.blade itself has a bunch of dynamic fields that add a new product to the order via 'add-new' button that clones the product fields.
Part of that form is a bunch of days checkboxes that work fine and are stored correcly.
Where I'm Getting Stuck
I've made an edit.blade to be used to correct any mistakes that would be made while creating an order.
To call back the section that refers to the dates checkboxes I've used the following blade syntax (I know its different from create, mainly due to me trying to fix the problem)
#foreach($orders as $orderkey => $order)
#foreach($days as $day)
{{ Form::hidden($day.'[]', 0, array('id'=> $day.'_hidden_'.$orderkey, 'class' => 'is-checkradio')) }}
{{ Form::checkbox($day.'[]', 1, $order->{$day}, array('id'=> $day.'_'.$orderkey, 'class' => 'is-checkradio')) }}
<label for="<?php echo $day.'_'.$orderkey; ?>"><?php echo $day; ?></label>
#endforeach
#endforeach
OrderController - Update
I've had to use the following in my controller to get the fields to update however whenever a checkbox is left unchecked it will overwrite the next checked value.
$customer = Customer::find($id);
foreach($customer->orders as $key => $order){
$Monday[] = $request->Monday[$key];
};
$updates = array(
'Monday' => $Monday,
);
foreach($updates['orders'] as $k => $update){
$update_order->Monday = $updates['Monday'][$k];
$update_order->save();
};

This part:
foreach($customer->orders as $key => $order){
$Monday[] = $request->Monday[$key];
};
Is creating an array where if the existing data is true and the new data is true, save it. Otherwise delete it. That means any checkboxes that have been deselected will be captured, but any newly checked checkboxes won't be. Is this your intention?
Why not just do:
$updates = array(
'Monday' => $request->Monday,
);
I may not have fully understood your question so please comment and/or amend the Q if you need to clarify further,

Found out how to fix it from Unchecked checkbox returning null value
I needed to add my $orderkey to the name []
So in the end this worked:
#foreach($days as $day)
{{ Form::hidden($day.'['.$orderkey.']', null, array('id'=> $day.'_hidden_'.$orderkey, 'class' => 'is-checkradio')) }}
{{ Form::checkbox($day.'['.$orderkey.']', 1, $order->{$day}, array('id'=> $day.'_'.$orderkey, 'class' => 'is-checkradio')) }}
<label for="<?php echo $day.'_'.$orderkey; ?>"><?php echo $day; ?></label>
#endforeach

Related

Symfony form with several inputs text type to fill array property of entity object

I need to render a Symfony form to add entity object with his properties in the database. On of those properties is an array.
I want to display in the twig view several inputs text type field to fill this array. So i tried this following the doc but it doesn't display anything.
$builder
->add('tracklist', CollectionType::class, [
'entry_type' => TextType::class,
'entry_options' => [
'attr' => ['class' => 'fs-1 text-center text-uppercase']
]
])
I have looked for answers a lot everywhere but nothing worked. I do something wrong and can't figure out what.
I'm not arrived at this point but at the end my point is to use some javascript to display an additional input text type each time the one before is filled. All those inputs will fill the array in the database. This is to add a tracklist for discs so I never know how many inputs i'll need.
Thanks for the help guys !
// EDIT
OK after multiples tries and fails. I finally did it without using Symfony. It's much more simple for what I need.
Here is the template part
<p>TRACKLIST</p>
<div id="tracklist_container">
<label for="tracks">TRACK 1</label>
<input type="text" name="tracks[]" id="tracks">
</div>
<button id="tracklist-button">ADD A TRACK</button>
The JS part
let tracklistContainer = document.querySelector('#tracklist_container')
let label = tracklistContainer.querySelector('label')
let input = tracklistContainer.querySelector('input')
let addButton = document.querySelector('#tracklist-button')
let i = 1
addButton.addEventListener('click', (e) => {
e.preventDefault()
i++
labelClone = label.cloneNode(true)
inputClone = input.cloneNode(true)
labelClone.textContent = "TRACK" + i
inputClone.value = ""
tracklistContainer.appendChild(labelClone)
tracklistContainer.appendChild(inputClone)
})
And the PHP Controller part
$safeTracks = array_map('trim', array_map('strip_tags', $_POST['tracks']));
$disc->setTracklist($safeTracks);
I get what I needed that way !

How to retrieve a value from a query string that stems from a <select> form input?

I simply need to get the selected value from a query string. Currently I just get the index of the list and not the actual value. I cant use Post as I need the value for a pagination search.
I dont get an error but just the number of the index of the list returned. The answer must be simple and I have tried many combinations. I have tried ['Student'] in front of the query as well.
I just couldnt see the answer in the docs and previous posts on this topic didnt work for me either. I am stuck.
The query string has a number {url}students/myindex5?address_suburb=1 //suburb should be a string and it appears as a string in the drop down list
public function myindex5() {
$this->set('filterSuburb', $this->Student->find('list', array(
'fields' => array('Student.address_suburb')
)));
$havefilter = false;
$tsub = $this->request->query['address_suburb'];
// $tsub = array_combine($tsub, $tsub);//didnt work
debug($tsub); //I just get the index value of the list
if (!empty($tsub)) {
// ...
View
echo $this->Form->create('Student', array(
'type' => 'get',
'url' => array('controller' => 'students', 'action' => 'myindex5')
));
echo $this->Form->input('address_suburb', array(
'options' => $filterSuburb,
'empty' => '(choose one)')
);
echo $this->Form->end('Search');
For reference
how to get the selected values from a drop down list in cake php
http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html
When you use a select input, the value send is the value of the option tag:
<select>
<option value="1">Option 1</option>
</select>
If I choose "Option 1", you will get 1, not "Option 1".
If you want to change the value attribute, you need to set something else to the FormHelper::input method options parameter, something like:
array(
'value1' => 'Text 1',
/** etc. **/
);
If you want your value to be ids of Student, just change your find call to:
$this->set('filterSuburb', $this->Student->find('list', array(
'fields' => array('Student.id', 'Student.address_suburb')
)));
If you look at find('list') documentation, you'll see this:
When calling find('list'), the fields passed are used to determine what should be used as the array key and value, and optionally what to group the results by.
So passing Student.id and Student.address_suburb will output a select with Student.id as option value and Student.address_suburb as option text.
If you want something else than Student.id, just change it in the find('list') call, you can even change it to have option like <option value="redcliff">redcliff</option> (same value and text), by doing:
$this->set('filterSuburb', $this->Student->find('list', array(
'fields' => array('Student.address_suburb', 'Student.address_suburb')
)));

cakephp undefined index when definitely defined

For reference, please visit this page here. When trying to get a view display on one particular model, I am getting an undefined index error. Specifically, any data from my Coupon model. Here is my controller code:
public function seafood() {
$this->paginate['Restaurant']=array(
'limit'=>9,
'order' => 'RAND()',
'contain'=>array(
'User'=>array(
'id', 'user_name'),
'Coupon'=>array(
'id','description','expires','end_date','promo_code','restaurant_id')
),
'conditions'=>array(
'Restaurant.active'=>1,
'Restaurant.seafood'=>'Seafood'
)
);
$data = $this->paginate('Restaurant');
$this->set('seafood', $data);
when I debug($seafood) in my view, all data for Coupon shows, so I know it is correctly pulling data and associating it with my Restaurant model. However, when I create a foreach loop with my $seafood array, I get nothing but undefined index errors for anything Coupon-related. What's weird is that I also have my controller pulling from the User model and anything I call up from that model in the view gets rendered. Here is my view code:
<?php foreach ($seafood as $res) { ?>
.....irrelevant code.....
<p><?php if($res['Coupon']['description'] !=''){
echo $this->Text->truncate($res['Coupon']['description'], 200, array('ending'=>'...', 'exact'=>false) );
}
else echo 'Sorry, a description of this restaurant\'s promotion is not available. <br><br><br>';
?><em> (read more -->)</em></p>
<br />
<div>
<span style="margin-left:36px;">Promo Code: <span style="font-style:bold; color:#FF0000;"><?php echo $res['User']['user_name']; ?></span></span>
<span style="margin-left:24px;">Print</span>
<?php } ?>
......more irrelevant code.....
I have tried removing the containable behavior from the array but the results are the same. I should point out that when the debug array prints, it goes in order: Restaurant, User, Coupon. Is cake somehow losing the Coupon array because it is 3rd? Or is my view code just screwy?
Looks like Restaurant hasMany Coupon so Coupon is an indexed array. You'll need a nested for loop.
foreach ($seafood as $res) {
//irrelevant
foreach ($res['Coupon'] as $coupon) {
if($coupon['description'] !=''){
//do stuff
}
}
}

cakephp view will not display

I have an order form to purchse a voucher but for some reason now when I click phurcase it displays a blank screen. I cant see what has changed and why the view is not being passed the information from the controller.
Vourchers form
<h2>Vouchers</h2>
<?php
foreach($vouchers as $v){
?>
<div id="voucher_box" class="add_shadow column span-8">
<h3><?=$v['Voucher']['title'];?></h3>
<p>
<?=$v['Voucher']['description'];?>
</p>
<?php
echo $this->Form->create('Voucher',array('id'=>'ResVoucherForm','url'=>'/res/voucher'));
echo $this->Form->input('slug',array('type'=>'hidden','value'=>$v['Voucher']['slug']));
?>
<select id="VoucherPrice" name="data[Voucher][price]">
<? $prices = explode(',',$v['Voucher']['prices'])?>
<? foreach($prices as $price){?>
<option value="<?=$price?>">€ <?=$price?></option>
<? } ?>
</select>
<div class="submit"><input type="submit" id="check_rates" value="Purchase this" class="ui-button ui-widget ui-state-default ui-corner-all" /></div>
</form>
</div>
<?
}
?>
Controller
function voucher() {
$this->layout = '360';
$msg[0] = array(); // 0 = bad messages
$msg[1] = array(); // 1 = good messages
$total_price = 0.00;
if(isset($data['Voucher'])) { $this->data['Voucher'] = $data['Voucher']; }
if(isset($this->data['Voucher'])) {
// if we have posted a voucher purchase: add it to session array
if(isset($this->data['Voucher']['slug'])){
$slug = $this->data['Voucher']['slug'];
$voucher = $this->getVoucher($slug);
$voucher['Voucher']['price'] = $this->data['Voucher']['price'];
$vouchers = $this->Session->read('Res.Vouchers'); // read existing voucher orders
if(is_array($vouchers) && isset($voucher['Voucher'])){
$temp['id'] = $voucher['Voucher']['id'];
$temp['title'] = $voucher['Voucher']['title'];
$temp['description'] = $voucher['Voucher']['description'];
$temp['slug'] = $voucher['Voucher']['slug'];
$temp['price'] = $this->data['Voucher']['price'];
$vouchers[] = $temp;
}
$this->Session->write('Res.Vouchers',$vouchers);
} else {
$vouchers = $this->Session->read('Res.Vouchers'); // read existing voucher orders
}
$this->set('voucher_orders', $vouchers);
}
This next view displays blank, I do not know how to test the information in the controller
<?php
/*
if voucher show
*/
if (isset($voucher)) {
?>
<div id="voucher_box" class="add_shadow column span-8">
<h3><?=$voucher['Voucher']['title'];?></h3>
<p>
<?=$voucher['Voucher']['description'];?>
</p>
<?php
echo $this->Form->create('Voucher',array('id'=>'ResVoucherForm','url'=>'/res/voucher'));
echo $this->Form->input('slug',array('type'=>'hidden','value'=>$voucher['Voucher']['slug']));
?>
<select id="VoucherPrice" name="data[Voucher][price]">
<? $prices = explode(',',$voucher['Voucher']['prices'])?>
<? foreach($prices as $price){?>
<option value="<?=$price?>">€ <?=$price?></option>
<? } ?>
</select>
<div class="submit"><input type="submit" id="check_rates" value="Purchase this" class="ui-button ui-widget ui-state-default ui-corner-all" /></div>
</form>
</div>
<?
}
// end if voucher show
?>
Upadate Error Returned #######################################################
Notice (8): Undefined index: id [APP/controllers/res_controller.php, line 739]
Notice (8): Undefined index: title [APP/controllers/res_controller.php, line 740]
Notice (8): Undefined index: description [APP/controllers/res_controller.php, line 741]
Notice (8): Undefined index: slug [APP/controllers/res_controller.php, line 742]
Array
(
[0] => Array
(
[id] =>
[title] =>
[description] =>
[slug] =>
[price] => 100
)
)
In the view, you have this around the whole HTML:
if (isset($voucher)) {
// ...
}
Meaning: display voucher information if there is a voucher, and do not display anything otherwise.
Now, in your controller, you don't seem to be passing a voucher variable to the view (which should be done with $this->set('varname', $var);
So, your view does not get any data, thus it does not display anything.
This could explain your issue. But if the screen is completely blank (not even the layout displays), then you must enable error logging to check what's going on.
You are setting 'voucher_orders' to your view not 'voucher' the name of the variable in the view is always the string passed in the set method. Also I don't quite understand what you are doing in the controller with the $data variable, where does it come from? Also it's redundant doing $this->data['Voucher'] = $data['Voucher'] and the checking $this->data isset if you already checked if $data is set. You might be overwriting your $this->data array, what you are doing is not necessary since the view already gives you a populated $this->data if its a form submission.
You should really try doing some tutorials and reading up a little before jumping in, you seem to not properly understand the CakePHP structure and workflow.
Thanks for all your help. By using the pr() or debug() in the controller I found the problem. It was in the function that was getting called on the line $voucher = $this->getVoucher($slug);. I now have a better understanding of cakephp.

Cakephp paginator not going to first page after a form submit

Below I have pasted code snippets of a page where it displays cars by year and model. This list is paginated. For this example, imagine that you go to page 5 of the list displayed. At the bottom of the page, there is a form that lets you refine your search. When you fill in another year and model and push "Search", it reloads the page with a new list of cars and years. The issue is that when you submit the form and the page reloads, the displayed content is on page 5 of the new search. How do I get the form submit to show the new search at page 1. I think one possible cause is that the url has "../search/page:5" in it when you try to submit the form:
$paginator->options(array('url' => array($condition_string)));
echo $paginator->sort('Year', 'Car.year', array('url' => array('page' => 1)));
echo $paginator->sort('Model', 'Car.model', array('url' => array('page' => 1)));
//table code that displays years and models
echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));
echo $paginator->numbers();
echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled'));
//form that submits new search
echo $form->create('Car', array('action' => 'search'));
echo $form->input('model');
echo $form->input('year');
echo $form->end('Search');
try using the "url"-option of the form-helper, like:
<?= $form->create('Car',array('url' => '/.../search')) ?>
EDIT (quick n' dirty fix):
<form action=".../search" method="post">
<input type="text" name="data[Car][model]" />
<input type="text" name="data[Car][year]" />
<?=$form->end("Search")?>

Resources