I am currently pretty confused why Inertia.js is not reloading or rerendering my page.
I have a form that could be filled, once submitting this will execute:
Inertia.post("/ban", ban);
This will redirect to a POST in the web.php of my Laravel.
That looks like this:
Route::post("/ban", [Speler::class, "ban"]);
This redirects to a class called "Speler", in there is a function called "ban".
Once done some SQL statements it will execute this return:
return Redirect::route("speler", [$steam])->with("success", "Ban doorgevoerd!");
This will go back to the web.php, and go to the route speler with the session data "success".
That redirect goes into the web.php:
Route::get("/speler/{steam}", [PageLoader::class, "speler"])->name("speler");
This one goes to the PageLoader controller, and execute the "speler" function.
But here it gets weird, this will return a Inertia::render of the same page the person was on, but would need to add another prop, or change the prop. (so i can show a popup with te text that it succeeded)
return Inertia::render("Panel/Speler",
["steamNaam" => $steamNaam, "discord" => $discord, "karakterAantal" => $karakterAantal, "karakters" => $karakters, "sancties" => $sanctiesReturn, "punten" => $aantalPunten, "steamid" => $steamid, "success" => $melding]
);
The "success" prop contains $melding that simply contains a string.
But for some reason it doesn't seem to re-render the page, the form stays filled, and the props are the same.
Does someone have a solution?
If you setup your form with the form helper, you can reset the form on a successful post like this:
form.post('/ban', {
preserveScroll: true,
onSuccess: () => form.reset(), // reset form if everything went OK
})
The success message, which you set with
return Redirect::route("speler", [$steam])->with("success", "Ban doorgevoerd!");
is usually taken care of by the Inertia middleware and made available as 'Shared data'. See this docs page on how to configure that. Shared data is rendered in $page.props variable. That is where you can find the Ban doorgevoerd! message. You can show these to the user as follows:
<div v-if="$page.props.flash.message" class="alert">
{{ $page.props.flash.message }}
</div>
Depending on your implementation, you would need to watch this property. See the FlashMessages component on the pingCRM demo app for an example implementation.
Related
I want to load a new vue component and show its id in the URL. This can be done like so:
<template>
<button #click="submit">Load new page with id in url</button>
</template>
<script>
import {Inertia} from "#inertiajs/inertia";
const submit = () => {
const id = 1
Inertia.post('/admin/kreationen/bearbeiten/' + id, {id: id})
}
</script>
and on the laravel side (web.php):
Route::post('/admin/kreationen/bearbeiten/{id}', function (Request $request) {
return inertia('backend/cms-gallery-edit', ['id' => $request->id]);
});
Problem is, when I am reloading the page, this error is shown:
GET http://127.0.0.1:8000/admin/kreationen/bearbeiten/1 405 (Method Not Allowed)
I understand why this error is happening but how would I achieve the goal of showing the id in the new url without getting this error?
Edit:
I don't know why my original approach didn't work yesterday but now it does. For anyone interested:
<inertia-link :href="'/admin/kreationen/bearbeiten/' + data['id']">
<button>Load new page with id in url</button>
</inertia-link>
backend:
Route::get('/admin/kreationen/bearbeiten/{id}', function (Request $request) {
return inertia('backend/cms-gallery-edit', ['id' => $request->id]);
});
Probably you needed to use GET Request instead of POST Request. If yes, then just add to url your id and then pass the GET method to param:
const id = 1
Inertia.visit('/admin/kreationen/bearbeiten/' + id, {method: 'get'})
And for Backend side in Laravel url stays as it is, but recieved parameter is only $id and method needs to change to GET:
Route::get('/admin/kreationen/bearbeiten/{id}', function ($id) {
return inertia('backend/cms-gallery-edit', ['id' => $id]);
});
The 405 (Method Not Allowed) occurs when you try to load the POST methoded url via GET method and vice versa.
So first when you click, the post method is working fine, but when you reloading the page, it counts as GET method (just like direct opening the page). So recieving 405 error is fair, if you are able to use GET method to your needs, then use GET method (if you are ok with whenever user accesses the page directly without any form posted).
If not, then you might firstly do you POST requests in different route, then redirect user to another route (To prevent re-sending form when reloading the page, but to opening another page with some form data (ofcourse it must be saved somewhere like session or db))
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
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.
I'm doing a website based laravel 4.2 and Bootstrap. I want a bootstrap modal pop up dialog to load on certain routes provided that the user is not already logged in.
So far i have accomplsihed it to load for the entire application upon loading which is not i want but am in the right direction.
This is my ajax call
script type="text/javascript"> $(document).ready(function() {
$.get("status", function(data, status){
data.status == false ? $('#modal-form').modal({backdrop: 'static'}) : $('#modal-form').modal('hide');
});
});
Status refers to a URL defined in this route
Route::get('/status', 'LoginController#getLoginStatus');
and the method is defined here
public function getLoginStatus()
{
return Response::json(array( 'status' => Sentry::check()));
}
From that, the modal dialog loads on each route across the entire application. I would want to limit the dialog to load on certain routes provided the user is not logged in.
Thing Laravel filter would do the trick for me but i have failed to do so.
Something like
Route::filter('status', function()
{
});
and then the route be like:
Route::get('profile', array('as' => 'submit-profile','before' => 'status','uses' => 'ProfileController#getProfile'));
Thanks guys hope you can give me some advice.
You could use the
Route::currentRouteName()
to check what route your on and then do your preferred action,
like calling the ajax get request for the modal.
I am using cakephp and pippoacl plugin and I simply cannot add a new role. What I modify in the plugin is to make the submit using ajax, something like this in my view (add.ctp):
<?php echo $ajax->submit(
'submit',
array(
'url' => array('controller' => 'roles', 'action' => 'add'),
'before' => 'beforeSubmitAdd();',
'complete' => 'completeSubmitAdd(request);'
)
);
?>
When the add.ctp gets loaded for the first time, I can print_r something from the controller. But the ajax submit above only executes the javascript on 'before' and 'complete'. I check on the firebug, the response is blank.
On my controller:
function add() {
print_r("start");
if (!empty($this->data)) {
print_r("add new role");
// save new role
}
}
I use ajax submit for user and I don't have any problem adding new user. Is there any idea where I should check? I have been comparing the user and role code for a week and I have asked a friend to look at my code, too, but we still cannot find what causes this.
Thanks in advance! :D
I am not so familiar with the Ajax helper, but I haven't using it from so long that I can't remember what is it doing :).
Back to the problem.
Did you check if the requested URL in the Ajax address is correct? This should work straightforward, but it's possible that the url to be invalid.
Are you using Security component (even just adding it on the var $components variable)?. This could lead to blank screen especially if you modifying the fields in the form somehow. Try to remove it and see if it's working without.
Finally I would say how I would do it with jQuery.
Following code should do the job:
$(document).ready(function(){
$('form').live('submit', function(){ //handles also dynamically loaded forms
var form = $(this).addClass('loading'); //indicate somehow that the form has been submitted
$('#content').load($(this).attr('action'), $(this).serialize(), function(){
form.removeClass('loading');
});
})
});
This will handle all submits in the forms of the system, but you can modify of course.