RoR - optionally filling form fields based on external data - ruby

I recently started with Rails, making some good progress but hit another snag now.
I have a form that users should fill out manually. An example would be something like a human resources pages where one can enter name, address, phone number of an employee.
What I would want to do is have another field "remote_id" that is optional and when filled out, will do a REST call to a remote resource to retrieve name/address/phone number and fill out the form on the fly but not immediately submit it. A time saver, if you will.
And I have no clear idea of what that would entail in terms of form filling (the controller action for the remote call is probably not a problem), but it seems to go beyond what rails will do "out of the box". JQuery, AJX, something else? A pointer would be really appreciated!
Cheers,
Marc

The most important thing you need to check out for is the url of the remote resource and possible need to authenticate your request before having access to the resource. You might then make an ajax request to the resource. Using jQuery
$("remote_id").click(function(event){
event.preventDefault()
$.ajax("http://externalresourceurl.com", {
success: function(data) {
// fill each form field with corresponding item in the data object
$('#first_name').html($(data).first_name);
...
},
error: function() {
$('#notification-bar').text('An error occurred');
}
}
);
});

Related

Link change SESSION var

I have a listing page for an e-commerce website with various items (item_list.php). This page is generated with a PHP loop and displays each item inside a <li> element. Every item is a link to the same page, called item_details.php .
When clicking on the link i want to run a script that changes a SESSION var to a certain $id (which will be excracted from the <li> itself with .innerHTML function) and then allowing the browser to move into the next page (item_details).
This is needed so i can display the proper information about each item.
I think this is possible with Ajax but I would prefer a solution that uses JS and PHP only.
(P.S.This is for a University project and im still a PHP newbie, i tried searching for an answer for a good while but couldn't find a solution)
No JS or other client-side code can set session values, so you need either an ajax call to php, or some workaround. This is not a complete answer, but something to get you thinking and hopefully going on the project again.
The obvious answer is just include it in the link and then get it in PHP from the $_GET -array, and filter it properly.
item title
If, however, there is some reason this is not a question with an obvious answer:
1.) Closest what you're after can be achieved with a callback and an ajax call. The idea is to have the actual link with a click function, returning false so the link doesn't fire at once, which also calls an ajax post request which finally will use document.location to redirect your browser.
I strongly advice against this, as this will prevent ctrl-clicks causing a flawed user experience.
Check out some code an examples here, which you could modify. You will also need an ajax.php file which will actually set the session value. https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#product-click
2.) Now, a perhaps slightly better approach, if you truly need to do this client-side could be to use an click handler which instead of performing an ajax call or setting session directly, would be to use jQuery to set a cookie and then access this data on the item_list.php -page.
See more information and instructions here: https://www.electrictoolbox.com/jquery-cookies/
<script>
$('product_li a).click(function(){
$.cookie("li_click_data", $(this).parent().innerhtml());
return true;
});
</script>
......
<li class="product_li">your product title</li>
And in your target php file you check for the cookie. Remember, that this cookie can be set to anything, so never ever trust user data. Test and filter it in order to make sure your code is not compromised. I don't know what you want to do with this data.
$_COOKIE['li_click_data'];
3.) Finally, as the best approach, you should look at your current code, and see if there is something you can re-engineer. Here's a quick example.
You could do the following in php to save an array of the values in the session on each page load, and then get that value provided you have some kind of id or other usable identifier for your items:
// for list_items.php
foreach($item as $i) {
// Do what you normally do, but also set an array in the session.
// Presuming you have an id or some other means (here as item_id), to identify
// an item, then you can also access this array on the item_details -page.
$_SESSION['mystic_item_data_array'][$i['item_id]] = $i['thedata'];
}
// For item_details.php
$item_id = // whatever means you use to identify items, get that id.
$data_you_need = $_SESSION['mystic_item_data_array'][$item_id];
Finally.
All above ways are usable for small data like previous page, filters, keys and similar.
Basically, 1 and 2 (client-side) should only be used, if the data is actually generated client-side. If you have it in PHP already, then process it in php as well.
If your intention is to store actual html, then just regenerate that again on the other page and use one of the above ways to store the small data in case you need that.
I hope this gets you going and at least thinking of how to solve your project. Good luck!

Restful URL After Insert

I am new to RESTful URLs and I have a general question. Let's say I have a URL that I use to retrieve student records: somesite.com/students/123 which retrieves the details for the student with ID 123.
I then do the following to load an empty form for adding students: somesite.com/students/0 where zero indicates that I want to display an empty student detail form (or somesite.com/students/new).
The question I have is that after I add a student record I get back a new Id. However, if I add the record using AJAX without submitting and refreshing the page, my URL still shows somesite.com/students/0. If a user clicks refresh then the empty form is displayed again rather than the new student record.
How should that be handled?
It's not like your server can't respond to AJAX requests, right?
All you need to do is send back the newly generated ID, and then:
Use window.location = 'new_url' to redirect the user
Or even better, use history.pushState() (if available) to change the URL without any redirection (and reloading) happening at all
One thing that seems off, though, is the use of GET page/students/0 to get an "empty record", or, as I understand it, a "template" for new records. I don't think that's how RESTful services work, but then again, I'm not an expert in REST services.

Ajax security: how to be sure that data sent back to the server is generated by my code?

I apologize in advance if this question sounds naive to you.
The problem is this: I have this function and I want the callback function to send the "response" back to my server via Ajax.
function FbInviteFriends()
{
FB.ui({
method: 'apprequests',
message: 'Hi! Join me on XXXXXXX'
},
//My callback function
function(response){
//Send response to my server
}
Is there a way to check that the response I'm going to receive server-side is actually the same I got when the callback function is called and that the response hasn't been modified on the client-side by the user?
Thanks!
There's a few ways, but all of them fall on the same principle - you can never know for sure, so treat it with a grain of salt and validate.
That said, one way to put at least one usage constraint may look like this:
Page accessed: Generate a token GUID. Render it at the client.
Store in the user session the moment it was created/used, together with user profile.
Client appends the token to all Ajax posts.
Token is validated at the server; must match SessionID, user profile (if any), and maximum usage timeout.
If it fails validation, abort the operation.

Use CodeIgniter form validation in a view

I have footer view that's included on all my pages which contains a form. I would like to be able to make use of CI's form validation library to validate the form. Is that possible?
Currently the form posts back to the current page using the PHP_SELF environment variable. I don't want to get it to post to a controller because when validation fails it loads the controller name in the address bar, which is not the desired behaviour.
Any suggestions gratefully received.
Thanks,
Gaz
One way, whilst far from ideal, would be to create a "contact" function in every controller. This could be in the form of a library/helper.
CI doesn't natively let you call one controller from another, although I believe there are extensions that enable this.
Another option would be an AJAX call instead, which would allow you to post to a generic controller, validate etc whilst remaining on the current page.
In this use case, I would definitely go for an AJAX call to a generic controller. This allows you to show errors even before submitting in the origin page.
Another way (slightly more complex), involves posting your form data to a generic controller method, passing it a hidden input containing the current URL.
The generic controller method handling your form can then redirect to the page on which the user submitted the form, passing it the validation errors or a success message using flash session variables: $this->session->set_flashdata('errors',validation_errors()) might do the trick (untested)
The good thing about this is that you can use the generic form-handling method for both the ajax case (suppressing the redirect) and the non-ajax case
AJAX would be best, just like everyone else says.
I would redirect the form to one function in one controller, you could make a controller just for the form itself. Then have a hidden value with the return URL. As far as errors go you could send them back with flashdata.
Just remember to never copy paste code, it a bad practice and guarantees bugs.
//make sure you load the proper model
if ($this->form_validation->run() == FALSE){
// invalid
$redirect = $this->input->post('url');
$this->session->set_flashdata('errors',validation_errors());
redirect($redirect);
} else {
/*
success, do what you want here
*/
redirect('send them where ever');
}

How do I prevent tampering with AJAX process page?

I am using Ajax for processing with JQUERY. The Data_string is sent to my process.php page, where it is saved.
Issue: right now anyone can directly type example.com/process.php to access my process page, or type example.com/process.php/var1=foo1&var2=foo2 to emulate a form submission. How do I prevent this from happening?
Also, in the Ajax code I specified POST. What is the difference here between POST and GET?
First of all submit your AJAX form via POST and on a server side make sure that request come within same domain and is called via AJAX.
I have couple of functions in my library for this task
function valid_referer()
{
if(isset($_SERVER['HTTP_REFERER']))
return parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) == $_SERVER['SERVER_NAME'];
else
return false;
}
function is_ajax()
{
$key = 'HTTP_X_REQUESTED_WITH';
return isset($_SERVER[$key]) && strtolower($_SERVER[$key]) == 'xmlhttprequest';
}
You might read this post regarding difference between post and get
While as Jason LeBrun says it is pretty much impossible to prevent people simulating a form submission, you can at least stop the casual attempts to. Along with implementing Nazariy's suggestions (which are both easy to get round if you really want to), you could also generate some unique value on the server side (i'll call it a token), which gets inserted into the same page as your Ajax. The Ajax would would then pass this token in with your other arguments to the process.php page whereupon you can check this token is valid.
UPDATE
see this question with regards to the token
anti-CSRF token and Javascript
You can not prevent people from manually emulating the submission of form data on your website. You can make it arbitrarily more difficult, but you won't be able to prevent it completely.

Resources