How to call a route & send data with javascript - javascript

I'm working with Laravel 5 and I've the following code
HTML
<div id="row">
<textarea class="form-control" rows="3" id="comment" placeholder="Update your Post"></textarea>
</div>
<a href="#" id="btn-post" dusk="postButton" class="btn btn-primary" role="button" data-toggle="modal" data-target="#addPost">
<span class="ion-plus-circled"> Post</span>
</a>
JS
$(document).ready(function(){
$("#btn-post").click(function(){
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var comment = $('textarea#comment').val();
var postData = {
post_content: comment.val();
groupId: window.location.href.split("/")[4] // hack to get group id
}
console.log(postData);
$.ajax({
type: "POST",
url: "/post",
data: JSON.stringify(postData),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data, status){
$("#addPost").modal('toggle');
//window.location.href = data.redirectTo;
}
});
});
});
web.php
Route::post('post', 'GroupController#post');
GroupController.php
public function post(Request $request){
$post_content = $request->input('post_content');
$userId = Auth::user()->id;
$groupId = $request->input('groupId');
$post = PostGroup::firstOrNew(['group_id' => $groupId, 'post_content' => $post_content]);
$post->user_id = $userId;
$post->save();
$redirectPath = '/groups/' . $groupId;
return response()->json(['message' => 'Your post have been published! Take a look at',
'redirectTo' => $redirectPath]);
}
What I want to do is to call the javascript function btn-post at the click of the link-button Post. This function takes the content of the textarea (which I don't know if I wrote correctly) and sends it to the GroupController using the same javascript function, to the route "/post", calling the function post (as defined in web.php), but for some reason it doesn't work, and I don't know where I was wrong (I think the problem is in the javascript function, as if it weren't called).

You have a syntax and a logic error in your Javascript here:
var comment = $('textarea#comment').val();
var postData = {
post_content: comment.val();
groupId: window.location.href.split("/")[4] // hack to get group id
}
Logic error: you assign textarea value to the var comment. Then 2 lines after that, you call comment.val() on it, although it's a string at this point. No need to call .val() again.
Syntax error: you shouldn't use ; within the postData JSON definition. You separate JSON fields with a comma.
This is the fix for the above 2 problems:
var postData = {
post_content: comment, // <----
groupId: window.location.href.split("/")[4] // hack to get group id
}
I suggest you start using developer tools to debug your Javascript

Related

jQuery AJAX Autocomplete not working when trying to make it dynamic

