Laravel 4 Search Query with Ajax - javascript

I'm trying to have a search option for users to fill in and search multiple tables for orders, commissions, etc without having to reload the page. Never used AJAX before so if anyone could point out where I'm going wrong or help me get this working it would be very much appreciated! Right now when I click on the submit button nothing happens except for getting an 500 (Internal Server Error) message.
Here is my View (home):
<div class="large-6 columns">
{{Form::open( array('route' => 'search', 'method' => 'post', 'id' => 'search_form'))}}
{{ Form::select('search_table',
array(
'select' => 'Search...',
'commissions' => 'Search commissions',
'estimates' => 'Search estimates',
'orders' => 'Search orders',
'warranties' => 'Search warranties',
), null, array('id' => 'search_table')) }}
<div class="search_box" id="search_column_div">
<!-- Search_column select goes here -->
</div>
<div id="search_input_div">
<!-- Search_input text field goes here -->
</div>
{{ Form::submit('Search', array('id' => 'search_button','class' => 'button expand radius search_button no_display'))}}
{{ Form::close() }}
</div>
<div id="search_results_div">
</div>
</div>
Because the search has a lot of variables but I didn't want to make it take up a lot of space I have JS insert the next part of the query based on their previous selection. So they will start with the ability to pick a table to search, then a column, then they will have an input field to write what exactly they are searching for.
JS (where my problem probably is):
$(document).ready(function($){
$('#search_form').on('submit', function(){
$.post(
$(this).prop('action'),{
"search_table": $('#search_table').val(),
"search_column": $('#search_column').val(),
"search_input": $('#search_input').val(),
},
function(data){
$('#search_results_div').html(data);
},
'json'
);
return false;
});
});
Controller:
public function searchPost(){
$search_table = Input::get('search_table');
$search_column = Input::get('search_column');
$search_input = Input::get('search_input');
$search = DB::table($search_table)->where($search_column, 'LIKE', "%{$search_input}%")->get();
return $search;
}
And the Route:
/*Search Page for Ajax*/
Route::post('/search', array(
'as' => 'search',
'uses' => 'HomeController#searchPost'
));
Thanks again for your time and help! Please feel free to make suggestions for best practices!

Well, for a start, you're didn't say what the problem was, but just looking at that code, you're setting HomeController#searchPost as the action for your post method, but your search method is actually HomeController#search.
You're also using the wrong variables. You're passing in search_table, search_column and search_input as the keys in your Javascript, but you're trying to read table_searched, column_searched and input_searched - so all those variables will always be nulls in your server-side code.
Your $search query will also always fail. '%LIKE%' is not valid SQL - the % need to go around the search term. What you really want is:
$search = DB::table($search_table)->where($search_column, 'LIKE', "%{$search_input}%")->get();
Try fixing all of those and see if it deals with your problem :)

It looks like there are several issues. I see that you've already made some changes but there are some more problems you need to fix. Your AJAX request is using a POST request but your route is listening for a GET request. Even once that's fixed, you'll need to included some sort of error handling or validation for the controller and database query before returning the result. After that you need to look at how you're handling what is being returned by the AJAX request.
The 500 error you're getting means that there's a problem with your server-side code. More than likely something isn't "wired-up" correctly. If you're having troubles getting a detailed error report, use "console.log()" to output what's returned via AJAX to the dev console. From there you can debug the problem.

Related

POST request using Mechanize to pull GUID from .aspx website

