Updating pivot table with checkbox - laravel

I have a users table and a services table. I made a many-many pivot table to store which user offers which services. When I try to check or uncheck a service checkbox in my profile blade to modify the user the data is not inserted or removed in the pivot table.
User Model:
public function services(){
return $this->belongsToMany(Service::class);
}
Service Model:
public function user(){
return $this->belongsToMany(User::class);
}
My code in store function in ProfileController:
$user = Auth::user();
if(isset($request->services)){
foreach($request->services as $service_id){
$service=Service::find($service_id);
$service->user()->syncWithoutDetaching($user->id);
}
}
Blade:
<div class="form-group row">
<label class="col-md-4 col-form-label text-md-right">Type de services</label>
<label for="peinture">Peinture</label>
<input type="checkbox" id="peinture" name="services[]" value="1"
<?php if (in_array(1, $services->toArray())) echo "checked" ?> >
<label for="neige">Déneigement</label>
<input type="checkbox" id="neige" name="services[]" value="2"
<?php if (in_array(2, $services->toArray())) echo "checked" ?> >
<label for="gardiennage">Gardiennage</label>
<input type="checkbox" id="gardiennage" name="services[]" value="3"
<?php if (in_array(3, $services->toArray())) echo "checked" ?> >
<label for="entretien">Entretien paysager</label>
<input type="checkbox" id="entretien" name="services[]" value="4"
<?php if (in_array(4, $services->toArray())) echo "checked" ?> >
</div>
If I do dd($request); everything seems in it. No clue what I'm doing wrong, thanks for any help.

you don't need to iterate the services in your controller. just do this:
$user = Auth::user();
$user->services()->sync($request->services);
this will first clean the pivot table, then will attach the new values all at once.
i really encourage you not to use $request values without validating them. in this case run this before start syncing the pivot table:
$this->validate($request, [
'services' => 'required|array',
'services.*' => 'exists:services,id',
]);

Related

How to insert (create) data (CRUD) FORM in blade in multiple languages into database and read it out with LARAVEL MULTILANGUAGE - LOCALIZE?