I have my autocomplete working fine if there is hard coded data being fed into it. My PHP is returning a JSON result. I'm not sure where I am going wrong.
HTML
<div class="form-group bgcolor">
<label for="send_to">Direct to: </label><input type="text" name="send_to" id="send_to" class="form-control send_to typeahead" placeholder="Leave blank normally">
</div>
Jquery
$('.typeahead').typeahead({
source: {
groupName: {
ajax({
url: 'scripts/order_messaging.php',
method: 'POST',
data: JSON.stringify({action: 'autocomplete_to_user', query:query}),
contentType: 'application/json',
dataType: 'json',
success:function(data)
{
result($.map(data, function(item){
return item;
}));
}
})
},
},
debug: true
});
PHP
//autocomplete user name for user_to
if ( $_POST['action'] == 'autocomplete_to_user' ) {
$stmt = $pdo->prepare('select * from login where username like :query');
$stmt->bindValue('query', '%'.$_POST['query'].'%');
$stmt->execute();
$result = array();
while($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
array_push($result, $user_name->username);
}
echo json_encode($result);
}
I think it's this line in my jQuery: data: {action: 'autocomplete_to_user', query:query}, Maybe I have a syntax problem.
As per jQuery Ajax Documentation, dataType: 'json' evaluates the response as JSON and returns a JavaScript object.
You need to stringify your data by using JSON.stringify({action: 'autocomplete_to_user', query:query}) before you send it to PHP. Also, you need to add header Content-Type: 'application/json' that tells you PHP code that request data is JSON. You can do this by adding contentType: 'application/json' in your Ajax settings.
Your final jQuery code would look like this:
$('.typeahead').typeahead({
source: function(query, result)
{
$.ajax({
url: 'scripts/order_messaging.php',
method: 'POST',
data: JSON.stringify({action: 'autocomplete_to_user', query:query}),
contentType: 'application/json',
dataType: 'json',
success:function(data)
{
result($.map(data, function(item){
return item;
}));
}
})
}
});
Refer to jQuery Ajax Documentation for mode details.
Hope this helps!
EDIT:
You need to update your PHP code to read JSON. Please refer to this link.
Your PHP Code should look like this:
<?php
// Read the input stream
$body = file_get_contents("php://input");
// Decode the JSON object
$object = json_decode($body, true);
//autocomplete user name for user_to
if ( $object ['action'] == 'autocomplete_to_user' ) {
$stmt = $pdo->prepare('select * from login where username like :query');
$stmt->bindValue('query', '%'.$object['query'].'%');
$stmt->execute();
$result = array();
while($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
array_push($result, $user_name->username);
}
echo json_encode($result);
}
?>
In my humble opinion, the documentation has some errors. For instance, in the demos, specifically the example Country v2 states
A POST request will be sent with data myKey: myValue
when in actuality the request being sent in the example is GET, because it depends on the type key of the ajax object of the first source (country in this case), which is not set, thus defaulting to GET.
So, that being said, you really should stick to the proposed HTML structure (at least start with it, then take away stuff you don't want gradually as long as it'll let you).
HTML
<form id="form-country_v2" name="form-country_v2">
<div class="typeahead__container">
<div class="typeahead__field">
<div class="typeahead__query">
<input class="typeahead" name="country_v2[query]" placeholder="Search" autocomplete="off">
</div>
<div class="typeahead__button">
<button type="submit">
<i class="typeahead__search-icon"></i>
</button>
</div>
</div>
</div>
</form>
JS
$(document).ready(() => {
$('.typeahead').typeahead({
template: "{{display}} <small style='color:#999;'>{{group}}</small>",
source: {
users: { //might as well be 'willy wonka', it doesn't matter
ajax: {
type: "POST",
url: "scripts/order_messaging.php",
//this is not actually needed for the request to work (reach the server),
//this is used to access said request's returned data, it all
//depends on how you structure the response in the server,
//check out the php part
path: "data.users",
data: {
action: 'autocomplete_to_user',
query: 'username'
}
}
}
},
callback: {
//this is just to help you show the response in the html
onResult: function(node, query, result, resultCount) {
if (query === "") return;
var text = "";
if (result.length > 0 && result.length < resultCount) {
text = "Showing <strong>" + result.length + "</strong> of <strong>" + resultCount + '</strong> elements matching "' + query + '"';
} else if (result.length > 0) {
text = 'Showing <strong>' + result.length + '</strong> elements matching "' + query + '"';
} else {
text = 'No results matching "' + query + '"';
}
$('#result-container').html(text);
},
onInit: function(node) { //and this is just informational
console.log('Typeahead Initiated on ', node, node.selector);
}
}
});
});
order_messaging.php
if ($_POST['action'] == 'autocomplete_to_user') {
$stmt = $pdo->prepare('select * from login where username like :query');
$stmt->bindValue('query', '%' . $_POST['query'] . '%');
$stmt->execute();
$result = array();
while ($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
array_push($result, $user_name->username);
}
echo json_encode(array(
"status" => true,
"error" => null,
//here you use whatever structure you want to return the data in,
//as long as the payload is an array ($result).
//remember in the JS you are expecting 'data.users'?
//this is where it's coming from
"data" => array(
"users" => $result,
)
));
} else
echo json_encode(array(
"status" => true,
"error" => null,
"data" => array(
"users" => [],
)
));
HIH
Well, after much trial and error I got an autocomplete working using jQuery .autocomplete.
I don't know what I was doing wrong with the typeahead but the documentation was hard to understand (probably because of my limited experience with jQuery).
To all those in the future that need some help with this; here is a tutorial I found that was helpful: jquery ui autocomplete tutorial
Thank you to everyone
I've tested the library and you need to change two things in order to make it work.
1) You need to restructure the source parameter. You were giving it an AJAX callback which is not supported. According to the documentation, it accepts an array or an object with settings, so AJAX needs to be defined like this:
$('.typeahead').typeahead({
source: {
// source has an "ajax" property where you just need to place
// the object with AJAX params (the one you'd normally place inside
// an $.ajax() call)
ajax: {
url: 'scripts/order_messaging.php',
method: 'POST',
data: {
action: 'autocomplete_to_user',
query: query,
},
dataType: 'json',
path: '',
},
},
});
The path property of the ajax object is key here. It tells the typeahead function where to look for the data that was returned by the AJAX action. Since you're encoding a one-dimensional array of values, you need to set it to an empty string, meaning your data is in the root of the response.
If you were to return, for example, an array like echo json_encode(['users' => $result]); then you'd have to set the path to 'users' (because that is the index in the response that holds your data).
2) You have to follow a strict HTML structure in order to make it work:
<div class="typeahead__container">
<div class="typeahead__field">
<div class="typeahead__query">
<input class="js-typeahead" name="q" autocomplete="off">
</div>
</div>
</div>
If you leave out any of these elements, it doesn't trigger the functionality. This HTML structure is one of the first things they mention in the documentation.