there is a website called https://www.guidgenerator.com/online-guid-generator.aspx which generates a global unique identifier. I'm trying to use perl's Mechanize to post to the site to pull that guid. I realize that this is based on javascript but was wondering if I could issue the proper post to pull the number. I trace it from my browser and I've got the headers all in the request but the returned html doesn't contain the guid.
This is from a successful run:
<textarea name="txtResults" rows="2" cols="20" id="txtResults" style="font-family:Courier New,Courier,monospace;font-size:Larger;font-weight:bold;height:152px;width:421px;">qk5DF22bhkm4C2AwZ5OcZw==</textarea>
and this is from my script:
<textarea name="txtResults" rows="2" cols="20" id="txtResults" style="font-family:Courier New,Courier,monospace;font-size:Larger;font-weight:bold;height:152px;width:421px;"></textarea>
This is the form within the page:
In my script I dump out the form and the input fields required with the following:
my #forms = $mech->forms;
foreach my $form (#forms) {
my #inputfields = $form->param;
print Dumper \#inputfields;
}
resulting in
$VAR1 = [
'__EVENTTARGET',
'__EVENTARGUMENT',
'__LASTFOCUS',
'__VIEWSTATE',
'__VIEWSTATEGENERATOR',
'__EVENTVALIDATION',
'txtCount',
'chkUppercase',
'chkBrackets',
'chkHypens',
'chkBase64',
'chkRFC7515',
'chkURL',
'LocalTimestampValue',
'btnGenerate',
'txtResults'
];
and this is the post
my $mainpage = "https://www.guidgenerator.com/online-guid-generator.aspx";
$mech->post( "$mainpage",
fields => {
'txtCount' => "1",
'chkBase64' => "on",
'LocalTimestampValue' => "Date%28%29.getTime%28%29",
'btnGenerate' => "Generate+some+GUIDs%21",
'txtResults' => "",
'__EVENTTARGET' => 'on',
'__EVENTARGUMENT', => 'on',
'__LASTFOCUS', => 'on',
'__VIEWSTATEGENERATOR' => "247C709F",
'__VIEWSTATE' => 'on',
'__EVENTVALIDATION' => 'on',
'chkUppercase' => 'off',
'chkBrackets' => 'off',
'chkHypens' => 'off',
'chkRFC7515' => 'off',
'chkURL' => 'off',
},
);
When I do the trace on the website I get the headers but there is another tab called Payload. That contains most of the fields listed above. I try to input these fields into the POST but not sure if I should be doing this differently or it doesn't matter because its javascript?
I know this is a lot of information. I'm not even sure that perl's mechanize can pull this information. Any help would be appreciated. Please let me know any other data you want me to post here.
You can use Mech's built-in stuff to do this. There is no need to submit any extra fields or headers.
use strict;
use warnings;
use feature 'say';
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('https://www.guidgenerator.com/online-guid-generator.aspx');
$mech->field( txtCount => 10 );
$mech->click;
say $mech->value('txtResults');
This will output something like:
$ perl mech.pl
211b3cad1665483ca303360bdbda0c61
ecc3348d83cb4bb5bdcb11c6148c5ae1
0a3f2fe5748946a1888a4a5bde8ef2e6
acb26deb9fda4411aa64638cdd1ec5f1
2afe609c355b4a10b6a0ae8c74d3aef1
30fd89ab170147cfb24f131346a203e3
2301d258e1d045aa8f0682f2ea14464c
f064507ca3e14a4eb860b0a30ba096ed
9a42b15d5c79420c921dcc07c306459b
5bea2e345f75453caaf795681963866a
The crux here was that you cannot use $mech->submit as that wouldn't submit the value of the submit button. That's a bit annoying. So instead, you have to use $mech->click, which pretends the default form's default submit button was clicked, hence submitting that value as well. That's just how buttons work on forms, and in this case the backend checks the value to see which one was clicked.
You can then use $mech->value to get the field value out. You'd probably want to split it to process it further.
The JavaScript in this page is actually completely irrelevant to the functionality. All it does is save and restore the settings you've chosen in a cookie, so that when you come back the same checkboxes will be ticked. That's nice, but nowadays probably better done with local storage on the frontend side. However you don't have to deal with the JS at all to crawl this page. The main functionality is backend side.
You might also be interested in $mech->dump_forms, which is a nice debugging aid that prints out all the forms with fields and values. Another good debugging aid when working with Mech (or any LWP based class) is LWP::ConsoleLogger::Everywhere. That's what I used to compare my program's request with my browser's one to find the missing button form field.
Disclaimer: I am a maintainer of WWW::Mechanize and I wrote LWP::ConsoleLogger::Everywhere.

Sending data between two php functions using ajax

