Codeigniter - How to reveal info after is password entered via ajax - php

I am working on a codeigniter site, the client has requested that the price columns in a datatable are hidden from view unless a user enters a correct password(which they will give out to clients over the phone).
The obvious way is to make the user login which then reveals a new table/page with prices included.
Can I achieve this via AJAX somehow?, i.e. a dialog box appears, the user enters a password, a request is sent and a new table loads with prices included?
I am a total rookie at Codeigniter, but I am learning everyday, please could someone point me in the right direction?
Thanks
Dan

actually its not really a code igniter issue, more javascript. add a controller function in ci which you call via ajax (a javascript framework like jquery is highly recommended).
to keep it simple you could add the password to the request. the controller function checks the password and if its correct it echos the price.
the javascript code might look something like that:
$.ajax({
type: "POST",
url: 'controller/function',
data: {'password': $('#password').attr(value)},
success: function(data){
$('#price').html(data);
},
});

You could achieve it via ajax: it would work something like this:
1.) User enters password in box and clicks button
2.) Click event on button triggers the following:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('POST', 'getPrices.php', true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.readState == 200)
putPricesIntable(xmlhttp.responseXML)
}
}
xmlhttp.send('password=' + 'password');

This question really has very little to do with a specific language or framework, but more a matter of how to best approach a problem. The problem in this case is displaying a column only if a password is entered correctly. So first you need to have a means of allowing the user of the website to enter the password. How this is done is again fairly irrelevant, it could be a form on the page, or it could be a separate page.
Once the password is submitted and found to be correct a session will need to be created for the user. This session is basically what will tell the page whether or not to display the column.
You would probably not want to solely rely on an ajax method as if the user has JavaScript disabled then they would never be able to see the column, instead only use JavaScript to enhance the usability of the website.

