Ludo237
Ludo237

Reputation: 1717

Laravel 4 Many to Many with Eloquent and checkboxes

I'm trying to fix a problem with my Application using Laravel 4. The problem is about Eloquent and M:M relationship.

Here's my situation: I've many users that can choose many services, for each service they can provide a dedicated price. In the database I've tables named "services","users" and "users_services". So at the moment I can save the services and the prices that every user choose BUT my problem is that I don't know how to retrive and show them to the user, I mean I don't know how to set up "checked" to the checkboxes of every selected service and the price for each one too.

You can check the code here on Paste Laravel for any fork. I paste it here too.

    <?php

class Service extends Eloquent {

    public static $rules = array();

    protected $guarded = array('id');

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'services';

    /**
     * -------------------------------------
     * All Joins w/ other tables
     * -------------------------------------
     **/
    public function users()
    {
        return $this->belongsToMany('User','users_services','services_id','user_id');
    }
}

......

<?php

class User extends Eloquent {

    public static $rules = array();

    protected $guarded = array('id');

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * -------------------------------------
     * All Joins w/ other tables
     * -------------------------------------
     **/
    public function services()
        {
            return $this->belongsToMany('Service','users_services','user_id','service_id');
        }       
}

................

// Inside the controller 

$services = Service::all();
$this->layout->content = View::make('private.user.services')->with(compact('services'));

...............

// The view
@foreach($services as $service)
 <div class="pull-left col-lg-6 service-container">
  <div class="checkbox pull-left">
   <label>
    <input type="checkbox" name="services[]" value="{{ $service->id }}"><span>{{ $service->name }}</span>
   </label>
  </div>
  <div class="input-group service-price pull-right">
  <input type="number" min="0" name="prices[{{$service->id}}]" class="form-control pull-rigth" placeholder="0">
   <span class="input-group-btn">
    <button class="btn btn-default" type="button" disabled><i class="icon-eur"></i></button>
   </span>
  </div>
 </div>
@endforeach

Upvotes: 2

Views: 4539

Answers (3)

JasonJensenDev
JasonJensenDev

Reputation: 2407

msturdy's answer is quite nice, but for checkboxes, I would put "checked" instead of "selected". Other than that, it works great. Thanks!

Upvotes: 0

Gadoma
Gadoma

Reputation: 6565

this should work for you

1) in controller, store the list of services related to some user (the currently logged in user?) and than pass them to the view

 // ... get some $user
 $some_users_services = $user->related()->lists('service_id');
 // ... view make stuff etc.

2) in your view, while generating the checkbox list, check if it matches the user's chosen services (related services ids)

 @if( in_array($service->id, $some_users_services) ) checked="checked" @endif 

hope this helps you out

Upvotes: 2

msturdy
msturdy

Reputation: 10794

In your view, as you're looping through all possible services, you need to check if the current user has that service selected.

One way would be to send a second collection to the page, of the user's services, then use the contains() method to check it.

In your Controller pull the services from the User's relationship into a new variable:

$services      = Service::all();
$user_services = $user->services;
$this->layout->content = View::make('private.user.services')->with(compact('services'))->with('user_services', $user_services);

In your view just add the checked attr to the checkbox..

@foreach($services as $service)
 <div class="pull-left col-lg-6 service-container">
  <div class="checkbox pull-left">
   <label>
    <input type="checkbox" name="services[]" value="{{ $service->id }}" @if( $user_services->contains($service->id) ) selected@endif><span>{{ $service->name }}</span>
   </label>
  </div>
  <div class="input-group service-price pull-right">
  <input type="number" min="0" name="prices[{{$service->id}}]" class="form-control pull-rigth" placeholder="0">
   <span class="input-group-btn">
    <button class="btn btn-default" type="button" disabled><i class="icon-eur"></i></button>
   </span>
  </div>
 </div>
@endforeach

Note, it's not tested, and I don't know the relationships you have between the models.. but it should be ok :)

(note, you have a typo in one of your classes.. pull-rigth)

Upvotes: 5

Related Questions