CodeIgniter - 来自数据库的动态依赖下拉列表
CodeIgniter - Dynamic dependant dropdowns from database
有人可以帮忙吗?
我正在尝试将此代码转换为 CI,但我在使用 JQuery 时遇到问题,因为我不太理解它。
原始代码来自 - http://www.99points.info/2010/12/n-level-dynamic-loading-of-dropdowns-using-ajax-and-php/ - 在 CI.
之外完美运行
我可以显示第一个下拉菜单。
然后在 'index2.php' 的第 15 行加载 'get_chid_categories.php' 时出现错误 - 我明白为什么(尝试从 'root' 中的文件读取数据库),但我有不知道如何解决它。
我的看法 - index2.php
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="/jquery.livequery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
//$('#loader').hide();
$('.parent').livequery('change', function() {
$(this).nextAll('.parent').remove();
$(this).nextAll('label').remove();
$('#show_sub_categories').append('</application/views/img src="loader.gif" style="float:left; margin-top:7px;" id="loader" alt="" />');
$.post("/get_chid_categories.php", {
parent_id: $(this).val(),
}, function(response){
setTimeout("finishAjax('show_sub_categories', '"+escape(response)+"')", 400);
});
return false;
});
});
function finishAjax(id, response){
$('#loader').remove();
$('#'+id).append(unescape(response));
}
</script>
<style>
.both h4{ font-family:Arial, Helvetica, sans-serif; margin:0px; font-size:14px;}
#search_category_id{ padding:3px; width:200px;}
.parent{ padding:3px; width:150px; float:left; margin-right:12px;}
.both{ float:left; margin:0 0px 0 0; padding:0px;}
</style>
</head>
<body>
<div id="show_sub_categories">
<select name="search_category" class="parent">
<option value="" selected="selected">-- Categories --</option>
<?php
foreach ($view->result() as $row)
{
?>
<option value="<?php echo $row->id;?>"><?php echo $row->category;?></option>
<?php
}
?>
</select>
</div>
<br clear="all" /><br clear="all" />
</body>
</html>
控制器 - Swim.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Swim extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->datestring = '%d/%m/%Y';
$this->datewrite = 'Y-d-m';
$this->load->model('Swim_model');
$this->load->helper('date');
$data['not_logged_in'] = 'You are not logged in';
$this->session->set_userdata($data);
}
public function index2()
{
$data['main_view'] = 'index2';
$data['view'] = $this->Swim_model->CRUD_categories();
$this->load->view('load_view',$data);
}
}
型号 - Swim_model.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Swim_model extends CI_Model {
public function __construct()
{
// Call the CI_Model constructor
parent::__construct();
}
public function CRUD_categories()
{
return $this->db->select('*')
->from('categories')
->where('pid', '0')
->get();
}
}
get_child_categories.php - 如果我把它放在 'root'
中,我只能让它包含这个文件
<?php
if($_REQUEST)
{
$id = $_REQUEST['parent_id'];
$query = $this->db->select('*')
->from('categories')
->where('pid', $id)
->get();
?>
<select name="sub_category" class="parent">
<option value="" selected="selected">-- Sub Category --</option>
<?php
foreach ($query->result() as $row)
{
?>
<option value="<?php echo $row->id;?>"><?php echo $row->category;?></option>
<?php
}?>
</select>
<?php
}
?>
jquery.livequery.js - 也在 'root'
/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* Version: 1.0.3
* Requires jQuery 1.1.3+
* Docs: http://docs.jquery.com/Plugins/livequery
*/
(function($) {
$.extend($.fn, {
livequery: function(type, fn, fn2) {
var self = this, q;
// Handle different call patterns
if ($.isFunction(type))
fn2 = fn, fn = type, type = undefined;
// See if Live Query already exists
$.each( $.livequery.queries, function(i, query) {
if ( self.selector == query.selector && self.context == query.context &&
type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )
// Found the query, exit the each loop
return (q = query) && false;
});
// Create new Live Query if it wasn't found
q = q || new $.livequery(this.selector, this.context, type, fn, fn2);
// Make sure it is running
q.stopped = false;
// Run it immediately for the first time
q.run();
// Contnue the chain
return this;
},
expire: function(type, fn, fn2) {
var self = this;
// Handle different call patterns
if ($.isFunction(type))
fn2 = fn, fn = type, type = undefined;
// Find the Live Query based on arguments and stop it
$.each( $.livequery.queries, function(i, query) {
if ( self.selector == query.selector && self.context == query.context &&
(!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )
$.livequery.stop(query.id);
});
// Continue the chain
return this;
}
});
$.livequery = function(selector, context, type, fn, fn2) {
this.selector = selector;
this.context = context || document;
this.type = type;
this.fn = fn;
this.fn2 = fn2;
this.elements = [];
this.stopped = false;
// The id is the index of the Live Query in $.livequery.queries
this.id = $.livequery.queries.push(this)-1;
// Mark the functions for matching later on
fn.$lqguid = fn.$lqguid || $.livequery.guid++;
if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;
// Return the Live Query
return this;
};
$.livequery.prototype = {
stop: function() {
var query = this;
if ( this.type )
// Unbind all bound events
this.elements.unbind(this.type, this.fn);
else if (this.fn2)
// Call the second function for all matched elements
this.elements.each(function(i, el) {
query.fn2.apply(el);
});
// Clear out matched elements
this.elements = [];
// Stop the Live Query from running until restarted
this.stopped = true;
},
run: function() {
// Short-circuit if stopped
if ( this.stopped ) return;
var query = this;
var oEls = this.elements,
els = $(this.selector, this.context),
nEls = els.not(oEls);
// Set elements to the latest set of matched elements
this.elements = els;
if (this.type) {
// Bind events to newly matched elements
nEls.bind(this.type, this.fn);
// Unbind events to elements no longer matched
if (oEls.length > 0)
$.each(oEls, function(i, el) {
if ( $.inArray(el, els) < 0 )
$.event.remove(el, query.type, query.fn);
});
}
else {
// Call the first function for newly matched elements
nEls.each(function() {
query.fn.apply(this);
});
// Call the second function for elements no longer matched
if ( this.fn2 && oEls.length > 0 )
$.each(oEls, function(i, el) {
if ( $.inArray(el, els) < 0 )
query.fn2.apply(el);
});
}
}
};
$.extend($.livequery, {
guid: 0,
queries: [],
queue: [],
running: false,
timeout: null,
checkQueue: function() {
if ( $.livequery.running && $.livequery.queue.length ) {
var length = $.livequery.queue.length;
// Run each Live Query currently in the queue
while ( length-- )
$.livequery.queries[ $.livequery.queue.shift() ].run();
}
},
pause: function() {
// Don't run anymore Live Queries until restarted
$.livequery.running = false;
},
play: function() {
// Restart Live Queries
$.livequery.running = true;
// Request a run of the Live Queries
$.livequery.run();
},
registerPlugin: function() {
$.each( arguments, function(i,n) {
// Short-circuit if the method doesn't exist
if (!$.fn[n]) return;
// Save a reference to the original method
var old = $.fn[n];
// Create a new method
$.fn[n] = function() {
// Call the original method
var r = old.apply(this, arguments);
// Request a run of the Live Queries
$.livequery.run();
// Return the original methods result
return r;
}
});
},
run: function(id) {
if (id != undefined) {
// Put the particular Live Query in the queue if it doesn't already exist
if ( $.inArray(id, $.livequery.queue) < 0 )
$.livequery.queue.push( id );
}
else
// Put each Live Query in the queue if it doesn't already exist
$.each( $.livequery.queries, function(id) {
if ( $.inArray(id, $.livequery.queue) < 0 )
$.livequery.queue.push( id );
});
// Clear timeout if it already exists
if ($.livequery.timeout) clearTimeout($.livequery.timeout);
// Create a timeout to check the queue and actually run the Live Queries
$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
},
stop: function(id) {
if (id != undefined)
// Stop are particular Live Query
$.livequery.queries[ id ].stop();
else
// Stop all Live Queries
$.each( $.livequery.queries, function(id) {
$.livequery.queries[ id ].stop();
});
}
});
// Register core DOM manipulation methods
$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
// Run Live Queries when the Document is ready
$(function() { $.livequery.play(); });
// Save a reference to the original init method
var init = $.prototype.init;
// Create a new init method that exposes two new properties: selector and context
$.prototype.init = function(a,c) {
// Call the original init and save the result
var r = init.apply(this, arguments);
// Copy over properties if they exist already
if (a && a.selector)
r.context = a.context, r.selector = a.selector;
// Set properties
if ( typeof a == 'string' )
r.context = c || document, r.selector = a;
// Return the result
return r;
};
// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091)
$.prototype.init.prototype = $.prototype;
})(jQuery);
此文件会将类别加载到 MYSQL 数据库中
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(11) NOT NULL auto_increment,
`category` varchar(50) NOT NULL,
`pid` int(11),
PRIMARY KEY (`id`)
);
--
-- Dumping data for table `categories`
--
INSERT INTO `categories` (`id`, `category`, `pid`) VALUES
(1, 'Barncroft',0),
(2, 'Mary Rose',0),
(3, 'Petersfield',0),
(4, 'Redwood',0),
(5, 'Springfield',0),
(6, 'Mon',1),
(7, 'Tue',1),
(8, 'Wed',1),
(9, 'Thu',1),
(10, 'Fri',1),
(11, 'Sat',1),
(12, 'Sun',1),
(13, 'Mon',2),
(14, 'Tue',2),
(15, 'Wed',2),
(16, 'Thu',2),
(17, 'Fri',2),
(18, 'Sat',2),
(19, 'Sun',2),
(20, 'Mon',3),
(21, 'Tue',3),
(22, 'Wed',3),
(23, 'Thu',3),
(24, 'Fri',3),
(25, 'Sat',3),
(26, 'Sun',3),
(27, 'Mon',4),
(28, 'Tue',4),
(29, 'Wed',4),
(30, 'Thu',4),
(31, 'Fri',4),
(32, 'Sat',4),
(33, 'Sun',4),
(34, 'Mon',5),
(35, 'Tue',5),
(36, 'Wed',5),
(37, 'Thu',5),
(38, 'Fri',5),
(39, 'Sat',5),
(40, 'Sun',5),
(41, '07:00',6),
(42, '07:30',6),
(43, '08:00',6),
(44, '08:30',6),
(45, '09:00',6),
(46, '09:30',6),
(47, '10:00',6),
(48, '10:30',6),
(49, '11:00',6);
我会尝试将 get_child_categories 添加到您的 Swim 控制器作为一种方法:
function get_child_categories()
{
$id = $_REQUEST['parent_id'];
$query = $this->db->select('*')->from('categories')->where('pid', $id)->get();
$html = '<select name="sub_category" class="parent">';
$html .= '<option value="" selected="selected">-- Sub Category --</option>';
foreach ($query->result() as $row){
$html .= '<option value="'.$row->id.'">'.$row->category.'</option>';
}
$html .= '</select>';
echo $html;
}
在你看来,你会这样称呼它:
$.post("swim/get_child_categories", { //etc
有人可以帮忙吗?
我正在尝试将此代码转换为 CI,但我在使用 JQuery 时遇到问题,因为我不太理解它。
原始代码来自 - http://www.99points.info/2010/12/n-level-dynamic-loading-of-dropdowns-using-ajax-and-php/ - 在 CI.
之外完美运行我可以显示第一个下拉菜单。
然后在 'index2.php' 的第 15 行加载 'get_chid_categories.php' 时出现错误 - 我明白为什么(尝试从 'root' 中的文件读取数据库),但我有不知道如何解决它。
我的看法 - index2.php
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="/jquery.livequery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
//$('#loader').hide();
$('.parent').livequery('change', function() {
$(this).nextAll('.parent').remove();
$(this).nextAll('label').remove();
$('#show_sub_categories').append('</application/views/img src="loader.gif" style="float:left; margin-top:7px;" id="loader" alt="" />');
$.post("/get_chid_categories.php", {
parent_id: $(this).val(),
}, function(response){
setTimeout("finishAjax('show_sub_categories', '"+escape(response)+"')", 400);
});
return false;
});
});
function finishAjax(id, response){
$('#loader').remove();
$('#'+id).append(unescape(response));
}
</script>
<style>
.both h4{ font-family:Arial, Helvetica, sans-serif; margin:0px; font-size:14px;}
#search_category_id{ padding:3px; width:200px;}
.parent{ padding:3px; width:150px; float:left; margin-right:12px;}
.both{ float:left; margin:0 0px 0 0; padding:0px;}
</style>
</head>
<body>
<div id="show_sub_categories">
<select name="search_category" class="parent">
<option value="" selected="selected">-- Categories --</option>
<?php
foreach ($view->result() as $row)
{
?>
<option value="<?php echo $row->id;?>"><?php echo $row->category;?></option>
<?php
}
?>
</select>
</div>
<br clear="all" /><br clear="all" />
</body>
</html>
控制器 - Swim.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Swim extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->datestring = '%d/%m/%Y';
$this->datewrite = 'Y-d-m';
$this->load->model('Swim_model');
$this->load->helper('date');
$data['not_logged_in'] = 'You are not logged in';
$this->session->set_userdata($data);
}
public function index2()
{
$data['main_view'] = 'index2';
$data['view'] = $this->Swim_model->CRUD_categories();
$this->load->view('load_view',$data);
}
}
型号 - Swim_model.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Swim_model extends CI_Model {
public function __construct()
{
// Call the CI_Model constructor
parent::__construct();
}
public function CRUD_categories()
{
return $this->db->select('*')
->from('categories')
->where('pid', '0')
->get();
}
}
get_child_categories.php - 如果我把它放在 'root'
中,我只能让它包含这个文件<?php
if($_REQUEST)
{
$id = $_REQUEST['parent_id'];
$query = $this->db->select('*')
->from('categories')
->where('pid', $id)
->get();
?>
<select name="sub_category" class="parent">
<option value="" selected="selected">-- Sub Category --</option>
<?php
foreach ($query->result() as $row)
{
?>
<option value="<?php echo $row->id;?>"><?php echo $row->category;?></option>
<?php
}?>
</select>
<?php
}
?>
jquery.livequery.js - 也在 'root'
/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* Version: 1.0.3
* Requires jQuery 1.1.3+
* Docs: http://docs.jquery.com/Plugins/livequery
*/
(function($) {
$.extend($.fn, {
livequery: function(type, fn, fn2) {
var self = this, q;
// Handle different call patterns
if ($.isFunction(type))
fn2 = fn, fn = type, type = undefined;
// See if Live Query already exists
$.each( $.livequery.queries, function(i, query) {
if ( self.selector == query.selector && self.context == query.context &&
type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )
// Found the query, exit the each loop
return (q = query) && false;
});
// Create new Live Query if it wasn't found
q = q || new $.livequery(this.selector, this.context, type, fn, fn2);
// Make sure it is running
q.stopped = false;
// Run it immediately for the first time
q.run();
// Contnue the chain
return this;
},
expire: function(type, fn, fn2) {
var self = this;
// Handle different call patterns
if ($.isFunction(type))
fn2 = fn, fn = type, type = undefined;
// Find the Live Query based on arguments and stop it
$.each( $.livequery.queries, function(i, query) {
if ( self.selector == query.selector && self.context == query.context &&
(!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )
$.livequery.stop(query.id);
});
// Continue the chain
return this;
}
});
$.livequery = function(selector, context, type, fn, fn2) {
this.selector = selector;
this.context = context || document;
this.type = type;
this.fn = fn;
this.fn2 = fn2;
this.elements = [];
this.stopped = false;
// The id is the index of the Live Query in $.livequery.queries
this.id = $.livequery.queries.push(this)-1;
// Mark the functions for matching later on
fn.$lqguid = fn.$lqguid || $.livequery.guid++;
if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;
// Return the Live Query
return this;
};
$.livequery.prototype = {
stop: function() {
var query = this;
if ( this.type )
// Unbind all bound events
this.elements.unbind(this.type, this.fn);
else if (this.fn2)
// Call the second function for all matched elements
this.elements.each(function(i, el) {
query.fn2.apply(el);
});
// Clear out matched elements
this.elements = [];
// Stop the Live Query from running until restarted
this.stopped = true;
},
run: function() {
// Short-circuit if stopped
if ( this.stopped ) return;
var query = this;
var oEls = this.elements,
els = $(this.selector, this.context),
nEls = els.not(oEls);
// Set elements to the latest set of matched elements
this.elements = els;
if (this.type) {
// Bind events to newly matched elements
nEls.bind(this.type, this.fn);
// Unbind events to elements no longer matched
if (oEls.length > 0)
$.each(oEls, function(i, el) {
if ( $.inArray(el, els) < 0 )
$.event.remove(el, query.type, query.fn);
});
}
else {
// Call the first function for newly matched elements
nEls.each(function() {
query.fn.apply(this);
});
// Call the second function for elements no longer matched
if ( this.fn2 && oEls.length > 0 )
$.each(oEls, function(i, el) {
if ( $.inArray(el, els) < 0 )
query.fn2.apply(el);
});
}
}
};
$.extend($.livequery, {
guid: 0,
queries: [],
queue: [],
running: false,
timeout: null,
checkQueue: function() {
if ( $.livequery.running && $.livequery.queue.length ) {
var length = $.livequery.queue.length;
// Run each Live Query currently in the queue
while ( length-- )
$.livequery.queries[ $.livequery.queue.shift() ].run();
}
},
pause: function() {
// Don't run anymore Live Queries until restarted
$.livequery.running = false;
},
play: function() {
// Restart Live Queries
$.livequery.running = true;
// Request a run of the Live Queries
$.livequery.run();
},
registerPlugin: function() {
$.each( arguments, function(i,n) {
// Short-circuit if the method doesn't exist
if (!$.fn[n]) return;
// Save a reference to the original method
var old = $.fn[n];
// Create a new method
$.fn[n] = function() {
// Call the original method
var r = old.apply(this, arguments);
// Request a run of the Live Queries
$.livequery.run();
// Return the original methods result
return r;
}
});
},
run: function(id) {
if (id != undefined) {
// Put the particular Live Query in the queue if it doesn't already exist
if ( $.inArray(id, $.livequery.queue) < 0 )
$.livequery.queue.push( id );
}
else
// Put each Live Query in the queue if it doesn't already exist
$.each( $.livequery.queries, function(id) {
if ( $.inArray(id, $.livequery.queue) < 0 )
$.livequery.queue.push( id );
});
// Clear timeout if it already exists
if ($.livequery.timeout) clearTimeout($.livequery.timeout);
// Create a timeout to check the queue and actually run the Live Queries
$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
},
stop: function(id) {
if (id != undefined)
// Stop are particular Live Query
$.livequery.queries[ id ].stop();
else
// Stop all Live Queries
$.each( $.livequery.queries, function(id) {
$.livequery.queries[ id ].stop();
});
}
});
// Register core DOM manipulation methods
$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
// Run Live Queries when the Document is ready
$(function() { $.livequery.play(); });
// Save a reference to the original init method
var init = $.prototype.init;
// Create a new init method that exposes two new properties: selector and context
$.prototype.init = function(a,c) {
// Call the original init and save the result
var r = init.apply(this, arguments);
// Copy over properties if they exist already
if (a && a.selector)
r.context = a.context, r.selector = a.selector;
// Set properties
if ( typeof a == 'string' )
r.context = c || document, r.selector = a;
// Return the result
return r;
};
// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091)
$.prototype.init.prototype = $.prototype;
})(jQuery);
此文件会将类别加载到 MYSQL 数据库中
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(11) NOT NULL auto_increment,
`category` varchar(50) NOT NULL,
`pid` int(11),
PRIMARY KEY (`id`)
);
--
-- Dumping data for table `categories`
--
INSERT INTO `categories` (`id`, `category`, `pid`) VALUES
(1, 'Barncroft',0),
(2, 'Mary Rose',0),
(3, 'Petersfield',0),
(4, 'Redwood',0),
(5, 'Springfield',0),
(6, 'Mon',1),
(7, 'Tue',1),
(8, 'Wed',1),
(9, 'Thu',1),
(10, 'Fri',1),
(11, 'Sat',1),
(12, 'Sun',1),
(13, 'Mon',2),
(14, 'Tue',2),
(15, 'Wed',2),
(16, 'Thu',2),
(17, 'Fri',2),
(18, 'Sat',2),
(19, 'Sun',2),
(20, 'Mon',3),
(21, 'Tue',3),
(22, 'Wed',3),
(23, 'Thu',3),
(24, 'Fri',3),
(25, 'Sat',3),
(26, 'Sun',3),
(27, 'Mon',4),
(28, 'Tue',4),
(29, 'Wed',4),
(30, 'Thu',4),
(31, 'Fri',4),
(32, 'Sat',4),
(33, 'Sun',4),
(34, 'Mon',5),
(35, 'Tue',5),
(36, 'Wed',5),
(37, 'Thu',5),
(38, 'Fri',5),
(39, 'Sat',5),
(40, 'Sun',5),
(41, '07:00',6),
(42, '07:30',6),
(43, '08:00',6),
(44, '08:30',6),
(45, '09:00',6),
(46, '09:30',6),
(47, '10:00',6),
(48, '10:30',6),
(49, '11:00',6);
我会尝试将 get_child_categories 添加到您的 Swim 控制器作为一种方法:
function get_child_categories()
{
$id = $_REQUEST['parent_id'];
$query = $this->db->select('*')->from('categories')->where('pid', $id)->get();
$html = '<select name="sub_category" class="parent">';
$html .= '<option value="" selected="selected">-- Sub Category --</option>';
foreach ($query->result() as $row){
$html .= '<option value="'.$row->id.'">'.$row->category.'</option>';
}
$html .= '</select>';
echo $html;
}
在你看来,你会这样称呼它:
$.post("swim/get_child_categories", { //etc