I have this vue function where there are basically two methods. The first one postStatus is used to save a post just after the user clicks on the save button, and the other one getPosts is used to retrieve all previous posts of that user from the database.
Here is the vue.js, where there is an ajax call to a controller (in Laravel 5.3)
$(document).ready(function () {
var csrf_token = $('meta[name="csrf-token"]').attr('content');
/*Event handling within vue*/
//when we actually submit the form, we want to catch the action
new Vue({
el : '#timeline',
data : {
post : '',
posts : [],
token : csrf_token,
limit : 20,
},
methods : {
postStatus : function (e) {
e.preventDefault();
//console.log('Posted: '+this.post+ '. Token: '+this.token);
var request = $.ajax({
url : '/posts',
method : "POST",
dataType : 'json',
data : {
'body' : this.post,
'_token': this.token,
}
}).done(function (data) {
//console.log('Data saved successfully. Response: '+data);
this.post = '';
this.posts.unshift(data); //Push it to the top of the array and pass the data that we get back
}.bind(this));/*http://stackoverflow.com/a/26479602/1883256 and http://stackoverflow.com/a/39945594/1883256 */
/*request.done(function( msg ) {
console.log('The tweet has been saved: '+msg+'. Outside ...');
//$( "#log" ).html( msg );
});*/
request.fail(function( jqXHR, textStatus ) {
console.log( "Request failed: " + textStatus );
});
},
getPosts : function () {
//Ajax request to retrieve all posts
$.ajax({
url : '/posts',
method : "GET",
dataType : 'json',
data : {
limit : this.limit,
}
}).done(function (data) {
this.posts = data.posts;
}.bind(this));
}
},
//the following will be run when everything is booted up
ready : function () {
console.log('Attempting to get the previous posts ...');
this.getPosts();
}
});
});
So far the, first method postStatus is working fine.
The second one is supposed to be called or fired right at the ready function, however, nothing happens. I don't even get the console.log message Attempting to get the previous posts .... It seems it's never fired.
What is the issue? How do I fix it?
Notes: I am using jQuery 3.1.1, Vue.js 2.0.1
I see that you are using Vue 2.0.1. There is no ready method in Vue 2.0 and above.
Here is the link to list of all Vue 2.0 changes: https://github.com/vuejs/vue/issues/2873
As mentioned in the page above, you can use mounted instead of ready.
Not an issue, but just a note: You are mixing jQuery and Vue extensively. If you need jQuery only for http related functions, you may instead use vue-resource - https://github.com/vuejs/vue-resource
EDIT: Update on vue-resource
As pointed out by #EmileBergeron in the comments, vue-resource was retired way back in November 2016 itself (few weeks after I provided this answer with that last paragraph on vue-resource). Here is more info on the same:
https://medium.com/the-vue-point/retiring-vue-resource-871a82880af4
#Mani's suggestion of using mounted(){} works on the component that's not hidden. If you like to run a function in the component when visible and the elements which are hidden using conditions like v-if="" or v-show="" then use updated(){}.
Related
I'm trying to make a DOM event where the user clicking a table row's header (th) cell will delete the corresponding row from the database that supplies the table's data.
This code worked as intended framework-less, by just POST'ing an AJAX containing the row's id info from index.php to delete.php which then ran a sql query.
However, after moving the site to Laravel I ran into an error:
POST http://sandbox.app/delete 419 (unknown status)
The JavaScript piece responsible for attaching the delete event and posting the id through AJAX:
function attachDelete() {
$("#mainTable tbody tr th").on("click", function(e){
console.log(e.target.innerText + " was clicked");
var token = $('meta[name="csrf-token"]').attr('content');
var id_to_delete = e.target.innerText;
$.ajax({
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
type: 'POST',
dataType: 'text',
url: 'delete',
data: {
'id_to_delete': id_to_delete,
"_method": 'POST',
"_token": token
},
success: function () {alert("Deleted!"); },
failure: function() {alert("Error!");}
});
});
}
attachDelete();
The console.log(e.target.innerText + " was clicked"); goes off.
However, the success / error messages do not appear.
Going to http://sandbox.app/delete directly brings up a Laravel error window with lots of text, and this part highlighted:
protected function methodNotAllowed(array $others)
{
throw new MethodNotAllowedHttpException($others);
}
I've added the token variables after reading answers to related questions on StackOverflow. This didn't help.
In case it matters, the route:
Route::post('/delete', 'TasksController#delete');
The controller :
class TaskController extends Controller
{
public function delete()
{
include 'config.php';
$stmt = $pdo->prepare('DELETE FROM food WHERE id = :id');
$stmt->execute(['id' => $_POST['id_to_delete']]);
}
}
The code inside delete() used to just be the contents of a delete.php file in the old, framework-less site, where everything worked.
I've tried doing it without the controller by creating a delete.php view (with the same code as the delete() function). It didn't make a difference though:
Route::post('/delete', function () {
return view('delete');
});
Well, it seems if you are communicating with POST at the backend. So, you should be configuring your routes on the api.php instead of web.php
Place your route associated with controller
Route::post('/delete', 'TasksController#delete');
Inside api.php file.
How can I use Ajax to pass a Javascript variable to Php and retrieving those?
I am using a Jquery Ui Slider and on each slide I want to pass the javascript slider value to php so to say.
I have no ( not much ) experience in Ajax and really appreciate help.
This is how my slider looks:
$("#sliderNumCh").slider({
range: "min",
min: 0,
max: 20,
step: 1,
value: numbersOfChapters,
change : function(e, slider){
$('#sliderAppendNumCh').empty();
var i = 0;
var sliderValue = slider.value;
var getSliderVal = document.getElementById('sliderValue').value = sliderValue;
$.ajax({
type: 'POST',
url: '',
headers: {'X-Requested-With': 'XMLHttpRequest'},
data: {
value: getSliderVal
},
success: function (option) {
console.log(getSliderVal);
}
});
...
}
})
My route example:
Edit my route looks like this now:
Route::post('edit/{productID}', ['as' => 'editProductPost', 'uses' => 'ProductController#editProduct']);
Edits what I have tried:
url: '{{ route("editProductWeb") }}',
and got this error:
POST http://localhost/myApp/public/product/edit/%7BproductID%7D 500 (Internal Server Error)
and tried this:
url: 'edit',
and got this error:
POST http://localhost/myApp/public/product/edit 500 (Internal Server Error)
Edit my edit controller method:
public function editProduct($productRomID = 0)
{
$product = ProductRom::find($productID);
$sheets = Chapters::where('product_id', '=', $productID)->get();
$productId = $product->id;
$sheetCount = count($sheets);
return view('product.edit', [
'productId' => $productId,
'product' => $product,
'sheets' => $sheets,
'sheetCount' => $sheetCount,
'type' => 'edit',
'route' => 'updateProductRom'
]);
}
Edit using haakym suggestion so far:
$.ajax({
type: 'post',
url: "{{ Route('editProduct', $product->id) }}",
headers: {'X-Requested-With': 'XMLHttpRequest'},
data: {
value: getSliderVal,
productId : getPrId
},
success: function (option) {
console.log(getSliderVal);
}
});
does print me the id + the current slider value in my debug, so that works so far. Now I need to get that value and use it in my view(php) any suggestion how to proceed?
using this in my controller method:
$sliderValue = $request->input('value');
returns me
null
Edit I also tried this:
$sliderValue = Input::get('value');
which also returned me
null
Edit I added a Log:
Log::info(Input::all());
This shows the correct slider value and product id on slide.
But my Input::get('value') still returns me null
Edit I think I should add this information:
I changed my routes to this now:
Route::get('edit/{productID}', ['as' => 'editProduct', 'uses' => 'ProductController#editProduct']);
Route::post('edit/{productID}', ['as' => 'editProductPost', 'uses' => 'ProductController#editProductPost']);
The get shows the data from the database for a specific product and shows them in my view, I added the post one to post the slidervalue data to the editProductPost method and returns afterwards the value(sliderValue) in the edit view, is this correct?(Btw still does not work)
EDIT
If I put this in my controller method:
if ($request->isMethod('post')){
return response()->json(['response' => 'This is post method']);
}
return response()->json(['response' => 'This is get method']);
I keep getting the following error (if I slide):
POST http://localhost/myApp/public/product/edit/54 500 (Internal
Server Error)
I have this in my head:
<meta name="csrf-token" content="{{ csrf_token() }}">
and put this before my ajax post:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
EDIT:
Doing this returns the correct current slider value in the logs:
Log::info($request->get('value'));
I tried this:
return view('productRom.edit', [
'value' => $value,
]);
But I get an error in the console:
Failed to load resource: the server responded with a status of 500
(Internal Server Error) http://localhost/myApp/public/product/edit/73
As #julqas stated you need to include the URL in your $.ajax() method.
As you have a named route editProduct, you can output the link using blade:
$.ajax({
type: 'POST',
url: '{{ route("editProduct" }}',
...
Edit 1:
Your route is get and your ajax method is post, I guess this is the issue. You need to make them the same.
If you change the route to post you will need to add the CSRF token to the ajax request when it is sent. There is some guidance on the docs how to do this here:
https://laravel.com/docs/5.2/routing#csrf-x-csrf-token
The docs recommend adding this in your HTML head:
<meta name="csrf-token" content="{{ csrf_token() }}">
then use the following code before sending the request:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
alternatively you can add it to the request in the ajax call.
Edit 2
A side point - I was just guessing what the error is, it would have been better if I'd asked you if you could debug it yourself in order to see what the error was. Learning to debug ajax requests is very useful and not too difficult.
The best way to do that is by using the developer console in your browser of choice when making the ajax request. If you're using Chrome for example open Developer tools and then click on the Network tab before making your request. After making the request you can inspect the request and its details. Hope that helps!
Edit 3
I would change your editProduct() method to not accept any parameter and instead get the id value for the product from the request
public function editProduct()
{
// value here is referring to the key "value" in the ajax request
$product = ProductRom::find(\Request::get('value');
...
}
Consider changing the value key in your json to something more useful, such as productId
data: {
productId: getSliderVal
}
you haven't entered value for 'url'. Create any route then put it in url:'{any_route_name}' and then check in console weather your value has been posted or not
You have to do some R&D at your level for this .
I have the following code (jQuery) to create a json file:
$( ".save" ).on("click", function(){
var items=[];
$("tr.data").each(function() {
var item = {
item.Code : $(this).find('td:nth-child(1) span').html(),
itemQuantity : $(this).find('td:nth-child(4) span').html()
};
items.push(item);
});
});
Now this is my AJAX function:
(function() {
$.ajax({
url : "",
type: "POST",
data:{ //I need my items object, how do I send it to backend server (django)??
calltype:'save'},
dataType: "application/json", // datatype being sent
success : function(jsondata) {
//do something
},
error : function() {
//do something
}
});
}());
Now, my doubt is how do I send the 'item[]' object that I created to the backend? I do need to send both the item[] object and the variable 'calltype' which signals what made the AJAX call, as I have the same Django View (its the Controller equivalent for Django) in the backend being called by different AJAX functions.
How will my AJAX function look like?
Hey guys just got my answer right.
I used the following ajax function to get it right:
(function() {
$.ajax({
url : "",
type: "POST",
data:{ bill_details: items,
calltype: 'save',
'csrfmiddlewaretoken': csrf_token},
dataType: 'json',
// handle a successful response
success : function(jsondata) {
console.log(jsondata); // log the returned json to the console
alert(jsondata['name']);
},
// handle a non-successful response
error : function() {
console.log("Error"); // provide a bit more info about the error to the console
}
});
}());
So, this is sort of a self answer!!! :) Thanks a lot SO!!
I'm having a problem with ajax, as it sends only once my request, i have a cssmap plugin, and that plugin have the option onSecondClick which gives me the ability to do something when i click on it twice, my post request sends some data, to the sessions.php, in session.php i delete session, and then i put one again.
The js lines :
'onSecondClick' : function(e){
var regionName = e.children("A").eq(0).text(),
regionHref = e.children("A").eq(0).attr("href"),
regionClass = e.attr("class").split(" ")[0];
if(regionClass == "eu13" || regionClass == "eu16" || regionClass == "eu47"){
//open model success
$.ajax({
type: "POST",
url: 'session',
data: { country : regionClass },
cache: false,
success: function(data){
$( "#success" ).click();
}
});
//$( "#success" ).click();
}else{
//open model error
$( "#error" ).click();
}
},
PS - the url is right, thats the url of the file, and the session is set, but only once and doesn't upadate.
session.php:
if(Input::get('country')){
$countries = array(
'eu13' => 'france',
'eu16' => 'germany',
'eu47' => 'united kingdom',
//end of playable countries, the rest is bots!
'eu5' => 'belgium',
'eu27' => 'luxembourg',
'eu33' => 'netherlands',
'eu44' => 'switzerland',
'eu20' => 'ireland'
);
if(Session::get('selected');){
Session::delete('selected');
}
Session::put('selected',$countries[Input::get('country')]);
}
On the success, i click a button, which open a "model" from Bootstrap.
everything is ok, but the session always return the previous clicked country, and no matter how much i click other country, it doesn't change.
i've got no idea what the problem is, tried e.preventdefault(), cache: false, and some more options, nothing seems to fix it.
It's hard to tell where the problem lies from your description, but if it's about presentation (i.e. you can verify that session.php does it's job, but still the modal presents the wrong info), this is probably the reason.
Bootstrap modals are only, by default, filled with content once. After that it will use .toggle to show or hide.
If you want to update the information, you'll have to clear it first:
$('body').on('hidden.bs.modal', '.modal', function () {
$(this).removeData('bs.modal');
});
This will clear any content from modals with class modal when it hides/closes. You can also use an id selector of course, like #myModal.
edit:
Try this ajax. What does the alert return?
$.ajax({
type: "POST",
url: "session",
data: { "country": regionClass },
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
cache: false,
success: function(data){
alert(data);
$("#success").click();
}
});
And add something like this to the end of your session.php:
echo $countries[Input::get('country')];
(php is not really my thing. I think that's correct though)
I have this ajax function (refer below)
$.ajax({
url: "processor.php",
type:"POST",
data: { 'id' : "itemid, 'itemname' : itemname, 'itemdesc' : itemdesc" } ,
success:function(e){
if(($.trim(e) == "success")){
alert("success");
}else{
alert(e);
}
},error:function(){
alert("critical error");
}
});
assume that I already have the linked script of jquery and the content of those variables that has been declared on the data argument inside ajax function. Now I have a processor.php (refer below)
//this is the processor php
echo "success";
so base from above references, the ajax function submit a post request to processor.php and then the processor.php will respond "success" string as declared with the "echo success" but what happen is it doesn't get the success response instead the whole html tags on the current page is pop up (alert), why?? any ideas, clues, recommendation, suggestion would be greatly appreciated. Thank you.
PS: i know the response is not success but why it popup (alert) the whole html tags in the current page?
Try this i think your are passing parameter is wrong way.i just create an example change this code as per your requirement.
$.ajax({
url: "script.php",
type:"POST",
data: { id : itemid, itemname : itemname, itemdesc : itemdesc },
success: function(data, status, settings)
{
alert(The request URL and DATA);
}
,
error: function(ajaxrequest, ajaxOptions, thrownError)
{
alert("error");
}
});
there is syntax error in posted data and you probably have a redirect to new page instead of processor.php.
EDIT
Also make sure that processor.php returns only the word "success" and there is no more html tags in the source of page.
wrong syntax:
data: { 'id' : "itemid, 'itemname' : itemname, 'itemdesc' : itemdesc" }
suggested change:
data: { id : itemid, itemname : itemname, itemdesc : itemdesc }
I've been experienced that before, check your folder and file structure and if you're running server side script (such as php) or communicating with database, check your virtual host configuration.