troubleshooting Question

CodeIgniter, Ajax and Knockout.js

Avatar of Marco Gasi
Marco GasiFlag for Spain asked on
PHPJavaScriptjQuery
20 Comments1 Solution1263 ViewsLast Modified:
Hi all.
Maybe it's  more than I can chew, but here I am.

Following pieces of code works well together (source just a bit modified here: http://phpsblog.agustinvillalba.com/adding-ajax-codeigniter-jquery/

The goal in following code is the get a select filled up accordingly to another select selected option.

CategoryList.php
<?php
class CategoryList extends CI_Controller
{

	public function __construct()
	{
		parent::__construct();
		$this->load->model( 'categories_model' );
	}

	public function index()
	{
		
	}

	public function list_products()
	{
		//Get all the categories in the system
		$data["categories"] = $this->categories_model->get_categories();
		//Loading the view for the record edition
		$this->load->view( 'templates/header', $data );
		$this->load->view( 'list_products', $data );
		$this->load->view( 'templates/footer' );
	}
}

SubcategoryList.php
<?php

class SubcategoryList extends CI_Controller
{

	public function __construct()
	{
		parent::__construct();
		$this->load->model( 'subcategories_model' );
	}

	public function index()
	{
		
	}

	public function list_dropdown()
	{
		$cat_id = $this->input->post( 'cat_id' ); //Read the category id sent by POST
		$subcategories = $this->subcategories_model->get_subcategories_by_category( $cat_id ); //Get the matches list for that tournament from the DB
		$data["subcategories"] = $subcategories;
		$this->load->view( 'list_dropdown_view', $data );
	}

}

Categories_model.php
<?php

class Categories_model extends CI_Model
{

	public function __construct()
	{
		$this->load->database();
	}

	public function get_categories()
	{
		$query = $this->db->get( 'categories' );
		return $query->result_array();
	}

}

Subcategories_model.php
<?php

class Subcategories_model extends CI_Model
{

	public function __construct()
	{
		$this->load->database();
	}

	public function get_subcategories_by_category( $catid )
	{
		$query = $this->db->get_where( 'subcategories', array( 'category_id' => $catid ) );
		return $query->result_array();
	}

}

First view: list_products.php
<div class="slider-wrapper">
</div>
<div class="container marketing">
	<!-- Three columns of text below the carousel -->
	<div class="row">
		<div class="col-lg-12">

			<strong>Categories:</strong>
			<select id="category_list">
				<?php
				foreach ( $categories as $category )
				{
					echo "<option value='{$category["category_id"]}'>{$category["category_name"]}</option>";
				}
				?>
			</select>
			<br />
			<strong>Match:</strong>
			<select id="subcategory_list">
			</select>

		</div>
	</div>
</div>

Second view list_dropdown_view.php
<?php
if(empty($subcategories))
{
    echo "<option value=''>No available subcategory</option>";
}
else
{
	foreach ( $subcategories as $subcategory )
	{
			echo "<option value='{$subcategory["subcategory_id"]}'>{$subcategory["subcategory_name"]}</option>";
	}
}

Finally the javascript:
$(document).ready(function()
{
	var subcategories = [];
	$(document).on('change', 'select#category_list', function()
	{
		var cat_id = $('select#category_list').val(); //Get the id of the tournament selected in the list
		$.ajax(
		{
			type: 'POST',
			url: baseurl+'subcategorylist/list_dropdown', //We are going to make the request to the method "list_dropdown" in the match controller
			data: 'cat_id='+cat_id, //POST parameter to be sent with the tournament id
			success: function(resp) 
			{ //When the request is successfully completed, this function will be executed
			//Activate and fill in the matches list
			 subcategories = resp;
				$('select#subcategory_list').html(resp); //With the ".html()" method we include the html code returned by AJAX into the matches list
			}
		});
	});
	$('select#category_list').trigger('change');
});

Both views are wrapped within header and footer:

header:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
<!--    <link rel="icon" href="../../favicon.ico">-->

    <title>1Stop-HomeShop</title>

    <!-- Bootstrap core CSS -->
    <link href="<?php echo base_url('assets/css/bootstrap.min.css')?>" rel="stylesheet">

    <!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
    <!--[if lt IE 9]><script src="<?php //echo base_url('js/ie8-responsive-file-warning.js')?>"></script><![endif]-->
    <script src="<?php echo base_url('assets/js/ie-emulation-modes-warning.js')?>"></script>

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->

    <!-- Custom styles for this template -->
    <link href="<?php echo base_url('assets/css/carousel.css')?>" rel="stylesheet">
    <link href="<?php echo base_url('assets/css/frac_reset.css')?>" rel="stylesheet">
    <link href="<?php echo base_url('assets/css/frac_style.css')?>" rel="stylesheet">
    <link href="<?php echo base_url('assets/css/fractionslider.css')?>" rel="stylesheet">
    <link href="<?php echo base_url('assets/css/app.css')?>" rel="stylesheet">
  </head>
<!-- NAVBAR
================================================== -->
  <body>
    <div class="navbar-wrapper">
      <div class="header-container">

        <nav class="navbar navbar-inverse navbar-static-top" role="navigation">
          <div class="container">
						<img src="<?php echo base_url('assets/images/logomio.png')?>" alt="1Stop-HomeShop" />
              <ul class="nav navbar-nav pull-right">
                <li class="active"><a href="#">Home</a></li>
                <li class="dropdown">
									<a href="#" class="dropdown-toggle" data-toggle="dropdown">Furniture <span class="caret"></span></a>
                  <ul class="dropdown-menu" role="menu">
                    <li><a href="#">Action</a></li>
                    <li><a href="#">Another action</a></li>
                    <li><a href="#">Something else here</a></li>
                  </ul>
								</li>
                <li class="dropdown">
									<a href="#" class="dropdown-toggle" data-toggle="dropdown">Kitchen Ware <span class="caret"></span></a>
                  <ul class="dropdown-menu" role="menu">
                    <li><a href="#">Action</a></li>
                    <li><a href="#">Another action</a></li>
                    <li><a href="#">Something else here</a></li>
                  </ul>
								</li>
                <li class="dropdown">
									<a href="#" class="dropdown-toggle" data-toggle="dropdown">Lightning <span class="caret"></span></a>
                  <ul class="dropdown-menu" role="menu">
                    <li><a href="#">Action</a></li>
                    <li><a href="#">Another action</a></li>
                    <li><a href="#">Something else here</a></li>
                  </ul>
								</li>
                <li class="dropdown">
									<a href="#" class="dropdown-toggle" data-toggle="dropdown">Textiles <span class="caret"></span></a>
                  <ul class="dropdown-menu" role="menu">
                    <li><a href="#">Action</a></li>
                    <li><a href="#">Another action</a></li>
                    <li><a href="#">Something else here</a></li>
                  </ul>
								</li>
                <li><a href="#contact">Contact</a></li>
              </ul>
						<!--{__NAV__}-->
          </div>
        </nav>

      </div>
    </div>

footer:
    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="<?php echo base_url('assets/js/bootstrap.min.js')?>"></script>
    <script src="<?php echo base_url('assets/js/docs.min.js')?>"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script src="<?php echo base_url('assets/js/ie10-viewport-bug-workaround.js')?>"></script>
    <script src="<?php echo base_url('assets/js/jquery.fractionslider.min.js')?>"></script>
    <script src="<?php echo base_url('assets/js/fractionslider_init.js')?>"></script>
    <script src="<?php echo base_url('assets/js/knockout.js')?>"></script>
		<script type="text/javascript">
			var baseurl = "<?php print base_url(); ?>";
    <script src="<?php echo base_url('assets/js/test.js')?>"></script>
  </body>
</html>

Finally, the routes.php
$route['default_controller'] = "welcome";
$route['404_override'] = '';
$route['categorylist/(:any)'] = 'categorylist/list_products';
$route['subcategorylist/(:any)'] = 'subcategorylist/list_dropdown';

What's the problem, now? I'd like to use knockout.js and I have two distinc questions about:
1. I have the doubt using knockout.js (or similar javascript framework) within a php framework ibe useless or at lease less useful than using it without a php framework: after all, the above code get the same result, maybe a better result in a whole perspective: more robust, more secure (it's  server side), a bit less elegant, maybe, but concise and clear. So the question is: does it make sense to try to integrate a javascript framework with a php frame work and more specifically knockout.js with CodeIgniter? If the answer is 'No', the second question can just be skipped.

2. The second question is: how to implement knockout.js logic? I tried to modify the list_product.php code this way:
<div class="slider-wrapper">
</div>
<div class="container marketing">
	<!-- Three columns of text below the carousel -->
	<div class="row">
		<div class="col-lg-12">

			<strong>Categories:</strong>
			<select id="category_list">
				<?php
				foreach ( $categories as $category )
				{
					echo "<option value='{$category["category_id"]}'>{$category["category_name"]}</option>";
				}
				?>
			</select>
			<br />
			<strong>Match:</strong>
			<select id="subcategory_list" data-bind="options: subcategories">
		</div>
	</div>
</div>

and the javascript this way:
$(document).ready(function()
{
	var subcategories = [];
	var subcat = {
			subcategories: ko.observableArray([])
	};	

But I can't fighure out how to modify views and I'm just blocked here.

I know this is can be a hard question and I apologize if it's too theoretical or confused: I'm confused me too :-)

As usual, thanks in advance to all.

As a side note: can I win something  for the most long question posted at EE? lol
ASKER CERTIFIED SOLUTION
Join our community to see this answer!
Unlock 1 Answer and 20 Comments.
Start Free Trial
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 20 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros