JDubbleU JDubbleU - 19 days ago 4
SQL Question

Laravel Routing Issues For Modal Form

I have a web app project I've been working on, most of the applications functionality works except for submitting a flag on a resource. I want to use a modal form to submit the data to the database, then on the Flagged view page display all flagged resources

Name & Description
(from the Resources table)
Flag_Reason & Other_Comments
(from the Flagged table) I had it working to where it was submitting only the
Flag_Reason and Other_Comments
and not updating my Resources Table at all. I believe I'm having issues with routes now, because after changing my function to update my Resources table AND create a new Flag entry in the DB I get an error like this

Missing argument 1 for App\Http\Controllers\FlagsController::addFlag()


Here's some of my code, hopefully someone can help me finally figure this out once and for all.

Routes



Route::get('resource', array('as'=>'viewResource', 'uses' => 'ResourceController@resource'));

Route::get('flags', 'FlagsController@index');

Route::post('resource', ['as' => 'resource', 'uses'=>'FlagsController@addFlag']);

///Route::post('resource', ['as' => 'resource', 'uses'=>'FlagsController@postFlag']);///
This route works fine, and only inserts the Flagged table data into the database.





If I modify my route to look like this
Route::post('resource/{Resource_ID}', ['as' => 'resource', 'uses'=>'FlagsController@addFlag'])


I receive an error like this
Missing required parameters for [Route: resource] [URI: resource/{Resource_ID}].


Flags Controller



class FlagsController extends Controller
{
public function index()
{
$resources = Resources::where('Flagged', 1)->with('flags')->get();

return view('pages.flags', ['resource' => $resources]);
}

public function addFlag($id)
{
$flag = Flagged::create(Request::all());

$resource = Resources::findOrFail($id);

$resource->update(array('Flagged' => 1));

$resource->flags()->attach([$flag->id]);

dd($resource::all());
return back();
}
//////// This function inserts only the Flagged table data into the Flagged table, It doesnt do what I want it to do, so i've commented it out/////
public function postFlag()
{
$flag = Flagged::create([
'Flag_Reason' => Input::get('reason'),
'Other_Comments' =>Input::get('comments')]);
$flag->save();

\Session::flash('flash_message', 'Flagged!');

return redirect('resource');
}
}





Resource View



...

@foreach($resources as $resource) @foreach ($resource->locations as $location)
<tr>
<td> <a class="btn btn-small btn-default" style="float:right; margin-right:5px;" href="{{ URL::to('resource/addToCart/' .$resource->Resource_ID) }}">+</a> {{ $resource->Name }}</td>
<td>{{ $resource->Description }}</td>
<td>{{ $location->Address }}</td>
<td>{{ $location->City }}</td>
<td>{{ $location->Zip_Code }}</td>
<td>{{ $location->County }}</td>
<td>
<button type="button" class=" msgBtn btn btn-default" style=" display:inline; margin-right:auto;"><a href="pages/editresources/{{$resource['Resource_ID']}}">Edit</a>
</button>
<button type="button" id="submitFlag" class=" msgBtn btn btn-default" style=" display:inline; margin-right:auto;"><a href="#flagResource" data-toggle="modal" data-resource-id="{{ $resource->Resource_ID }}" data-resource-name="{{ $resource->Name }}">Flag</a>
</button>
<button type="button" class=" msgBtn3 btn btn-default pull-right" style="display:inline; margin-right:auto;"><a href="pages/deleteResource/{{$resource['Resource_ID']}}">Delete</a>
</button>
</td>

</tr>
@endforeach
@endforeach





Modal, inside the Resources View



<div class="modal fade" id="flagResource" tabindex="-1" role="dialog" aria-labelledby="flagModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"
id="flagResourceLabel" style="text-align:center;"> Flagged
</h4>

</div>
<div class="modal-body">
{!! Form::open(array('route'=>'resource', 'class'=>'form', 'method'=>'POST')) !!}
<div class="form-group">
<label for="reason" class="control-label">Reason for Flagging:</label>
{!! Form::text('reason', null, array('class'=> 'form-control', 'placeholder'=>'Reason')) !!}
</div>

<div class="form-group">
<label for="comments" class="control-label">Other Comments:</label>
{!! Form::text('comments', null, array('class'=> 'form-control', 'placeholder'=>'Comments')) !!}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<span class="pull-right">
<button id="submitFlag" type="submit" class="btn btn-primary" style="margin-left:5px;">Flag</button>
</span>
</div>
{!! Form::close() !!}
</div>
</div>
</div>
<script>
$('#flagResource').on('show.bs.modal', function(e) {
//var submitFlag = $(e.relatedTarget);
var resourceName = $(e.relatedTarget).data('resource-name');
var resourceId = $(e.relatedTarget).data('resource-id');
var modal = $(this);
modal.find('.modal-title').text(resourceName);
});

</script>





The problem I think is happening is my form open inside my modal
{!! Form::open(array('route'=>'resource', 'class'=>'form', 'method'=>'POST')) !!}
, and my
addFlag
function accepts an ID, but my resource route doesn't need an {id} on it.

If someone could take a look at my routes and help me debug it, it would be great. Thanks in advance.

Answer

You need to keep the route how you had it so it passes the Resource_ID but then you need to also pass it when you setup your form.

{!! Form::open(array('route'=>'resource' array('Resource_ID' => $yourId), 'class'=>'form', 'method'=>'POST')) !!}

Regarding your comment, and looking closer at your code, I think it might make sense to re-consider how this works.

You are passing multiple resources to this view so I think adding the resource id to the URL like I originally suggested is not the best idea because it needs to be dynamic depending on what resource was clicked on and the URL isn't the easiest thing to change via javascript.

I think a better solution would be to go back to using Form::open(array('route'=>'resource', 'class'=>'form', 'method'=>'POST')) !!}, then removing the /{Resource_ID} portion from your route and also removing the $id from public function addFlag() since we are no longer passing it via the URL.

Then in your form, add a hidden valid for resource_id

<input type="hidden" name="resource_id" id="resource_id" value="" />

Then you are already listening for the bootstrap show event and grabbing the right resource id, we just need to add it to the value.

        $('#flagResource').on('show.bs.modal', function(e) {
                //var submitFlag = $(e.relatedTarget);
                var resourceName = $(e.relatedTarget).data('resource-name');
                var resourceId = $(e.relatedTarget).data('resource-id');
                var modal = $(this);
                modal.find('.modal-title').text(resourceName);
                $('#resource_id').val(resourceId);
        });

No in your addFlag() method, you can grab the resource id via...

$id = \Input::get('resource_id');