Welcome Guest, Not a member yet? Register   Sign In
ajax call on success redirect page from controller loaded in place of form
#1

[eluser]axmed[/eluser]
Hello Everyone

i have this problem cant find a solution for it.this is how it goes, i have Form using Ajax i would call a controller and it will respond by sending back the form with the validation errors, but when no errors are found and a redirect is made by the controller the Ajax call loads the redirected page in the place of the form, leaving me with a page in a page
(header header footer footer).
so how can i handle Calling the redirect() function in an AJAX call to go to another page.

here is the code

jquery:
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) {
                  $("#center").html(data);                  
          }
      })

   return false;
  })

PHP Controller
Code:
function get_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');
}

side notes rest library for template, Autoform is to create a form.

Any advices?
Thanks
#2

[eluser]PhilTem[/eluser]
Maybe this snippet from my code can help you

Code:
$('form#ajax_form :submit').click(function() {
        // return true;
        
        var theButton = $(this);
        var theForm = $('form#ajax_form');
        
        // alert(theForm.serialize());
        
        $.ajax({
            url: theForm.attr('action'),
            type: "POST",
            dataType: "json",
            data: theForm.serialize(),
            success: function(ajaxResult) {
                // alert(jQuery.type(ajaxResult.status));
                if ( theButton.attr('redirect') && ( ajaxResult.status == "redirect" ) )
                {
                    var theRedirect = theButton.attr('redirect');
                    
                    [removed].href = theRedirect;
                }
                else
                {
                    $('form .hidden').html(ajaxResult.append);
                }
            },
            error: function(jqXHR, textStatus, errorThrown) {
                $('form .hidden').html(textStatus);
            }
        });
        
        return false;
    });

What it does is fairly simple: Attached to each submit button of a form (I tend to have one for "Save and close" and one for "Apply" for which the first does a redirect) I have an AJAX-call. This goes to the same page we're on but for the one call (AJAX) it will only produce a redirect if the "save and close" button was pressed (So it checks if there is a html-attribute called "redirect" for the button).

The buttons are created with
Code:
&lt;input type="submit" name="smt_submit" class="btn primary" redirect="http://example.com/thisToRedirectTo.php" value="Save changes" /&gt;
&lt;input type="submit" name="smt_apply" class="btn primary" value="Apply Changes" /&gt;

On another way (and to cut a probably long story short):
You have to check within your controller, whether you want to perform a redirect (on an ajax-call) and then send the string to redirect to to your ajax success-function. Then just use

Code:
\window\.\location\.href = theRedirect; // without the \ but I had to add them since the forum stripped them

and with pure magic you have a redirect working.

My example won't work out of the box but should guide you towards a functional script Wink
#3

[eluser]pickupman[/eluser]
By using the third parameter of load->view you can get the html from the page.
Code:
if ( !$this->input->is_ajax_request())
{
   $this->load->view('normal_page', $data);
}else {
   $data['html'] = $this->load->view('ajax_content', $data, TRUE); //Get html from view
   $this->output
    ->set_content_type('application/json')
    ->set_output(json_encode($data));  
}
Then in your success callback you just replace the form content with the html returned in the JSON response.
#4

[eluser]axmed[/eluser]
this problem driving me mad since i know so little about ajax, i tried using http headers and nothing ajax continued to ignore the redirect and load it in the div, so i tried what PhilTem said, is this the correct way to do it? will it be supported by browsers or cause any error.
here is the fix:

jquery

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(); //window./location./href could not post so ignore /
                  return false;
              }
              $("#center").html(data);
          },
          error: function() {

          }
      })

   return false;
  });


and in the Controller

Code:
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>';
        }

}
#5

[eluser]Aken[/eluser]
Yes, that is a more appropriate way to do it. You cannot use a redirect in your PHP code and expect Javascript to enact it - just not the way the two languages work together.

See this StackOverflow article about JS redirects for more info, if you haven't seen it already.
#6

[eluser]axmed[/eluser]
Thanks guys for all the help, especially PhilTem for the solution Smile




Theme © iAndrew 2016 - Forum software by © MyBB