Laravel form only saving last in array - laravel-5

Right now I have a chat and what I am working on is being able to take selected chat messages and turn them into a post with comments. My struggle is that right now I am only getting the very last comment to save and none of the comments before it. This has to do with not being able to write the foreach loop correctly when saving in the controller I believe.
The error I am getting right now is
Invalid argument supplied for foreach()
I am showing the commenters array but not saving it correctly. The commentors are ids of users involved and the user_id (not userId) is what I need to save for both, right now only getting '11' and not '9'. as you can see from the error message
...'commenters' => ' 9, 11, ', 'user_id' => '11', 'comment' => 'hey there'), 'userId' => '9', 'commentorIds' => array(), 'createPost' => object(Post)))
Form
<div class="selectedChatSection" style="padding: 15px 15px 15px 15px;">
{!! Form::open(['url'=>'post/selectedChatPost']) !!}
<div class="jumbotron">
<center><img src="/img/icons/icon-chat.png"></center>
</div>
#foreach ($postSavers as $postSaver)
<div class="postSaverId" data-id="{{$postSaver->id}}"></div>
#endforeach
<input type="hidden" name="space-id" value="">
<input type="hidden" multiple="multiple" name="commenters" value="#foreach($selectedChats as $selectedChat){{$selectedChat->id}}, #endforeach ">
#foreach ($selectedChats as $selectedChat)
<div style="border-top: 1px solid #eee;padding: 10px 10px 10px 10px;">
<p><img src="/assets/avatars/{{$selectedChat->avatar}}" height:"75" width="75" style="border-radius:50px;"> <input type="hidden" name="user_id" value="{{$selectedChat->id}}">{{$selectedChat->name}} : <input type="hidden" name="comment" value="{{$selectedChat->body}}">{{$selectedChat->body}}</p>
#endforeach
</div>
<div class="modal-footer">
{!! Form::submit('post', ['id'=> 'post-button']) !!}
{!! Form::close() !!}
</div>
Controller
public function storeSelectedChat() {
$input = Request::all();
$userId = Auth::user()->id;
$commentorIds = array();
$createPost = new Post;
$createPost->space_id = 8;
$createPost->user_id = $userId;
// $createPost->content = $input['content'];
$createPost->linkPhoto = "/img/icons/icon-chat.png";
$createPost->save();
//needs to be a foreach loop here for each comment/chat segment.
foreach(Input::get('commenters') as $commenter) {
$createComments = new Comment();
$createComments->post_id = $createPost->id;
$createComments->comment = $input['comment'];
$createComments->user_id = $commenter;
$createComments->save();
}
}
Any help would be greatly appreciated. I have done this before but nothing seems to work in this instance for some reason. Thanks.

Your <input type="hidden" multiple="multiple" name="commenters" value="#foreach($selectedChats as $selectedChat){{$selectedChat->id}}, #endforeach "> should not have multiple attribute.
The multiple attribute works with the following input types: email,
and file.
According to http://www.w3schools.com/tags/att_input_multiple.asp. Even though the multiple attribute logically makes sense to you because logically you have multiple commentors, semantically it is incorrect. You still have one <input> attribute and what it contains logically is up to you interpret. You should use regex to separate your comma delimited input and then use foreach on that resulting array.

Related

Save array [ ] of form data in same columns individual row - Laravel