I am currently working on user verification on the website. What I am trying to do is to ask the user to input the credentials and push the "send confirmation" button, then send the code to the user using something (SMS or messenger) and make the user insert this code into the field and click "confirm" to check if it is correct. The Issue that I am facing right now is how do I pass the correct code from one PHP function (which I currently call using ajax) to the other. For obvious reasons of security I can't just send the code through JavaScript, but you are welcome to prove me wrong :) . Here is the HTML that I have:
<button type="button" onclick="send_sms()">Send verification</button><br>
Code from the SMS: <input type="text" id="fi" value=""><br>
<p id="res"></p>
<button type="button" onclick="check_sms()">Check</button>
<script>
function check_sms() {
jQuery.post(
ajax_object.ajax_url,
{action: "confirm_sms",
code: document.getElementById("fi").value
},
function( response ) {
// showing the result of confirmation
document.getElementById("res").textContent = response;
}
);
}
function send_sms() {
jQuery.post(
ajax_object.ajax_url,
{action: "send_sms",
phone: document.getElementById("phone").value
},
function( response ) {
// temporarely showing the code in console (shold not be there 🤫)
console.log("not an sms, but the code for now is " + response);
}
);
}
</script>
Now, in functions.php I have:
add_action( 'wp_ajax_confirm_sms', 'confirm_sms' );
function confirm_sms() {
$code = $_POST['code'];
// yes, I know that it will not output anything after, but it is beside the point anyway.
// and yes, I will not send the real code as the output of the function (just for testing)
wp_send_json($_SESSION['real_sms_code']);
if ($code != $_SESSION['real_sms_code']) {
wp_send_json('The code is not correct, please, try again');
return;
}
wp_send_json("Nice code, awesome balls!");
}
add_action( 'wp_ajax_send_sms', 'send_sms' );
function send_sms() {
// my attempt at storing the code, not the same session as I suspected, but was worth a try
$_SESSION['real_sms_code'] = strval(rand(100000, 999999));
wp_send_json($_SESSION['real_sms_code']);
}
The issue here is that the confirm_sms function always outputs 'None' (It should be the code set by the other function) and I can't figure out how to fix that. I was thinking about just creating a file containing this code, but
a) It is unreliable
b) I can't (reliably) identify which user the code belongs to since this is before they are registered
c) This may be slow with many users
There is got to be a better way of handling this.
So I have figured out the issue: I have copied the $_SESSION part from somewhere, but the guy there never mentioned that you have to use session_start(); before the functions in PHP. Now it works flawlessly. Kinda frustrating that I have lost a day because of someone not posting the whole code, please don't be like that :)

Ajax requests, database and security

