用PHPRPC实现Ajax级联下拉菜单

级联下拉菜单就是从一个下拉菜单中选中一项后,相应的另一个下拉菜单的内容会随之改变。

一般来说,最简单的,就是每次选中都提交一次表单,刷新整个页面。这也是用户体验度最差的。

另一种是把所有选项在第一次加载时就全部载入整个页面中的 javascript 数组中,然后级联通过 JavaScript 来控制,在整个数据量不大时,这是一个不错的实现无刷新并且快速的方法,但是当整个数据量非常大时,这种方法就会使第一次加载变得非常慢了。

还有就是采用 Ajax 方式,即开始只载入第一层菜单的内容,当用户选中第一层菜单的某项时,再通过 XmlHttpRequest 来获取相应选项所对应的第二层菜单的内容。这种方式效果最好,但是采用传统方式来编写这样的 Ajax 程序代码量会比较多。而且如果设计不好,服务器端返回菜单内容的程序的可复用性也会很差。

但是在本文中你会看到用 PHPRPC 来实现这种 Ajax 效果是多么的简单,并且还会具有非常高的可复用性。

本文以省市两级级联下拉菜单为例,为了举例方便,本文中采用的是 SQLite 数据库,因为这个文件型数据库比较容易部署,而且查询效率很高(当然创建该数据库的效率不高,但创建仅一次而已,该数据库在该程序中内容是不变的),不过服务器需要安装 SQLite 扩展。

这个数据库中的表只有 2 个,一个 province 表,一个 city 表。province 表中,只有 id 和 name 两个字段,分别是省份编号(主键)和省名。city 表中,有 id、name 和 pid 三个字段,id 是城市编号,name 是城市名,pid 是城市所在省的编号,与 province 表中的省份编号相对应。

创建该数据库的程序这里就不给出来了,它包含在后面提供的实例下载中。

下面来看看创建这个程序的服务器端有多么简单,为了提高可复用性,我们把服务器端分为了 2 个文件,一个是 function.php,另一个是 rpc.php。function.php 中定义了实际的远程调用函数,但是他们也可以作为服务器端的本地函数调用,你会发现他们跟服务器端的普通函数没有任何区别:

下载: function.php
<?php
$sqlite = new SQLiteDatabase('area.db');

function get_province() {
global $sqlite;
$sql = "select * from province order by id";
return $sqlite->arrayQuery($sql, SQLITE_ASSOC);
}

function get_city($pid) {
global $sqlite;
$pid = sqlite_escape_string($pid);
$sql = "select * from city where pid = $pid order by id";
return $sqlite->arrayQuery($sql, SQLITE_ASSOC);
}
?>
而 rpc.php 更加简单,它是提供给客户端调用的接口,它只有 3 行语句:

下载: function.php
<?php
require_once('function.php');
require_once('phprpc_server.php');
new phprpc_server(array('get_province', 'get_city'));
?>
其中最后一句,就是指定哪些函数要暴露给客户端。只有指定的函数客户端才可以调用,这样可以保证服务器的安全性。

服务器端到此就创建完了。你会发现服务器端只负责把数据查询出来返回给客户端就完事了,其它的不做任何处理。

那么下面该看一看客户端了,客户端虽然很简单,但是我还是把它分成了两个文件,一个 js 文件,一个 html 文件,你会发现用 PHPRPC,客户端都不需要用 PHP。

下载: area.js
// 创建 phprpc 客户端对象 rpc
phprpc_client.create('rpc');

var city = []; // 用于缓存已加载的城市数据

/*
* 清除 select 中的选项,该方法可复用
*
* so: 要清除选项的 select 对象
*
*/
function clear_select(so) {
for (var i = so.options.length - 1; i > -1; i--) {
// 有些浏览器不支持 options 属性的 remove 方法,
// 但支持 DOM 的 removeChild 方法(比如:Konqueror)
if (so.options.remove) {
so.options.remove(i);
}
else {
so.removeChild(so.options[i]);
}
}
}

/*
* 设置 select 中的选项,该方法可复用
*
* so: 要设置选项的 select 对象
* d: 选项数据数组
* vf: 选项值所对应的数组中的字段名
* tf: 选项文本所对应的数组中的字段名
*/
function set_select(so, d, vf, tf) {
for (var i = 0, n = d.length; i < n; i++) {
var opt = document.createElement('option');
opt.text = d[i][tf];
opt.value = d[i][vf];
// 有些浏览器不支持 options 属性的 add 方法,
// 但支持 DOM 的 appendChild 方法(比如:Konqueror)
if (so.options.add) {
so.options.add(opt);
}
else {
so.appendChild(opt);
}
}
}

// 设置省份的下拉菜单
function set_province_select(d) {
var so = document.getElementById('province');
set_select(so, d, 'id', 'name');
// 设置首选省份的城市下拉列表
change_province(1);
}

// 设置城市的下拉菜单
function set_city_select(d, vf, tf) {
var so = document.getElementById('city');
// 清空原有选项
clear_select(so);
// 设置新选项
set_select(so, d, vf, tf);
}