laravel, ajax call from input to controller function 500 error

I'm not sure what's happening with this but when my ajax call is made to my php controller method, I'm getting a 500 error and I'm wondering if it's possibly a data type error or just simply syntax.
The value I'm passing from my form input through tha ajax call and into my function is being passed into a url endpoint in my service.php file.
The ajax itself is calling the function successfully but I can't verify the results from my $searchResults in the function because it seems to fail at the point of passing.
I started typing Test into my input with a breakpoint in the browser and it showed the value for my input as "T". Should I need to strip quotes or anything like that if it's being used in the query of the endpoint?
What else does it look like I could be doing wrong here?a
service.php
public function getSearch($query)
{
return $this->get("/search/search?query={$query}" );
}
I also set a new route for the controller and function
Route::post('autocomplete','Controller#autoComplete');
controller.php
public function autoComplete(Request $request)
{
$search_result = $request->search_result;
$service = new service();
//$search_result = "test"; /*this hard coded value works for passing*/
$searchResults = $service->getSearch($search_result);
return $searchResults;
}
view.blade.php
$('#productInput').on('input', function(){
if($(this).val() === ''){
return;
}else{
const searchResult = $(this).val();
$.ajax({ url: '/account/autocomplete',
data: {
'search_result':searchResult
},
type: 'POST',
success: function(response){
console.log(response);
}
});
}
});
Add this to your head
<meta name="csrf-token" content="{{ csrf_token() }}">
and pass the token to ajax:
$('#productInput').on('input', function(){
if($(this).val() === ''){
return;
}else{
const searchResult = $(this).val();
$.ajax({ url: '/account/autocomplete',
data: {
'search_result':searchResult
},
"_token": "{{ csrf_token() }}", // **** THIS LINE IS ADDED ***** //
type: 'POST',
success: function(response){
console.log(response);
}
});
}
});
I take the ajax part from this answer, so thanks to Deepak saini. If this answer solved your problem, give his answer a plus.

Error: Undefined Index while calling Ajax

