Getting Ajax to display your search result from a class - ajax

I'm working with a recipe API and at the moment you get an error because I'm calling for something that doesn't exist ($contentSearch for example) and I think I can solve this with using Ajax, and no matter what I want to use it to learn how it works.
I'm using fork2fork API and working in Laravel 5.
So far I've looked around but haven't found anything that works. Maybe because I'm calling for a function and from there getting the result?
Feel free to mess up my entire code, I want to learn how to make it right instead of making it just work!
And to make my question clear: How do I show my result from the search by using Ajax?
Here is the html:
#extends('app')
#section('content')
{!! Form::open(['url' => 'searchRecipe']) !!}
{!! Form::text('search') !!}
{!! Form::submit('Search recipe') !!}
{!! Form::close() !!}
<p>if you lucky and have more than one thing in your fridge, separate them with a ',' and nothing else. As in no space.</p>
<div class="text-info">
<ul class="list-unstyled">
#foreach($contentSearch->recipes as $recipe)
<li>{{$recipe->title}}</li>
#endforeach
</ul>
</div>
#stop
And here is the function that is getting called if you push the submit button:
public function getSearch() {
$apiKey = "thats a secret i never tell";
$search = Request::get('search');
// insert search and API key in URL
$apiUrl = "http://food2fork.com/api/search?key=" . $apiKey
. "&q=". $search ;
// get the content of the file
//header('Content-Type: application/json');
$contentSearch = json_decode(file_get_contents($apiUrl));
return view('index', compact('contentSearch'));
}

I'm not sure I've fully understood the question but I hope this helps.
View
{!! Form::open(['url' => 'recipes']) !!}
{!! Form::text('search', null, ['id' => 'search']) !!}
{!! Form::submit('Search recipe') !!}
{!! Form::close() !!}
<ul id="result"></ul>
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<script>
$(document).ready(function(){
// get the form submit event
$('form').submit(function(event){
// stop the form from submitting
event.preventDefault();
// the form object
var form = $(this);
// perform ajax post request
$.post(
form.attr('action'), // this will go to form url
form.serialize(), // grab the form data
function(data) { // do something with the response
console.log(data); // see response in the console
// add title of recipes in a list
$.each(data.recipes, function(key, value) {
$('#result').append($('<li></li>').text(value.title));
});
}
);
});
});
</script>
routes.php just for demo you can move this to your controller
Route::post('recipes', function() {
$apiKey = "yourAPIkey";
$search = \Request::get('search');
// insert search and API key in URL
$apiUrl = "http://food2fork.com/api/search?key=" . $apiKey . "&q=". $search ;
// get the content of the file
//header('Content-Type: application/json');
$contentSearch = json_decode(file_get_contents($apiUrl));
return response()->json($contentSearch);
});
I'm guessing as an alternative you could use JSONP, but I'm new to JSONP and struggled to get it working with food2fork's api. Perhaps research JSONP and see if it's what you want. Example of JSONP with JQuery: https://learn.jquery.com/ajax/working-with-jsonp/

Related

laravel prefil form inputs from controller

Hi I'm using laravel forms.
{!! Form::text('product_name', null, array('class' => 'form-control date_pick')) !!}
Is there a way to set this default input from controller?. Think we can do it with Flash but I couldn't find an example. I want to take vlues from a model and prepopulate.
$products = Products::all();
It would be great if someone know how to do this. What is the easiest way to do it?
This is done with a basic edit route where you simply use:
In ModelController you would call the edit page:
public function edit(ModelName $model) {
return view('name.of.the.blade.view', compact('model')); // if using compact then without dollar symbol
}
In blade view simply make the form with all the input fields you have for that model:
{!! Form::model($model, ['method' => 'PATCH', 'route' => ['model.update', $model->id],]) !!}
Now all the form fields will have the values from that model.
{!! Form::close() !!}
And the edit and update route (inside routes/web.php) would be like this:
Route::get('/model/{model}/edit', 'ModelController#edit')->name('model.edit');
Route::patch('/model/{model}', 'ModelController#update')->name('model.update');

How to convert array in controller to string in views in laravel

