codeigniter ajax not setting sessions asynchronously - php

I am new to codeigniter ajax and i have a problem with sessions.My sessions are not being set and unset
asynchronously and i have to refresh the page just to see the changes.
view/header:
<?php
if(!empty($product)){
$pid=$product[0]['product_id'];
}
?>
<script>
$(document).ready(function(){
if($('.add_to_basket').find('img')){
$('.add_to_basket').click(function(){
var message=$('#badgemessage');
$('#msgcart').append(message);
message.show('slow');
var trigger=$(this);
var param=trigger.attr("rel");
var item=param.split("_");
$.ajax({
type: 'POST',
url: '<?= base_url()."cart_c/myfunk/".$pid?>',
data: { id: item[0], job: item[1] },
dataType:'json',
success: function(data) {
console.log(data);
},
error:function(){
alert("error");
}
});
return false;
});
}
});
</script>
model/basket_model:
<?php
class Basket_model extends CI_Model{
function activeButton($sess_id){
$e=$this->session->userdata('basket');
if(isset($e[$sess_id])){
$id=0;
$label="<img src='".base_url()."images/remove.png' />";
}else{
$id=1;
$label="<img src='".base_url()."images/add.png' />";
}
$out="<a href='#' class='add_to_basket' rel='".$sess_id."_".$id."'>".$label."</a>";
return $out;
}
function setItem($pide,$qty=1){
$e=$this->session->userdata('basket');
if(isset($e)){
$e[$pide]['qty']=$qty;
$this->session->set_userdata('basket',$e);
}else{
$arr=array($pide=>array('qty'=>$qty));
$this->session->set_userdata('basket',$arr);
}
}
function removeItem($pide,$qty=null){
$e= $this->session->userdata('basket');
if($qty != null && $qty < $e[$pide]['qty']){
$e[$pide]['qty']=($e[$pide]['qty']-$qty);
$this->session->set_userdata('basket',$e);
}else{
$e[$pide]=null;
unset($e[$pide]);
$this->session->set_userdata('basket',$e);
}
}
}
?>
controller/cart_c:
<?php
class Cart_c extends CI_Controller{
function __construct(){
parent::__construct();
$this->load->model('catalogue_model');
$this->load->model('products_model');
$this->load->model('basket_model');
}
function myfunk($id){
if(isset($_POST['id']) && isset($_POST['job']))
$out=array();
$pid=$_POST['id'];
$job=$_POST['job'];
if(!empty($id)){
switch($job){
case 0:
$this->basket_model->removeItem($pid);
$out['job']=1;
break;
case 1:
$this->basket_model->setItem($pid);
$out['job']=0;
break;
}
echo json_encode($out);
}
}
}
?>
controller/products:
<?php
class Products extends CI_Controller{
function __construct(){
parent::__construct();
$this->load->model('catalogue_model');
$this->load->model('products_model');
$this->load->model('basket_model');
}
function product($id){
$kitties['cats']=$this->catalogue_model->get_categories();
$data['product']=$this->products_model->get_product($id);
$data['active_button']=$this->basket_model->activeButton($id);
$this->load->view('header',$data);
$this->load->view('sidebar',$kitties);
$this->load->view('product',$data);
$this->load->view('footer');
}
}
?>
view/product:
<div class="contentwrap">
<div id="content_area">
<?php
$e=$this->session->userdata('basket');
print_r($e);
if(!empty($product)){
foreach($product as $p){
?>
<h1><?=$p['product_name']?></h1>
<div id="product_image">
<img src="<?=base_url()?>/images/<?=$p['image']?>" width="400" height="300" />
</div>
<div id="product_desc">
<?=$p['description']?>
<br><br>
<?=$active_button?>
</div>
<?php
}
}else{
echo "Product unavailable";
}?>
</div>
</div>
The problem is my $active_button in the product view is not changing asynchronously but the sessions are being set and unset
i can see items being pushed into and out of the session array when i refresh the page.When i hit the button my chrome console displays: object{job:0}