The problem that I'm facing is that I'm getting an Undefined Index variable while calling Ajax.
I need to post "json" data to the "update.php" page on click of submit button. Basically, I need to capture the values in textbox and send it to the database.
so, I have created a form on the submit button, for which the code is below:
<form action="update.php" method = "post" class="form-inline">
<input type="submit" class="btn btn-info" id = "saveEdits" disabled = "disabled" onclick = "updateVal()" name="saveEdits" value="Update"/>
/form>
This submit button Calls for an UpdateVal function that captures the value on the text-boxes shown on the page and using AJAX send it to the another php page.
updateVal function is as below:
function updateVal() {
var node_list = document.getElementsByTagName('input');
var c = 0;
var fieldName = [];
var fieldText = []
var ID = [];
for (var i = 0; i < node_list.length; i++) {
var node = node_list[i];
if (node.getAttribute('type') == 'text') {
fieldName[c] = node.name;
fieldText[c] = node.value;
ID[c] = node.id;
c++;
}
}
var postData = {
fieldName: fieldName,
fieldText: fieldText,
ID: ID
};
$.ajax({
type: "post",
url: "update.php",
dataType: "json",
data: {'postData' : JSON.stringify(postData)},
contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
});
The run time data i.e value in textboxes is being captured and can be shown at console, however, when I'm posting this data on update.php, where I would be capturing the json and will update the database, I'm getting the error:
Notice: Undefined index: in update.php on line 11
Below is my update.php
<?php
$json = $_POST["postData"];
$result = json_decode($json);
var_dump($result);?>
Remove your action attribute from your form, since you send your data per Javascript/AJAX you don't need it.
What you do now is: you send the data twice, once per updateVal() and once per default submit handling of the form.
Since the form-submitted data doesn't contain a input named postData, you are getting your undefined index error.
Edit:
You stated you are not comfortable with the whole AJAX topic. Here is a nice simple answer covering the basics.
Edit2:
to listen for the response of your server add a callback to your ajax-request:
$.ajax({
type: "post",
url: "update.php",
dataType: "json",
data: {'postData' : postData},
contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
}).done(function (response, textStatus, jqXHR){
// Show an alert on response
alert(response);
});

Ajax form within eModal does not submit

I use eModal to call for a modal remotely via ajax. Although within the modal I have a form and the javascript code does not listen to it and thus it doesn't post. My codes are as follows;
eModal and Ajax for the form;
$(document).ready(function() {
// process the PROJECT UPDATE form
$('#proj-edit').submit(function(event) {
// get the form data
var formData = {
'projID' : $('input[name=projID]').val(),
'projname' : $('input[name=projname]').val(),
'projstart' : $('input[name=projstart]').val(),
'projend' : $('input[name=projend]').val(),
'projhotel' : $('input[name=projhotel]').val(),
'projcity' : $('input[name=projcity]').val(),
'projstatus' : $('#projstatus').val()
};
if (formData.projname == '' ||
formData.projstart == '' ||
formData.projend == '' ||
formData.projhotel == '' ||
formData.projcity == '') {
return false;
}
// process the form
$.ajax({
type : 'POST',
url : 'inc/prjedit.ajax.php',
data : formData,
dataType : 'json',
encode : true
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
// here we will handle errors and validation messages
if ( ! data.success) {
} else {
$('#proj-edit').trigger('reset');
swal("Success!", "Edit success!", "success");
}
})
// using the fail promise callback
.fail(function(data) {
// show any errors
console.log(data);
});
event.preventDefault();
});
$('button[id=demo]').click(function() {
var value = $(this).val();
ajaxDemo(value)
});
function ajaxDemo(value) {
var title = 'Ajax modal';
var params = {
size: eModal.size.lg,
title: title,
type: 'GET',
url: 'inc/demo.ajax.php?pID='+ value
};
eModal.setEModalOptions({
loadingHtml: '<div class="text-center"><span class="fa fa-circle-o-notch fa-spin fa-5x text-primary"></span></div>',
});
return eModal
.ajax(params);
}
});
The modal content is rather simple;
<form class="form" method="POST" action="" id="proj-edit" name="proj-edit">
// the input fields are here. Although since it is too long, I did not include them in here.
<button type="submit" class="btn btn-info" name="update-prj">Register</button>
</form>
I should note that the JavaScript code is in a different document named magic.js, the modal works although it does not submit the form. What am I missing here or what am I doing wrong?
The console log has this to say about all this;
(When eModal opens ->) XHR finished loading: GET "http://localhost/parantez/inc/demo.ajax.php?pID=301".k.cors.a.crossDomain.send # jQuery-2.1.4.min.js:4n.extend.ajax # jQuery-2.1.4.min.js:4n.fn.load # jQuery-2.1.4.min.js:4ajax # eModal.js:336ajaxDemo # magic.js:270(anonymous function) # magic.js:253n.event.dispatch # jQuery-2.1.4.min.js:3r.handle # jQuery-2.1.4.min.js:3
(When form is submitted ->) Navigated to http://localhost/
This issue has now been solved thanks to this post. Thank you very much for taking your time to answer, I highly appreciate your input. Kudos to all of you.
you are passing javascript object to php which is not valid in ajax request
use JSON.stringify() to convert json object into string and inside php use json_decode function to make object of json ...
like this
$.ajax({
type : 'POST',
url : 'inc/prjedit.ajax.php',
data : JSON.stringify(formData),
dataType : 'json',
encode : true
})
if you don't want to send json data then use
formData to send data with ajax same as from submission like that
data = new FormData();
data.append('projID', $('input[name=projID]').val());
do this for all and then simply pass data to ajax function like this
$.ajax({
url: 'http://example.com/script.php',
data: data,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
ok hope this will help ...

jquery .ajax always returns error - data being added to database

I am trying to add users to a database using jquery ajax calls. The users get added just fine to the database, but the ajax always returns with error. I'm not sure how to retrieve the specific error either. Below is my code, form, php, and jquery.
Here is the jquery
$(document).ready(function() {
//ajax call for all forms.
$('.button').click(function() {
var form = $(this).closest('form');
$.ajax({
type: "POST",
url: form.attr('data'),
dataType: 'json',
data: form.serialize(),
success: function (response) {
alert('something');
},
error: function() {
alert('fail');
}
});
});
});
Here is the PHP
<?php
include 'class_lib.php';
if(isset($_POST['username'])) {
$user = new Users;
$user->cleanInput($_POST['username'], $_POST['password']);
if($user->insertUser()) {
echo json_encode('true');
} else {
echo json_encode('false');
}
}
Here is the HTML
<div id='newUser' class='tool'>
<h3>New User</h3>
<form method='post' name='newUser' data='../php/newUser.php'>
<span>Username</span><input type='text' name='username'><br>
<span>Password</span><input type='password' name='password'>
<input type='submit' name='submit' class='button' style='visibility: hidden'>
</form>
<span class='result'> </span>
</div>
#Musa, above you mentioned
My guess is its a parsing error, try removing dataType: 'json', and see if it works
You absolutely solved the problem I was having! My ajax post request was similar to above and it just kept returning to the 'error' section. Although I checked using firebug, the status was 200(ok) and there were no errors.
removing 'dataType:json' solved this issue for me. Thanks a lot!
Turns out I had to add async: false to the $.ajax function. It wasn't getting a response back from the php.
I know this is an old question but I have just run into a weird situation like this ( jquery ajax returns success when directly executed, but returns error when attached to button, even though server response is 200 OK )
And found that having the button inside the form tags caused JQuery to always return error. Simply changing the form tags to div solved the problem.
I believe JQuery assumes the communication should be form encoded, even though you say it is application/json.
Try moving your button outside your form and see what happens...
I had the same problem and discovery there. All the time the problem is the version of my jQuery, I had use jquery version (jquery-1.10.2.js) but this version is not Ajax stablish. So, I change version for (jquery-1.8.2.js) and this miracle heppened.
Good Luck Guy!
You should specify status Code 200 for successful response.
<?php
http_response_code(200);
?>
See here: http://php.net/manual/en/function.http-response-code.php
The first solution
Try to remove dataType in your js file like that:
$(document).ready(function() {
$('.button').click(function() {
var form = $(this).closest('form');
$.ajax({
type: "POST",
url: form.attr('data'),
data: form.serialize(),
success: function (response) {
alert('something');
},
error: function() {
alert('fail');
}
});
});
});
The second solution
Send a real clean JSON to AJAX like that:
PHP
if(isset($_POST['username'])) {
$user = new Users;
$user->cleanInput($_POST['username'], $_POST['password']);
if($user->insertUser()) {
$error = [
"title"=> 'true',
"body"=> 'some info here ... '
];
echo json_encode($error);
} else {
$error = [
"title"=> 'false',
"body"=> 'some info here ... '
];
echo json_encode($error);
}
}
JavaScript
$(document).ready(function() {
$('.button').click(function() {
var form = $(this).closest('form');
$.ajax({
type: "POST",
url: form.attr('data'),
dataType: 'json',
data: form.serialize(),
success: function (data) {
let x = JSON.parse(JSON.stringify(data));
console.log(x.title);
console.log(x.body);
},
error: function() {
//code here
}
});
});
});

Categories