Ajax just means your login controller will return something machine readable (json/xml) rather than html.
Your controller really just needs to set a session variable.
class Login extends Controller {
function __construct() {
parent::Controller();
$this->load->model('user_m');
}
function json_login() {
$user = $this->user_m->get_user($_POST['username']);
if($user->password == md5($_POST['password'])) {
$this->session->set_userdata('username',$user->username);
print json_encode($this->user);
}
else {
print json_encode(FALSE);
}
return;
}
function logout() {
$this->session->destroy();
redirect('/theloginpage');
}
}
Assuming you are using jquery for the javascript the ajax call could work something like this:
$('#login_form').submit(function(event) {
event.preventDefault();
$.ajax({
type:"POST",
data:$(this).serialize(),
dataType:"json",
url:"/login/json_login",
success: function(data) {
if(data['username'] != null) {
$(this).append('<p>You are now logged in</p>');
reload_table_data();
}
else if(data == flase){
$(this).append('<p>Fail whale, wrong username or password</p>');
}
}
});
}
Now when displaying the data check if the 'username' has been set in the session. Also don't forget to create a logout method which destroys the session. You can return the table data as an html snippet and insert it straight into the DOM or json/xml loop though it.
The login form could be displayed anywhere on the page and there are plenty of libraries for jquery, dojo, prototype etc which will provide a dialogue box.

Related

Why my AJAX function blocks the header of PHP that I have on my page?

I am doing a program in PHP (MVC) in which I need to delete a row from the database when I click on a link on the View side. So, when I click on the link, the following ajax function it is called.
var deleteCar = function(id)
{
$.ajax({
type: "POST",
url: "http://localhost/project/car/deleteCar/" + id,
success: function(response){
}
});
}
but I do not want to send any data so it is the reason why I put it as above.
Then, in the Controller side I have the following method:
public function deleteCar($id)
{
//Here I call the function to delete the Car that I send by id. It works fine.
header('Location: http://localhost/project/car');
}
If I call directly the method deleteCar on the link without Ajax the header works properly but in the same moment I use Ajax to call it, I have to refresh the page to see the content that I have modified, I mean, that the Car have been deleted.
The code works fine, just I do not want to refresh the page after AJAX function had finished.
Thanks in advance!
I am guessing the use case is to allow the app to work when the user does not have JS enabled - so they just click the links and get a non-AJAX experience. In this case you probably want to redirect ONLY if the page was requested via GET, not POST. something like
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
header('Location: http://localhost/project/car');
}
is likely what you are looking for.
You will then have to actually remove the element representing the car from the DOM in your success handler, with something like:
var deleteCar = function(id)
{
$.ajax({
type: "POST",
url: "http://localhost/project/car/deleteCar/" + id,
success: function(response){
$('#car-row-' + id).remove();
}
});
}
(that won't be it exactly, it depends how the HTML of your page is setup how exactly you will do this).
I believe the key thing to understand here is - when your PHP function has completed it has removed the car from the database, but the browser still has the same HTML it got from the page originally. Just sending an AJAX request won't change that. If you want the HTML in the browser to change to reflect the new state of the database, you will NEED to do one of two things:
Refresh the page, so the entire thing is rebuilt by PHP based on the current database state
Use javascript to change the HTML in the browser, to reflect the changes you have made to the database state.
It is wrong on so many levels but it's difficult to put in words. It's subtle.
Long story short - think about jquery.ajax as of another virtual tab of you browser.
When you make ajax-request to the server - you create new virtual tab.
You php header could affect this virtual tab and redirect it where that header defined.
But it will redirect that virtual tab, not your current tab - if that makes sense.
What are your options? On success - make redirect with pure javascript.
success: function(response){
location.href = "http://localhost/project/car";
}
This would be the basic way to solve your problem.

Receive data on php file send by jquery function

I have the following function that is called when I click on a button to submit a form:
function dadosFormularios(preenchimentoForm){
//var path = document.location.pathname;
//alert(path);
alert(preenchimentoForm);
//window.location.href = 'wp-content/themes/template/index.php';
var qstringA = '';
//dados dos campos
var nome=document.getElementById("nome").value;
qstringA = 'nome='+ nome;
//alert(qstringA);
if(preenchimentoForm==false){
alert('Please correct the errors in the Form');
}
else{
if(preenchimentoForm==true){
window.location.href = 'index.php?'+qstringA;
return false;
}
}
}
Since I'm using this way of processing the data, how can I alert my page index.php that the data sent by the function arrived on the index? I can't use a if (isset($_POST['button']..) since I send the information by the function and not through the button of the form, right?
window.location.href = 'index.php?'+qstringA;
This line is just redirecting to index.php with a query string ?nome=nome_value.
For example. index.php?nome=nome_value
So, in your index.php You can simply get everything posted with $_GET.
Check it by doing a print_r($_GET); there.
In index.php, you can simply check
if(isset($_GET["nome"])){
//Nome is set
//Do something here
}
P.S. Although, without knowing the other circumstances or reasons behind usage of this function, it can be said that this function is just doing what a simple <form action=index.php> would have done.
P.P.S. Although you have mentioned jQuery in title and also tagged it, I am not sure this function is using any of the jQuery code. I think it is just a simple Javascript function.
If you're using jQuery, check out .ajax(). Just remember, it's asynchronous, so the results may not be what you think they are. You don't need to reload the whole page (which is what your window.location.href = 'index.php?'+qstringA; would do) just to submit information.
If you want to alert or something when the ajax call completes, you can define a function to call on a successful ajax call.
Use ajax() like :
$.ajax({
type: 'POST',
url: url,
data: data,
success: success,
dataType: dataType
});
http://api.jquery.com/jQuery.ajax/

AJAX Login form, update page content after logging in

Imagine that I have a page, with a login/logout function in the header, which works fully via AJAX.
If a user isn't logged in, I want to show him "Hey, login" and allow him to login via ajax. That's all good, and it works.
But if the user logs in, I can't access anything that DIDN'T get put on the page -- the content that is there when the user accesses the page when they are successfully logged in.
If I view the page source, elements are there, but if I do things such as $("#container").show(), .slideDown(), .html(), none of them are doing anything.
Do I have to make the user refresh the page, or store all of the code in javascript to deploy? I hope not.
I've included my Javascript for the login below, but that's not really the point. That's working. Where I say $("#all").slideDown() is the problem. Even when accessing it through the console, it won't do anything.
The problem is probably related to dying with PHP if the user isn't logged in. This code is executed in $(function() { }
Code:
/* Get the AJAX Login form Ready */
$("#login-form").submit(function() {
$("#login-error").hide();
var username = $("#username").val();
var password = $("#password").val();
if (username == "" || password == "") {
$("#login-error").show();
$("#login-error-heading").html("You've entered something wrong.");
$("#login-error-content").html("Please enter both a username and a password.");
return false;
}
$.get(
"process-login.php",
{
username:username,
password : password
}, function(data) {
if (data.success == 1) {
/* Hide the login form */
$("#login").modal("hide");
/* remove the login button */
$('#nav-login').remove();
/* add the logout button to the DOM */
$("#nav-container").append('<ul id="user-options" class="nav pull-right"><li class="divider-vertical"></li><li class="dropdown">Logged in as ' + data.username + '<b class="caret"></b><ul class="dropdown-menu"><li>Logout</li></ul></li></ul>');
$("#all").slideDown();
} else {
$("#login-error").show();
$("#login-error-heading").html("You've entered something wrong.");
if (data.success == 3) {
$("#login-error-content").html("This account is locked out because of incorrect password usage. Please try again in 10 minutes.");
} else {
$("#login-error-content").html("The username and password combination was not found.");
}
}
},
"json"
);
return false;
});
First of all, I don't think it's a good idea to use AJAX to divide your presentation logic. I'd use PHP to detect whether they're logged in first, and separate the views accordingly.
If you must use AJAX to do this, I'd suggest redirecting because that's what I like when I log in. It feels like a fresh start. If you don't want to redirect, why don't you put all of the layout changes in a separate function like:
function openSesame() {
$('div.welcome_page').slideUp();
$('div.treasure_trove').show();
}
And call it in your AJAX's success setting.
Without code, we can't do much. I would check to make sure that you aren't attempting to use a bound event on something that didn't exist at the time of the initial bind. If something doesn't exist until your AJAX callback, then you'll have to bind it after it's been loaded.
I may be wrong, but I believe the issue is that your new content, while in the DOM isn't bound to any of the jquery event handlers. The way to bind events to future elements is to use the .on() method, like so:
$("#dataTable tbody tr").on("click", function(event){
alert($(this).text());
});
As #jamie said, don't mix JS and business logic if you don't have to.
This is where you need to use a templating engine, and make an attempt at building something that resembles MVC. Check out Smarty http://www.smarty.net/, or if you really want a legit MVC framework you can go with CakePHP or Symfony.
You do not need to redirect. It's slow and not exactly enjoyable for the user.
Let's just take a pseudo-code example using Smarty:
global $smarty;
//go grab your user object
$user = PseudoUser::validate_current_user();
if( $user->login_status === true )
{
//user is logged in
$smarty->assign( 'user', $user );
$smarty->display( 'logged_in_template.tpl' );
}
else
{
//user is logged out
$smarty->display( 'logged_out_template.tpl' );
}
Bada bing bada boom.
With the js ajax login, yes, you should just refresh the page in this case. Your PHP controller should have already established what to do when the page is reloaded.
It sounds like you have a javascript error on your page. I'm assuming your logged in section is being served over HTTPS. If that's the case, and if your javascript functionality is stored in a .js file, then you might need to include your javascript file over https as well.
Using a network path reference (or protocol agnostic path) helps resolve these kinds of https vs http issues.
<script src="\\js\myJsFile.js"></script>
Edit:
You might try the $.ajax function so that you can catch any errors that do occur... This might tell you more about what is actually happening with your request.
$.ajax({
url: "process-login.php",
data: {
username: username,
password: password
},
success: function (data) {
// your function
},
error: function (jqXhr, error) { // see http://stackoverflow.com/a/1956505/296889
alert("readyState: " + jqXhr.readyState + "\nstatus: " + jqXhr.status);
alert("Response Received: " + jqXhr.responseText);
},
dataType: 'json'
});

Keeping $_session['username'] inside a ajax function

I've been messing with a script, and i'm now currently at the protection part.
Basically i cant manage to receive a $_session['username'] request.
I can not use cookies, as these can be faked. And it's a pretty big security hole.
Is this a common issue?
(The non-ajax and ajax page have the same session-id, and yes. i do use session_start();)
If you know any good comment-scripts it would be appriciated if you would like to link! c: )
edit:
The user logs in, and the session is started.
Now i'm combining a page/post with a modified comment script. (found here: http://tutorialzine.com/2010/06/simple-ajax-commenting-system/ )
What i've done is that i made it work with multiple pages, and removed the user & password thing that was provided with the script.
The request is something similar to this:
$user = $_session['username'];
if(!($data['user'] = $user)){
$errors['error'] = $_session['username']; //just to see if it can find the username
}
The above request returns a null value, but if i run "echo $_session['username'];" on the page that calls java, i get "powback".
EDIT:
i couldn't get this to work, but i made a bypass. I managed to insert $_session['username'] directly into the database with an other kind of validation. The current one was stupid... It should work properly now. Thank you!
How are you passing the session ID if not via a cookie? If you're passing it via URL (which is an even bigger security risk), make sure you pass it in the URL of your AJAX request.
Try this
var v="any variable to be passed";
$.post( "passingfile.php",{name:v},
function(data) {
Alert("Pass OK");
});
return false;
});
If you for the security try not to pass session id via url
you can use this inside any function or document ready. and change page name where you want to post value.
var postRecord = 'variable='+value;
$.post("PHP_Page_Where_you_are_using_session.php", postRecord, function(response,status, xhr){
if (status == "success") {
alert('done');
}
else if (status == "error") {
alert('Something went wrong, we are working to fix it');
}
});
on another page you can get post value within $_POST['variable'];
change name of variable to another one that you want to use.