I have followed this tutorial (https://mydnic.be/post/how-to-build-an-efficient-and-seo-friendly-multilingual-architecture-for-your-laravel-application) about laravel multilanguage and localization. Everything seems ok, except I want to CREATE a CRUD for inserting this posts with title and content in multiple language - and STORE it in database - and then read it out in index blade.
Can you show me an example of CRUD in this way in blade for CREATE and in Controller for CREATE and STORE function. How to make this to work?
This is my simple main CRUD, how to extend this to be able to creating and storing into multiple language when creating.
And how to extend the controller for storing in multiple language when using this translatable package from tutorial above (link).
CRUD:
<form method="POST" action="/posts">
#csrf
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title">
</div>
<div class="form-group">
<label for="content">Content</label>
<textarea id="content" name="content" class="form-control"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Publish</button>
</div>
</form>
CONTROLLER
public function store(Request $request)
{
$post = Post::all();
$this->validate(request(), [
'title' => 'required',
'content' => 'required'
]);
$post = new Post;
$post->title = $request->title;
$post->content = $request->content;
$post->save();
return redirect('/');
THANKS :)
I'm the author of the tutorial.
The whole point of that implementation is that you don't have to worry about the model locale at all. The locale is set through the URL "/en/..."
So if you make a POST request to your model store URL like so :
POST /en/post {payload}
The App Locale of your laravel application will be automatically set before you even reach the PostController#store method.
Then, you can simply create your model like you would usually do (like in your exemple, that's correct) , and the model will be stored with the according locale.
Now that your model is initially created with the defined locale, you should be able to edit it in another language.
So you can go to this URL: /en/post/:id/edit then switch to another locale : /fr/post/:id/edit and you will notice that all input of the translatable fields are blank. That's normal because the 'fr' translation of that model doesn't exist yet.
You can thus fill the form with the 'fr' translated field, then save (update the model). And the translation will be saved. Your model is now translated :)
Hope this helps !
PS you can have a look at the example code here https://github.com/mydnic/Laravel-Multilingual-SEO-Example
So based on the tutorial, you'll have a column in your posts table called locale
Then in your view, you can add a select field from which you can chose the locale
<div class="form-group">
<label for="locale">Locale</label>
<select id="locale" name="locale" class="form-control">
<option value="en">English</option>
<option value="fr">French</option>
</select>
</div>
Then in your controller add the following line:
$post->locale = $request->locale;
Put locale in your $fillable array within the post model.
THIS IS WORKING WELL IN THIS SITUATION:
CONTROLLER:
public function create()
{
return view('services.new');
}
public function store(Request $request)
{
$service = new Service();
$service->save();
$this->validate($request, [
'title2' => 'required|max:350',
'content2' => 'required'
]);
foreach (['en', 'bs'] as $locale) {
$service->translateOrNew('en')->title = $request->title;
$service->translateOrNew('en')->content = $request->content;
$service->translateOrNew('bs')->title = $request->title2;
$service->translateOrNew('bs')->content = $request->content2;
}
$service->translateOrNew('en')->title = $request->title;
$service->translateOrNew('en')->content = $request->content;
$service->translateOrNew('bs')->title = $request->title2;
$service->translateOrNew('bs')->content = $request->content2;
// $article->translateOrNew('en')->text = ['texten'];
// $article->translateOrNew('ka')->name = ['nameka'];
// $article->translateOrNew('ka')->text = ['textka'];
// return $article;
// exit();
$service->save();
return redirect()->back();
}
BLADE FOR CREATE + CSS (in background):
<form action="{{route('service.store')}}" method="POST">
{{csrf_field()}}
<div class="tabset">
<!-- Tab 1 -->
<input type="radio" name="tabset" class="radio1" id="tab1" aria-controls="marzen" checked>
<label for="tab1">Bosanski</label>
<!-- Tab 2 -->
<input type="radio" class="radio1" name="tabset" id="tab2" aria-controls="rauchbier">
<label for="tab2">Engleski</label>
{{-- <!-- Tab 3 -->
<input type="radio" name="tabset" id="tab3" aria-controls="dunkles">
<label for="tab3">Dunkles Bock</label> --}}
<div class="tab-panels">
<section id="marzen" class="tab-panel">
<h2>Dodaj novu uslugu</h2>
<div class="form-group">
<lebal>Naslov*(bs)</lebal>
<input type="text" class="form-control" name="title2">
</div>
<div class="form-group">
<lebal>Opis*(bs)</lebal>
<textarea class="form-control" name="content2"></textarea>
</div>
</section>
<section id="rauchbier" class="tab-panel">
<h2>Dodaj novu uslugu</h2>
<div class="form-group">
<lebal>Title (EN)</lebal>
<input type="text" class="form-control" name="title">
</div>
<div class="form-group">
<lebal>Description (EN)</lebal>
<textarea class="form-control" name="content"></textarea>
</div>
</section>
<section id="dunkles" class="tab-panel">
<h2>Tab3</h2>
</section>
</div>
<input type="submit" value="Submit">
</form>
WEB.PHP:
Route::post('/create',[
'uses' => 'ServicesController#store',
'as' => 'service.store'
]);

Laravel $request value is null

I want to make dropdown menu where you choose company and it shows you owners that are in that company but when i request data from my blade.php in my controller i get NULL.
This is my blade.php
<form>
<label>Company:</label>
<select id="test" name="test" class="form-control input-sm">
#foreach($companies as $company)
<option value="{{$company->id}}">{{$company->name}}</option>
#endforeach
</select>
</form>
and this is my controller
public function index(Request $request)
{
$companies = Company::all();
$company_id = $request->get('company');
$owners = Owner::where('company_id',$company_id)->get();
return view ('owners', compact('owners','companies'));
}
and it's not showing any user but if I put any number manually like this
$company_id = 1;
then it shows owners from company where ID is 1.
UPDATE 2
My form looks like this now
<form action="{{ action('OwnerController#index') method="get"}}">
and my route is this
Route::get('owners', 'OwnerController#index');
Its still same.
Not sure what you want. But here is something for you.
File => create.blade.php
<form action='/item' method='POST'>
<label>Item Name:</label>
<input type="text" name="name" class="form-control input-sm">
<label>Company:</label>
<select id="company" name="company" class="form-control input-sm">
#foreach($companies as $company)
<option value="{{ $company->id }}">{{ $company->name }}</option>
#endforeach
</select>
<button class="btn btn-primary">Create</button>
</form>
File => ItemController.php
public function store(Request $request)
{
try {
$this->validate($request, [
'company_id' => 'required',
'name' => 'required|unique:items,name'
]);
$obj = new Item();
$obj->company_id = $request->input('company_id');
$obj->name = $request->input('name');
$obj->save();
return redirect()->route('item.index')
->with('success', 'Create Successful');
} catch (\Exception $ex) {
Log::error($ex->getMessage());
return redirect()->route('item.create')
->with('fail', $ex->getMessage());
}
}
As I said before I was missing some script. This solved my problem.
<form method="get" id="company_change">
<label for="company">Company:</label>
<select id="company" name="company" onchange="document.getElementById('company_change').submit()">
<option value="">----Select Company-----</option>
#foreach($companies as $company)
<option value="{{$company->id}}">{{$company->name}}</option>
#endforeach
</select>
</form>
My route is
Route::resource('owners', 'OwnerController');
You dont need a form to fill your dropdown;
You create a relationship in your model between Company and Owner and you dont even need a where,simply use eloquent like this
$owners = Owner::get();
And then in your view simply get the company using eloquent:
$owner->company->name;
That's it done!

How handle this validation context?

I have below a form for a user enter some info to do a registration in a congress.
In the form below there is this part:
#foreach($selectedRtype['questions'] as $customQuestion)
<div class="form-group">
<label for="participant_question">{{$customQuestion->question}}</label>
<input type="text" #if($customQuestion->required == "1") required #endif class="form-control" name="participant_question[]" value="">
</div>
#endforeach
That code shows for each ticket type the custom questions associated with that ticket type. And adds the "required" attribute if in the ticket_type_questions table the required field is "1".
My doubt is how to validate in the RegistrationController storeRegistrationInfo(), because the field might be required or not, it depends of wether is "1" or "0" in the column "required" of the ticket_type_questions table. Do you know how to handle this context?
public function storeRegistrationInfo(Request $request, $id, $slug = null, Validator $validator){
$validator = Validator::make($request->all(),[
'name' => 'required|max:255|string',
'surname' => 'required|max:255|string',
'email' => 'required|max:255|string',
'participant_name.*' => 'required|max:255|string',
'participant_surname.*' => 'required|max:255|string',
'participant_question.*' => '?????'
]);
...
}
Table relationships relevans for the question:
1 to many between congress and ticket types (a congress can have many ticket types)
1 to many between ticket types and ticket_type_questions (a ticket type can have many custom questions)
1 to many between questions and ticket_type_questions (a question can be associated with many ticket types)
Example of the ticket_type_questions table:
id ticket_type_id question_id required
1 2 3 1 (means the ticket type with id 2 has the custom question 3 and is a required field)
// registration form
<form method="post" action="">
{{csrf_field()}}
<div class="form-group font-size-sm">
<label for="name" class="text-gray">Name</label>
<input type="text" required class="form-control" id="name"
name="name" value="{{ (\Auth::check()) ? Auth::user()->name : old('name')}}">
</div>
<div class="form-group font-size-sm">
<label for="surname" class="text-gray">Surname</label>
<input type="text" id="surname" required class="form-control" name="surname" value="{{ (\Auth::check()) ? Auth::user()->surname : old('surname')}}">
</div>
<!-- other form fields -->
<!-- if the all_participants is 1 in the confernece table it should appear for each selected ticket a section for the user
that is doing the registration insert the name and surname of each paarticipant -->
#if (!empty($all_participants))
#if($all_participants == 1)
#foreach($selectedTypes as $k=>$selectedType)
#foreach(range(1, $selectedType['quantity']) as $test)
<h6>Participant - 1 - {{$k}}</h6> <!-- $k shows the ticket type name -->
<div class="form-group font-size-sm">
<label for="participant_name" class="text-gray">Name</label>
<input type="text" name="participant_name[]" required class="form-control" value="">
</div>
<div class="form-group font-size-sm">
<label for="participant_surname" class="text-gray">Surname</label>
<input type="text" required class="form-control" name="participant_surname[]" value="">
</div>
#foreach($selectedType['questions'] as $customQuestion)
<div class="form-group">
<label for="participant_question">{{$customQuestion->question}}</label>
<input type="text" required class="form-control" name="participant_question[]" value="">
</div>
#endforeach
#endforeach
#endif
#endif
<input type="submit" href="#" value="Next"/>
</form>
You could create a Request class using following artisan command php artisan make:request RegisterRequest there you could give the column the property to be nullable, which means that the user does not need to check that specific input.
The Request Class would look something like this, its basically a validation class:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required',
'email' => 'nullable',
];
}
}
In this example the user does not have to fill the field email.
Further you just replace your Request class in your controller function parameter like this:
public function sent(RegisterRequest $request)
{
$data = $request->all();
....
}
And of course you have to import / use it properly like this:
use App\Http\Requests\RegisterRequest;

