justdoit 发表于 2012-2-28 22:43:55

与数据库进行交互的省市三级联动

本帖最后由 justdoit 于 2012-6-11 15:08 编辑

       之前,在网上查找与数据库进行交互的省级联动这方面的资料,发现大多数要不是紧紧实现了三级联动的效果,但是却不能与数据库,后台进行交互,要不就是方法不够简洁。
      此种场景多数用在网站的个人用户管理中心里面。      
   今天凑一时间,把我的思路和核心代码拿出来与大家分享,希望对大家能够有所帮助。效果图如下:

      
(注:此数据全是从数据库中取得的,当你修改相应的选项之后,表中的数据也会发生相应的变化,页面再次显示的时候也会相应的变化)
    1: 先说控制器:info.php
    function index()
    {      
       $data = array();
    $data['css'] = "<link type='text/css' rel='stylesheet' href='".base_url()."css/userhome.css'>";
    $data['css'] = "<link type='text/css' rel='stylesheet' href='".base_url()."css/user_userinfo.css'>";
    $data['title'] = '个人资料';
    $this->load->model('customer_model');
         //从session中取出用户(用户管理中心)对应的id,然后通过此id来取出对应的用户的相关资料信息
    $data['customer'] = $this->customer_model->load($this->session->userdata('user_id'));
         $this->load->model('customer_address_model');
         //通过取出来的id来到customer_address表中相关的信息
    $data['address'] = $this->customer_address_model->load($data['customer']['id']);
         //var_dump($data['address']);
         //为空的话,说明此用户还没有添加自己的相关资料信息
    if (empty($data['address'])){
         $data['address'] = array(
                'id' => null,
                'address_name' => null,
    'consignee' => null,
    'phone' => null,
    'mobile' => null,
    'invoice_head' => null,
    'province_id' => null,
    'city_id' => null,
    'district_id' => null,
    'address' => null,
    'postcode' => null,
    'fax' => null,
    'remark' => null,
    'is_default' => null,
            );
    }
          //如果不为空的话,说明用户已经添加了 自己的相关资料信息
          //将信息传给视图
    $this->load->view('customer/info',$data);
    }
2:模型:customer_model.php里的load()方法
    function load($id)
    {
      if (!$id){
            return array();
      }
      $query = $this->db->get_where('customer',array('id' => $id));
      
      if ($row = $query->row_array()){
            return $row;
      }
      return array();
    }
3:模型 customer_address_model.php里的load()方法   
/**
* load by id
*customer_address表里面包含了 收货人的基本信息province_id,city_id,district_id等
*
*/
    function load($customer_id)
    {
      if (!$customer_id){
            return array();
      }
      $query = $this->db->get_where('customer_address',array('customer_id' => $customer_id,'is_default' => 1));
      if ($row = $query->row_array()){
            return $row;
      }
      return array();
    }
4:模型:info.php里的部分html代码
   <tr>
<td align="center">所属地区:</td>
<td>
                  <!--在这里将数组中的 所属地区的那三个id赋值,传给子视图district_select-->
    <?php
   $data['province_selected'] = $address['province_id'];
   $data['city_selected'] = $address['city_id'];
   $data['district_selected'] = $address['district_id'];
   $this->load->view('widget/district_select', $data)
   ?>
         </td>
   </tr>