when the user click add more and submit their form data, I'm having a problem saving form array like this (service[], Amount[], Description[]) in database rows. I have two related tables of invoices and invoice_details, i want the form array to submit the list of form data into the invoice_details table. I have successfully created the models and relations between the invoice and invoice_details.
<!--Blade -->
<div class="service-box">
<div class="row">
<div class="col-md-12 service-group">
<div class="row">
<div class="form-group mb-3 col-md-6">
<label class="form-label">Service</label>
<div >
<select type="text" class="form-select" placeholder="Services" value="" name="service[]" id="service">
<option value="" disabled selected>Select your option</option>
#foreach ($services as $service)
<option value="{{$service->service_name}}" data-id="{{$service->amount}}">{{$service->service_name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group mb-3 col-md-6">
<label class="form-label">Amount</label>
<div >
<input type="text" class="form-control" name="amount[]" id="amount" placeholder="Amount" readonly>
</div>
</div>
<div class="form-group mb-3 col-md-12">
<label class="form-label">Description</label>
<textarea class="form-control" id="description" name="description[]" rows="6" placeholder="Description.." ></textarea>
</div>
</div>
</div>
</div>
</div>
//Controller
$invoicedetailModel = new Invoice_detail;
//Here is where the problem lies, I have to save for arrays.
$invoicedetailModel->service = request('service');
$invoicedetailModel->amount = request('amount');
$invoicedetailModel->description = request('description');
$invoiceModel->Invoice_details()->save($invoicedetailModel);
It seems to me (correct me if I'm misinterpreting) that you're trying to save a batch of different InvoiceDetails and attach them to an original Invoice model.
The problem here is that you're trying to do so by passing arrays to a single invoiceDetails model so let's suppose you have the you have two detail instances passed by form you would have the request parameters structured like this:
$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Lorem', 'Ipsum']
So if you tried to create the model you're trying to save in your code you would be doing something like this:
Invoice_Details::create([
'service' => ['serviceX', 'serviceY'],
'amount' => [1,2]
'description' => ['Lorem', 'Ipsum']
]);
Which can not work because those values are not set as Json to the database, and also explains why the createMany is not working, because there's a single object that uses an array of values for each value. What you might want is a situation like this:
Invoice_Details::createMany([
[
'service' => 'serviceX',
'amount' => 1
'description' => 'Lorem'
],
[
'service' => 'serviceY',
'amount' => 2
'description' => 'Ipsum'
]
]);
So you should iterate the request parameters and save a whole array of single models rather than try to stuff everything into a single one.
Also, it's pretty legitimate to ask yourself "Sure, but they all have two parameters, why doesn't it just split them when I use the createMany method?" Well, let's suppose the same situation with different parameters:
$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Ipsum']
To which model does that description belong to? We could just go by appearence order, but this kind of assumption might lead to huge problems in case of bad implementations. This sadly means that everytime we need to create multiple models we need to define every single one, even though it means adding an iteration beforehand.
TL;DR: Instead of an array of parameters you need an array of models. Iterate through your parameters and build your models before saving them.
//Supposing you already fetched the arrays and they are all of the same length
$details = [];
foreach($services as $key => $service) {
$invoicedetailModel = new Invoice_detail();
$invoicedetailModel->service = $services[$key];
$invoicedetailModel->amount = $amounts[$key];
$invoicedetailModel->description = $descriptions[$key]);
$details[] = $invoicedetailModel;
}
// code to create and attach the many models

(Vue + Laravel) v-if / v-else inside <td> throws no matching end tag error

I apologize in advance if my question is silly-- Vue newbie here but very eager to learn!
In order to create an interface to manage user privileges in a web app, I've made a component in which I want to create a table with nested v-fors.
For each row, I want 5 cells (): the first one includes text depending on the current iteration of object permisos and the other 4 should be created from the object tipos_permisos (which is an object with 'fixed' values).
The problem:
When I try to compile, I get multiple errors claiming that some tags have no matching end tag. I assume it is due to the v-for nested inside another v-for and/or the v-if inside the innermost v-for... or something like this. The claim is that has no matching tag or that the element uses v-else without corresponding v-if :/
I've tried writing out the last 4 cells manually (without using the tipos_permisos object) but even then, I get errors. In this case, claiming that , and have no matching end tag.
The desired result:
Please note that for some of the resources listed, some of the privileges might not apply (i.e., the log viewer is read-only always so it doesn't have the C (create), U (update) or D (delete) privileges, hence the conditional to show either a checkbox or an icon)
My component:
<template>
<form :action="usr.url.savepermisos" method="post" class="">
<div class="card">
<div class="card-header bg-gd-primary">
<h3 class="card-title">Privilegios de {{ usr.nombre }}</h3>
</div>
<div class="card-content">
<p class="mb-3">
El usuario
<span class="font-w700">{{ usr.nombre }}</span>
tiene los siguientes privilegios:
</p>
<table class="table">
<thead>
<tr>
<th>Recurso</th>
<th>Alta / Creación</th>
<th>Visualización</th>
<th>Edición</th>
<th>Eliminación</th>
</tr>
</thead>
<tbody>
<tr v-for="(recurso, idxrecurso) in permisos">
<td :data-order="recurso.id">{{ recurso.etiqueta }}</td>
<td class="align-middle" v-for="(color,tp) in tipos_permisos">
<label :class="'checkbox checkbox-' + color + ' mycheckbox'" v-if="(typeof recurso[tp] !== "undefined")">
<input type="checkbox" class="checkbox-input check_permiso" />
<span class="checkbox-indicator"></span>
</label>
<i class="fas fa-minus-square fa-lg text-muted" data-toggle="tooltip" title="N/A" v-else></i>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</template>
<script>
export default {
data() {
return {
tipos_permisos: {
'C': 'success',
'R': 'info',
'U': 'warning',
'D': 'danger'
}
}
},
props: [
'usr',
'permisos',
'perm_log'
]
}
</script>
If something is unclear please let me know so that I can provide further info.
There is a missing "=" after v-for:
<td class="align-middle" v-for"(color,tp) in tipos_permisos">
I didn't understand this part:
v-if="(typeof recurso[tp] !== "undefined")"
If undefined in your code is a string, your condition should be
v-if="recurso[tp] !== 'undefined'"
If it's a real undefined, it should be like this:
v-if="recurso[tp] !== undefiened"

[Contact form]How to convert object to string in Laravel?

I'm studying contact form script. It works fine but after I add this lines
I'm having this error.
htmlspecialchars() expects parameter 1 to be string, object given (View: /home/------/resources/views/mail.blade.php)
Here is my contact.blade.php
#php
$week = array( "日", "月", "火", "水", "木", "金", "土" );
$s_date = date("Y年m月d日 H時i分");
$dayofweek = "(".$week[date("w")].")";
$s2_date = $s_date . $dayofweek;
$k_no_raw = strval("km_".date("Y_md_His_A") ."_". date('w'));
#endphp
<br>
<input name="sdate" type="hidden" value="{{ $s2_date }}">
<input name="k_no" type="hidden" value="{{ $k_no_raw }}">
I tried to change object to string.
but I still got same error.
Controller part of this section
\Mail::send('mail', array(
'sdate' => $request->get('sdate'),
'k_no' => $request->get('k_no'),
),
Here is mail.blade.php
{{ $k_no }}
Could someone teach me right code please?
UPDATE

Laravel custom validation message for multiple fields with the same name

I have the following validation in the controller's action:
foreach ($request['qtys'] as $key => $val){
if (!$this->_validateMinQty($key, $job, $val)){
$customerTitle = $job->customers()->where('customer_id',$key)->first()->title;
return redirect()->back()->withErrors(['qtys' => __('The qty of the customer :customerTitle is less than allowed qty',['customerTitle' => $customerTitle])]);
}
}
This check multiple form's input named qtys in the view:
#foreach($job->customers as $customer)
<div class="form-group {{$errors->first('qtys has-error')}}">
{!! Form::label('qtys-'.$customer->id, __('Qty').' '.$customer->title) !!}
<div class="row">
<div class="col-md-9">
{!! Form::text('qtys['.$customer->id.']',$customer->pivot->e_production,['class' =>'form-control qtys', "data-sumequal"=>"qty",'required' => 'required','title' => $customer->pivot->aid,'id' => 'qtys-'.$customer->id]) !!}
<div class="help-block with-errors"></div>
#php ($eleE = $errors->first('qtys'))
#include('layouts.form-ele-error')
</div>
<div class="col-md-3">
<i class="fox-add"></i>{{__('Add Storage')}}
</div>
</div>
</div>
#endforeach
The above code works, but with the following limitation:
The error message is rendered under every input named qtys[x] where x is an integer and the first input only Testana has the invalid qty, like the following screen shot:
In the controller's action return message, I have tried to use indexed name for the input like the following:
return redirect()->back()->withErrors(['qtys.10' => ....
However, it prevents rendering the error message under any qtys field. Is there any solution?
The solution that I have found starts from the definition of first method found in the view :
#php ($eleE = $errors->first('qtys'))
This, in my code, should be changed to:
#php ($eleE = $errors->first('qtys.'.$customer->id))
Because the multiple fields have gotten keys equals to the customer id. This is a technique I usually use, when I want to send double piece of data in single post or in single form element.
Then in the controller, I keep the first try,
return redirect()->back()->withErrors(['qtys.'.$key => __('The qty of the customer :customerTitle is less than allowed qty',['customerTitle' => $customerTitle])]);
Where $key is an integer.

Getting TokenMismatchException in VerifyCsrfToken.php line 53 in Laravel 5.1 while using csrf token

I am getting TokenMismatchException in VerifyCsrfToken.php line 53:
I am using {!!Form::open()!!}
{!!Form::close!!}. When I click the add Button in my form with empty field for the first time, it shows me error as I set the validation rule. But when I click the Add button again without refreshing the page, it shows me the TokenMismatchException error. I have checked with dd() and it shows me the token like this:
array:3 [▼
"_token" => "5dXwRHbz4GNY1tx9OVeWPcOkirVIm0YtpkZufFbr"
"menu_name" => ""
"menu_price" => ""
Here is my form code:
{!! Form::open(array('route' =>'upcoming.store', 'method'=>'POST')) !!}
<div class="col-lg-6 col-sm-offset-3 top-spacing">
<input type="text" name="menu_name" placeholder="Menu Name.." class="form-control">
</div>
<div class="col-lg-6 col-sm-offset-3 top-spacing">
<input type="text" name="menu_price" placeholder="Menu Price.." class="form-control">
</div>
<div class="col-sm-2 col-sm-offset-8 top-spacing">
<button class="btn btn-success">
Add +
</button>
</div>
</div>
{!! Form::close() !!}
Here is my controller store function:
public function store(Request $request)
{
dd($request->all());
$this->validate($request, array(
'menu_name'=>'required',
'menu_price'=>'required',
));
$upcoming = new Upcomingfood;
$upcoming->menu_name=$request->menu_name;
$upcoming->menu_price=$request->menu_price;
$upcoming->save();
Session::flash('success','Food Menu Added Successfullly');
return redirect()->back();
}
Can anyone help?
I have solved this problem by going to
`VerifyCsrfToken.php`
and then I have changed
throw new TokenMismatchException;
by
else{
return redirect()->back();
}
But I am not sure am I right or wrong to apply this way. will it bring any problem in my future work in this project. anyone please make me sure. please.
Try add {{ csrf_field() }} inside the form.
I really recommend that you read official documentation https://laravel.com/docs/5.4/csrf

Resources