I would like to be able to construct a query using laravel, and serialize it into a url string.
This would allow me to create routes which would unserialize a query builder, run the query, and make a view which displays the database results.
For example, to implement a button which refreshes a list of posts made by kryo:
http://example.com/ajax/posts.php?name=kryo&order_by=created_at&order_type=desc
Posts.php would simply be a route which unserializes, validates, and runs the query in the url params, and provides the results to a view.
Perhaps this is not useful in general, but I would personally find it handy specifically for ajax requests. If anyone knows how to implement this as a laravel plugin of some nature, that would be fantastic.
I'll try to give you a basic idea:
In Laravel you have to create a route to make a request to a function/method, so at first you need to create a route which will be listening for the ajax request, for example:
Route::get('/ajax/posts', array('uses' => 'PostController#index', 'as' => 'showPosts'));
Now, create a link in the view which points to this route, to create a link you may try this:
$url = to_route('showPosts');
If you use something like this:
<a class='ajaxPost' href="{{ $url }}?name=kryo&order_by=created_at&order_type=desc">Get Posts</a>
It'll create a ink to that route. So, make sure you are able to pass that $url to your JavaScript or manually you can write the url using /ajax/posts?name=.... Once you done creating the link then you need to create your JavaScript handler for this link (maybe using click event) then handle the click event from your handler, make ajax request, if it's jQuery then it could be something like this:
$('.ajaxPost').on('clcik', function(e){
e.preventDefault();
var url = $(this).attar('href');
$.getJSON(url, function(response){
$.each(response, function(key, value){
// loop... you may use $(this) or value
});
});
});
In your PostController controller class, create the index method:
class PostController extends BaseController {
public function index()
{
$name = Input::get('name');
$order_by = Input::get('order_by');
$created_at = Input::get('created_at');
$order_type = Input::get('order_type');
$posts = Post::whereName($name)->orderBy($order_by, $order_type)->get();
if(Request::ajax()) {
return Response::json($posts);
}
else {
// return a view for non ajax
}
}
}
If you want to send a rendered view from the server side to your JavaScript handler as HTML then change the getJson to get and instead of return Response::json($posts); use
return View::make('viewname')->with('posts', $posts);
In this case make sure that, your view doesn't extends the master layout. This may not be what you need but it gives you the idea how you can implement it.
Related
My table has the option edit. A row can be updated and saved to the database. While I was trying to implement this option I came across uncertainty. What do I have to do with the data from my edited row when it arrives at my controller? It doesn't seem clear to me do I have to use the edit, the update or combine them both? Do I need edit to find the id of the row that needs to be updated?
I am using the following code in methods to send data to my controller
<template slot="actions" slot-scope="row">
<span #click="updateProduct(row.item);" class="fas fa-pencil-alt green addPointer"></span>
</template>
updateProduct: async function(productData) {
axios.post('/product/update', {
productData: productData
.catch(function(error){
console.log(error)
})
})
}
In my controller, I think I have to find the id. I am pretty sure I am confusing different methods together. Thanks for any input.
public function edit()
{
$product = Product::with('id')->find($id);
// do something with it
}
public function update(Request, $request){
$product->update([
'name' => $request->productData->Name,
'description' => $request->productData->Descr
]);
}
the difference is significant. Edit is for displaying a form to apply changes and Update is used to set them up to server.
Edit is via GET http Update is via PUT http
In Laravel resource controller you can see these two functions "edit" & "update"
For example, you have a resource route 'post'
Edit:
you can return your edit form with your previously stored data
you can call using GET method & URL will be "/post/{id}/edit" and the route will be "post.edit"
update:
you can submit your data which you want to update
you can call using PUT/PATCH method & URL will be "/post/{id}" and the route will be "post.update"
For more information refer : laravel.com -> controllers
I'm using RESTful controller and passing variables (using forms) works just fine here.
Now for some reason I need to use simple link, created with action() and dedicated route for #create action.
My view creates few similar links with different parameters:
<a href="{!! action('\App\Http\Controllers\Admin\Franch\Category\SubCategoryController#create', array('mainCategoryName' => $mainCategoryName)) !!}">
It works, because I can see this in URL:
/create?mainCategoryName=some_sample_name
But the route doesn't pass variables to the #create action OR controller doesn't recieve it for somereason:
Route::get('admin/franch/sub_categories/create', ['uses' => 'Admin\Franch\Category\SubCategoryController#create');
I wonder how can I pass variables from views to specific controllers, using GET and POST methods?
And this is my #create controller:
public function create($mainCategoryName = false)
{
dd($mainCategoryName);
....
Which is always gives false.
Well You can create a function on the link and in that function user Ajax
$.ajax({
type: "POST",//Or Get
url: url,
data: {"var_name":variable},
success: success,
dataType: dataType
});
Now you can send you variables in the data. and then you can get value of the variable in your controller by:
Input::get('var_name');
It would be much better if you make all your "calculations" in the controller and pass a resulting value to the view like so
class SomeController() extends Controller
{
public function getView():View
{
$mainCategoryName = "fix";
$formUrl = action('\App\Http\Controllers\Admin\Franch\Category\SubCategoryController#create', array('mainCategoryName' => $mainCategoryName));
return view('view.show', compact('formUrl'));
}
...
Your mistake is in keeping meaningful data in the view, when the view should only have processed values:
<a href="{!! $formUrl !!}">
And if you really want to go "nuts", you can create a class that would generate HTML using a blade-view and the controller data and then you can execute this class in the controller to have your "partial" ready to be incorporated in a view as HTML. But not the other way round. Keep the calculations out of your views.
from Ajax the controller does get the keyword I want, as it confirms it (because I echo it), and my idea was that on getting that keyword, it should redirect to the page I want. Yet, it does not, and also, while it does change the locale, I have to reload the page, otherwise, it won't show any translation and locale changes on the page. In Firebug when I hover over the POST, I get the correct URL to where I would want to go: sort of http://myweb.com/es but the controller does not change the http URL box of my browser on my web to go there.
I am simplifying the Controller code here, but actually I will want it to go to different URLs depending on the keyword it gets, something that I would do with a switch statement or IF else if etc.
So the controller is as simple as this:
public function changelanguage()
{
$lang = \Input::get('locale');
echo "I got $lang";
Session::put('locale', $lang);
return redirect('/es');
}
If instead of using ajax I use a Form, then I dont need to reload, the Action of the form makes the controller change the locale and translate the page without reloading. But I need to use ajax and in any case, the controller does get correctly the keyword ('en', 'es', 'de' etc ) for languages, so it should take it from there and redirect me to the URL page, but it just doesnt move.
if you are curious about the Ajax, here it is, but it does send the keyword as I said.
$(document).ready(function(){
$('.choose-language').on('click', function(e){
e.preventDefault();
var selectedlanguage = $(this).data('value');
$.ajax({ // so I want to send it to the controller
type:"POST", // via post
url: 'language',
data:{'locale': selectedlanguage},
}); // HERE FINISHES THE $.POST STUFF
}); //HERE FINISHES THE CLICK FUNCTION
}); // HERE FINISHES THE CODE
ROUTES
Route::post('language', array(
'as' =>'language',
'uses' => 'LanguageController#changelanguage'
));
If you’re trying to perform the redirect in the AJAX-requested script, then it won’t work. You can’t redirect from a script request via AJAX otherwise people would be doing all kinds of nefarious redirects.
Instead, set up a “success” handler on your AJAX request that refreshes your page if the request was successful. It can be as simple as:
var url = '/language';
var data = {
locale: $(this).data('value');
};
var request = $.post(url, data)
.success(function (response) {
// Script was successful; reload page
location.reload();
});
I’m not sure how you’re allowing users to select locales, but since you need a reload any way I think AJAX is pointless here. Just have a traditional form that submits the new locale to an action, set the locale in a session/cookie/whatever, and then redirect back to the referring page.
Inside a component's view, I have something like this:
<?php echo TestcompHelperFind::loadStates(...); ?>
<?php echo TestcompHelperFind::loadCounties(...); ?>
The above static functions load <select> dropdowns with the state names and countries respectively.
The class TestcompHelperFind is located in the file /administrator/components/com_testcomp/helpers/find.php.
How do I load States dropdown list based on the country selected using AJAX? I'm not sure what url I should provide in the ajax function.
On the client, you will need a function that watches the country select for changes, and when it happens calls the appropriate url with a callback that will populate the counties select.
On the server, you need to output the select content.
Since you have the html output already working, let's use this approach. As an alternative you could have your server method return a json object and use the javascript to parse it and populate the select. But let's stick to html communication, i.e. the server returns the html contents of the select.
1. On the server
1.a. Output the counties select
We only need to return the result of the TestcompHelperFind::loadCounties(...); to the ajax call. This is achieved easily writing a new method in the component's controller, i.e. the controller.php in the root of the component folder or one of the sub-controllers if appropriate. It's up to you to place it in a meaningful spot.
Inside the controller simply add a new public task such as
class SomethingController extends JController
{
public function getCountiesHTML() {
$input = JFactory::getApplication()->input;
$country = $input->getCMD('filter_country');
// load helper if necessary, then:
echo TestcompHelperFind::loadCounties($country);
exit; // this will stop Joomla processing, and not output template modules etc.
}
Please note the exit; at the end, this will make Joomla output only the component's output (our echo) and not the whole template/modules etc.
1.b Add an ID to the country and county selects so that it will be possible to manipulate them on the client; I'll assume filter_country and filter_county ;
2. On the client
you will want to invoke the url
index.php?option=com_something&action=getCountiesHTML&filter_country=UK
when the country select is changed. It will also need to cancel any pending requests to avoid overlapping messages. To keep things simple, let's assume you use a library to handle Ajax, I'll write an example for jQuery:
<script>
var xhr;
jQuery(function($) {
$('#filter_country').change(function(){
var filterCountry = $('#filter_country').val();
if (xhr && xhr.abort) {xhr.abort();xhr=false;}
xhr = jQuery.ajax(
url: 'index.php',
data: 'option=com_something&task=getCountiesHTML&filter_country='+filterCountry,
success: function(data){
jQuery('#filter_county').replaceWith(data);
}
);
});
});
</script>
For cancelling the previous request, please see a dedicated answer such as this one.
sorry for asking this question ..i am working on a Cakephp 2.x ... i have a view page in my controller name folder e.g Controller/index.ctp ... and i have ajaxfiles are stored in app/webroot/ajax/ajaxfile.html
now on my index.php file i am acessing the ajax page like this
<a href="ajax-demo/ajaxfile.html" class="file-link">
<span class="icon file-png"></span>
Simple gallery</a>
Controller
public function index(){
}
now the problem is i want to send the variables to both of my pages ... index.ctp and ajaxfile ... how can i do this ??what is the best approach to tackle these things ....
do i have to move the ajaxfiles from webroot and paste under the controller name folder?
if is it so then how can i send variables to ajax files which has no model and controller
please if any one know the solution then please advice me. and give an example too
There are different way to achieve this, here I'm writing the simplest one
First you need to move your "index.ctp" file to your "View/YOUR CONTROLLER NAME/" folder.
1) To access the variable in view you need to set it from your controller's method like this
public index(){
$this->set('yourVariable', 'Your Value');
}
2) To access the value in your view file (index.ctp), you need to call this variable like this
$yourVariable;//If you want to print this then you can write like this
echo $yourVariable;
3) To call a ajax file from your index.ctp the simplest method is to call a onclick event on this anchor, the onclick event will call a JAVASCRIPT method which will further make a ajax call and will place the output in an element in your index.ctp, The ajax call will further call your controller method (implement your html related logic here)
For example,
<span class="icon file-png"></span>Simple gallery
<div id="yourAjaxFileOutputReplaceMentDiv"></div>
4) create a javascript method in your JS file, this JS file must be loaded in your layout file.
function yourAjaxCallMethod(BaseURL,yourVarible)
{
//Initialize Ajax Method
var req = getXMLHTTP();//Let's this method Initialize your Ajax
if (req)
{
req.onreadystatechange = function() {
if (req.readyState == 4)
{
if (req.status == 200)
{
document.getElementById('yourAjaxFileOutputReplaceMentDiv').innerHTML=req.responseText;
} else {
alert("There was a problem while using XMLHTTP:\n" + req.statusText);
}
}
}
var URL = BaseURL+yourVarible+'/'+Math.random();
req.open("GET", URL, true);
req.send(null);
}
}
5) Your AJAX file related method in your controller "yourController". Set autoRender to False
public function ajaxMethod(){
$this->autoRender = false;
//Check $this->request['pass'] for arguments send from ajax call
$retreivedVariable = $this->request['pass'][0];
echo 'I retrieved variable'.$retreivedVariable;
}
However instead of writing core javascript and ajax method you can call the inbuild Ajax Helper for same.