5:子视图:district_select.php
<?php
$CI = get_instance();
$CI->load->model('region_model', 'region');
$provinces   = $CI->region->provinces();   //此处代码的作用是取出所有的省份。下面的省份的下拉框取值就是用次来循环的
$citys = $CI->region->children_of($province_selected);
?>
<scriptlanguage="JavaScript">
<!--
//判断$province_selected,$city_selected,$district_selected等这些值是否为空,为空的话,说明该用户还没有添加自己的所属地区,不为空的话就赋给相应的JS变量,它是从数据库中取出来的值,以便在下拉框中该选择哪个省份的时候与循环出来的结果集进行比较,从而来决定哪一个值该选中
<?php if(isset($province_selected)):?>
var province_selected = <?php echo (int)$province_selected?>;
<?php else:?>
var province_selected = 0;
<?php endif?>
<?php if(isset($city_selected)):?>
var city_selected = <?php echo (int)$city_selected?>;
<?php else:?>
var city_selected = 0;
<?php endif?>
<?php if(isset($district_selected)):?>
var district_selected = <?php echo (int)$district_selected?>;
<?php else:?>
var district_selected = 0;
<?php endif?>
$(document).ready(function() {
var change_city = function(){
$.ajax({
   url: '<?php echo site_url('region_change/select_children/parent_id')?>'+'/'+$('#province_id').val(),//也就是发送给控制器region_change.php()的select_children()方法
   type: 'GET',
   dataType: 'html',
   success: function(data){
city_json = eval('('+data+')');//转化为对象
var city = document.getElementById('city_id');
city.options.length = 0;
city.options = new Option('城市', ''); //创建新的option
for(var i=0; i<city_json.length; i++){    //对json对象进行循环
            var len = city.length;
   city.options = new Option(city_json.region_name, city_json.region_id); //分别取出json数据返回的name和region_id,并赋给下拉框
   if (city.options.value == city_selected){
    city.options.selected = true;
   }
}
change_district();//重置地区
   }
});
}
change_city();//初始化城市
$('#province_id').change(function(){
   change_city();
});

var change_district = function(){
$.ajax({
   url: '<?php echo site_url('region_change/select_children/parent_id')?>'+'/'+$('#city_id').val(),
   type: 'GET',
   dataType: 'html',
   success: function(data){
      district_json = eval('('+data+')');
var district = document.getElementById('district_id');
district.options.length = 0;
district.options = new Option('县/区', '');
for(var i=0; i<district_json.length; i++){
            var len = district.length;
   district.options = new Option(district_json.region_name, district_json.region_id);
   if (district.options.value == district_selected){
    district.options.selected = true;
   }
}
   }
});
}
$('#city_id').change(function(){
   change_district();
});


});
//-->
</script>
<select name="province_id" id="province_id"style="width:100px;">
    <option value="" >省份</option>
<?php foreach($provinces as $key => $province): ?>
<option value="<?php echo $province['region_id']; ?>" <?php if($province['region_id']==$province_selected){echo 'selected';}?> ><?php echo $province['region_name']; ?></option>
<?php endforeach; ?>
</select>
<select name="city_id" id="city_id"style="width:100px;">
    <?php foreach($citys as $key => $city): ?>
<option value="<?php echo $city['region_id']; ?>" <?php if($city['region_id']==$city_selected){echo 'selected';}?> ><?php echo $city['region_name']; ?></option>
<?php endforeach; ?>
</select>
<select name="district_id" id="district_id" style="width:100px;">
    <option value=""></option>
</select>
7:控制器region_change.php()
function select_children()
{
            $segments = $this->uri->uri_to_assoc();
            //var_dump($segments['parent_id']);
            $this->load->model('region_model');
            $data['children']   = $this->region_model->children_of($segments['parent_id']);
            echo json_encode($data['children']);//返回json格式的数据
}
8:模型:region_model.php里的 provinces()和children_of()方法
function provinces()
    {
      //调用children_of(1)函数,并将parent_id=1;这样的话,就取出了所有parent_id为1的值,即所有的省份
      return $this->children_of(1);
    }
    function children_of($parent_id, $select="*")
    {
      $parent_id = (int)$parent_id;
      //echo $parent_id;
      $regions = array();
      $this->db->select($select);
      $this->db->where('parent_id', $parent_id);
      //从region表中由parent_id选取所有的子集
      if ($query = $this->db->get('region')){
            $res=$query->result_array();
            //print_r($res);
            return $query->result_array();//返回一个关联数组
}
return array();      
    }
至此,思路和核心代码已经完成希望对大家能够有所帮助。如有疑问,可留言。



sqq421687517 发表于 2012-2-29 15:27:32

asdsad

believe 发表于 2012-3-17 10:23:45

好样的,学习了,最近做一个旅游网,刚好可以用到这个,试用了

zhengfeity 发表于 2012-3-17 13:42:51

不错的分享 呵呵!

hlh54321 发表于 2012-8-1 17:51:22

很棒的文章,谢谢

yogo 发表于 2013-2-3 21:49:05

{:soso_e179:}

mark35 发表于 2013-5-16 22:20:00

这是我写的无限级联动下拉菜单,支持本地js数据源和ajax获取
http://linkagesel.xiaozhong.biz/
页: [1]
查看完整版本: 与数据库进行交互的省市三级联动