ok after looking and studying youre code. you can implement what you want by retrieving the button again when making your AJAX call. The way to retrieve it is by calling that model again, then using jquery to replace the current button. Try the following:
Controller - Cart_c
function myfunk($id) {
if (isset($_POST['id']) && isset($_POST['job'])) {
$out = array();
$pid = $_POST['id'];
$job = $_POST['job'];
if (!empty($id)) {
switch ($job) {
case 0:
$this->basket_model->removeItem($pid);
$out['active_button'] = $this->basket_model->activeButton($pid);
break;
case 1:
$this->basket_model->setItem($pid);
$out['active_button'] = $this->basket_model->activeButton($pid);
break;
}
echo json_encode($out);
}
}
}
JS in header view:
<script>
$(document).ready(function() {
function add_to_basket($this) {
var param = $this.attr("rel");
var item = param.split("_");
$.ajax({
type: 'POST',
url: '<?= base_url() . "cart_c/myfunk/" . $pid ?>',
data: {id: item[0], job: item[1]},
dataType: 'json',
success: function(data) {
console.log(data);
$this.replaceWith(data.active_button);
$('.add_to_basket').click(function() {
add_to_basket($(this));
});
},
error: function() {
alert("error");
}
});
return false;
}
$('.add_to_basket').click(function() {
add_to_basket($(this));
});
});
</script>

Ok I think perhaps we should start by discussing the proper flow of your app. Assuming that your URL looks something like this Products/product/10 and you intially load the page, your function runs providing you with right button and products as expected.. Lets say in this case product 10 does not exist in the session/cart so you see the ADD image button come up.. All good.. Now, when you click add, and from what you are saying, it adds the product to the session/cart, and you get a return JSON of ‘job:0’. So far it works as expected from the code I am seeing. A return of job:0 means that you ran the setItem function. Now the problem you are saying is that the view “is not changing asynchronously”. By this, do you mean that you expect the page to reload and run the function again so that the image can now say “remove”?

Related

Display ajax posted array in codeigniter view

I need to display objects of an array in a view that has been posted to controller from another view.
Jquery ajax call
details is an array with few objects
$(document).ready(function () { // working
$("#nxt").click(function() {
var tmp = details;
var more_details = JSON.stringify(tmp);
$.ajax({
type: "POST",
url: 'http://localhost/application/index.php/Welcome/detailsLoad',
data: {more_details : more_details },
success : function(){
console.log('Posted');
location.href="http://localhost/application/index.php/Welcome/detailsLoad"
},
error: function(){
alert('Error!');
}
});
});
});
Controller
public function detailsLoad()
{
$moreDetails= $this->input->post('more_details');
$this->load->view('simulation',$moreDetails);
}
View
<?php
foreach($moreDetails['more_details'] as $result) {
echo $result['object1'], '<br>';
echo $result['object2'], '<br>';
}
?>
help me to modify and fix this code
If you want to data from the ajax call to move from your controller to your view you should set the name of the variable to be used inside your view:
$data = [];
$data['moreDetails'] = $this->input->post('more_details');
$this->load->view('simulation',$data);
Then you can use the variable $moreDetails inside the view:
foreach ($moreDetails as $result) {
echo $result['object1'], '<br>';
echo $result['object2'], '<br>';
}

store form data in mysql database using ajax in codeigniter

