Roshdy
Roshdy

Reputation: 1812

CakePHP - Load view with php variables and return in ajax

Ok, this has been driving me crazy for the past couple of days.

I have a form:

echo $this->Form->create(FALSE, array('id' => 'AdminGeneralReport', 'class' => 'ReportForm'));
                echo '<div class="row">';
                echo $this->Form->input('ReportCenter', array(
                    'type'=>'select', 'div' => 'form-group', 
                    'options' => $centers,
                    'label' => 'المركز', 
                    'class' => 'form-control report-center',
                    'selected' => isset($selections['CenterID'])? $selections['CenterID']['value'] : 'default'
                    ));

                echo $this->Form->input('ReportYears', array(
                    'type'=>'select', 'div' => 'form-group', 
                    'options' => $years,
                    'label' => 'العام الدراسي', 
                    'class' => 'form-control report-year',
                    'selected' => isset($selections['YearID'])? $selections['YearID']['value'] : 'default'
                    ));
echo $this->Form->end();                    

Submit jQuery:

$('.ReportForm').off('submit').on('submit', function(e){
    e.preventDefault();
    var formID = $(this).attr('id');
    var data = JSON.stringify($(this).serializeObject());
    var url = base_url + "Reports/" + formID;
    var targetSelector = $(this).attr('data-target') || '.results-row';     
    var $target = $(targetSelector);

    // Show app loading
    $('#AppLoading').show();

    $.ajax({
        url         : url,
        type        : 'POST',
        ContentType : 'application/json',
        data        : {'data': data}
    }).done(function(response){
        try{        
            response = JSON.parse($response);
            if(response.status == 'success'){
                $target.html(response.html);
            }               
            else{
                $('#AppWell').show('slow').children('p').html(response.msg);
            }
        } 
        catch (ex) {
            var msg = 'عذراً، حدث خطأ في إنشاء التقرير. برجاء المحاولة لاحقاً';
            $('#AppWell').show('slow').children('p').html(msg);
            console.log('Exception :: ' + ex.toString());
            console.log('Response :: ' + response);
        }
    }).fail(function(request, status, error){
        var msg = 'عذراً، حدث خطأ في إنشاء التقرير. برجاء المحاولة لاحقاً';
        $('#AppWell').show('slow').children('p').html(msg);
        console.log('XXXXX Ajax Failure :: ' + error);
    }).always(function(){
        // Hide app loading
        $('#AppLoading').hide();
    }); 
});

Question/Need: I want to load another view and append it after this form using json or whatever the way it's possible.


This is part of the view I want to load:

<?php if(isset($selections['Filtered']) && $selections['Filtered'] == TRUE ){
echo '<div class="row">';
$Report = '';   
if(isset($selections['SexID']) && $selections['SexID']['value'] != 'default'){
    $Report .= '<div class="report-info">
                    <p class="title">الجنس</p>
                    <p class="value">'.$selections['SexID']['text'].'</p>
                </div>';                    
}
if(isset($selections['GovID']) && $selections['GovID']['value'] != 'default'){
    $Report .= '<div class="report-info">
                    <p class="title">المحافظة</p>
                    <p class="value">'.$selections['GovID']['text'].'</p>
                </div>';                    
}   

echo '</div>';
?>
<div class="cur-report custom-inverse">
    <?=$Report;?>
</div>

And this is part of the PHP code:

// This is the function the ajax calls
public function AdminGeneralReport()
{
    // Enable automatic view class switching on content types
    public $components = array('RequestHandler');

    // Disable auto rendering
    $this->autoRender = false;          
    // Create new view to return to ajax request
    $view = new View($this, false);

    // Define selections array
    $selections = array();

    // Get AJAX data
    $postData = $this->request->data;
    // Decode post data to JSON object
    $data = json_decode($postData);

    // Create response object
    $response = new stdClass();
    $response->status = 'fail';     // Should be changed by success scenario

    // ********* Center Condition ********* //
    $centerCond = '';
    // Check if Center is set
    if($data->ReportCenter != 'default'){
        $centerID = $data->ReportCenter;
        $selections['CenterID']['value'] = $centerID;
        $selections['CenterID']['text'] = $centers[$centerID];
        $selections['Filtered'] = TRUE;

        $centerCond = array('CenterID' => $centerID);
    }
    // *********************************************** //

    // ********* Year Condition ********* //
    $yearCond = '';
    // Check if Academic Year is set
    if($data->ReportYears != 'default'){
        $yearID = $data->ReportYears;
        $selections['YearID']['value'] = $yearID;
        $selections['YearID']['text'] = $years[$yearID];
        $selections['Filtered'] = TRUE;

        $yearCond = array('YearID' => $yearID);

        $allTerms = $this->Term->find('all', array('conditions' => array('YearID' => $yearID), 
            'fields' => array('ID', 'TermName')));
        // Convert results from 3D array to 1D array
        for($i = 0; $i < count($allTerms); $i++){
            $terms[$allTerms[$i]['Term']['ID']] = $allTerms[$i]['Term']['TermName'];
        }
        $terms['default'] = 'الكل';
    }
    // *********************************************** //

    if($selections){                                                                
        $response->status = 'success';
    }
    else{
        $response->msg = 'لا توجد بيانات لهذه الإختيارات';
    }           

    $view->set(compact('results','selections'));        
    $view->set('_serialize', array('results', 'selections'));
    $html = $view->render('Admin/General', FALSE);
    $response->html = $html;

    echo json_encode($response);
    die();
}

NOTE: I have this configured in Config/router.php

/**
* Enable extensions routing for data views
*/
Router::parseExtensions('json');

Upvotes: 3

Views: 3245

Answers (1)

Roshdy
Roshdy

Reputation: 1812

FINALLY SOLVED!!!

I was confusing my self by trying to make it a data view json/xml... while all i needed to do was formatting the returned view:

The returned view has a lot of "\r\n\'\""...all the escape sequences that fail to be JSON parsed in jQuery code.

and i don't have to include the Router::parseExtensions('json'); as well as the public $components = array('RequestHandler');


So this is the PHP Code:

$results = array();     // Fill it
$selections = array();    // Fill it
...
// Disable auto rendering
$this->autoRender = false;          
// Create new view to return to ajax request
$view = new View($this, false);
$view->set(compact('results','selections'));            
$view->set('_serialize', array('results', 'selections'));

$html = stripcslashes( stripslashes( $view->render('Admin/General', FALSE) ) );
$response->html = $html;

echo json_encode($response);
die();

NOTE: stripcslashes() removes the "\r\n" escape sequences, while stripslashes will remove "\'\"" escape sequences


The jQuery Code:

$.ajax({
    url         : url,
    type        : 'POST',
    ContentType : 'application/json',
    data        : {'data': data}
}).done(function(response){
    try{        
        response = JSON.parse(response);
        if(response.status == 'success'){
            $target.html(response.html);
        }               
        else{
            // ERROR HANDLING
        }
    } 
    catch (ex) {
        // ERROR HANDLING
        console.log('Exception :: ' + ex.toString());
        console.log('Response :: ' + response);
    }
}).fail(function(request, status, error){
    // ERROR HANDLING
    console.log('XXXXX Ajax Failure :: ' + error);
}).always(function(){
    // Hide loading     
}); 

Upvotes: 2

Related Questions