// 当省份改变,相应的改变城市列表
function change_province(pid) {
// 如果已缓存,则直接显示缓存中的列表
if (city[pid]) {
set_city_select(city[pid], 'id', 'name');
}
else {
// 否则,先显示载入中
set_city_select([['', 'Loading...']], 0, 1);
// 然后调用远程过程载入城市信息
// 调用远程过程时,最后一个参数指定的是回调函数
rpc.get_city(pid, function (result) {
// 把载入的数据放入缓存
city[pid] = result;
// 更新城市列表
set_city_select(result, 'id', 'name');
});
}
}

// 定义当 rpc 客户端初始化(use_service)完毕后执行的内容
rpc.onready = function () {

时间: 2024-08-23 00:31:32

用PHPRPC实现Ajax级联下拉菜单的相关文章

用 PHPRPC 实现 Ajax 级联下拉菜单

ajax|菜单|下拉 级联下拉菜单就是从一个下拉菜单中选中一项后,相应的另一个下拉菜单的内容会随之改变. 一般来说,最简单的,就是每次选中都提交一次表单,刷新整个页面.这也是用户体验度最差的. 另一种是把所有选项在第一次加载时就全部载入整个页面中的 javascript 数组中,然后级联通过 JavaScript 来控制,在整个数据量不大时,这是一个不错的实现无刷新并且快速的方法,但是当整个数据量非常大时,这种方法就会使第一次加载变得非常慢了. 还有就是采用 Ajax 方式,即开始只载入第一层菜

jquery无限级联下拉菜单简单实例演示_jquery

本文实例讲述了jquery无限级联下拉菜单代码以及jquery无限级联下拉菜单实现思路.分享给大家供大家参考.具体如下: 最终效果图: 因为是级联,所以数据必须是树型结构的,这里的测试数据如下: 看下效果图: 1.效果图一:   2.效果图二:   3.效果图三:     由图可知,下拉框的个数并不是写死的,而是动态加载的.每当下拉框选择改变的时候,会发送一次ajax请求,请求成功返回json格式数据,当返回的数据不为空时(即有子节点时),则会向页面中添加一个下拉框,没有则不添加. 插件的实现代

Bootstrap每天必学之级联下拉菜单_javascript技巧

本文将介绍自定义的bootstrap级联下拉菜单,主要应用场合有省市级关联菜单等等,那么就先拿这个例子来讲,当然其他场景的关联菜单也同样适用.说实话,封装好一个通用的组件还是需要花费很多精力的和时间的,所谓通用,自然要考虑周全,叹!这次整理的Bootstrap关联select,里面也涉及到了很多jquery.ajax.springMVC等等知识点,可谓包罗万象! 首先,请允许我代表该自定义组件做一番小小的介绍. "hi,你好,我叫yunm.combox.js,主人给我起的名字,其实呢,挺俗的.我

js实现全国省份城市级联下拉菜单效果代码_javascript技巧

本文实例讲述了js实现全国省份城市级联下拉菜单效果代码.分享给大家供大家参考.具体如下: 这是一个大家都知道的网页小功能,很常见,全国省份与城市级联菜单,采用Select下拉的方式选择数据,不过现在很多都Ajax了,貌似这种老形式已经过时了,不过在兼容性方面,仍然是不落后的. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-conv-city-xl-menu-style-codes/ 具体代码如下: <!DOCTYPE html PUBLI

求关于asp.nat二级级联下拉菜单的做法

问题描述 asp.nat二级级联下拉菜单的做法,有两个表,都要从数据库中提取请诸位高手多多指教了. 解决方案 解决方案二:ajax解决方案三:css+[li,ul]isok解决方案四:up解决方案五: 解决方案六:2级数据不多的话可以用js来进行数组生成下拉菜单html如果数据多就用ajax调用返回html

AJAX级联下拉框的简单实现案例

 本篇文章主要是对AJAX级联下拉框的简单实现案例进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 需要的JAVA类    代码如下: package com.ajaxlab.ajax;  import java.util.ArrayList;  import java.util.Collection;  import java.util.Iterator;  import org.jdom.Document;  import org.jdom.Element;  import org.

java省市级联下拉菜单实例代码_java

本文实例为大家分享了java省市级联的具体代码,供大家参考,具体内容如下 1.LoadAreaServlet.java package com.scce.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; im

yii实现级联下拉菜单的方法_php实例

本文详细讲述了yii实现级联下拉菜单的方法,具体步骤如下: 1.模版中加入如下代码: <?php echo $form->dropDownList($model, 'src_type_id', OrderSrc::options(), array( <span style="white-space:pre"> </span>'id' => 'task-order-src-id', )); echo $form->dropDownList(

JS二级级联下拉菜单

问题描述 有一个二级级联下拉菜单,但是就是不显示,大侠们看看啥问题? <tr><td align="right">学院:</td><td><select name="role" onBlur="checkRole(this)" onchange="populateMajor(this.options[this.selectedIndex].value)"><op