0

in my project I need to post the data from view model to controller, but my AJAX post code is not working. Could you please help me in solving this problem?

My modal code which contains form in view:

<div class="modal fade" id="modal_form">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title">Modal title</h4>
            </div>
            <div class="modal-body">

                <form action="#" method="post" id="form" role="form">
                    <legend>Form title</legend>
                    <div class="form-group">
                        <label >First Name</label>
                        <input name="firstname" type="text" class="form-control" placeholder="Input field">
                    </div>
                    <div class="form-group">
                        <label >Last Name</label>
                        <input name="lastname" type="text" class="form-control" placeholder="Input field">
                    </div>
                    <div class="form-group">
                        <label >gender</label>
                        <input name="gender" type="text" class="form-control" placeholder="Input field">
                    </div>

                    <div class="form-group">
                        <label >Address</label>
                        <textarea name="address" id="input" class="form-control" rows="3" required="required"></textarea>
                    </div>
                    <div class="form-group">
                        <label >Dob</label>
                        <input name="dob" type="date" class="form-control" placeholder="Input field">
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" id="savebtn" onclick="save()" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
   </div>

My ajax and jquery code to post the data to controller,

function save(){
    $('#savebtn').text('saving...');
    $('#savebtn').attr('disabled',true);


     $.ajax({
        url : "<?php echo base_url('index.php/Crud/add_details')?>",
        type: "POST",
        data: $('#form').serialize(),
        dataType: "JSON",
        success: function(data)
        {

            if(data.status) //if success close modal and reload ajax table
            {
                $('#modal_form').modal('hide');
                reload_table();
            }

            $('#savebtn').text('save'); //change button text
            $('#savebtn').attr('disabled',false); //set button enable 


        },
        error: function (jqXHR, textStatus, errorThrown)
        {
            alert('Error adding / update data');
            $('#savebtn').text('save'); //change button text
            $('#savebtn').attr('disabled',false); //set button enable 

        }
    });
  }

Controller function

public function add_details() { 
  $data = array(
            'firstName' => $this->input->post('firstName'), 
            'lastName' => $this->input->post('lastName'), 
            'gender' => $this->input->post('gender'), 
            'address' => $this->input->post('address'), 
            'dob' => $this->input->post('dob'), 
          ); 

   $insert = $this->person->save($data); 
   echo json_encode(array("status" => TRUE)); } 

But it is not posting data to my controller. Any kind of help would be appreciated. Thanks.

DFriend
  • 8,869
  • 1
  • 13
  • 26