CodeIgniter drop down list

I have two drop down lists in my form and after input data to all fields and click submit button, second drop down gives an form error to input data to that field. I'm getting data to those drop downs from separate two tables in database. Table names are "borrowers" and "books" from database.
public function form_validation2()
{
//echo 'OK';
$this->load->library('form_validation');
$this->form_validation->set_rules("borrower_name", "Borrower Name", 'required');
$this->form_validation->set_rules("borrowed_book", "Borrowed Book", 'required');
$this->form_validation->set_rules("borrowed_date", "Borrowed Date", 'required');
$this->form_validation->set_rules("lending_date", "Lending Date", 'required');
if($this->form_validation->run())
{
//true
$this->load->model("main_model");
$data = array(
"borrower_name" =>$this->input->post("borrower_name"),
"borrowed_book" =>$this->input->post("borrowed_book"),
"borrowed_date" =>$this->input->post("borrowed_date"),
"lending_date" =>$this->input->post("lending_date")
);
if($this->input->post("insert"))
{
$this->main_model->insert_borrowed($data);
redirect(base_url() . "main/inserted2");
}
}
else
{
//false
$this->borrower_page();
}
}
public function borrower_page(){
// $this->load->view("borrower_page");
$this->load->helper('url');
if($this->input->post("btn_for_books_page")){
redirect(base_url().'main/index');
}
$this->load->model("main_model");
$data["fetch_data2"] = $this->main_model->fetch_data2();
$data['borrower_name'] = $this->main_model->get_detail_in_dropdown();
$data['book_name'] = $this->main_model->dropdown2();
$this->load->view("borrower_page", $data);
}
From view
<div class="form-group">
<label>Borrower Name</label>
<select class="form-control" name="borrower_name">
<?php
foreach($borrower_name as $row)
{
echo '<option value="'.$row->borrower_name.'">'.$row->borrower_name.'</option>';
}
?>
</select>
<!-- <input type="text" name="borrower_name" class="form-control"> -->
<span class="text-danger"><?php echo form_error("borrower_name"); ?></span>
</div>
<div class="form-group">
<label>Borrowed Book</label>
<select class="form-control" name="book_name">
<?php
foreach($book_name as $row1)
{
echo '<option value="'.$row1->book_name.'">'.$row1->book_name.'</option>';
}
?>
</select>
<!-- <input type="text" name="borrowed_book" class="form-control"> -->
<span class="text-danger"><?php echo form_error("borrowed_book"); ?></span>
</div>
You have to name your form inputs correct. Try changing:
<select class="form-control" name="book_name">
To:
<select class="form-control" name="borrowed_book">
Change it in your view since you are fetching "borrowed_book" in your controller.