This post is more a question than an actual issue with code.
So for a long time when I had to display for example a list of items from database, I used to display the Id (primary key in the table) directly in the HTML like this for example :
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
So like this when I wanted to do an Ajax request of the current clicked item, it was easy because I just had to retrieve the attribute from the html like this :
$.ajax({
url: '/api/Item/'+$(this).attr('id'),
type: 'GET',
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
That's only after browsing a lot of websites that I noticed that nobody display the primary key (Id) directly in the HTML. But somehow they could still do ajax request to the API using the Id of the clicked item. So my question is : How can I get the current clicked Id to do my ajax request without displaying anywhere. I mean how does these websites manage to do that ? Maybe they get list from server that they use in the client then ? But it still does not explain how they manage to get the current clicked Id.
Appreciate your thoughts and suggestions on this.
Example of website : https://www.toneden.io/
The chat at the bottom right when connected see network and web browser console.
To get response from the server, you have to request something. In this case, you are saying i don't want to display primary key anyware in html side and get result from server. my suggestion on this, In php > you can use binary number instead of primary key and convert back to number and use acc. to requirements. Example :- decbin() and bindec()
There's nothing wrong with displaying an id. I've appended the database id such as id="game_1281" in cases where I only want to refer to the DOM in response to a server push update. Another option is to use a data attribute like so: data-id="1281". This allows you to get the value without any messy parsing before sending it to the server.
Referencing a unique id is not a security issue. Just make sure you are doing the appropriate server-side checks to ensure that the action taken is possible for that user based on various constraints and privileges.

looking for method of inserting Amazon data into php form

I have been looking around for help trying to fix my old system of inserting returned search results from Amazon into a form.
The way it worked was I have a PHP based form for saving book information. The user typed in the ISBN and clicked a button, then a JavaScript program generated a signed request that returned the data in XML form. The JS program used an xslt file that converted it to a json type of results that then was inserted into the form fields. The reason it all stopped working is Amazon stopped supporting any xslt requests to their server. I have been able to substitute with googleapis, but I would rather use Amazon if possible.
EDIT:
I'm looking at it a new way. The original way will never work again, thanks to Amazon's changes. I have found a good start on this blog: http://anchetawern.github.io/blog/2013/02/10/getting-started-with-amazon-product-advertising-api/. That lead me to making this search.php:
require_once('amazon_product_api_class.php');
$public = //amazon public key here
$private = //amazon private/secret key here
$site = 'com'; //amazon region
$affiliate_id = //amazon affiliate id
$itemID = $_POST["ASIN"];
$amazon = $amazon = new AmazonProductAPI($public, $private, $site, $affiliate_id);
$single = array(
'Operation' => 'ItemLookup',
'ItemId' => $ASIN, //'0718177517'
'ResponseGroup' => 'Medium,ItemAttributes,OfferFull'
);
$result = $amazon->queryAmazon($single);
$json = json_encode($result);
$array = json_decode($json, true);
echo json_encode($result);
This works exactly like I need, except it's in php, so I can't use it to fill in the form blanks. The sequence of events needs to be like this:
User opens PHP generated HTML book entry form and enters ISBN# into text field and clicks search button -> ISBN# is sent to some search function -> search function returns results -> results sorted and entered back into the original book entry form -> user then continues to fill out form and saves it when done.
What I did was call search.php from a jquery script using this is a function:
$.post('search.php', {SRCHISBN: srchASIN}, function(response) {
var items = JSON.parse(response);
$.each(items.Items, function () {
$("#edit-field-book-title-und-0-asin").val(this.ASIN);
});
$('#example').html(response);
});
The $('#example').html(response); prints out (simplified version):
Array
(
[Items] => Array
(
[Item] => Array
(
[ASIN] => 0718177517
[ItemAttributes] => Array
(
[Author] => Mark Owen With Kevin Maurer
[Binding] => Hardcover
[EAN] => 9780718177515
[ISBN] => 0718177517
[Label] => PENGUIN BOOKS
[Manufacturer] => PENGUIN BOOKS
[ProductGroup] => Book
[ProductTypeName] => ABIS_BOOK
[PublicationDate] => 2012-01-01
[Publisher] => PENGUIN BOOKS
[Studio] => PENGUIN BOOKS
[Title] => No Easy Day
)
)
)
)
So far the only one I can get to work is $("#edit-field-book-title-und-0-asin").val(this.ASIN). I can't seem to figure out how to get further into the returned results. I need to pull out the Author, EAN, Title, etc., and insert them into my form. Maybe I don't even need the the $.each? Is there a simpler way to access the data directly from items = JSON.parse(response)?
I think I might have found an answer. I don't know if this is the best or most efficient way of doing it though.
$.post('search.php', {SRCHISBN: srchASIN}, function(response) {
var parsedJSON = $.parseJSON(response);
$("#edit-field-book-title-und-0-asin").val(parsedJSON.Items.Item.ASIN);
$("#edit-field-author-und-0-value").val(parsedJSON.Items.Item.ItemAttributes.Author);
$("#edit-title").val(parsedJSON.Items.Item.ItemAttributes.Title);
$("#edit-field-publisher-und-0-value").val(parsedJSON.Items.Item.ItemAttributes.Publisher);
});
This does take the items from the returned Amazon data in json format, then inserts them into the blanks on my book form, like #edit-title. It works, but like I said, I don't know if it the best way. The items I need out of the returned data will always be the same, so I don't think a for next, or each loop is needed. The list of form items is longer that what I'm showing here. I just cut it short to save space.

POST facebook feed using graph api advanced parameters

Has anyone been able to customize a Facebook feed post by using parameters like from, to, actions, etc, as documented here:
http://developers.facebook.com/docs/reference/api/post/
For example HTTP POSTing this string:
message=mymessage&access_token=mytokenstring
to
https://graph.facebook.com/123456/feed works fine and posts to your feed. Similarly parameters like picture, description, etc all work too.
But I can't get the more complicated parameters to work. Does anyone know the proper formatting? My guess below, and similar combinations, doesn't work at the moment:
message=mymessage&access_token=mytokenstring&from={"name":"Bob", "id":"123456"}
thanks for any help!
This is how I used PHP to implement actions:
$attachment = array
(
'access_token'=>$facebook->getAccessToken(),
'message' => 'I\'ve been testing my IQ!',
'name' => 'IC-YOUR-IQ',
'caption' => 'This is my result:',
'link' => 'http://apps.facebook.com/icyouriq/',
'actions' => array('name'=>'Sweet FA','link'=>'http://www.facebookanswers.co.uk'),
'description' => $cmsg,
'picture' => 'http://www.facebookanswers.co.uk/img/misc/iq.jpg'
);
The key line is the "actions" element. From my experiments I was only ever able to get one action to appear. But hopefully you get the picture.
The full article I wrote on this can be found here:
http://facebookanswers.co.uk/?p=270
hmm that makes sense but doesn't appear to work. In the end they are expecting json I guess. Also I don't think 'from' or 'to' tags are supported when creating a post, but actions are. This string worked:
&actions=[{"name":"My%20Link","link":"http%3A%2F%2Fmysite.com%2Fdownload.html"}]
close, but it should be:
from[name]="Bob"&from[id]=123456
so mainKey[subKey]=value&mainKey[subKey2]=value2
In javascript you can use the function ui , with the feed method, There is an example here:
http://aplicacionesfacebookparadummies.blogspot.com/2011/09/compartir-en-aplicaciones-facebook.html
fields=posts.fields(message,actions)

Categories