Boopathi N
  • 298
  • 2
  • 4
  • 16
  • What kind of error(s) do you get? – TrueStory Sep 27 '16 at 12:24
  • Actually it not post any value to my controller,if i tried to print the $_POST in controller it will be empty. – Boopathi N Sep 27 '16 at 12:25
  • But do you receive an error in your controller, is the success part executed or the error part from your ajax script – TrueStory Sep 27 '16 at 12:26
  • ya its display the error part in ajax code – Boopathi N Sep 27 '16 at 12:27
  • Please paste your php code written in the function that is called here : `index.php/Crud/add_details` – shivgre Sep 27 '16 at 12:29
  • Try hardcoding the url like http://example.com/index.php/... for a sec, I suspect that your PHP code cannot be executed – TrueStory Sep 27 '16 at 12:30
  • 2
    [The Network tab is immensely useful in actually debugging code.](http://stackoverflow.com/a/21617685/2191572) – MonkeyZeus Sep 27 '16 at 12:30
  • Also check in the source code whether your ajax URL is properly shown, also use firebug in firefox and go to console and check the ajax request there – shivgre Sep 27 '16 at 12:31
  • public function add_details() { $data = array( 'firstName' => $this->input->post('firstName'), 'lastName' => $this->input->post('lastName'), 'gender' => $this->input->post('gender'), 'address' => $this->input->post('address'), 'dob' => $this->input->post('dob'), ); $insert = $this->person->save($data); echo json_encode(array("status" => TRUE)); } – Boopathi N Sep 27 '16 at 12:31
  • Your code looks fine, can you try placing a `die("TESTING");` before $data var to check if your function is getting called or not. – shivgre Sep 27 '16 at 12:38
  • Also, `console.log(errorThrown)` will be informative. – Jerry Sep 27 '16 at 18:45
  • it might be bad url issue /crud/add_details vs /index.php/crud/add_details, or htacces, or unavailable route. – cssBlaster21895 Sep 27 '16 at 21:20
  • i used the same url in from action /index.php/crud/add_details it works but in ajax call it not works. – Boopathi N Sep 28 '16 at 04:02
  • XMLHttpRequest cannot load http://[::1]/ajax_crud/index.php/Crud/add_details. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. This is the error i got in console – Boopathi N Sep 28 '16 at 04:10

1 Answers1

-1

WOW!! 9 months & No Answer Posted - :| $-$ @_@

Okay, it's CodeIgniter (& I love CodeIgniter), I can't let it Go..

Wiki Start :D

If your url working on browser (you are doing GET request) & not working with POST/AjaxPOST request and getting 500/403 Response/Status, It's means: YOU NEEDS To SEND CSRF TOKEN ALONG WITH POST/AjaxPOST

If you are using CodeIgniter CSRF Protection $config['csrf_protection'] = TRUE; inside CodeIgniter/application/config.php YOU MUST BE SEND CSRF TOKEN ALONG WITH POST/AjaxPOST

You can use CSRF token inside your html form:

<form action="#" method="post" id="form" role="form">
    <input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>">
    <!-- Your Other Stuff Waiting Here....  -->
</form>

or, using CodeIgniter built-in Form Helper (Default method would be POST)

<?=form_open('controller/action', 'id="ci_form_csrf" class="form-controller"'); ?>
    <!-- Your Other Stuff Waiting Here....  -->
<?=form_close();?>

If Not using CodeIgniter CSRF Protection $config['csrf_protection'] = FALSE; inside CodeIgniter/application/config.php

and..

  • Url working with GET request

  • Url not working with POST request or AjaxPOST request

Check your Controller method, If you have any Request Check Condition or have Code for GET only..

public function my_method () {
    if($this->input->get()){

    }
}
  • Url not working with GET request

  • Url not working with POST request

  • Url working with AjaxPOST/AjaxGET request

Check your Controller method, If you have any Request Check Condition or have Code for AJAX only..

public function my_method () {
    if ($this->input->is_ajax_request()) {

    }
}
  • Url not working with GET request

  • Url not working with POST request

  • Url not working with AjaxPOST/AjaxGET request .. and your OS or Server is LINUX/UNIX

Make sure you have Correct Naming Convention for CodeIgniter Controller & Model file : See CodeIgniter Change log:


Class file names now must be Ucfirst and everything else in lowercase


CodeIgniter Class Standard Naming: Ucfirst_controller, Ucfirst_model...

That means Every Class File must be Adhere The CodeIgniter Standard Naming Convention

Controller file name User.php or User_controller.php

class User extends CI_Controller {}

Correct access url: http://www.website.com/controller/method/param

Model file name User_model.php

class User_model extends CI_Model {}

Correct way to load model in controller: $this->load->model('User_model')

Wait... what about AjaxPOST :|

There is 2 Common approach to send CSRF token along with AjaxPOST

1 - Use PHP Code inside inline JavaScript, $this->security->get_csrf_token_name() & $this->security->get_csrf_token_hash()

2 - Define a JavaScript global var/object to store CSRF name & value & pass on later as calling JavaScript global variable.

3 - Add CSRF meta tag on top head html body and put token name and value there.

<meta id="CsrfSecrets" name="<?=$this->security->get_csrf_token_name()?>" content="<?=$this->security->get_csrf_hash()?>"/>

4 - Set CSRF token within in AjaxSetup,

// attach CSRF object for each AjaxPOST automatically
$.ajaxSetup({
  data: CsrfSecret
}); 

OMG!! :/ It's so confusing for me.. do you have any example for me plzzzzzz.. :(

Hmmm.. no worry, I am giving you example to make you Happy :)

Example First - (CodeIgniter CSRF Demo | AjaxPOST)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <!-- Using meta tag to retrive CodeIgniter CSRF token -->
    <meta name="<?=$this->security->get_csrf_token_name()?>" content="<?=$this->security->get_csrf_hash()?>"/>
    <title>CodeIgniter CSRF Demo | AjaxPOST</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript">
    // Set CodeIgniter base_url in JavaScript var to use within
    var _BASE_URL_ = "<?=base_url()?>";
    var _CSRF_NAME_ = "<?=$this->security->get_csrf_token_name()?>";
    (function($) {
        // getting meta object from body head section by csrf name
        var CsrfMetaObj = $('meta[name="' + _CSRF_NAME_ + '"]'),
        CsrfSecret = {};
        // get meta tag name & value
        CsrfSecret[CsrfMetaObj.attr('name')] = CsrfMetaObj.attr('content');
            // attach CSRF object for each AjaxPOST automatically
            $.ajaxSetup({
                data: CsrfSecret
            });
        })(jQuery);
    </script>
