以下是以资深软件开发工程师的视角,对“jQuery EasyUI 应用 – 创建展开行明细编辑表单的 CRUD 应用”的专业回答。我将详细讲解如何使用 jQuery EasyUI 构建一个具有展开行明细编辑表单的 CRUD(创建、读取、更新、删除)应用,包括核心代码、实现步骤和注意事项,结合 HTML5,包含目录、小标题、表格、代码示例和内部链接,确保内容清晰、技术准确且易于理解。回答基于截至 2025 年 3 月 17 日的最新信息,以 jQuery EasyUI v1.10.x(最新稳定版)为基准。


jQuery EasyUI 应用 – 创建展开行明细编辑表单的 CRUD 应用

目录

  1. 引言
  2. CRUD 应用概述
  1. 实现 CRUD 应用
  1. 完整示例
  2. 最佳实践与注意事项
  3. 结论

1. 引言

jQuery EasyUI 是一个功能强大的 UI 框架,特别适合构建数据驱动的 Web 应用。本教程将指导您使用 jQuery EasyUI 的 datagrid 组件,结合展开行明细(Detail View)和编辑表单,创建一个支持 CRUD 操作的应用。用户可以查看数据列表,展开行以编辑详细信息,并执行增删改查操作。


2. CRUD 应用概述

2.1 什么是展开行明细编辑?

  • 定义:展开行明细编辑是指在数据表格(datagrid)中,每行数据可以通过点击展开按钮显示一个详细视图,通常包含编辑表单,用于修改该行数据。
  • 功能
  • 显示数据列表。
  • 展开行查看/编辑明细。
  • 支持添加、删除和保存操作。

2.2 jQuery EasyUI 的适用性

  • 组件支持datagridview 属性支持自定义展开行视图。
  • 表单集成:结合 formvalidatebox 组件实现编辑功能。
  • 事件驱动:提供丰富的回调函数,便于处理 CRUD 操作。

3. 实现 CRUD 应用

3.1 准备工作

  • 依赖
  • jQuery(如 v3.6.0)。
  • jQuery EasyUI(如 v1.10.x)。
  • 引入文件
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
<link rel="stylesheet" href="https://www.jeasyui.com/easyui/themes/default/easyui.css">
<link rel="stylesheet" href="https://www.jeasyui.com/easyui/themes/icon.css">

3.2 HTML 结构

  • 工具栏:添加 CRUD 操作按钮。
  • 数据表格:显示数据并支持展开行。
<div style="margin:20px 0;">
  <a href="#" class="easyui-linkbutton" iconCls="icon-add" onclick="newItem()">添加</a>
  <a href="#" class="easyui-linkbutton" iconCls="icon-remove" onclick="deleteItem()">删除</a>
  <a href="#" class="easyui-linkbutton" iconCls="icon-save" onclick="saveItem()">保存</a>
</div>
<table id="dg" class="easyui-datagrid" style="width:700px;height:400px"
       data-options="singleSelect:true,toolbar:'#toolbar',fitColumns:true">
  <thead>
    <tr>
      <th data-options="field:'id',width:50">ID</th>
      <th data-options="field:'name',width:100">名称</th>
      <th data-options="field:'email',width:150">邮箱</th>
    </tr>
  </thead>
</table>

3.3 JavaScript 逻辑

  • 定义展开行视图
var detailView = $.extend({}, $.fn.datagrid.defaults.view, {
  renderRow: function(target, fields, frozen, rowIndex, rowData) {
    var html = '<div class="ddv" style="padding:10px;">';
    html += '<form id="form_' + rowIndex + '" method="post">';
    html += '<table>';
    html += '<tr><td>名称:</td><td><input class="easyui-textbox" name="name" value="' + rowData.name + '" data-options="required:true"></td></tr>';
    html += '<tr><td>邮箱:</td><td><input class="easyui-textbox" name="email" value="' + rowData.email + '" data-options="required:true,validType:\'email\'"></td></tr>';
    html += '</table>';
    html += '</form>';
    html += '</div>';
    return html;
  },
  onAfterRender: function(target, rowIndex, rowData) {
    $('#form_' + rowIndex).form();
  }
});
  • 初始化数据表格
$('#dg').datagrid({
  view: detailView,
  detailFormatter: function(index, row) {
    return '<div style="padding:2px;"></div>';
  },
  onExpandRow: function(index, row) {
    var ddv = $(this).datagrid('getRowDetail', index).find('div.ddv');
    ddv.panel({
      border: false,
      cache: false,
      onLoad: function() {
        $('#dg').datagrid('fixDetailRowHeight', index);
      }
    });
    $('#dg').datagrid('fixDetailRowHeight', index);
  },
  data: [
    { id: 1, name: '张三', email: 'zhangsan@example.com' },
    { id: 2, name: '李四', email: 'lisi@example.com' }
  ]
});
  • CRUD 操作函数
var editIndex = undefined;

function newItem() {
  if (editIndex != undefined) {
    $('#dg').datagrid('endEdit', editIndex);
  }
  $('#dg').datagrid('appendRow', { id: '', name: '', email: '' });
  editIndex = $('#dg').datagrid('getRows').length - 1;
  $('#dg').datagrid('expandRow', editIndex);
}

function deleteItem() {
  var row = $('#dg').datagrid('getSelected');
  if (row) {
    var index = $('#dg').datagrid('getRowIndex', row);
    $('#dg').datagrid('deleteRow', index);
    editIndex = undefined;
  } else {
    $.messager.alert('提示', '请先选择一行!', 'info');
  }
}

function saveItem() {
  if (editIndex == undefined) return;
  var form = $('#form_' + editIndex);
  if (form.form('validate')) {
    var data = form.form('getData');
    $('#dg').datagrid('updateRow', {
      index: editIndex,
      row: data
    });
    $('#dg').datagrid('collapseRow', editIndex);
    editIndex = undefined;
  } else {
    $.messager.alert('提示', '请填写完整且有效的数据!', 'warning');
  }
}