Edit:
It was a problem with localhost and I think with the htaccess file. Although I couldn't make it in localhost, the script is running fine on the web host.
I want to store my form data in to the database using ajax in codeigniter. The problem is that everything is fine, except I'm getting a 500 server internal error.
My contoller:
public function order()
{
$order = $this->main_model->order($_POST);
if($order)
{
return true;
}
else
{
return false;
}
}
my model:
function order($options = array())
{
$options = array(
'client_Name' => $this->input->post('oName'),
'client_Phone' => $this->input->post('oPhone')
);
$this->db->insert('md_orders', $options);
return $this->db->insert_id();
}
and of course I'm using stepsForm script and this is the js code I have:
var theForm = document.getElementById( 'theForm' );
new stepsForm( theForm, {
onSubmit : function( form ) {
var form_data = {
oName: $('#oName').val(),
oPhone: $('#oPhone').val(),
};
$.ajax({
url: "<?php echo base_url() . 'main/order/'; ?>",
type: 'POST',
data: form_data,
success: function(msg) {
alert(msg);
}
});
}
} );
and this is the HTML code:
<form id="theForm" class="simform" autocomplete="off">
<ol class="questions" id="questions">
<li>
<span><label for="oName">Your name:</label></span>
<input class="finput" id="oName" name="oName" type="text"/>
</li>
<li>
<span><label for="oPhone">Your Phone Number:</label></span>
<input class="finput ltr" data-validate="number" id="oPhone" name="oPhone" type="text"/>
</li>
</ol>
</form>
and the error I'm getting is :
POST http://localhost/123/main/order/ 500 (Internal Server Error)
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
and nothing is stored in the database. What am I doing wrong?!
Try to check your input in controller before send it to model, although it is not mandatory. In your model you need just feed of your array. So you can just set name of parameter.
Your model something like this:
public function order($options) {
$data = array();
$data['client_Name'] = $options['oName'];
$data['client_Phone'] = $options['oPhone'];
$this->db->insert('md_orders', $data);
if($this->db->affected_rows() > 0) {
return $this->db->insert_id();
else {
return false;
}
}
Your controller something like this:
public function order() {
$order = $this->main_model->order($this->input->post());
if( $order !== false ) {
echo "Inserted!";
} else {
echo "Not inserted!";//These are your ajax success function msg parameter
}
}
Also, I can't see the logic of form parameter inside onSubmit property's function( form ). Maybe you could remove it?
In your view,place the following code in your script,please...
one_field = $('#one_field').val();
second_field = $('#second_field').val();
$.ajax({
type:"post",
data:{one_field:one_field, second_field:second_field},
url :'<?=base_url("directory/controller_name/your_method_name")?>',
success: function(data)
{
alert("success");
}
});
Now the place the following in your controller.
function your_method_name()
{
$your_data = array(
"table_field_1" => $this->input->post('one_field'),
"table_field_2" => $this->input->post('second_field')
);
$last_id = $this->your_model->insert_data_function($your_data);
if(isset($last_id)
{
//your code
}
else
{
//your code
}
}
In your Model,place the following.
public function insert_data_function($your_data)
{
$this->db->insert("your_table",$your_data);
return $this->db->insert_id(); //will return last id
}
Instead of using base_url() in your JS, you should try and use site_url()
Your CodeIgniter website runs through the index.php file.
The base_url() function will return the URL to your base directory.
The site_url() will return the URL to your index.php file.
Your form is trying to access "http://localhost/123/main/order" when it should be trying "http://localhost/123/index.php/main/order"
Hope this helps.
Edit
You should also have a look at the form helper.
https://ellislab.com/codeIgniter/user-guide/helpers/form_helper.html

Codeigniter Ajax Post not working

Hello guys im trying to create a simple voting for comments like and dislike but i want to do that with jquery Ajax so i don't want to refresh the page when someone like it.
And this is my jquery code
$(document).ready(function(){
$(".vote-btn").click(function() {
var voteId = this.id;
var upOrDown = voteId.split('_');
// alert(upOrDown); = provides --> id,name
// var all = 'voteId:'+upOrDown[0]+ ',upOrDown:' +upOrDown[1];
// alert(all);
$.ajax({
type: "POST",
url: "http://localhost/Dropbox/cipr/index.php/demo",
cache: false,
dataType:'json',
data:{'voteId='+upOrDown[0] + '&upOrDown=' +upOrDown[1],
success: function(response){
try{
if(response=='true'){
var newValue = parseInt($("#"+voteId+'_result').text()) + 1;
$("#"+voteId+'_result').html(newValue);
}else{
alert('Sorry Unable to update..');
}
}catch(e) {
alert('Exception while request..');
}
},
error: function(){
alert('Error while request..');
}
});
});
});
this is my Controller code Demo.php
<?php
class Demo extends CI_Controller {
function Demo(){
parent::Controller();
$this->load->model('sygjerimet');
}
public function index(){
$voteId= $this->input->post('voteId');
$upOrDown= $this->input->post('upOrDown');
$status ="false";
$updateRecords = 0;
if($upOrDown=='voteup' || true){
$updateRecords = $this->sygjerimet->updateUpVote($voteId);
}else{
$updateRecords = $this->sygjerimet->updateDownVote($voteId);
}
if($updateRecords>0){
$status = "true";
}
echo $status;
}
And this is my model code sygjerimet.php
<?php
Class Sygjerimet extends CI_Model
{
function shtoSygjerimin()
{
$permbajtja = $this->input->post('idea');
$data = array(
'permbajtja' => $permbajtja
);
$this->db->insert('pr_sygjerimet', $data);
}
function updateDownVote($voteId){
$sql = "UPDATE pr_sygjerimet set vote_down = vote_down+1 WHERE ID =?";
$this->db->query($sql, array($voteId));
return $this->db->affected_rows();
}
function updateUpVote($voteId){
$sql = "UPDATE pr_sygjerimet set vote_up = vote_up+1 WHERE ID =?";
$this->db->query($sql, array($voteId));
return $this->db->affected_rows();
}
}
And this is my view Code
<?php
$query = $this->db->query('SELECT * FROM pr_sygjerimet');
foreach ($query->result() as $row)
{
echo "<div class='sygjerimi'>";
echo htmlspecialchars($row->permbajtja);
if(!$log_in):
echo '<br>';
echo ' <button id="'.$row->ID.'_votedown" class="vote-btn"><i class="fa fa-thumbs-down">'.htmlentities($row->vote_down).'</i></button> ';
echo ' <button id="'.$row->ID.'_voteup" class="vote-btn"><i class="fa fa-thumbs-up">'.htmlentities($row->vote_up).'</i></button> ';
endif;
echo "</div>";
}
?>
That's it guys when i cilck vote it executes this code
alert('Error while request..');
If anyone can help that would be Great :) Thanks
Most likely this is the CI CSRF protection; if you use POST, CI automatically checks the CSRF hidden field and since you are building the ajax post yourself, it's not sending the hidden field so it bags on you.
Check the several $config['csrf_*'] lines in your config/config.php file. You can disable (but I don't recommend this). You can also serialize the form in jQuery and send that, and it should work for you, and keep you a bit more protected from CSRF attacks.
Just to rule this in or out, you can disable the 'csrf_protection' and if it works then, you can enable it again and then change your javascript to serialize the form and use that as your data with your ajax post.
try this
$.ajax({
//pull the toke csrf like this
data:{'<?php echo $this->security->get_csrf_token_name();?>':'<?php echo $this->security->get_csrf_hash();?>'},
});

Calling php class function in javascript (ajax)

I was wondering if is there any good practices to call method from php class with Javascript, by the way of Ajax.
This is my current "style" to execute it.
(The method in the class are only here for example)
PHP side :
<?php
if(isset($_POST['action']) && $_POST['action'] != null)
{
extract($_POST);
if($action)
{
$ajaxCommand = new EleveUpdate();
if(method_exists($ajaxCommand, $action))
{
$reponse = call_user_func(array($ajaxCommand, $action),$_POST);
echo $reponse;
exit(0);
}
else
{
throw new Exception("Cette méthode n'existe pas");
}
}
}
else
{
echo 'Cette action n\'est pas autorisée';
return false;
}
class EleveUpdate
{
public function __construct()
{
}
public function testfunct($data)
{
echo $data['eleve'];
}
}
Javascript side:
$(document).ready(function() {
$.ajax({
url: 'eleveupdate.php',
type: 'POST',
data: {
action: "testfunct",
eleve: 1
},
beforeSend: function()
{
loading(true);
},
error: function()
{
console.log('error');
},
success: function(data)
{
loading(false);
console.log(data);
}
});
});
The problem is that the isset $_POST is always in my class, I'm pretty sure this is not the right way to do it so, I'm here to found help about it.
Thanks you in advance
Simon
The problem is it's not easy to call scope-namings based on a string-request.
You can use something called LAMBDA, or anonymous functions. This way you can store an array of strings with a LAMBDA attached to them. Like this:
<?php
class EleveUpdate {
private $funcs = array();
function __construct($which_function) {
$funcs['testfunct'] = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
$funcs[$which_function];
}
}
?>
See more info here: http://www.php.net/manual/en/function.create-function.php
You probably won't even need the Class anymore with this method, but just showing.

CodeIgniter ajax call using jquery when call redirect it prints the whole page i div

no title that fits this bug but this how it goes, i have form with a submit button when pressed jquery ajax calls the controller and the form validation is done if it fails the form is redrawn if it passes the page is redirected to the home page with flash message successes and thats where the bug happens it redraws the whole page in the content(header header footer footer). i hope it makes sense seeing is believing so here is the code
side notes: "autform" is a lib for creating forms "rest" is a lib for templates.
the jquery code:
$("form.user_form").live("submit",function() {
$("#loader").removeClass('hidden');
$.ajax({
async :false,
type: $(this).attr('method'),
url: $(this).attr('action'),
cache: false,
data: $(this).serialize(),
success: function(data) {
$("#center").html(data);
$('div#notification').hide().slideDown('slow').delay(20000).slideUp('slow');
}
})
return false;
});
the controller
function forgot_password()
{
$this->form_validation->set_rules('login',lang('email_or_login'), 'trim|required|xss_clean');
$this->autoform->add(array('name'=>'login', 'type'=>'text', 'label'=> lang('email_or_login')));
$data['errors'] = array();
if ($this->form_validation->run($this)) { // validation ok
if (!is_null($data = $this->auth->forgot_password(
$this->form_validation->set_value('login')))) {
$this-> _show_message(lang('auth_message_new_password_sent'));
} else {
$data['message']=$this-> _message(lang('error_found'), false); // fail
$errors = $this->auth->get_error_message();
foreach ($errors as $k => $v){
$this->autoform->set_error($k, lang($v));
}
}
}
$this->autoform->add(array('name'=>'forgot_button', 'type'=>'submit','value' =>lang('new_password')));
$data['form']= $this->autoform->generate('','class="user_form"');
$this->set_page('forms/default', $data);
if ( !$this->input->is_ajax_request()) { $this->rest->setPage(''); }
else { echo $this->rest->setPage_ajax('content'); }
}
}
function _show_message($message, $state = true)
{
if($state)
{
$data = '<div id="notification" class="success"><strong>'.$message.'</strong></div>';
}else{
$data = '<div id="notification" class="bug"><strong>'.$message.'</strong></div>';
}
$this->session->set_flashdata('note', $data);
redirect(base_url(),'refresh');
}
i think it as if the redirect call is caught by ajax and instead of sending me the home page it loads the home page in the place of the form.
thanks for any help
regards
OK found the problem and solution, it seemed you cant call a redirect in the middle of an Ajax call that is trying to return a chunk of HTML to a div, the result will be placing the redirected HTML in the div.
The solution as suggested by PhilTem at http://codeigniter.com/forums/viewthread/210403/
is when you want to redirect and the call is made by Ajax then return a value with the redirect URI back to Ajax and let it redirect instead.
For anyone interested in the code:
The Jquery Ajax code:
$("form.user_form").live("submit", function(event) {
event.preventDefault();
$("#loader").removeClass('hidden');
$.ajax({
type: $(this).attr('method'),
url: $(this).attr('action'),
cache: false,
dataType:"html",
data: $(this).serialize(),
success: function(data) {
var res = $(data).filter('span.redirect');
if ($(res).html() != null) {
[removed].href=$(res).html();
return false;
}
$("#center").html(data);
},
error: function() {
}
})
return false;
});
The PHP Controller
function _show_message($message, $state = true, $redirect = '')
{
if ($state)
{
$data = '<div id="notification" class="success"><strong>'.$message.'</strong></div>';
} else {
$data = '<div id="notification" class="bug"><strong>'.$message.'</strong></div>';
}
$this->session->set_flashdata('note', $data);
if ( !$this->input->is_ajax_request())
{
redirect(base_url() . $redirect, 'location', 302);
}
else
{
echo '<span class="redirect">'.base_url().$redirect.'</span>';
}
}
just use individual errors
json_encode(array(
'fieldname' => form_error('fieldname')
));
AJAX
success: function(cb)
{
if(fieldname)
{
{fieldname}.after(cb.fieldname)
}
}
see this

Categories