精华内容
下载资源
问答
  • 列表框和组合框的使用

    千次阅读 2010-06-24 15:21:00
    列表框是显示一系列项供用户选择的控件,对选中的项可以进行后续的处理。用户选择可以是多项的,但本章的例程设计为单选的。组合框是一个编辑框带一个可以下拉的列表框,用户在下拉框中选择的项会进入编辑框中...

    列表框是显示一系列项供用户选择的控件,对选中的项可以进行后续的处理。用户选择可以是多项的,但本章的例程设计为单选的。组合框是一个编辑框带一个可以下拉的列表框,用户在下拉框中选择的项会进入编辑框中,再进行后续处理,选择也可以用键盘的光标键。在编辑框中也可以直接输入。

     

    本章要点

    1 列表框的设计、项的添加和删除
    2 组合框的设计和使用

     

    12.1 ListCombo程序运行时的界面和功能

     

     VC++60 <wbr>第十二章 <wbr>列表框和组合框
    chap12-01

    List1在初始化时加入了六项。点击[<]按钮就把选中的项移动到List2中去。点击[>]按钮则相反。点击[<<]和[>>]按钮则移动全部项。用[清除列表]按钮可删除List1的全部项。[加入到]按钮把你选中的在编辑框中项添加到List1中,[加入全部]按钮则把组合框设置的所有项添加到List1中。组合框预置了“中国”这一项,但没有设计删除功能。列表框和组合框都有一个从0开始的整数索引和一个用于显示的文本。

     

    12.2 对话框界面设计

     

    按控件属性表设计界面。

    控件类型 标题 ID and Genaral Styles Extended Styles
    listBox   IDC_LIST1
    显示checked
    选择Simple,Border
    Virteber scroll
    listBox   IDC_LIST2
    显示checked
    选择Simple,Border
    Virteber scroll
    ComboBox   IDC_CONTRIES_COMBO
    显示checked
    类型:Drop list
    Virteber scroll
    Static edge
    Button < IDC_MOVE_BUTTON
    Button > IDC_BACK_BUTTON
    Button << IDC_MOVEALL_BUTTON
    Button >> IDC_BACKALL_BUTTON
    Button 清除列表 IDC_CLEAR_BUTTON Client edge
    Button 加入到 IDC_ADD_BUTTON Client edge
    Button 加入全部 IDC_ADDALL_BUTTON Client edge
    Button 退出 IDC_EXIT_BUTTON Client edge
    Static edge
    Modal Frame

    属性表中列出的表示“选中”,TAB复选框都要选中,就省略了。组合框可以在DATA属性页中设置项的文本,本例采用这种方法。其数据是:
    中国,美国,俄罗斯,英国,法国,德国,印度,巴基斯坦,
    日本,加拿大,澳大利亚,韩国,伊朗,伊拉克

    逗号处要改为换行,换行用Ctrl+<回车键>。设计好的界面如图chap12-02所示。

    VC++60 <wbr>第十二章 <wbr>列表框和组合框
    chap12-02

     

    12.3 设计变量和编写代码

     

    1 为三个列表框和组合框引进变量
    因为我们要对列表框的项进行操作,所以要申明三个对象类型的变量
    m_myList1
    m_myList2
    m_myCombo。

     

    2 定义一个字符串数组
    定义一个字符串数组m_myItems用来存放组合框的项的文本。在对话框的头文件的类CListCombaDlg的构造函数中申明:
        CString m_myItems[20];

     

    3 给初始化函数编写代码
    在OnInitDialog()中我们要从组合框控件获取项目的文本,给字符串数组m_myItems赋值。再用它的前六项为List1初始化。最后为组合框设置项“中国”为预选项。
    从组合框控件获取项用函数GetLBText(index, str),它把索引值为index的项的文本拷贝给str。给列表框赋值用AddString(string)函数,它在列表的尾部增加一项。类似地还可以用插入函数InsearString(...)。在// TODO: Add extra initialization here 这行的后面,我们添加如下代码:

       int count = m_myCombo.GetCount();  //获取组合框的项数
       int i =0;
        //从组合框控件获取项的文本
        for(i =0; i<count; i++)
             m_myCombo.GetLBText(i, m_myItems[i]);
        //List1初始化,六项
        for(i =0; i<6 ; i++)
            m_myList1.AddString(m_myItems[i]);
        //设置组合框默认选择项为"中国"
        m_myCombo.SetCurSel(0);

     

    4 给4个移动按钮写代码
    MOVE按钮[<]的功能是从List1中得到用户选定顶的索引号,再从这索引号获取选定顶的文本,然后删除这一项,在List2中添加一项。当前项
    获取索引号函数 index=GetCurSel()返回整数。 获取选定项的文本用函数GetText(index, item),它把指定项的文本拷贝到字符串item中。
    OnMoveButton()函数的完整代码如下:

    来源:(http://blog.sina.com.cn/s/blog_5e8a23f90100czpt.html) - VC++60 第十二章 列表框和组合框_东方一峰_新浪博客

    void CListCombaDlg::OnMoveButton()
    {
        CString item;
        int index = m_myList1.GetCurSel(); //获取选定顶索引号
        m_myList1.GetText(index, item);       //获取选定顶的文本
        m_myList1.DeleteString(index);         //删除一项
        m_myList2.AddString(item);              //添加到List2中
        m_myList1.SetCurSel(0);                   //设置首项为当前项
    }

    MOVEALL按钮的代码与上面的类似,加上循环语句就行。

    void CListCombaDlg::OnMoveallButton()
    {
      
      // TODO: Add your control notification handler code here
        CString item;

        int index =0 ;
        while(m_myList1.GetCount() >0){
            m_myList1.GetText(0, item);
            m_myList1.DeleteString(0);
            m_myList2.AddString(item);   
        };
    }
    BACK和BACKALL按钮的代码和上面的一样,只要把m_myList1和m_myList2对调就行。

     

    5 从组合框向列表框1加入当前项的代码
    这与列表框不同的是获取文本的函数名不大一样,用函数GetLBText,其余都相同。在OnAddButton()中加入代码:

    void CListCombaDlg::OnBackallButton()
    {
        // TODO: Add your control notification handler code here
        CString item;
        int index =0 ;
        while(m_myList2.GetCount() >0){
            m_myList2.GetText(0, item);
            m_myList2.DeleteString(0);
            m_myList1.AddString(item);   
        };
    }

    从组合框向列表框1加入全部项的代码如下:

    void CListCombaDlg::OnAddallButton()
    {
       //Clear old items in Linst at first
        CString item;
        while(m_myList1.GetCount()>0)
            m_myList1.DeleteString(0);
        int n = m_myCombo.GetCount();
        //Add all items
        for(int i=0; i<n; i++){
            m_myCombo.GetLBText(i, item);
            m_myList1.AddString(item);
        }   
    }

     

    6 [清除列表]和[退出]按钮的代码

    [清除列表]的按钮的代码:
        while(m_myList1.GetCount()>0)
            m_myList1.DeleteString(0);

    [退出]按钮的代码: OnOK();

     

    12.4 编译和运行

     

    至此,我们完成了界面设计和代码编写,可以编译和Build了。编译通过就可以在运行中测试程序,检查是否满足我们的设计要求。但是,代码编写常常会有许多错误,编译器会报告一大堆错误。虽然指出了错误所在的行,但要明白是什么错误还是很费劲的。如果我们在完成一部分工作后就编译一次,错误就比较少,容易找到和纠正。所以我们分以下几步来编译。
    1、界面完成后编译一次,这时运行可以看到组合框有了信息和可以选择了。
    2、对话框初始化编写后编译和运行一次,这时可以看到列表框有了信息。
    3、MOVE按钮写了代码后编译和运行一次,这时可以测试移动功能是否正确。如果成功,那这代码可以放心地复制到其他三个按钮去了。
    4、全部完成后的编译和运行。

     

    12.5 小结

     

    1 列表框和组合框属性设置中有类型选择
    组合框有三种情况:Simple, Dropdown, Drop List。Simple类型的组合框的列表框部分是固定显示的,不能下拉;而其余两种带一个下拉手柄。设计中别忘记添加滚动条。Dropdown与Drop List的区别是后者的编辑框不能输入。列表框也有三种情况:Simple, Multiple, Extended,它们决定了用户选取项的方法。Simple模式只能够选取单项,Multiple模式可以按Ctrl键+鼠标左键选取多个项,而Extended则可以通过鼠标拖处矩形一次选取连续的项,也可以加按Ctrl键作多次选择。

    2 列表框在属性页不能设置项的文本(字符串),而组合框能。

    3 列表框和组合框中的“项”都有索引号(0,1,2,...)和文本(在窗口显示)。两者都有成员函数来获取和设置这些信息。得到文本的函数名称不一样,列表框是GetText(),组合框是GetLBText()。字母LB的意思是ListBox,GetLBText的意思是“从自身的列表框中获取文本”。

    4 列表框和组合框常用的几个函数原型

    列表框的取索引号和文本的函数原型
    获取文本:
    void GetText( int nIndex, CString& rString ) const;
    用于单选模式的获取和设置索引号:
    int GetCurSel( ) const;
    int SetCurSel( int nSelect );
    用于多选模式的:
    int GetSel( int nIndex ) const;
    上式如果nIndex项是被选中的,就返回它的索引号,否则返回0。
    int SetSel( int nIndex, BOOL bSelect = TRUE );
    bSelect = TRUE就选中索引为nIndex的项,如是FALSE,则取消“选中”:如果nIndex=-1,就是全“选中”或全“不选中”。

    组合框的获取索引号和文本的函数原型
    int GetCurSel( ) const;
    int SetCurSel( int nSelect );
    void GetLBText( int nIndex, CString& rString ) const;

    添加、插入和删除项的函数原型
    int AddString( LPCTSTR lpszItem );
    int InsertString( int nIndex, LPCTSTR lpszItem );
    int DeleteString( UINT nIndex );

     

    展开全文
  • 作者:圈圈来源公众号:宏基因组学习R语言,需要先安装R语言,只需要从 https://www.r-project.org/ 下载适合你系统的最新版本软件安装即可。R语言有...
        

    640?wxfrom=5&wx_lazy=1

    作者:圈圈

    来源公众号:宏基因组

    640?wx_fmt=gif&wxfrom=5&wx_lazy=1

    学习R语言,需要先安装R语言,只需要从 https://www.r-project.org/ 下载适合你系统的最新版本软件安装即可。R语言有个优秀的环境叫Rstudio,具体安装可参考  《R语言学习 - 入门环境Rstudio》一文。


    R语言中的数据类型(Data Types)

    R语言的对象(Objects)主要包括向量、矩阵、数组、数据框和列表。

    640?wx_fmt=png&wxfrom=5&wx_lazy=1

    R语言的对象有五种最基本的类型,即,字符型(character)、数值型(numeric,包括小数)、整型(integer)、复数型(complex)以及逻辑型(logical,TRUE/FALSE)

    属性是R语言对象的一部分。主要包括以下几种:名字(names,dimnames),维度(dimensions,包括矩阵等),类别(class,包括数字、整数等),长度(length),以及其他。可通过 attributes()函数查看对象的属性,不是所有对象都有属性,如果没有则返回NULL。


    1. 向量

    向量(vector)是R语言中最基本的数据类型,执行组合功能的函数 c()可用来创建向量。

    各类向量如下例所示:

    1. a <- c (1, 2, 7, -4, 5)            ## numeric

    2. b <- c ("Rice", "Wheat")           ## character

    3. c <- c (TRUE, TRUE, FALSE, TRUE)   ## logical

    4. d <- c (1+0i, 2+4i)                ## complex

    5. e <- c (9:17)                      ## integer

    注意:单个向量中的数据必须拥有相同的类型(数值型、字符型或逻辑型)。

    创建空向量可以使用 vector()函数。例如创建一个指定长度为10、类型为数值型的空向量:

    1. > x <- vector("numeric", length = 10)

    2. > x

    3. [1] 0 0 0 0 0 0 0 0 0 0

    另外,标量是只含一个元素的向量,它们用于保存常量。例如

    1. f <- 3

    2. g <- "US"

    3. h <- TRUE

    2. 矩阵

    矩阵(matrice)是具有维度属性的向量,矩阵都是二维的,和向量类似,矩阵中也仅能包含一种数据类型。

    主要有三种创建矩阵的方法:

    (1)直接创建

    例:数字1-20自动创建为一个5行4列的矩阵,自动填充第一列之后开始填充第二列

    1. y <- matrix(1:20, nrow = 5, ncol = 4)

    2. > y

    3.     [,1] [,2] [,3] [,4]

    4. [1,]    1    6   11   16

    5. [2,]    2    7   12   17

    6. [3,]    3    8   13   18

    7. [4,]    4    9   14   19

    8. [5,]    5   10   15   20

    9. > dim(y)                          

    10. [1] 5 4                            ##dim()看维度,5行4列

    (2)矢量+维度向量

    添加维度向量 dim()是将矢量转变为矩阵的方法

    1. > m <- c(1:10)

    2. > m

    3. [1]  1  2  3  4  5  6  7  8  9 10

    4. > dim(m) <- c(2,5)                   ##2行5列          

    5. > m

    6.     [,1] [,2] [,3] [,4] [,5]

    7. [1,]    1    3    5    7    9

    8. [2,]    2    4    6    8   10

    (3)绑定行或列来创建矩阵

    绑定行或绑定列可以通过 cbind()rbind()来实现

    1. > x <- 1:3

    2. > y <- 10:12

    3. > cbind (x, y)

    4.     x  y

    5. [1,] 1 10

    6. [2,] 2 11

    7. [3,] 3 12

    8. > rbind (x, y)

    9.  [,1] [,2] [,3]

    10. x    1    2    3

    11. y   10   11   12

    3. 数组

    数组(array)与矩阵类似,但是维度可以大于2。数组可通过array函数创建。

    4. 列表

    列表(list)是一种可包含多种不同类型对象的向量,是一些对象(或成分,component)的有序集合。

    1. > x <- list(1, "a", TRUE, 1 + 4i)

    2. > x

    3. [[1]]

    4. [1] 1

    5. [[2]]

    6. [1] "a"

    7. [[3]]

    8. [1] TRUE

    9. [[4]]

    10. [1] 1+4i

    5.数据框

    数据框(Data Frames)是一种特殊的列表,其中所用元素长度都相等,列表中的每个元素都可以看作一列,每个元素的长度可以看作行数。

    创建显式数据框的方法是 data.frame()

    1. > ID <- c(1,2,3,4)

    2. > age <- c(25,26,55,43)

    3. > diabetes <- c("Type1","Type2","Type3","Type1")

    4. > status <- c("Poor", "Improved", "Excellent","Poor")

    5. > data <- data.frame(ID, age, diabetes, status)

    6. > data

    7.  ID age diabetes    status

    8. 1  1  25    Type1      Poor

    9. 2  2  26    Type2  Improved

    10. 3  3  55    Type3 Excellent

    11. 4  4  43    Type1      Poor

    参考资料:

    1. https://bookdown.org/rdpeng/rprogdatascience/R Programming for Data Science

    2. 《R语言实战》 Robert I. Kabacoff




    一套SVIP课程,15选8,每套课程均价112!知识付费的时代,一次旅游的钱便能收获8大全方位、多体系的课程
    更有全场六折优惠课程,为你加油助力!

    640?wx_fmt=png


    天善学院SVIP,只为让你更优秀!

    这里“阅读原文”,查看更多

    展开全文
  • 在Web页面中经常需要实现如图5-2所示的级联菜单的效果。即根据用户的选择,动态展开并显示出对应选项子菜单中的内容。本例中是根据用户所选择的商品类别信息,在子菜单中显示对应的商品名称。图5-2 级联菜单的效果...
    在Web页面中经常需要实现如图5-2所示的级联菜单的效果。即根据用户的选择,动态展开并显示出对应选项子菜单中的内容。本例中是根据用户所选择的商品类别信息,在子菜单中显示对应的商品名称。
    5-2  级联菜单的效果
    在传统的Web实现方式中,一般是在页面初始化时动态获取到服务器端数据库中对应所有子菜单中的信息,放置页面中对应的位置,然后在结合CSS层叠样式表动态控制对应子菜单的显示或者隐藏。
    采用这种方法的弊端在于会造成浏览器端下载的页面非常臃肿,许多根本用不到的信息也必须提前装载到页面中。
    而如果借助Ajax技术,我们可以实现当用户选择对应的菜单项后,将对应的请求以异步方式提交到服务器端,然后有选择地从服务器端获取到对应的子菜单信息,再返回浏览器端进行响应显示。
    首先在Eclipse中新建一个Web项目,项目名称为P52_Menu,对应的浏览器端页面代码如下:
    源文件:menu.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <head>
          <META http-equiv=Content-Type content="text/html; charset=UTF-8">
          <LINK href="images/css.css" type=text/css rel=stylesheet>
    </head>
    <script language="javascript">
           var XMLHttpReq;
           var currentSort;
           //创建XMLHttpRequest对象
          function createXMLHttpRequest() {
                 if(window.XMLHttpRequest) { //Mozilla 浏览器
                        XMLHttpReq = new XMLHttpRequest();
                 }
                 elseif (window.ActiveXObject) { // IE浏览器
                        try {
                               XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
                        } catch(e){
                               try{
                                     XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
                               } catch (e) {}
                        }
                 }
          }
          //发送请求函数
          function sendRequest(url) {
                 createXMLHttpRequest();
                 XMLHttpReq.open("GET", url, true);
                 XMLHttpReq.onreadystatechange = processResponse;//指定响应函数
                 XMLHttpReq.send(null);  // 发送请求
           }
           // 处理返回信息函数
          function processResponse() {
           if(XMLHttpReq.readyState == 4) { // 判断对象状态
                 if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息
                             updateMenu();
                      }else{ //页面不正常
                            alert("您所请求的页面有异常。");
                      }
                }
          }
          //更新菜单函数
          function updateMenu() {
                var res=XMLHttpReq.responseXML.getElementsByTagName("res")
                var subMenu = "";
                for(var i = 0; i < res.length; i++) {
                     subMenu = subMenu + "&nbsp;&nbsp;" + res[i].firstChild.data + "<br>";
                }
                currentSort.innerHTML = subMenu;
         }
         // 创建级联菜单函数
         function showSubMenu(obj) {
                currentSort =document.getElementById(obj);
                currentSort.parentNode.style.display = "";
                sendRequest("menu?sort=" + obj);
         }
     
    </script>
     
    <table  style="BORDER-COLLAPSE: collapse" borderColor=#111111
                     cellSpacing=0 cellPadding=0 width=200 bgColor=#f5efe7 border=0>
         <TR>
              <TD align=middle height=4><IMG height=4
              src="images/promo_list_top.gif" width="100%"
              border=0>
               </TD>
         </TR>
         <TR>
           <TD align=middle bgColor=#dbc2b0
                           height=19><B>笔记本品牌</B>
           </TD>
         </TR>
         <tr>
             <td height="20">
                      <a onClick="showSubMenu('IBM')">IBM</a>
              </td>
        </tr>
        <tr style="display:none">
             <td height="20" id="IBM"> </td>
        </tr>
        <tr>
             <td height="20">
                      <a onClick="showSubMenu('SONY')">SONY</a>
              </td>
        </tr>
        <tr style="display:none ">
            <td id="SONY" height="20"> </td>
        </tr>
    </table>
    在该页面中提供了对应的菜单以供用户进行选择,用户选择菜单后,将调用“showSubMenu('XXX')函数,该函数带参数,其中参数用于传递所选菜单项的标志信息,以决定获取服务器端的哪个子菜单信息。在“showSubMenu('XXX')函数中首先获取到所选菜单项的识别信息,然后再借助Ajax提交请求,并同时提交用户所选菜单的标识信息到服务器端,等待服务器端的处理。当服务器端处理完成后,将返回对应的子菜单信息,在Ajax提供的处理函数中对应菜单项的位置进行显示,这里用innerHTML属性实现定位显示。
    该Web应用的配置文件web.xml对应的代码如下所示。从该配置文件中可以了解到,当浏览器端提交“menu”请求时,将由服务器端的类名为“classmate.MenuAction的Servlet程序进行处理。
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
     
        <servlet>
             <servlet-name>ms1</servlet-name>
             <servlet-class>classmate.MenuAction</servlet-class>
        </servlet>
     
       <servlet-mapping>
             <servlet-name>ms1</servlet-name>
             <url-pattern>/menu</url-pattern>
        </servlet-mapping>
     
       
    <!-- The Welcome File List -->
      <welcome-file-list>
        <welcome-file>menu.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    下面我们关注一下服务器端Servlet程序MenuAction.java中对应的程序代码。当接收到浏览器端提交的请求后,Servlet程序将首先获取浏览器端提交的所选菜单项的标志信息,即所选择的商品类别信息,然后借助封装了数据库操作的JavaBean完成数据库的查询工作,依据类别获取到对应商品名称的信息。
    package classmate;
     
    import java.io.IOException;
    ……
    public class MenuAction extends HttpServlet {
       
           public void init(ServletConfig config) throws ServletException {
          }
     
          /*
           * 处理<GET> 请求方法
           */
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
         //设置接收信息的字符集
         request.setCharacterEncoding("UTF-8");
         //接收浏览器端提交的信息
                String sort = request.getParameter("sort");
                //设置输出信息的格式及字符集       
            response.setContentType("text/xml; charset=UTF-8");
            response.setHeader("Cache-Control", "no-cache");
            //创建输出流对象
            PrintWriter out = response.getWriter();
            //依据验证结果输出不同的数据信息
            out.println("<response>");   
     
            //数据库操作
            DB db = new DB();
               ResultSet rs;
            String strSql=null;
            //查找该品牌具体型号
            strSql = "select product.name from sort,product where sort.id=product.sortid
                          and sort.name='"+ sort + "'";
               rs = db.executeQuery(strSql);
               try {
                       while (rs.next()) {
                                out.println("<res>" + rs.getString("name") + "</res>");
                       }
               }catch (SQLException e) {
                       e.printStackTrace();
               }
     
               out.println("</response>");
               out.close();
        }
    }
    注意在本例中,返回的XML文档的格式如下所示:
    <response>
          <res>商品名称1</ res>
          <res>商品名称2</ res>
    </response>
    提示:读者可以进一步完善该程序,实现从服务器端动态获取菜单项信息,然后再依据用户选择动态显示子菜单信息的效果。这里所说的刷新,指的是通过重发URL请求来从服务器获得更新的数据以更新视图的显示。
    实现动态加载列表框

    本例中所实现的效果如图5-3所示。当用户在品牌选择的下拉列表框中选择了对应品牌后,该品牌下所有的商品信息将会动态出现在商品选择列表框中以供用户进一步选择。这种表单元素之间的联动效果在网页中非常常用。例如,随着所选专业,显示班级选择列表。随着所选部门,显示职务选择列表等。

    传统的Web实现方式,页面初始化时准备好所有列表框中的信息,并通过逻辑控制建立列表框之间对应选项的联系。再依据用户的选择,通过逻辑判断将事先准备好的列表框信息装入对应的联动列表框中。

    这种方法的弊端是造成浏览器端下载的页面非常臃肿,许多在本次交互中根本用不到的信息也必须提前装载到页面中。

    5-3  动态加载列表框的效果

    借助Ajax技术,可以实现当用户选择第一个列表框中对应的选项后,将对应的请求以异步方式提交到服务器端,然后有选择地从服务器端获取到下一个列表框中的列表信息,再返回浏览器端进行响应显示,下面介绍一下具体的实现过程。

    首先在Eclipse中新建一个Web项目,项目名称为P53_DyList,对应的浏览器端页面代码如下:

    源文件:dyList.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>

    <head>

         <META http-equiv=Content-Type content="text/html; charset=UTF-8">

    </head>

    <script language="javascript">

          var XMLHttpReq;

          //创建XMLHttpRequest对象      

          function createXMLHttpRequest() {

                 if(window.XMLHttpRequest) { //Mozilla 浏览器

                        XMLHttpReq = new XMLHttpRequest();

                 }

                 else if (window.ActiveXObject) { // IE浏览器

                        try {

                               XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");

                        } catch (e) {

                               try {

                                       XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");

                               } catch (e) {}

                        }

                 }

          }

          //发送请求函数

          function sendRequest(url) {

                 createXMLHttpRequest();

                 XMLHttpReq.open("GET", url, true);

                 XMLHttpReq.onreadystatechange = processResponse;//指定响应函数

                 XMLHttpReq.send(null);  // 发送请求

          }

          // 处理返回信息函数

          function processResponse() {

           if (XMLHttpReq.readyState == 4) { // 判断对象状态

                 if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息

                        updateList();

                } else { //页面不正常

                      window.alert("您所请求的页面有异常。");

                }

             }

        }

        // 刷新列表框函数

        function refreshList() {

             var sort = document.getElementById("sort").value;

             if(sort == "" ) {

                    clearList();

                    return;

             }

             var url = "dyList?sort=" + sort;         

              sendRequest(url)

         }

        // 更新列表框中列表项函数

         function updateList() {

              clearList();

              var product = document.getElementById("product");

              var results = XMLHttpReq.responseXML.getElementsByTagName("name");

              var option = null;

     

              for(var i = 0; i < results.length; i++) {

                   option = document.createElement("option");

                   option.appendChild(document.createTextNode(results[i].firstChild. nodeValue));

                   product.appendChild(option);

              }

         }

        // 清除列表框中原有选项的函数

         function clearList() {

              var product = document.getElementById("product");

              while(product.childNodes.length > 0) {

                   product.removeChild(product.childNodes[0]);

              }

         }

     

    </script>

     

    <table  style="BORDER-COLLAPSE: collapse" borderColor=#111111

                cellSpacing=0 cellPadding=2 width=200 bgColor=#f5efe7 border=0>

        <TR>

             <TD align=middle height=4 colspan="2"><IMG height=4

             src="images/promo_list_top.gif" width="100%"

             border=0>

              </TD>

        </TR>

        <TR>

           <TD align=middle bgColor=#dbc2b0

                           height=19 colspan="2"><B>商品搜索</B>

           </TD>

        </TR>

        <tr>

            <td height="20">

                       品牌选择:

             </td>

             <td height="20">

                    <select id="sort" οnchange="refreshList();">

                           <option value="default">请选择</option>

                           <option value="IBM">IBM</option>

                           <option value="SONY">SONY</option>

                           <option value="联想">联想</option>

                    </select>

              </td>

     

        </tr>

         <tr>

              <td height="20">

                     商品信息:

              </td>

              <td height="20">

              <select id="product" >

              </select>

              </td>

         </tr>

     

    </table>

    在该页面中,第一个列表框中提供了对应的品牌选项以供用户进行选择,当用户选择了所需的品牌信息后,将调用“refreshList()函数,在该函数中首先获取到所选列表项的标志信息,如果用户选择的是“请选择”,则调用“clearList()”函数清除第二个列表框中的内容,如果用户选择的是有效的品牌选项,则借助Ajax提交请求,并同时提交用户所选选项的标识信息到服务器端,等待服务器端的处理。当服务器端后续处理完成后,将返回第二个列表框中的信息,然后在Ajax提供的处理函数中在对应的列表框中显示,在显示时使用了本书第3章中介绍的使用DOM操作HTML的方式。

    Web应用的配置文件web.xml对应的代码如下所示。从该配置文件中可以了解到,当浏览器端提交“dyList”请求时,将由服务器端的类名为“classmate.DyListActionServlet程序进行处理。

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app version="2.4"

         xmlns="http://java.sun.com/xml/ns/j2ee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

     

         <servlet>

             <servlet-name>ms1</servlet-name>

             <servlet-class>classmate.DyListAction</servlet-class>

         </servlet>

     

        <servlet-mapping>

              <servlet-name>ms1</servlet-name>

              <url-pattern>/dyList</url-pattern>

         </servlet-mapping>

     

     

    <!-- The Welcome File List -->

      <welcome-file-list>

        <welcome-file>dyList.jsp</welcome-file>

      </welcome-file-list>

    </web-app>

    下面我们关注一下服务器端Servlet程序DyListAction.java中对应的程序代码。当接收到浏览器端提交的请求后,Servlet程序首先获取浏览器端提交的所选列表项的标志信息,即所选择的商品类别信息,然后借助封装了数据库操作的JavaBean完成数据库的查询工作,依据类别获取到对应的商品名称信息。

    package classmate;

     

    import java.io.IOException;

    ……

     

    public class DyListAction extends HttpServlet {

       

          public void init(ServletConfig config) throws ServletException {

         }

     

        /*

         *  处理<GET> 请求方法

         */

        protected void doGet(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

         //设置接收信息的字符集

         request.setCharacterEncoding("UTF-8");

         //接收浏览器端提交的信息

               String sort = request.getParameter("sort");

               //设置输出信息的格式及字符集       

             response.setContentType("text/xml; charset=UTF-8");

             response.setHeader("Cache-Control", "no-cache");

             //创建输出流对象

             PrintWriter out = response.getWriter();

             //依据验证结果输出不同的数据信息

             out.println("<response>");     

           

             //数据库操作

             DB db = new DB();

              ResultSet rs;

             String strSql=null;

             //查找该品牌具体型号

             strSql ="select product.name,product.id from sort,product where sort.id=
                          
     product.sortid and sort.name='"+ sort + "'";

              rs = db.executeQuery(strSql);

              try {

                    while (rs.next()) {

                           out.println("<name>" + rs.getString("name") + "</name>");

                    }

              } catch (SQLException e) {

                    e.printStackTrace();

              }

     

              out.println("</response>");

              out.close();

        }

    }

    注意在本例中返回的XML文档的格式如下所示

    <response>

           <name>商品名称1</ name>

           <name>商品名称2</name>

    </response>

    读者可以进一步完善该程序,实现从服务器端动态获取第一个列表框中的信息,然后再依据用户选择动态显示第二个列表框中的信息。

     实现自动刷新页面

    本例实现页面自动刷新的效果,该页面的内容如图5-4所示,在该页面中将根据数据库中存储的最新数据信息更新页面中热卖商品的信息,但是对这些信息的修改并不会导致整个页面的刷新。

    实际的Web应用中,诸如:天气预报、直播比赛以及股市行情等页面往往都需要定期进行自动刷新。

    传统的Web实现方式中,要想实现类似的效果必须进行整个页面的刷新,在网络速度受到一定限制的情况下,这种因为一个局部变动而牵动整个页面的处理方式显得有些得不偿失。

    5-4  自动刷新页面的效果

    借助Ajax技术,可以实现对页面中局部区域的动态刷新,使得用户能够以更好的方式获得最新的数据信息,下面介绍一下自动刷新页面的具体实现过程。

    首先在Eclipse中新建一个Web项目,项目名称为P54_AutoRefresh,对应的浏览器端页面代码如下:

    源文件aotuRefresh.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>

    <head>

          <META http-equiv=Content-Type content="text/html; charset=UTF-8">

    </head>

    <script language="javascript">

           var XMLHttpReq;

           //创建XMLHttpRequest对象      

          function createXMLHttpRequest() {

                  if(window.XMLHttpRequest) { //Mozilla 浏览器

                         XMLHttpReq = new XMLHttpRequest();

                  }

                  else if (window.ActiveXObject) { // IE浏览器

                         try {

                               XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");

                         } catch(e){

                               try {

                                  XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");

                               } catch (e) {}

                         }

                  }

           }

           //发送请求函数

           function sendRequest() {

                  createXMLHttpRequest();

                var url = "refresh";

                  XMLHttpReq.open("GET", url, true);

                  XMLHttpReq.onreadystatechange = processResponse;//指定响应函数

                  XMLHttpReq.send(null);  // 发送请求

           }

           // 处理返回信息函数

           function processResponse() {

           if (XMLHttpReq.readyState == 4) { // 判断对象状态

                  if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息

                            DisplayHot();

                            setTimeout("sendRequest()", 1000);

                  } else { //页面不正常

                        window.alert("您所请求的页面有异常。");

                  }

             }

          }

          // 显示更新数据信息的函数

          function DisplayHot() {

                var name = XMLHttpReq.responseXML.getElementsByTagName("name")[0]. firstChild.nodeValue;

                var count = XMLHttpReq.responseXML.getElementsByTagName("count")[0]. firstChild.nodeValue;

                document.getElementById("product").innerHTML = name;   

                document.getElementById("count").innerHTML = count;

          }

     

    </script>

     

    </SCRIPT>

    <body onload =sendRequest()>

    <table  style="BORDER-COLLAPSE: collapse" borderColor=#111111

                    cellSpacing=0 cellPadding=0 width=200 bgColor=#f5efe7 border=0>

        <TR>

             <TD align=middle height=4 colspan="2"><IMG height=4

             src="images/promo_list_top.gif" width="100%"

             border=0>

               </TD>

          </TR>

          <TR>

           <TD align=middle bgColor=#dbc2b0

                           height=19 colspan="2"><B>正在热卖的笔记本</B>

           </TD>

        </TR>

        <tr>

            <td height="20">

                     型号:

              </td>

            <td height="20" id="product">

              </td>

        </tr>

        <tr>

            <td height="20">

                         销售数量:

              </td>

              <td height="20" id="count">

              </td>

        </tr>

    </body>   

    </table>

    在该页面中在第一次进行页面装载时将调用sendRequest()函数在该函数中将借助Ajax提交请求等待服务器端的处理。当服务器端后续处理完成后,将返回最新热卖商品的信息,然后在Ajax提供的处理函数中调用“DisplayHot()”函数在页面的对应位置进行显示,在进行显示时使用了本书第3章中介绍的使用DOM操作HTML的方式,同时使用了对应元素的innerHTML属性。此外,为了能够实现页面的自动刷新,在“sendRequest()函数的最后设置了定时器,即在1000ms之后再次调用本函数,执行上面所有的处理工作,从而真正实现页面的自动刷新。注意本例中所使用的setTimeout ("sendRequest()", 1000)函数是HTML DOMwindow对象提供的设置定时器的方法。

    Web应用的配置文件web.xml对应的代码如下所示。从该配置文件中可以了解到,当浏览器端提交“refresh”请求时,将由服务器端的类名为classmate.AutoRefreshActionServlet程序进行处理。

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app version="2.4"

         xmlns="http://java.sun.com/xml/ns/j2ee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

     

         <servlet>

              <servlet-name>ms1</servlet-name>

              <servlet-class>classmate.AutoRefreshAction</servlet-class>

         </servlet>

     

        <servlet-mapping>

              <servlet-name>ms1</servlet-name>

              <url-pattern>/refresh</url-pattern>

        </servlet-mapping>

     

     

    <!-- The Welcome File List -->

      <welcome-file-list>

        <welcome-file>autoRefresh.jsp</welcome-file>

      </welcome-file-list>

    </web-app>

    下面我们关注一下服务器端Servlet程序AutoRefreshAction.java中对应的程序代码。当接收到浏览器端提交的请求后,借助封装了数据库操作的JavaBean完成数据库的查询工作,获取最新热卖的商品信息进行响应。

    package classmate;

     

    import java.io.IOException;

    ……

     

    public class AutoRefreshAction extends HttpServlet {

     

          public void init(ServletConfig config) throws ServletException {

         }

       

         /*

          *  处理<GET> 请求方法

          */

         protected void doGet(HttpServletRequest request, HttpServletResponse response)

         throws ServletException, IOException {

                //设置输出信息的格式及字符集       

              response.setContentType("text/xml; charset=UTF-8");

              response.setHeader("Cache-Control", "no-cache");

              //创建输出流对象

              PrintWriter out = response.getWriter();

              //依据验证结果输出不同的数据信息

              out.println("<response>");      

     

            //数据库操作

            DB db = new DB();

             ResultSet rs;

            String strSql=null;

            //查询热卖产品

            strSql = "select name,salecount from product order by salecount desc";

              rs = db.executeQuery(strSql);

              try {

                    if ( rs.next()) {

                            out.println("<name>" + rs.getString("name") + "</name>");

                            out.println("<count>" + rs.getString("salecount") + "</count>");

                    }

              } catch (SQLException e) {

                    e.printStackTrace();

              }

     

              out.println("</response>");

              out.close();

        }

    }

    注意在本例中返回的XML文档的格式如下所示

    <response>

          <name>热卖商品名称</ name>

         <count>热卖数量</count>

    </response>

    由于数据库中商品的销售数量一直在发生改变,因此,本例中实现的原则是通过页面自动刷新定期获取数据库中销售数量最高的商品信息,在浏览器端的页面中进行显示。

    实现Web页面的局部动态更新

    本例中实现的是页面中局部动态更新的效果,对应页面的显示效果如图5-5所示,在该页面中实现的相当于商品信息的后台维护页面,在该页面中用户可以动态增加新的品牌信息到数据库中,增加后的品牌信息将会直接在动态表格中进行显示。同时也可以借助动态表格中的删除按钮进行品牌信息的删除操作。同样在本例中对这些信息的修改并不会导致整个页面的刷新。

    5-5  Web页面的局部刷新效果

    传统的Web实现方式中,实现类似的效果必须进行整个页面的刷新。

    借助Ajax技术,可以实现对页面中局部区域的动态刷新,使得用户能够以更好的方式获得最新的数据信息,下面介绍一下具体的实现过程。

    首先在Eclipse中新建一个Web项目,项目名称为P55_DyUpdate,对应的浏览器端页面代码如下:

    源文件:dyUpdate.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>

    <head>

         <META http-equiv=Content-Type content="text/html; charset=UTF-8">

         <LINK href="images/css.css" type=text/css rel=stylesheet>

    </head>

    <script language="javascript">

          var XMLHttpReq;

          var PREFIX = "Sort";

          //创建XMLHttpRequest对象      

          function createXMLHttpRequest() {

                 if(window.XMLHttpRequest) { //Mozilla 浏览器

                        XMLHttpReq = new XMLHttpRequest();

                 }

                 else if (window.ActiveXObject) { // IE浏览器

                         try {

                                 XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");

                         } catch (e){

                                try {

                                     XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");

                                } catch (e) {}

                         }

                 }

          }

          // 处理增加品牌响应函数

         function AddStateChange() {

          if (XMLHttpReq.readyState == 4) { // 判断对象状态

                if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息

                        AddSortList();

                   }else { //页面不正常

                        window.alert("您所请求的页面有异常。");

                   }

                }

         }

         // 增加品牌函数

         function addSort() {

              name = document.getElementById("name").value;

              if(name == "" ) {

                   return;

              }

              var url = "dyUpdate?action=add" + "&name="+ name;

              createXMLHttpRequest();

              XMLHttpReq.onreadystatechange = AddStateChange;

              XMLHttpReq.open("GET", url, true);

              XMLHttpReq.send(null);

         }

     

         function AddSortList() {

              var AddID = XMLHttpReq.responseXML.getElementsByTagName("id")[0].firstChild. nodeValue;

              if (AddID!=null){

                      var row = document.createElement("tr");

                      row.setAttribute("id", PREFIX + AddID);

                      var cell = document.createElement("td");

                      cell.appendChild(document.createTextNode(name));

                      row.appendChild(cell);

     

                      var deleteButton = document.createElement("input");

                      deleteButton.setAttribute("type", "button");

                      deleteButton.setAttribute("value", "删除");

                      deleteButton.onclick = function () { deleteSort(AddID); };

                      cell = document.createElement("td");

                      cell.appendChild(deleteButton);

                      row.appendChild(cell);

     

                      document.getElementById("sortList").appendChild(row);

              //清空输入框

                      document.getElementById("name").value = "";

              }

        }

     

        // 删除品牌函数

        function deleteSort(id) {

              var url = "dyUpdate?action=delete" + "&id=" + id;

              createXMLHttpRequest();

              XMLHttpReq.onreadystatechange = DeleteStateChange;

              XMLHttpReq.open("GET", url, true);

              XMLHttpReq.send(null);

        }

        // 处理删除品牌响应函数

        function DeleteStateChange() {

        if(XMLHttpReq.readyState == 4) { // 判断对象状态

              if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息

                         deleteSortList();

                   }else { //页面不正常

                      window.alert("您所请求的页面有异常。");

                   }

              }

        }

     

        function deleteSortList() {

        deleteID = XMLHttpReq.responseXML.getElementsByTagName("id")[0].firstChild. nodeValue;

               if (deleteID!=null){

                      var rowToDelete = document.getElementById(PREFIX + deleteID);

                      var sortList = document.getElementById("sortList");

                      sortList.removeChild(rowToDelete);

               }

        }

     

     

    </script>

     

    <table  style="BORDER-COLLAPSE: collapse" borderColor=#111111

                     cellSpacing=0 cellPadding=2 width=400 bgColor=#f5efe7 border=0>

        <TR>

             <TD align=middle height=4 colspan="3"><IMG height=4

             src="images/promo_list_top.gif" width="100%"

             border=0>

              </TD>

        </TR>

        <TR>

           <TD align=middle bgColor=#dbc2b0

                           height=19 colspan="3"><B>品牌信息管理</B>

           </TD>

        </TR>

        <tr>

            <td height="20">

                     增加新品牌:

             </td>

             <td height="20">

                      <input id="name" type="text"    size="15">

             </td>

             <td height="20">

                      <img src="images/ok.gif" οnclick="addSort();">

             </td>

     

        </tr>

          <tr>

              <td height="20">

                    品牌信息管理:

             </td>

     

         </tr>

      <table border="1" width="400">

        <tr>

             <td height="20" valign="top" align="center">

                    品牌名称:

             </td>

            <td id="pos_1" height="20">

                    操作

             </td>

        </tr>

        <tbody id="sortList"></tbody>

      </table>

    </table>

    在该页面中当用户在文本框中输入新品牌的名称单击提交按钮后将调用addSort()函数在该函数中首先获取到用户输入的新品牌信息借助Ajax提交请求,同时提交文本框中用户填写的新的品牌信息,请求的格式为" dyUpdate?action=add" + "&name="+ name可以看到,为了表明请求的类型,使用了参数action,其值为“add,等待服务器端的处理。当服务器端后续处理完成后,将返回最新的商品品牌信息列表,然后在Ajax提供的处理函数中调用“AddSortList()”函数以动态表格的方式在页面的对应位置进行显示,在进行显示时使用了本书第3章中介绍的使用DOM操作HTML的方式。

    此外,当用户在动态表格中选择了对应品牌,单击“操作”按钮后,将调用“deleteSort()该函数带参数参数用于传递待操作的品牌标志信息deleteSort()函数中将提交请求同时提交品牌标志信息到服务器端,请求的格式为"dyUpdate?action=delete" + "&id=" + id可以看到为了表明请求的类型使用了参数action其值为delete。等待服务器端的处理。当服务器端后续处理完成后,将调用“deleteSortList()函数借助DOM操作HTML方式从动态表格中去除对应的品牌信息。

    Web应用的配置文件web.xml对应的代码如下所示。从该配置文件中可以了解到,当浏览器端提交“dyUpdate”请求时,将由服务器端的类名为classmate.DyUpdateActionServlet程序进行处理。

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app version="2.4"

         xmlns="http://java.sun.com/xml/ns/j2ee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

     

         <servlet>

              <servlet-name>ms1</servlet-name>

              <servlet-class>classmate.DyUpdateAction</servlet-class>

         </servlet>

     

        <servlet-mapping>

              <servlet-name>ms1</servlet-name>

              <url-pattern>/dyUpdate</url-pattern>

         </servlet-mapping>

     

       

    <!-- The Welcome File List -->

      <welcome-file-list>

        <welcome-file>dyUpdate.jsp</welcome-file>

      </welcome-file-list>

    </web-app>

    下面我们关注一下服务器端Servlet程序DyUpdateAction.java中对应的程序代码。当接收到浏览器端提交的请求后,首先获取请求的类型及相关的数据信息,然后借助封装了数据库操作的JavaBean完成数据库的操作,如果是添加新品牌信息的请求,则向数据库中进行记录插入,否则进行记录删除操作。

    package classmate;

     

    import java.io.IOException;

    ……

     

    public class DyUpdateAction extends HttpServlet {

       

          public void init(ServletConfig config) throws ServletException {

         }

       

         /*

          *  处理<GET> 请求方法

          */

         protected void doGet(HttpServletRequest request, HttpServletResponse response)

         throws ServletException, IOException {

         //设置接收信息的字符集

         request.setCharacterEncoding("UTF-8");

         //接收浏览器端提交的信息

               String action = request.getParameter("action");    

               String name = request.getParameter("name");

               String id = request.getParameter("id");

               //设置输出信息的格式及字符集       

             response.setContentType("text/xml; charset=UTF-8");

             response.setHeader("Cache-Control", "no-cache");

             //创建输出流对象

             PrintWriter out = response.getWriter();

             //依据验证结果输出不同的数据信息

             out.println("<response>");     

     

             //数据库操作

             DB db = new DB();

              ResultSet rs;

        String strSql=null;

              int insRes = 0;

             if ("add".equals(action)){

                    //判断用户名是否重复

                    strSql = "select max(id) from sort";

                     rs = db.executeQuery(strSql);

                     int iMaxId=0;

                     try {

                           if ( rs.next()) {

                                    iMaxId=rs.getInt(1)+1;

                           }

                           else {

                                    iMaxId=1;

                           }

                     } catch (SQLException e) {

                           e.printStackTrace();

                     }

                     if ( iMaxId>0 ){

                            strSql = "insert into sort values('"

                             + iMaxId    +"','"

                                  + name      +"')";

                             insRes = db. executeUpdate(strSql);

                   }

                     if(insRes>0){

                            out.println("<id>" + iMaxId + "</id>");

                            out.println("<name>" + name + "</name>");

                     }

             }

             else if ("delete".equals(action)){

                     strSql = "delete from sort where id= " + id;

                      insRes = db. executeUpdate(strSql);

                      if(insRes>0){

                             out.println("<id>" + id + "</id>");

                      }

             }

              out.println("</response>");

              out.close();

        }

    }

    在本例中,完成添加新品牌的请求处理之后,返回的XML文档的格式如下

    <response>

          <id>新品牌id</ id>

          <name>新品牌名称</name>

    </response>

    完成品牌删除的请求处理之后,返回的XML文档的格式如下

    <response>

          <id>删除品牌id</ id>

    </response>

    实现自动完成功能

    本章实现的最后一个效果如图5-6所示。该页面实现的效果对读者并不陌生,我们在著名的搜索网站Google中已经非常熟悉自动完成功能的效果。本例中当用户在文本框中输入待查询的商品名称时,页面中将根据用户输入的文字信息,及时给出提示列表,以帮助用户快速进行选择,该提示信息来源于服务器端数据库中的数据。当用户选择了对应商品名称,单击“搜索”按钮后,将会在文本区域中显示商品相关的描述信息。

    首先在Eclipse中新建一个Web项目,项目名称为P56_AutoComplete,对应的浏览器端页面代码如下:

    源文件autoComplete.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>

    <HTML><HEAD><TITLE>Shopping Online</TITLE>

         <META http-equiv=Content-Type content="text/html; charset=UTF-8">

         <LINK href="images/css.css" type=text/css rel=stylesheet>

    5-6  自动完成的效果

    </HEAD>

    <script language="javascript">

          var XMLHttpReq;

          var completeDiv;

          var inputField;

          var completeTable;

          var completeBody;

     

       

           //创建XMLHttpRequest对象      

          function createXMLHttpRequest() {

                 if(window.XMLHttpRequest) { //Mozilla 浏览器

                        XMLHttpReq = new XMLHttpRequest();

                 }

                 else if (window.ActiveXObject) { // IE浏览器

                        try {

                               XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");

                        } catch(e){

                               try{

                                    XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");

                               } catch (e) {}

                        }

                 }

        }

        //发送匹配请求函数

        function findNames() {

            inputField = document.getElementById("names");           

            completeTable = document.getElementById("complete_table");

            completeDiv = document.getElementById("popup");

            completeBody = document.getElementById("complete_body");

            if (inputField.value.length > 0) {

                   createXMLHttpRequest();           

                   var url = "autoComplete?action=match&names=" + escape(inputField.value);

                   XMLHttpReq.open("GET", url, true);

                   XMLHttpReq.onreadystatechange = processMatchResponse;//指定响应函数

                   XMLHttpReq.send(null); // 发送请求

            } else {

                   clearNames();

            }

        }

         // 处理返回匹配信息函数

        function processMatchResponse() {

         if (XMLHttpReq.readyState == 4) { // 判断对象状态

               if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息

                             setNames(XMLHttpReq.responseXML.getElementsByTagName("res"));

                   }else { //页面不正常

                         window.alert("您所请求的页面有异常。");

                   }

               }

         }

         //生成与输入内容匹配行

               function setNames(names) {           

                  clearNames();

                  var size = names.length;

                  setOffsets();

     

                  var row, cell, txtNode;

                  for (var i = 0; i < size; i++) {

                        var nextNode = names[i].firstChild.data;

                        row = document.createElement("tr");

                        cell = document.createElement("td");

                   

                        cell.onmouseout = function() {this.className='mouseOver';};

                        cell.onmouseover = function() {this.className='mouseOut';};

                        cell.setAttribute("bgcolor", "#FFFAFA");

                        cell.setAttribute("border", "0");

                        cell.onclick = function() { completeField(this); } ;

     

                        txtNode = document.createTextNode(nextNode);

                        cell.appendChild(txtNode);

                        row.appendChild(cell);

                        completeBody.appendChild(row);

                  }

               }

          //设置显示位置                

               function setOffsets() {

                   completeTable.style.width = inputField.offsetWidth; + "px";

                   var left = calculateOffset(inputField, "offsetLeft");

                   var top = calculateOffset(inputField, "offsetTop") + inputField. offsetHeight;

                   completeDiv.style.border = "black 1px solid";

                   completeDiv.style.left = left + "px";

                   completeDiv.style.top = top + "px";

               }

          //计算显示位置

        function calculateOffset(field, attr) {

          var offset = 0;

          while(field) {

            offset += field[attr];

            field = field.offsetParent;

          }

          return offset;

        }

        //填写输入框

        function completeField(cell) {

            inputField.value = cell.firstChild.nodeValue;

            clearNames();

        }

        //清除自动完成行

        function clearNames() {

            var ind = completeBody.childNodes.length;

            for (var i = ind - 1; i >= 0 ; i--) {

                    completeBody.removeChild(completeBody.childNodes[i]);

            }

            completeDiv.style.border = "none";

        }

         //搜索请求函数

        function search() {

            var sortName = document.getElementById("names");

            createXMLHttpRequest();           

            var url = "autoComplete?action=search&names=" + escape(inputField.value);

            XMLHttpReq.open("GET", url, true);

            XMLHttpReq.onreadystatechange = processSearchResponse;//指定响应函数

            XMLHttpReq.send(null); // 发送请求

        }

         // 处理返回匹配信息函数

        function processSearchResponse() {

         if (XMLHttpReq.readyState == 4) { // 判断对象状态

               if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息

                       var res=XMLHttpReq.responseXML.getElementsByTagName("res");

                       if (res.length>0){

                            document.getElementById("content").value=res[0].firstChild.data;

                       }

                  }else { //页面不正常

                       window.alert("您所请求的页面有异常。");

                  }

            }

        }

     

    </script>

     

     

    <table  style="BORDER-COLLAPSE: collapse" borderColor=#111111

                     cellSpacing=0 cellPadding=2 width=400 bgColor=#f5efe7 border=0>

         <TR>

             <TD align=middle height=4 colspan="3"><IMG height=4

             src="images/promo_list_top.gif" width="100%"

             border=0>

              </TD>

         </TR>

         <TR>

           <TD align=middle bgColor=#dbc2b0

                           height=19 colspan="3"><B>商品信息搜索</B>

           </TD>

         </TR>

         <tr>

             <td height="20">

                      输入品牌关键字:

                 </td>

                 <td height="20">

                             <input type="text"  size="15" id="names" οnkeyup="findNames();" style=
                           "height:20;">

                 <div style="position:absolute;" id="popup">

                         <table id="complete_table" bgcolor="#FFFAFA" border="0" cellspacing=
                                 "0" cellpadding="0"/>           

                                 <tbody id="complete_body"></tbody>

                         </table>

                 </div>

                  </td>

     

     

                  <td height="20">

                               <img src="images/search.gif" οnclick="search();">

                  </td>

     

        </tr>

        <tr>

              <td height="20" valign="top" align="center">

                    产品描述:

              </td>

            <td id="pos_1" height="80">

                    <textarea id="content">

     

                    </textarea>

              </td>

        </tr>

     

    </table>

    在该页面中一旦用户开始在文本框中输入待查询商品的名称,即触发“onkeyup”事件,调用“findNames()函数在该函数中首先获取到用户已经在文本框中输入的信息然后借助Ajax提交请求,同时提交文本框中用户已经填写的信息,请求的格式为" autoComplete? action=match&names=" + escape(inputField.value)可以看到,为了表明请求的类型,使用了参数action,其值为“match”,等待服务器端的处理。当服务器端后续处理完成后,将返回获取到的与用户已输入信息相匹配的信息列表,在Ajax提供的处理函数中调用“setNames(names)”函数以动态方式在页面的对应位置进行显示,在进行显示时还调用了“setOffsets()”函数以及“calculateOffsets()”函数。

    此外,当用户录入完待查询的商品名称,单击“搜索”按钮后,将调用“search()该函数将首先获取待查询的商品名称信息然后提交请求同时提交待查询商品信息到服务器端,请求的格式为" autoComplete?action=search&names=" + escape(inputField.value)可以看到为了表明请求的类型使用了参数action其值为search。等待服务器端的处理。当服务器端后续处理完成后,将调用“processSearchResponse()函数在对应的文本区域中显示查询的商品描述信息。

    Web应用的配置文件web.xml对应的代码如下所示。从该配置文件中可以了解到,当浏览器端提交“autoComplete”请求时,将由服务器端的类名为classmate.AutoCompleteActionServlet程序进行处理。

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app version="2.4"

         xmlns="http://java.sun.com/xml/ns/j2ee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

     

        <servlet>

             <servlet-name>ms1</servlet-name>

             <servlet-class>classmate.AutoCompleteAction</servlet-class>

        </servlet>

     

       <servlet-mapping>

             <servlet-name>ms1</servlet-name>

             <url-pattern>/autoComplete</url-pattern>

        </servlet-mapping>

     

     

    <!-- The Welcome File List -->

      <welcome-file-list>

        <welcome-file>autoComplete.jsp</welcome-file>

      </welcome-file-list>

    </web-app>

    下面我们关注一下服务器端Servlet程序AutoCompleteAction.java中对应的程序代码。当接收到浏览器端提交的请求后,首先获取请求的类型及相关的数据信息,然后借助封装了数据库操作的JavaBean完成数据库的操作,例如:获取候选商品名称信息,或者查询指定商品的描述信息等。

    package classmate;

     

    import java.io.IOException;

    ……

    public class AutoCompleteAction extends HttpServlet {

       

          public void init(ServletConfig config) throws ServletException {

         }

       

    ……

        protected void doGet(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

         //设置接收信息的字符集

         request.setCharacterEncoding("UTF-8");

         //接收浏览器端提交的信息

              String action = request.getParameter("action");   

              String name = request.getParameter("names");

              //设置输出信息的格式及字符集       

            response.setContentType("text/xml; charset=UTF-8");

            response.setHeader("Cache-Control", "no-cache");

            //创建输出流对象

            PrintWriter out = response.getWriter();

            //依据验证结果输出不同的数据信息

            out.println("<response>");   

           

            //数据库操作

            DB db = new DB();

             ResultSet rs;

            String strSql=null;

            //匹配

            if ("match".equals(action)){

                  strSql = "select * from product where name like'" + name + "%'";

             rs = db.executeQuery(strSql);

             try {

                   while(rs.next()) {

                         out.println("<res>" + rs.getString("name") + "</res>");

                   }

             }catch (SQLException e) {

                   e.printStackTrace();

             }

            }

            else if ("search".equals(action)){

                  strSql = "select contents from product where name ='" + name + "'";

             rs = db.executeQuery(strSql);

             try {

                   if ( rs.next()) {

                           out.println("<res>" + rs.getString("contents") + "</res>");

                   }

             }catch (SQLException e) {

                   e.printStackTrace();

             }

     

            }

             out.println("</response>");

             out.close();

        }

    }

    在本例中,完成match类型的请求处理之后,返回的XML文档的格式如下所示

    <response>

          <res>候选商品名称1</ res>

          <res>候选商品名称1</ res>

    <res>候选商品名称1</ res>

    </response>

    完成search类型的请求处理之后,返回的XML文档的格式如下所示:

    <response>

          <res>商品描述信息</ res>

    </response>

    至此,本章相关的案例介绍完毕,通过本章的学习,读者对Ajax的实际应用方式和技巧都应有了一定程度的掌握和理解。

    展开全文
  • Access-控件解析-组合-01-下拉列表

    千次阅读 2019-04-03 20:35:44
    微信公众号原文 系统:Windows 7 软件:Excel 2010 / Access 2010 这个系列介绍常用的控件 ...手动设置组合下拉列表:长江;黄河;珠江;淮河 通过代码修改组合下拉列表:1;2;3;4 应用场景,组合的下拉...

    微信公众号原文

    系统:Windows 7
    软件:Excel 2010 / Access 2010

    • 这个系列介绍常用的控件
    • 包括在界面端的设置及在代码端的实现

    Part 1:本篇目标

    1. 本篇介绍的控件为:组合框。涉及功能为:下拉列表的实现

    功能动图
    1.gif

    Part 2:实现功能

    1. 手动设置组合框下拉列表:长江;黄河;珠江;淮河
    2. 通过代码修改组合框下拉列表:1;2;3;4
    3. 应用场景,组合框的下拉列表随着另外一个控件的取值变化而变化。例如,两个组合框,一个显示省份,一个显示城市,当省份不同时,城市组合框下拉列表也会不同

    手动设置:打开组合框属性 - 数据选项卡 - 行来源类型设置为值列表 - 行来源设置下拉列表数据,以**分号;**隔开

    2.png

    Part 3:代码

    Private Sub Command4_Click()
        ctrlName = "Combo2"
        Set cbo = Me.Controls(ctrlName)
        cbo.RowSource = ""
        cbo.Value = ""
        
        arr = Array(1, 2, 3, 4)
        For Each x In arr
            cbo.AddItem x
        Next
    End Sub
    

    代码截图
    4.png

    Part 4:部分代码解读

    1. cbo.RowSource = "",将下拉列表清空
    2. cbo.Value = "",将组合框取值清空
    3. cbo.AddItem x ,增加组合框下拉列表

    本文为原创作品,如需转载,可加小编微信号learningBin


    更多精彩,请关注微信公众号
    扫描二维码,关注本公众号

    公众号底部二维码.jpg

    展开全文
  • 利用pandas自带的函数notnull可以很容易判断某一列是否为null类型,但是如果这一列中某一格为空字符串“”,此时notnull函数会返回True,而一般我们选择非空行并不包括这一点,所以需要把这一类也去掉。 # df为需要...
  • Access学习要点1----组合列表原理

    千次阅读 2017-05-11 17:00:03
    今天要带本科的一门课,惭愧,现在从头开始学,新的东西,开这个系列的博客只是为了记录自己在摸索中的一些...结果百度了以后,觉得组合列表也可以实现这个功能,就记录下了这个点的过程。 方法: 1、新建一个表→
  • 基于Python的HTTP接口自动化测试框架实现

    万次阅读 多人点赞 2011-04-22 14:36:00
    # 功能实现列表: # 1、Excel操作封装 # 2、参数组装 # 3、测试调用 # 4、测试报告保存 # # 适用范围: # 1、典型输入输出测试接口的测试,输入输出为一具体值,输入可以为多个参数,输出暂时支持1个输出,后期可...
  • 一、根据列条件,获取索引号并转成列表 #在dataframe中根据一定的条件,得到符合要求的某些元素所在的位置 import pandas as pd df = pd.DataFrame({'BoolCol': [1, 2, 3, 3, 4],'attr': [22, 33, 22, 44, 66]...
  • 阿里的Atlas组件化框架

    千次阅读 2018-05-10 23:05:11
    它基于手淘自研差量算法,主Bundle基于ClassLoader机制,业务Bundle基于差量merge,支持全业务类型。 另外,Atlas也支持Andfix作为插件使用,目标是快速故障修复,它的原理基于Native hook,主要做方法的修改,在...
  • 图片获取类:根据不同的来源去不同地方获取,比如网络、本地、内存等 调度器类:实现图片获取的入队、执行、完成、取消、暂停等 图片处理类:图片拿到后进行解码、反转、裁剪等 缓存类:图片的内存、磁盘缓存...
  • GIS软件列表

    万次阅读 2016-09-05 21:36:07
    Pentaho数据集成(Kettle)是一个功能强大的、元数据驱动的ETL(抽取、转换和加载)工具,致力于不同数据来源间的聚合。 GeoNetwork OpenSource :一个空间数据元数据的门户网站,实现国际地理元数据标准...
  • Dryad 微软的分布式运算框架

    万次阅读 2014-07-08 10:51:33
    Dryad的论文是微软早在2007年就发布的,Tez的核心思想来源于Dryad,差不多可以算是Dryad的开源实现吧。最近正好看到几个有趣的项目是基于Tez实现的,于是顺便追本溯源,学习了一下Dryad的理论基础
  • 与 JS 代码约定的 String 类型识别 name,JS 端通过 AppRegistry.registerComponent 方法设置这个 name,Java 端重写基类的 getMainComponentName 方法设置这个 name,这样两边入口就对上了。 3. launchOptions...
  • 来源 | 达达前端小酒馆 Vue概述: MVX模式简介,Vue框架简介,Vue.js的安装与使用。 Vue基础语法: 实例对象,生命周期,模板语法,计算属性,methods方法 Vue渲染: 列表渲染,条件渲染 Vue事件与表单: 事件...
  • AVFoundation 框架小结

    千次阅读 2017-12-17 23:55:45
    AVFoundation 小结 概述 ...对于播放不同类型的资源,需要进行的准备工作有所不同,这主要取决于资源的来源。资源数据可能来自本地设备上文件的读取,也可能来自网络上数据流。 对于本地...
  • 深度框架 MXNet/Gluon 初体验

    万次阅读 多人点赞 2018-05-17 14:26:27
    init是数据来源,Normal类即正态分布,sigma是正态分布的标准差; ctx是上下文,表示训练中参数更新使用CPU或GPU,如mx.cpu(); Gluon的Sequential类与其他的深度学习框架类似,通过 有序地 连接不同的操作...
  • BigInt目前是第3阶段提案, 一旦添加到规范中,它就是JS 第二个数字数据类型,也将是 JS 第8种基本数据类型:Boolean、Null、Undefined、Number、BigInt、String、Symbol、Object。 在本文中,咱们将详细介绍 ...
  • MVP框架 – Ted Mosby的软件架构

    万次阅读 2016-04-27 09:58:07
    作者:Hannes Dorfmann原文链接 : Ted Mosby...我给这篇关于Android库的博客起的名字灵感来源于《老爸老妈浪漫史》中的建筑设计师Ted Mosby。这个Mosby库可以帮助大家在Android上通过Model-View-Presenter模式做出一个
  • IOS框架和服务

    万次阅读 多人点赞 2014-06-06 19:49:10
    如提供特定类型方向的应用,例如一个显示地铁路线的应用,能登记请求接收地图应用提供的方向。 应用也能向苹果的服务器请求步行或驾驶方向,并与他们定制的方向的路径信息混合来为用户提供完整的点到点体验。 ...
  • Scrapy框架的使用之Scrapy通用爬虫

    万次阅读 多人点赞 2018-05-26 10:12:13
    我们要抓取新闻列表中的所有分页的新闻详情,包括标题、正文、时间、来源等信息。 四、新建项目 首先新建一个Scrapy项目,名为scrapyuniversal,如下所示: scrapy startproject scrapyuniversal 创建一个...
  • 初识Express框架-详细学习API

    万次阅读 2016-04-01 20:48:24
    express.static(root, [options]) express.static是唯一的一个express内置的中间件,他用于处理静态文件,是基于serve-static来完成的。  对于静态文件的请求时通过root+req.url拼接完成的。如果不存在这个静态文件...
  • 写自己的ASP.NET MVC框架(上)

    千次阅读 2016-04-25 09:47:24
    我的MVC框架对AJAX的支持来源于我对代码不断重构的过程,为了更好地了解我的MVC框架, 我认为有必要先来回忆一下以往是如何(在服务端)实现AJAX的。 在ASP.NET中有一种比较原始的实现Ajax的方式,那就是创建一个...
  • 来源:Yury Zhauniarovich | Publications 译者:飞龙 协议:CC BY-NC-SA 4.0 如我们在第1.2节中所描述的那样,应用程序框架级别上的安全性由 IPC 引用监视器实现。 在 4.1 节中,我们以 Android 中使用的...
  • JIRA配置手册 (1):问题类型管理

    千次阅读 2018-08-16 08:00:00
    作者:Misha 来源:原力注入你想学习Java ?资源都在这里,点击查看最近在工作中频繁接触Jira,从一脸懵逼的小白摸索成为一个准管理员,爬了不少坑,特此整理如下,望...
  • Hadoop整体框架

    千次阅读 多人点赞 2018-07-17 18:08:17
    视频教学来源:  http://www.imooc.com/learn/391 hadoop 的四大组件: HDFS:分布式存储系统 MapReduce:分布式计算系统 YARN: hadoop 的资源调度系统 Common: 以上三大组件的底层支撑组件,主要提供基础...
  • Elastic官方网络研讨会视频列表

    千次阅读 2021-04-09 11:07:24
    公众号视频列表入口 标题 日期 链接 简介 优诺案例-使用Elastic Stack来扩展优锘科技公司业务并改善用户体验 2019-12-18 课程链接 优锘科技是可视化软件研发者。优锘科技(北京优锘科技有限公司)致力于以Digital ...
  • .py文件来源于: https://github.com/fchollet/deep-learning-models/blob/master/vgg16.py VGG16默认的输入数据格式应该是:channels_last # -*- coding: utf-8 -*- '''VGG16 model for Keras. # ...
  • Qt ComboBox下拉列控件的用法

    千次阅读 2019-08-16 15:16:27
    QComboBox是下拉列表框组件类,它提供一个下拉列表供用户选择,也可以直接当作一个 QLineEdit 用作输入。QComboBox 除了显示可见下拉列表外,每个项(item,或称列表项)还可以关联一个 QVariant 类型的变量,用于...
  • GetLastError()返回值列表

    万次阅读 多人点赞 2013-11-01 15:32:37
    GetLastError()返回值列表: 〖0〗-操作成功完成。 〖1〗-功能错误。 〖2〗-系统找不到指定的文件。 〖3〗-系统找不到指定的路径。 〖4〗-系统无法打开文件。 〖5〗-拒绝访问。 〖6〗-句柄无效。 〖7〗-...
  • Ted Mosby - 一个MVP框架的软件架构

    千次阅读 2015-05-28 08:20:01
    我给这篇关于Android库的博客起的名字灵感来源于《老爸老妈浪漫史》中的建筑设计师Ted Mosby。这个Mosby库可以帮助大家在Android上通过Model-View-Presenter模式做出一个完善稳健、可重复使用的软件,还可以借助...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 67,920
精华内容 27,168
关键字:

列表框的行来源类型