0

in phalcon framework i want to populate dependent drop down category list. But i'm facing some problems in my code:

#1. On select category list -> subcategory list shows: undefined (it's not populating options with value)

#2. if database have no data console.log shows: Undefined variable: resData in my controller
#3. if select category which value is '0' its not disabling the subcategory list again What i'm doing wrong in my code? enter image description here

[Module.php]

use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Volt;

$di->setShared('view', function () use ($config){
    $view = new View();
    $view->setViewsDir(APP_PATH . $config->appB->viewsDir);
# Register Volt Template           
    $view->registerEngines(array( 
    ".volt" => function($view, $di) use ($config) {
        $volt = new Volt($view, $di);
        $volt->setOptions(
            array(
                'compiledPath'      => APP_PATH . $config->appB->cacheDir,
                'compiledExtension' => '.php',
                'compiledSeparator' => '_',
                'compileAlways'     => true,
                'autoescape'        => false,
                'stat'              => true
            )
        );
    $compiler = $volt->getCompiler();
    $compiler->addFunction('strtotime','strtotime');

    return $volt;
    }
    ));            
    return $view;
});

[CONTROLLER]

public function entryAction()
{
        $formAction = 'backend/index/insert';
        $this->view->setVar('action',$formAction);
        $this->view->product_title = '';
        $this->view->product_price = '';
        $this->view->product_keyword = '';
        $this->view->product_image = '';
        $this->view->product_desc = '';
        $category = Categories::find();
        $this->view->setVar('categories',$category);                       
        $this->view->pick("index/entry");
}

public function getSubcategoryAction()
{ 
    $id = $this->request->getPost('id');
    $data = Subcat::findBycategory_id($id); 
    $resData = array();    
    foreach($data as $result)
    {
        $resData[] = array('id' => $result->id, 'category_id' => $result->category_id, 'subcategory' => $result->subcategory_name);
    }
    echo(json_encode($resData));       
    //$this->view->setVar('subcategory',$resData);
}

[ENTRY VOLT]

Category:<select name="category" id="category">
    <option value="0">Choose Category ...</option>
{% for category in categories %}
    <option value="{{category.id}}">{{category.categoryname}}</option>
{% endfor %}
</select><br/>
sub-Category:<select name="subcategory" id="subcategory" disabled="disabled"><option value="0">Choose Sub-Category ...</option></select>
<br/>
    Products:<select name="products" id="products" disabled="disabled"><option value="0">Choose a Product ...</option></select>
<br/>

[JQUERY]

$("select[name='category']").on("change", function(e){
    e.preventDefault();
    var value = $(this).val();
    $("select[name='subcategory']").attr("disabled", false); 
    $.ajax({
        type: "POST",
        url: "http://localhost/shopping/backend/index/getSubcategory",
        data:'id='+value,       
    }).done(function(response){
        $("#subcategory").not(":first").remove();
        response = JSON.parse(response);
        response.forEach(function(value){               
            $('#subcategory').append('<option value="'+value.id+'">'+value.subcategory+'</option>');
        });

    }).fail(function(){
            console.log('error: Please reload page and try again!');
    }).always(function(){
            console.log('Complete:');
    });
});
Styled Bee
  • 141
  • 1
  • 12

2 Answers2

2

Notice that in the first lines in your controller you are disabling the views, so Volt is never processed. As you are working now, jQuery only receives JSON results, so you are appending JSON rather than Volt. You have to choose a path: either use Volt, in which case you have to remove lines 1 in both actions and process the view with parameters, or you keep sending JSON data to jQuery and you set it up properly for processing JSON response (check this answer )

In your case, getSubcategoryAction() would look like:

public function getSubcategoryAction()
{ 
    //$this->view->disable();  //Replaced by: 
    $this->view->setRenderLevel(
        View::LEVEL_ACTION_VIEW
     );        
    $id = $this->request->getPost('id');
    $data = Subcat::findBycategory_id($id);   
    foreach($data as $result)
    {
        $resData[] = array('id' => $result->id, 'category_id' => $result->category_id, 'subcategory' => $result->subcategory_name);
    }

    $this->view->setVar('categories', $resData);

}

This is assuming that you have set Volt as your render engine in your DI and your Volt template corresponds to ../app/views/index/getSubcategory.phtml, i.e.:

<?php

use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Volt;

// Register Volt as a service
$di->set(
    'voltService',
    function ($view, $di) {
        $volt = new Volt($view, $di);

        $volt->setOptions(
          [
            'compiledPath'      => '../app/compiled-templates/',
            'compiledExtension' => '.compiled',
          ]
        );

       return $volt;
    }
);

// Register Volt as template engine
$di->set(
    'view',
    function () {
        $view = new View();

        $view->setViewsDir('../app/views/');

        $view->registerEngines(
          [
            '.volt' => 'voltService',
          ]
        );

        return $view;
    }
);

The Volt registration code was copied from: https://docs.phalconphp.com/en/3.4/volt Modify the directories according to your App structure.

a_byte_late
  • 131
  • 5
  • Not understand in my case please throw a example related with my code how to use volt to get expected result! – Styled Bee Oct 24 '18 at 10:38
  • 1
    i follow your instruction and change controller action also jquery! but console.log shows nothing and drop menu not populated – Styled Bee Oct 24 '18 at 11:17
  • I just update my full code please check it and tell what im doing wrong to get expected result? – Styled Bee Oct 24 '18 at 11:46
  • If you visit `http://localhost/shopping/backend/index/getSubcategory` what do you receive? Also, if possible, include the definition of your Volt service. – a_byte_late Oct 24 '18 at 16:07
  • Receive undefined in console.log. using: console.log('success:'+value.subcategory_name); – Styled Bee Oct 24 '18 at 17:21
  • 1
    Ok, and when you visit the url directly with your browser? – a_byte_late Oct 24 '18 at 19:37
  • dropdown menu not populate data. just show "choose sub-category" which i set manually in volt. – Styled Bee Oct 25 '18 at 01:45
  • a_byte_late i just figure it by changing jquery and controller. i updated my code but the current problem is each time i select option from category subcategory render its data twice. could u plz tel me how to solved? – Styled Bee Oct 25 '18 at 02:26
  • I just saw your changes. `getSubcategoryAction()` is again returning a JSON response; if you are going to continue with this path, then you need to disable the view and forget about Volt. Please paste the result when you visit http://localhost/shopping/backend/index/getSubcategory directly in your browser. – a_byte_late Oct 25 '18 at 14:24
1

Follow This and just update your code...

[JQuery]

$("select[name='category']").on("change", function(e){
    e.preventDefault();
    var value = $(this).val();
    if(value === '0'){$("select[name='subcategory']").attr("disabled", true); $("select[name='products']").attr("disabled", true);}else{$("select[name='subcategory']").attr("disabled", false);} 
    $.ajax({
        type: "POST",
        url: "http://localhost/shopping/backend/index/getSubcategory",
        data:'id='+value,       
    }).done(function(response){
        $("#subcategory").find('option').not(":first").remove();    
        $("#products").find('option').not(":first").remove();
        response = JSON.parse(response);
        response.forEach(function(value){
            $('#subcategory').append('<option value="'+value.id+'">'+value.subcategory+'</option>');
        });
    }).fail(function(){
            console.log('error: Please reload page and try again!');
    }).always(function(){
            console.log('Complete:');
    });
});
munaz
  • 166
  • 2
  • 14