</head>
<body>
    <button class="button">Click Me to Trigger AjaxPOST</button>
    <script type="text/javascript">
        // on DOM ready
        $(document).ready(function(){
            // my button 
            $btn = $('.button');
            // on button click
            $btn.on('click', function(e){
                // stop default event
                e.preventDefault();
                // calling AjaxPOST
                $.ajax({
                    url: _BASE_URL_ + 'Controller/Method',
                    method: 'POST',
                    // or manually add csrf object
                    // data: $.extend({id:23, name:'scott'}, CsrfSecret); 
                    success: function(data){
                        alert('Success');
                    },
                    error: function(xhr, status, error){
                        alert(error);
                    }
                });
            });
        });
    </script>
</body>
</html>

Example Two - (CodeIgniter CSRF Refresh Demo | AjaxPOST) $config['csrf_regenerate'] = TRUE;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta id="CsrfSecrets" name="<?=$this->security->get_csrf_token_name()?>" content="<?=$this->security->get_csrf_hash()?>"/>
    <title>CodeIgniter Refresh CSRF Demo | AjaxPOST</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript">
    // Set CodeIgniter base_url in JavaScript var to use within
    var _BASE_URL_ = "<?=base_url()?>";
    var _CSRF_NAME_ = "<?=$this->security->get_csrf_token_name()?>";
    (function($) {
        /**
         * New jQuery function to set/refresh CSRF token in Body & to attach AjaxPOST
         * @param  {[type]} $ [description]
         * @return {[type]}   [description]
         */
         $.fn.CsrfAjaxSet = function(CsrfObject) {
            // getting meta object from body head section by csrf name
            var CsrfMetaObj = $('meta[name="' + _CSRF_NAME_ + '"]'),
            CsrfSecret = {};
            // if CsrfObject not set/pass in function
            if (typeof CsrfObject == 'undefined') {
                // assign meta object in CsrfObject
                CsrfObject = CsrfMetaObj;
                // get meta tag name & value
                CsrfSecret[CsrfObject.attr('name')] = CsrfObject.attr('content');
            }
            // CsrfObject pass in function
            else {
                // get Csrf Token Name from JSON
                var CsrfName = Object.keys(CsrfObject);
                // set csrf token name & hash value in object
                CsrfSecret[CsrfName[0]] = CsrfObject[CsrfName[0]];
            }
            // attach CSRF object for each AjaxPOST automatically
            $.ajaxSetup({
                data: CsrfSecret
            });
        };
        /**
         * New jQuery function to get/refresh CSRF token from CodeIgniter
         * @param  {[type]} $ [description]
         * @return {[type]}   [description]
         */
         $.fn.CsrfAjaxGet = function() {
            return $.get(_BASE_URL_ + 'Csrfdata', function(CsrfJSON) {
                $(document).CsrfAjaxSet(CsrfJSON);
            }, 'JSON');            
        };
    })(jQuery);
    // On DOM ready attach CSRF within AjaxPOST
    $(document).CsrfAjaxSet();
</script>
</head>
<body>
<button class="button">Click Me to Trigger AjaxPOST</button>
    <script type="text/javascript">
        // on DOM ready
        $(document).ready(function(){
            // my button 
            $btn = $('.button');
            // on button click
            $btn.on('click', function(e){
                // stop default event
                e.preventDefault();
                // trigger refresh csrf token
                var CSRF = $(document).CsrfAjaxGet();
                // use callback to put your AjaxPOST & Done!
                CSRF.success(function(){
                    $.ajax({
                        url: _BASE_URL_ + 'Controller/Method',
                        method: 'POST',
                        success: function(data){
                            alert('Success');
                        },
                        error: function(xhr, status, error){
                            alert(error);
                        }
                    });
                });
            });
        });
    </script>
</body>
</html>
Nono
  • 6,986
  • 4
  • 39
  • 39