I have a controller which passes an array data to view. Inside the view, I wanted to use the data as string in JSON object format.
Here is my controller:
class TestController extends Controller
{
private $user;
public function index()
{
return view('app')->with([
'userdata' => array('user' => 'John', 'age' => 20),
'access_token' => 'token_here'
]);
}
}
Here is my view app.php
<html>
<-- more html codes--->
<script>
let userdata = "{{ $userdata }}"; // ERROR: htmlspecialchars() expects parameter 1 to be string, array given
</script>
<-- more html codes--->
</html>
I tried using implode,
<script>
let userdata = "{{ implode(' ', $userdata)";
console.log(userdata);
</script>
It didn't have an error, but the problem is, the result becomes:
{"userdata":{&quotuser&quot .....}
How can I have a correct result like this:
{'userdata': {'user':'john', 'age': 20}...} // this should be a string
Does anybody know?
You can use json_encode:
{!! json_encode($userdata) !!}
note that you have to use {!! !!} to get exact string what you want. strings placed in {{ }} are escaped
Also you can user blade directive #json . depends which version of laravel you are using:
#json($userdata)
From Laravel blade docs.
Rendering JSON
Sometimes you may pass an array to your view with the intention of rendering it as JSON in order to initialize a JavaScript variable. For example:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
However, instead of manually calling json_encode, you may use the #json Blade directive. The #json directive accepts the same arguments as PHP's json_encode function:
<script>
var app = #json($array);
var app = #json($array, JSON_PRETTY_PRINT);
</script>

without select category not show subcategory

This is create.blade.php file. In this include css and js file too..
Html code and ajax code view file
#extends('layouts.app')
#section('content')
<link rel="stylesheet" href="http://www.codermen.com/css/bootstrap.min.css">
<script src="http://www.codermen.com/js/jquery.js"></script>
<form enctype="multipart/form-data" method="post" action="{{route('post.store')}}" >
#csrf
<div class="form-group col-md-8">
Category<select name="category" id="category" class="form-control">
<option>select</option>
#foreach($categories as $category)
<option value="{{$category->id}}">{{$category->category}}</option>
#endforeach
</select>
</div>
<div class="form-group col-md-8">
Category<select name="subcategory" id="subcategory" class="form-control">
<option>select</option>
#foreach($subcategories as $subcategory)
<option value="{{$subcategory->id}}">{{$subcategory->subcategory}}</option>
#endforeach
</select>
</div>
</form>
#endsection
This is controller code which create function code of category and subcategory
public function create(Request $request){
$categories = Category::all();
$subcategories = DB::table('subcategories')
->where('category_id', $request->category_id)
->pluck('subcategory', 'id');
return view('post.create', compact('categories', 'subcategories'));
}
This is route
Route::get('/post/create', 'PostController#create')->name('post.create');
Problem is if i select category still no show related to subcategory
The jquery append code looks like it is correct. I think the problem may be in your routing.
You've got
url:"{{url('create')}}?category_id="+categoryID,
as a GET request called through the Laravel method url(). It might help if you use url() here in the way you've got the route setup in web.php, which would use the full url path:
url:"{{url('post/create/')}}"+categoryID,
This lets the url() function add the parameter. However, it might also help to account for the incoming parameter on your routes file if it is a GET request (and add $category_id to the controller method):
Route::get('post/create/{id}', 'PostController#create')
I would probably make a separate function just to get the subcategories - then make your ajax call to that function and just pull the subcategories. A little cleaner.
But I think your problem may be in the routing and perhaps some of the above will help you.
you have done silly mistake , you are sending ajax request on change of category select dropdown to your create function , while your create function is rendering view post.create instead of return json response to ajax request .
so now what you can do ? 2 options available to you :
option 1 : create other function named "get_subcategory_by_category_id" and that will return subcategories in json , also create new route in routes/web.php for same .
option 2 : laravel provide $request->ajax() to detect that request is ajax or not ? so use that and return response in json , so you will get response .
public function create(Request $request){
$categories = Category::all();
$subcategories = DB::table('subcategories')
->where('category_id', $request->category_id)
->pluck('subcategory', 'id');
if($request->ajax()){
$response=array('categories'=>$categories,'subcategories'=>$subcategories);
return response()->json($response,200);
}
return view('post.create', compact('categories', 'subcategories'));
}
your ajax function should be like below :
<script type="text/javascript">
$(document).on('change','#category',function(){
var categoryID = $(this).val();
if(categoryID){
$.ajax({
type:"GET",
url:"{{url('create')}}?category_id="+categoryID,
dataType:'json',
success:function(res){
if(res){
console.log(res);
// forloop through subcategory and append
}else{
$("#subcategory").empty();
}
}
});
}else{
$("#subcategory").empty();
}
});
</script>
make sure that your request url is proper , also check Inspect Element > Network tab for ajax request response .

Laravel and dropzone using div and another form inputs

I want to use dropzone to upload multiple images with another form inputs
so i want a div that show the images when the user click,
also i have a button that trigger the form.
i have this but its not working
html:
<div class="col-md-12">
<h1>Upload Multiple Images using dropzone.js and Laravel</h1>
{!! Form::open([ 'route' => [ 'dropzone.store' ], 'files' => true, 'enctype' => 'multipart/form-data', 'class' => '', 'id' => '' ]) !!}
{!! Form::text('name'); !!}
<div class="dropzone" id="image-upload">
<h3>Upload Multiple Image By Click On Box</h3>
<button type="submit" class="btn btn-success" id="submit-all">
Enviar files
</button>
</div>
{!! Form::close() !!}
</div>
dropzone:
Dropzone.autoDiscover = false;
var imageUpload = new Dropzone("div#image-upload", {
url: "dropzone/store",
autoProcessQueue:false,
uploadMultiple: true,
maxFilesize:5,
maxFiles:3,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
init: function() {
var submitButton = document.querySelector("#submit-all")
//imageUpload = this; // closure
submitButton.addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
imageUpload.processQueue(); // Tell Dropzone to process all queued files.
});
// You might want to show the submit button only when
// files are dropped here:
this.on("addedfile", function() {
// Show submit button here and/or inform user to click it.
});
}
}
this gave me this error:
http://127.0.0.1/project/public/dropzone/store 419 (unknown status)
myController:
public function dropzone()
{
return view('dropzone-view');
}
/**
* Image Upload Code
*
* #return void
*/
public function dropzoneStore(Request $request)
{
$dir = public_path().'/upload/';
$files = $request->file('file');
foreach($files as $file){
$fileName = $file->getClientOriginalName();
$file->move($dir, $fileName);
}
}
routes: web.php
Route::get('dropzone', 'HomeController#dropzone');
Route::post('dropzone/store', ['as'=>'dropzone.store','uses'=>'HomeController#dropzoneStore']);
Laravel returns a 419 response when there is a token mismatch problem. The code you've shown POSTs files to your server, but does not pass a _token with the request. The web middleware, which is applied by default, will do token verification, and since there is no token, that will fail and throw a 419.
You can probably see this yourself if you look in your browser's devtools, click the network tab, click the POST request where the file is uploaded, and click the Preview or Response tabs.
So you need to pass a _token along with the request. There are many ways to do that, but the simplest is probably what is described in the docs:
Add the token to your <head>
<meta name="csrf-token" content="{{ csrf_token() }}">
Automatically pass it with every AJAX request:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