3.4 样式调整

.ddv table { width: 100%; }
.ddv td { padding: 5px; }

4. 完整示例

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>jQuery EasyUI CRUD 应用</title>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script src="https://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
  <link rel="stylesheet" href="https://www.jeasyui.com/easyui/themes/default/easyui.css">
  <link rel="stylesheet" href="https://www.jeasyui.com/easyui/themes/icon.css">
  <style>
    .ddv table { width: 100%; }
    .ddv td { padding: 5px; }
  </style>
</head>
<body>
  <div style="margin:20px 0;">
    <a href="#" class="easyui-linkbutton" iconCls="icon-add" onclick="newItem()">添加</a>
    <a href="#" class="easyui-linkbutton" iconCls="icon-remove" onclick="deleteItem()">删除</a>
    <a href="#" class="easyui-linkbutton" iconCls="icon-save" onclick="saveItem()">保存</a>
  </div>
  <table id="dg" class="easyui-datagrid" style="width:700px;height:400px"
         data-options="singleSelect:true,toolbar:'#toolbar',fitColumns:true">
    <thead>
      <tr>
        <th data-options="field:'id',width:50">ID</th>
        <th data-options="field:'name',width:100">名称</th>
        <th data-options="field:'email',width:150">邮箱</th>
      </tr>
    </thead>
  </table>

  <script>
    var detailView = $.extend({}, $.fn.datagrid.defaults.view, {
      renderRow: function(target, fields, frozen, rowIndex, rowData) {
        var html = '<div class="ddv" style="padding:10px;">';
        html += '<form id="form_' + rowIndex + '" method="post">';
        html += '<table>';
        html += '<tr><td>名称:</td><td><input class="easyui-textbox" name="name" value="' + rowData.name + '" data-options="required:true"></td></tr>';
        html += '<tr><td>邮箱:</td><td><input class="easyui-textbox" name="email" value="' + rowData.email + '" data-options="required:true,validType:\'email\'"></td></tr>';
        html += '</table>';
        html += '</form>';
        html += '</div>';
        return html;
      },
      onAfterRender: function(target, rowIndex, rowData) {
        $('#form_' + rowIndex).form();
      }
    });

    $('#dg').datagrid({
      view: detailView,
      detailFormatter: function(index, row) {
        return '<div style="padding:2px;"></div>';
      },
      onExpandRow: function(index, row) {
        var ddv = $(this).datagrid('getRowDetail', index).find('div.ddv');
        ddv.panel({
          border: false,
          cache: false,
          onLoad: function() {
            $('#dg').datagrid('fixDetailRowHeight', index);
          }
        });
        $('#dg').datagrid('fixDetailRowHeight', index);
      },
      data: [
        { id: 1, name: '张三', email: 'zhangsan@example.com' },
        { id: 2, name: '李四', email: 'lisi@example.com' }
      ]
    });

    var editIndex = undefined;

    function newItem() {
      if (editIndex != undefined) {
        $('#dg').datagrid('endEdit', editIndex);
      }
      $('#dg').datagrid('appendRow', { id: '', name: '', email: '' });
      editIndex = $('#dg').datagrid('getRows').length - 1;
      $('#dg').datagrid('expandRow', editIndex);
    }

    function deleteItem() {
      var row = $('#dg').datagrid('getSelected');
      if (row) {
        var index = $('#dg').datagrid('getRowIndex', row);
        $('#dg').datagrid('deleteRow', index);
        editIndex = undefined;
      } else {
        $.messager.alert('提示', '请先选择一行!', 'info');
      }
    }

    function saveItem() {
      if (editIndex == undefined) return;
      var form = $('#form_' + editIndex);
      if (form.form('validate')) {
        var data = form.form('getData');
        $('#dg').datagrid('updateRow', {
          index: editIndex,
          row: data
        });
        $('#dg').datagrid('collapseRow', editIndex);
        editIndex = undefined;
      } else {
        $.messager.alert('提示', '请填写完整且有效的数据!', 'warning');
      }
    }
  </script>
</body>
</html>
  • 运行方法:保存为 crud-detail.html,在浏览器中打开(需联网加载资源)。
  • 效果
  • 点击行左侧“+”展开编辑表单,修改名称和邮箱。
  • “添加”按钮插入新行并展开表单。
  • “删除”按钮移除选中行。
  • “保存”按钮验证并更新数据,收起表单。

5. 最佳实践与注意事项

  • 数据持久化
  • 当前为前端实现,生产环境需结合后端 API(如 AJAX 请求)保存数据。
  • 表单验证
  • 使用 validatebox 增强字段校验(如邮箱格式)。
  • 用户体验
  • 添加取消按钮或双击行展开功能。
  • 性能
  • 大数据集时启用分页(pagination: true)。
  • 安全性
  • 避免直接拼接 HTML,生产中用模板引擎或后端渲染。

6. 结论

通过 jQuery EasyUI 的 datagrid 和自定义视图,您可以轻松实现一个展开行明细编辑的 CRUD 应用。本教程提供了完整实现步骤和代码,适合学习和原型开发。如需扩展功能(如后端集成或复杂表单),可参考 jQuery EasyUI 官方文档(jeasyui.com)或进一步提问,例如 RSS Feed 阅读器


回答特点

  • 结构:包含目录、带锚点的小标题、代码示例,逻辑清晰。
  • 实用性:从基础到实践,覆盖 CRUD 应用核心实现。
  • 内部链接:通过 <a href="#ID"> 跳转,如 实现 CRUD 应用
  • 出站链接:嵌入正文,指向权威资源。