Submit drop down value to database with code igniter

I currently have a form which includes a drop down menu that has menu items taken from a database.
What I'm looking to achieve is to allow the user to select one of these values and add it to the database.The form is currently submitting and inserting properly except for the database. When I try to add the drop down value to the database all input comes back as null. If I take it out, it works fine though.
<form name = "form1" id = "form1" method ="post"> <!--action="<?php echo base_url()."index.php/Admin/create_user"; ?>"-->
<?php echo validation_errors(); ?>
<label for="first_name" class = "labelForm">First Name:</label>
<input type="text" id="first_name" name="first_name" class = "input2">
<label for="last_name" class = "labelForm">Last Name:</label>
<input type="text" id="last_name" name="last_name" class = "input2">
<label for="username" class = "labelForm">Username:</label>
<input type="text" id="username" name="username" class = "input2" onblur="check_if_exists();">
<label for="password" class = "labelForm">Password:</label>
<input type="password" id="password" name="password" class = "input2" onblur="validatePassword();">
<label for="passconf" class = "labelForm">Password:</label>
<input type="password" id="passconf" name="passconf" class = "input2" onblur="checkPasswords();">
<label for="email" class = "labelForm">Email:</label>
<input type="text" id="email" name="email" class = "input2">
<!-- <label for="hospital" class = "labelForm">Hospital:</label>
<select name="product" class = "input2" id = "hospitals">
<option selected disabled hidden style='display: none' value=''></option>
<?php foreach($hospital_dropdown as $option){?>
<option id = "hospitals" name="hospitals" value="<?php $option->hospitalName;?>"> <?php print_r($option->hospitalName); ?> </option>
<?php }?>
</select>-->
<label for="hospitals" class = "labelForm">Hospital:</label>
<select name="product" class = "input2" id = "hospitals">
<?php foreach($hospital_dropdown as $index => $option):?>
<option id = "hospitals_<?=$index?>"
name="hospitals"
value="<?=$option->hospitalName;?>"
><?=$option->hospitalName;?></option>
<?php endforeach;?>
</select>
<button type="button" id = "new_user_submit">Add New User</button>
</form>
Controller:
function create_user(){
$this->load->model('User_model');
$password = $this->input->post('password');
$hash = $this->bcrypt->hash_password($password);
$data = array(
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'username' => $this->input->post('username'),
'password' => $hash,
'class' => $this->input->post('userclass'),
'hospital' => $this->input->post('hospitals'),
'email' => $this->input->post('email'),
);
$this->User_model->create_user($data);
$username = $this->session->userdata('username');
$data['hospital_dropdown'] = $this->User_model->hospital_dropdown();
$data['main_content'] = 'admin';
$this->load->view('includes/admin/template', $data);
}
Model:
function create_user($data){
$insert = $this->db->insert('users', $data);
return $insert;
}
If I take out the hospital part in the controller it submits fine but when I leave it in , all the fields come back as null and won't submit.
Any Ideas?
Thanks!
You have several mistakes in your php part of the mark-up:
create a unique id: <option id = "hospitals" > is not unique
you need to echo out the option value, right now it is empty
you use print_r() to echo out your hospitalName. Normally, in your scenario you do that with echo(). print_r is useful to test variable content, see more here
there are other syntax to mix php with your mark-up, CodeIgniter suggest these:
the <select></select> tag has missing/wrong name attribute, see here. You are using the name attribute "product" instead, but in you controller you write 'hospital' => $this->input->post('hospitals')
resuming: below should fix your issue(s)
<select name="hospitals" id="hospitals">
<?php foreach($hospital_dropdown as $index => $option):?>
<option value="<?=$option->hospitalName;?>">
<?=$option->hospitalName;?>
</option>
<?php endforeach;?>
</select>

Resources