Laravel 5.4 - Populate dropdown based on another dropdown selected value

I want when select one value from first dropdown to automatcly populate another dropdown based on first dropdown value.
My view:
<label for="category">Catégorie(s):</label>
{!! Form::select('category', $category,null, array('class' => 'form-
control')) !!}
<label for="brand">Marque:</label>
{!! Form::select('brand_name', $brand_name,null, array('class' => 'form-control')) !!}
My controller:
public function index()
{
$category = Category::pluck('categoryName', 'id');
$brand = Brand::pluck('brandName', 'id');
return view ( 'site.indexS',compact('brand','category') );
}
How to populate another dropdown? Any idea?
you can easily do it with a little bit of ajax and get method. May be you are trying to load brand depend on category lets roll :
Your controller:
public function index()
{
$category = Category::pluck('categoryName', 'id');
// no need to query brand here because we will load it depend on category
$brand = [];
return view ( 'site.indexS',compact('brand','category') );
}
// here we are adding another method in your controller which will return brand object depend on category id
public get_brand($categpry_id){
// hope your brand table contain category_id or any name as you wish which act as foreign key
$brands= Brand::where('category_id',$category_id)
->pluck('brandName','id');
return json_encode($brands);
}
Now in route we need to add this to hit this url :
Route::get('get-brand','YourControllerName#get_brand');
In view :
{{-- i am adding id for both dropdown --}}
Catégorie(s):
{!! Form::select('category', $category,null, array('id' => 'category_dropdown','class' => 'form-
control')) !!}
<label for="brand">Marque:</label>
{!! Form::select('brand_name', $brand_name,null, array('id' => 'brand_dropdown','class' => 'form-control')) !!}
now in our view file we need to use ajax, there is many other way i am preferring ajax here
<script type="text/javascript">
var url = "{{url('/')}}";
</script>
<script type="text/javascript">
$('#category_dropdown').on('change', function() {
$('#brand_dropdown').empty();
var id = $('#category_dropdown').val();
$('#brand_dropdown').html('<option selected="selected" value="">Loading...</option>');
var url = url + '/get-brand/'+id;
$.ajax({
url: url,
type: "GET",
dataType: "json",
success:function(data) {
//console.log(data);
$('#brand_dropdown').html('<option selected="selected" value="">Select Brand</option>');
$.each(data, function(key, value) {
$('#brand_dropdown').append('<option value="'+key+'">'+value+'</option>');
});
}
});
});
</script>

Resources