How stop an HTML form from submitting if user is not signed in, but allow submit if user is signed in?

In my app, a user must be signed in to submit form info.
After a user clicks on the form submit button, my jQuery checks if a user is signed in.
If not signed in, then an error message pops up, requesting sign in/up.
I can now successfully stop the default action (submit).
However, how do I also allow the default action if the user is already signed in?
With my current code, the default action is also blocked if the user is signed in.
Here's my code:
jQuery('.member-only').click(function(event) {
var $element = jQuery(this);
var SignedIn;
jQuery.ajax({
type: 'POST',
url: '/ajax/member',
dataType: 'json',
success: function(data) {
var $err = jQuery('<div></div>')
.addClass('member-check')
.html(data.msg)
.css('left', $element.position().left);
SignedIn = data.SignedIn;
if (!(data.SignedIn)) { // not signed in
$element.after($err);
$err.fadeIn('slow');
return false;
}
}
});
jQuery('.member-check').live('click', function() {
jQuery(this).fadeOut('slow', function() {jQuery(this).remove(); });
});
if (!SignedIn) {
event.preventDefault();
event.stopImmediatePropagation();
return false; // block default submit
}
});
Thanks.
You need to let your JS function return false; to block the event's default action.
However, this doesn't cover users who have JS disabled or are capable to spoof it. So you should handle this gracefully in the server side as well :)
Update: As per your update, please add
alert(typeof Signedin);
alert(Signedin);
right before if(!Signedin) and tell what you get for both cases. It might be of the wrong type and/or value which is causing that you're always entering the if block and thus always returning false.
For example, a type of undefined will always cause !Signedin to evaluate true. You'd like it to be a boolean type all the time with values true or false.
This is a Moo question. Your not loged in user should have never seen a form that he can't submit in the first place.
Fix your PHP so as to not write a form that a non-logged in user can't submit.
$(form_id).submit(function(){ //triggered when user submits form
var signed_in = check_if_user_is_signed_in(); //checking
if(signed_in){ //singed in
//Do stuff
return true; //submit form
} else{ //user not signed in
//Do stuff
return false; //prevent form from being submitted
}
})
See if there is any user logged in . keep a flag for it. If flag is not set just disable the submit button . or just set the form action part using jquery only if flag is set.
Use event.preventDefault(); in your event handler. Return false only works in some cases (it's more of a workaround).
http://api.jquery.com/event.preventDefault/
https://developer.mozilla.org/en/DOM/event.preventDefault
I would also add an ajax request to check if user is logged in if your website often is opened in multiple windows.
Please review my modifications to your code. Let me know the datatype of the returned data.SignedIn; I added a console.log to return it to firebug.
My example takes action on the document being ready, as opposed to waiting for the user to interact, thus preventing the usability problem of showing the user that an ansynchronous call is happening in the background (the ajax spinner):
$(document).ready(function($){
var memberStatus;
jQuery.ajax({
type: 'POST',
url: '/ajax/member',
dataType: 'json',
success: function(data) {
console.log(data.SignedIn) //I need to know what format this is returned (Boolean: True/False?)
memberStatus = data.SignedIn;
}
});
if (memberStatus) { //if true, that means they are a member
//draw member box
} else {
$("#submitButtonID").attr('disabled',true);
}
});

Categories