layui 乱入前端

功能包含

本实例代码为部分傻瓜框架,插入引用layui。因为样式必须保证跟系统一致,所以大部分功能都是自定义的。代码仅供需要用layui框架,但原项目又不是layui搭建的提供解题思路。代码较为通用

  • 自定义分页功能
  • 自定义筛选列功能
  • 行内编辑下拉、文本、时间、文本域
  • 自定义头部下拉搜索
  • 自定义头部输入搜索

功能截图

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="zh">
<head><!--# include file="/html/ads/meta.html" --><meta name="viewport" content="width=device-width, initial-scale=1"><title>客户明细1</title><style>body {background-color: var(--fontcr);}body > div:nth-child(1) {padding: 10px;}.cument > div table td {border-bottom: 1px solid rgba(0, 0, 0, 0.2);}.cument > div table {border-bottom: 1px solid rgba(0, 0, 0, 0.2);}.layui-panel {background-color: rgb(242 242 242);margin-left: -15px;}layui-table > tbody > tr:hover {background-color: rgba(0, 0, 0, 0.05); /* 鼠标悬停时改变背景色 */}</style>
</head><body style="overflow: hidden;">
<!--layui工具按钮-->
<script type="text/html" id="barDemo"><!--  <div class="layui-clear-space">--><button lay-event="save">保存</button><!--  </div>-->
</script><script type="text/html" id="select_channal">{{#  var list = default_select_data.channal_id; }}<select name="channal_id" lay-filter="filter_channal_id" lay-append-to="body" lay-search><option value="">请选择</option>{{# layui.each(list, function(i, v){ }}<option value="{{= v.key }}" {{=v.key=== d.channal_id?'selected' : '' }}>{{= v.value }} </option>{{# }); }}</select>
</script>
</script>
<script type="text/html" id="select_budget">{{#  var list = default_select_data.budget; }}<select name="budget" lay-filter="filter_budget" lay-append-to="body"><option value="">请选择</option>{{# layui.each(list, function(i, v){ }}<option value="{{= v }}" {{=v=== d.budget?'selected' : '' }}>{{= v }}</option>{{# }); }}</select>
</script>
<script type="text/html" id="select_intent">{{#  var list = default_select_data.intent; }}<select name="intent" lay-filter="filter_intent" lay-append-to="body"><option value="">请选择</option>{{# layui.each(list, function(i, v){ }}<option value="{{= v }}" {{=v=== d.intent?'selected' : '' }}>{{= v }}</option>{{# }); }}</select>
</script>
<script type="text/html" id="select_grade">{{#  var list = default_select_data.grade;}}<select name="grade" lay-filter="filter_grade" lay-append-to="body"><option value="">请选择</option>{{# layui.each(list, function(i, v){ }}<option value="{{= v }}" {{=v=== d.grade?'selected' : '' }}>{{= v }}</option>{{# }); }}</select>
</script><script type="text/html" id="bargain_time"><input class="layui-input bargain_time" lay-filter="filter_bargain" placeholder="选择成交日期" name="bargain_time"value="{{= d.bargain_time || '' }}"/>
</script>
<div style="margin-left: 10px;margin-top: 10px"><!-- 头部按钮--><div style="display: flex"><form id="search" onsubmit="return false;" class="tool"><div><input type="text" name="wc_date"  between onchange="cms.reload()" placeholder="可选日期"/></div><div><button type="button" onclick="cms.reset();">重置</button></div><div><button type="button" onclick="cms.reload();">刷新</button></div><div><!--                需要打开此功能只需要打开table.hideCol处的注释和这个注释即可--><button type="button" id="dropdown_cols" lay-options="{trigger: 'hover'}">筛选列</button></div>
<!--            <div>-->
<!--                <button type="button" οnclick="cms.export_xls();">导出</button>-->
<!--            </div>--></form></div><div class="cument"><div id="thead_box"><!--            <table name="table">--><!--                <thead name="thead">--><!-- layui表格--><table class="layui-hide" id="test" lay-filter="test"></table><!--                </thead>--><!--            </table>--></div><div id="tbody_box"><table name="table"><tbody name="tbody"></tbody></table><ul id="mouse_menu" hidden></ul></div><div id="tfoot_box"><table name="table"><tfoot name="tfoot"></tfoot></table></div><!-- 分页组件--><nav id="nav" style="margin-bottom: 10px"></nav><!-- 其他区域--><div class="extra"></div></div>
</div><!-- 当前页码隐藏域 -->
<input type="hidden" id="p" name="p" value="1"><!-- 总页数隐藏域 -->
<input type="hidden" id="pmax" name="pmax" value="1"><!--# include file="/html/ads/footer.html" -->
<script type="text/javascript">layui.config({base: '/html/plugins/layui/ext/',}).extend({excel: 'excel',});
</script>
<script>const baseURL = config.api_url;//解决首次重复请求问题let first_load = true;let cms = new Cms({}, {}, {});//缓存数据let cache_data = [];//头部输入搜索 对应header_inputlet fields = [{key: 'wechatno', selector: '#wechatno_header'},// {key: 'nickname', selector: '#nickname_header'},];//存储输入值let header_input = {"wechatno": '',};//头部下拉字段let select_fields = ['channal_id', 'budget', 'intent', 'grade'];//缓存选中的头部下拉let header_select = {"budget": [],"intent": [],"grade": [],"channal_id": [],};// 存放头部下拉 支持对象数组,但对象数组格式一定是key value格式let default_select_data = {'budget': ["中6位", "中万", "中千", "千万级", "大6位", "大万", "大千", "客户没说", "小6位", "小万", "小千", "百万级"],'intent': ["不回复", "不回复删除", "不感兴趣", "中意向(学习,了解,鉴定等)", "低意向 (1k以内)", "同行或推广", "回复后删除", "已成交", "高意向(有明确产品需求或有明确预算)"],'grade': ["vip大客户100w+", "成交客户10w内", "未成交", "重点客户10-100w"],"channal_id": [],};//用于存放显示列缓存const cache_key_cols = "cache_key_cols";//默认显示列 对应default_colslet select_cols = ["avatar", "nickname", "friendid", "gender", "dq", "uname", "c_name", "c_phone", "channal_id", "budget", "intent", "grade", "bargain_time","memo1", "u_project", "u_group", "xsavatar", "xswechatnick", "wechatid", "wechatno", "incoming_time", "create_time"];//显示列下拉列表let default_cols = [{key: "avatar", value: "客户头像"}, {key: "nickname", value: "客户昵称"}, {key: "friendid",value: "客户微信"}, {key: "gender", value: "客户性别"}, {key: "dq", value: "客户地区"}, {key: "uname", value: "录入人"}, {key: "c_name",value: "客户姓名"}, {key: "c_phone", value: "客户手机"}, {key: "channal_id",value: "渠道"}, {key: "budget", value: "预算"}, {key: "intent", value: "意向"}, {key: "grade", value: "等级"}, {key: "bargain_time", value: "成交时间"}, {key: "memo1",value: "备注"}, {key: "u_project", value: "项目"}, {key: "u_group", value: "组"}, {key: "xsavatar",value: "销售头像"}, {key: "xswechatnick", value: "销售昵称"}, {key: "wechatid", value: "销售微信ID"}, {key: "wechatno", value: "微信号"}, {key: "create_time", value: "进线时间"}, {key: "create_time",value: "创建时间"}];//远程渠道数据let channals = [];//表格列let table_cols = [{field: 'id', title: 'ID', hide: true},{field: 'avatar', title: '客户头像', width: 100, templet: function (d) {return '<img src="' + d.avatar + '" style="width: 30px; height: 30px; border-radius: 50%;">';},},{field: 'nickname',title: '客户昵称',width: 170},{field: 'friendid',title: '客户微信',width: 80, templet: function (d) {return '***';},},{field: 'gender', title: '客户性别', width: 40, templet: function (d) {// 假设性别1为男,2为女,这里简单处理return d.gender === '1' ? '男' : d.gender === '2' ? '女' : '未知';}},{field: 'dq',title: '客户地区',width: 100},{field: 'uname',title: '录入人',width: 100},{field: 'c_name',title: '客户姓名',edit: 'text',width: 100},{field: 'c_phone',edit: 'text',title: '客户手机',width: 120},{field: 'channal_id',title: '<div id="dropdown_channal_id" lay-options="{trigger: \'hover\'}" >渠道</div>',width: 200,templet: '#select_channal'},{field: 'budget',title: '<div id="dropdown_budget" lay-options="{trigger: \'hover\'}" >预算</div>',width: 200,templet: '#select_budget'},{field: 'intent',title: '<div id="dropdown_intent" lay-options="{trigger: \'hover\'}" >意向</div>',width: 200,templet: '#select_intent'},{field: 'grade',title: '<div id="dropdown_grade" lay-options="{trigger: \'hover\'}" >等级</div>',width: 200,templet: '#select_grade'},{field: 'bargain_time', title: '成交时间', width: 200, sort: true, templet: '#bargain_time'},{field: 'memo1',title: '备注',width: 200,edit: 'textarea'},{field: 'u_project', title: '项目', width: 100},{field: 'u_group', title: '组', width: 100},{field: 'xsavatar', title: '销售头像', width: 100, templet: function (d) {return '<img src="' + d.xsavatar + '" style="width: 30px; height: 30px; border-radius: 50%;">';}},{field: 'xswechatnick',title: '销售昵称',width: 200},{field: 'wechatid',title: '销售微信ID',width: 200},{field: 'wechatno',title: '<div><input id=\'wechatno_header\' type=\"text\" style=\'text-align: center;\' name=\"wechatno\" placeholder=\"搜索 微信号\" οnblur=\"cms.input_blur(this);\"></div>',width: 200},{field: 'create_time', title: '进线时间', width: 160},// {field: 'incoming_time', title: '进线时间', width: 200},{field: 'create_time', title: '创建时间', width: 160},{field: 'options', fixed: 'right', title: '操作', width: 100, minWidth: 80, toolbar: '#barDemo'}];cms.input_blur = (that) => {let field = that.nameheader_input[field] = that.value;$("#p").val(1);cms.reload();}cms.export_xls = () => {layui.use(['jquery', 'excel', 'layer'], function () {var layer = layui.layer;var excel = layui.excel;let filterCols = [];let headers = {};default_cols.forEach(item => {filterCols.push(item.key)headers[item.key] = item.value;});// 重点!!!如果后端给的数据顺序和映射关系不对,请执行梳理函数后导出cache_data = excel.filterExportData(cache_data, filterCols);// 重点2!!!一般都需要加一个表头,表头的键名顺序需要与最终导出的数据一致cache_data.unshift(headers);let timestart = Date.now();excel.downloadExcel(cache_data, '客户详情报表', 'xlsx');let timeend = Date.now();let spent = (timeend - timestart) / 1000;layer.alert('导出耗时 ' + spent + ' s');});};/*** 重载数据* @returns {Promise<void>}*/cms.reload = () => {if (first_load) {return new Promise((resolve, reject) => {});}let param = {p: $("#p").val(), //分页pmax: 20, //分页u_name: `${localStorage.getItem('u_name')}`,};//获取日期查询let wc_date = $("#wc_id").val();if (wc_date) {let searchDate = wc_date.split(" ");param["wc_date"] = 'BETWEEN \'' + searchDate[0].trim() + ' 00:00:00\' AND \'' + searchDate[2].trim() + ' 23:59:59\'';}//获取输入框的值Object.keys(header_input).forEach(key => {param[key] = header_input[key];});//获取头部复选框的值Object.keys(header_select).forEach(key => {param[key] = header_select[key].filter(e => !e || e !== '');});console.log(JSON.stringify(param));layui.use(['table', "laydate"], function () {var laydate = layui.laydate;let table = layui.table;table.reloadData('test', {where: param,scrollPos: 'fixed',  // 保持滚动条位置不变done: function () {//重新加载筛选列cms.load_cols(default_cols)//重新更新分页组件pagehelper.updateButtons();//重新渲染头部下拉组件Object.keys(default_select_data).forEach(key => {cms.load_header_select(key, default_select_data[key])});//重新填充头部输入框fields.forEach(field => {$(field.selector).val(header_input[field.key]);});// 加载行日期时间选择器laydate.render({elem: '.bargain_time',type: 'datetime',done: function (value, date, endDate) {}});//清理查询和数据缓存this.where = {};this.data = {};},}, true);});};/*** 日期条件重置* @returns {Promise<void>}*/cms.date_reset = () => {let date = new Date();$('#search input[name="wc_date"]').daterangepicker({timePicker: true,startDate: moment().startOf('month'),endDate: moment(),locale: {format: 'YYYY-MM-DD'},});cms.date_select($('#search input[name="wc_date"]'));}cms.reset = () => {$("#p").val(1);cms.date_reset()//重置输入条件fields.forEach(field => {header_input[field.key] = "";$(field.selector).val('');});//重置复选条件Object.keys(header_select).forEach(key => {header_select[key] = [];});cms.reload()}cms.addSelectListeners = (fields, formInstance) => {console.log('获取编辑的下拉框数据')// 确保fields是一个数组if (!Array.isArray(fields)) {throw new Error('fields must be an array');}// 遍历字段数组fields.forEach(function (fieldName) {// 构造lay-filter的值,这里假设lay-filter的值由'filter_'前缀和字段名组成let filterName = 'filter_' + fieldName;// 为每个select元素设置监听器formInstance.on('select(' + filterName + ')', function (data) {let field = data.elem.name; // 获取select元素的name属性,通常这与fieldName相同,但最好检查一下let value = data.value; // 获取选中的值var text = data.elem[data.elem.selectedIndex].text;//得到选中的文本内容console.log(value, text);});});}/*** 获取某个元素下的表单数据 通用函数* @param parent* @returns {{}}*/cms.form_data = (parent = '.label_top') => {// 获取表单元素,支持选择器模式和元素模式let form = typeof parent === 'string' ? document.querySelector(parent) : parent;if (!form) return {}; // 如果没有找到表单,则返回一个空对象// 创建一个对象来存储表单数据let formData = {};// 遍历表单内的所有元素form.querySelectorAll('input, select, textarea').forEach(function (input) {// 忽略没有name属性的元素if (!input.name) return;// 对于checkbox和radio,只有当它们被选中时才收集值if (input.tagName === 'SELECT') {// 对于单选select,直接获取valueformData[input.name] = input.value;} else if (input.type === 'checkbox' || input.type === 'radio') {if (input.checked) {// 如果是单选(radio),直接赋值if (input.type === 'radio') {formData[input.name] = input.value;} else {// 如果是多选(checkbox),检查是否已经存在该键,如果不存在则初始化为数组,然后添加值if (!formData[input.name]) {formData[input.name] = [];}formData[input.name].push(input.value);}}} else if (input.type === 'select-multiple') {// 对于多选的select元素,收集所有选中的值到数组中let selectedOptions = Array.from(input.selectedOptions);formData[input.name] = selectedOptions.map(opt => opt.value);} else {// 对于其他类型的输入,直接收集值formData[input.name] = input.value;}});return formData;};/*** 填充某个元素下的表单数据 通用函数* @param formData* @param parent* @returns {{}}*/cms.fill_form = (formData, parent = '.label_top') => {let form = document.querySelector(parent);if (!form) {console.error('Form not found with selector:', form);return;}// 遍历formData对象for (let key in formData) {if (formData.hasOwnProperty(key)) {const value = formData[key];const input = form.querySelector(`[name="${key}"]`);if (!input) {console.warn('Field not found with name:', key);continue;}// 根据input类型设置值switch (input.type) {case 'checkbox':// 对于checkbox,如果value是truthy值,则勾选input.checked = !!value;break;case 'radio':// 对于radio,需要找到value匹配的项并设置const radios = form.querySelectorAll(`[name="${key}"][type="radio"]`);radios.forEach(radio => {radio.checked = radio.value === value;});break;case 'select-multiple':// 对于select,可能是单选或多选if (input.multiple) {// 多选情况,需要处理数组if (Array.isArray(value)) {const options = input.querySelectorAll('option');options.forEach(option => {option.selected = value.includes(option.value);});}} else {// 单选情况,直接设置valueinput.value = value;}break;default:// 对于其他类型(如text, email, number等),直接设置valueinput.value = value;}// 触发change事件(如果需要)// input.dispatchEvent(new Event('change'));}}}document.addEventListener('DOMContentLoaded', async () => {cms.date_reset();//初始渠道数据const baseProject = 'ads'const func = 'set_channal'const url = `${baseURL}?class=${baseProject}&function=${func}`;cms.post_request(url, {"p": 1, "pmax": 10000}).then((res) => {channals = res.data;default_select_data.channal_id = channals.map(c => {return {key: `${c.id}`, value: `${c.platform_name}${c.channal}`};});});//设置默认列到缓存let cacheCols = JSON.parse(cache_manager.getCache(cache_key_cols));if (!cacheCols) {cache_manager.setCache(cache_key_cols, JSON.stringify(select_cols));}cacheCols = JSON.parse(cache_manager.getCache(cache_key_cols));table_cols.forEach((col, index) => {if (cacheCols.includes(col.field) || col.field == "options") {col.hide = false;} else if (col.field === "id") {col.hide = true;} else {col.hide = true;}})//加载筛选列cms.load_cols(default_cols)});/*** 请求工具类* @returns {Promise<void>}*/cms.post_request = (url, requestParam) => {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest();const params = new URLSearchParams();for (let key in requestParam) {if (requestParam.hasOwnProperty(key)) {params.append(key, requestParam[key]);}}xhr.withCredentials = true;xhr.open('POST', url, true);xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');xhr.send(params.toString());xhr.onload = function () {if (xhr.status === 200) {try {var response = JSON.parse(xhr.responseText);if (response.code === 200) {console.log('操作成功:', response.msg);resolve(response); // 在这里解决 Promise} else {console.error('操作失败:', response.msg);reject(new Error(response.msg)); // 在这里拒绝 Promise}} catch (error) {console.error('解析 JSON 响应时发生错误:', error);reject(error); // 在这里拒绝 Promise}} else {console.error('请求失败,状态码:', xhr.status);reject(new Error(`请求失败,状态码:${xhr.status}`)); // 在这里拒绝 Promise}};xhr.onerror = function () {console.error('请求过程中发生错误');reject(new Error('请求过程中发生错误')); // 在这里拒绝 Promise};});};/*** 更新插入* @returns {Promise<void>}*/cms.in_item = (data) => {const baseProject = 'ads'const func = 'update_wx_customerinfos'const url = `${baseURL}?class=${baseProject}&function=${func}`;cms.post_request(url, data).then(() => {cms.reload();layer.msg('提示框', {content: "保存成功",icon: 1, //-1透明  0 警告 1 成功 2错误time: 2000 // 设置 2 秒后自动关闭});});};cms.checkbox = (input, filed) => {let item = input.value;if (input.checked) {if (!header_select[filed].includes(item)) {header_select[filed].push(item);}} else {header_select[filed] = header_select[filed].filter(c => c !== item);}$("#p").val(1);cms.reload();};/*** 通用头部复选搜索* @returns {Promise<void>}*/cms.load_header_select = (currentField, data) => {if (Array.isArray(data)) {let htmls = `<div style="width: ${(200 - 3)}px; max-height: 640px;overflow-y: auto; overflow-x: hidden;">`; //搜索 (cols宽度-3)左右data.forEach((item, index) => {let value = typeof item === 'object' ? item.key || index : item; // 假设对象是带id的,否则使用索引let checked = header_select[currentField] && header_select[currentField].includes(value) ? ' checked' : '';htmls += `<label style="line-height: 2;letter-spacing: 1px;margin-left:10px;margin-top:20px;font-weight: bold;font-family: '宋体';font-size: 0.85rem;color: #343434;"><input type="checkbox" name="${currentField}" value="${value}" οnchange="cms.checkbox(this,'${currentField}')" ${checked} />${typeof item === 'object' ? item.value || item.toString() : item}</label><br />`;});htmls += "</div>";layui.use(function () {var dropdown = layui.dropdown;// 自定义内容dropdown.render({elem: `#dropdown_${currentField}`,content: htmls,className: `dropdown_class_${currentField}`,// style: 'width: 370px; height: 200px; box-shadow: 1px 1px 30px rgb(0 0 0 / 12%);',// shade: 0.3, // 弹出时开启遮罩 --- 2.8+// ready: function () {//     layui.use('element', function (element) {//         element.render('tab');//     });// }});});}};// cms.load_header_select 的副本,只是筛选列查询列分开好区分cms.load_cols = (data) => {if (Array.isArray(data)) {let htmls = `<div style="width: ${(120 - 3)}px; max-height: 360px;overflow-y: auto; overflow-x: hidden;">`; //搜索 (cols宽度-3)左右data.forEach((item, index) => {let value = typeof item === 'object' ? item.key || index : item; // 假设对象是带id的,否则使用索引let cacheCols = JSON.parse(cache_manager.getCache(cache_key_cols));let checked = cacheCols.length > 0 && cacheCols.includes(value) ? ' checked' : '';htmls += `<label style="line-height: 2;letter-spacing: 1px;margin-left:10px;margin-top:20px;font-weight: bold;font-family: '宋体';font-size: 0.85rem;color: #343434;"><input type="checkbox" name="cols" value="${value}" οnchange="cms.checkCols(this)" ${checked} />${typeof item === 'object' ? item.value || item.toString() : item}</label><br />`;});htmls += "</div>";layui.use(function () {var dropdown = layui.dropdown;// 自定义内容dropdown.render({elem: `#dropdown_cols`,content: htmls,className: `dropdown_class_cols`,});});}};cms.checkCols = (input) => {let item = input.value;let cacheCols = JSON.parse(cache_manager.getCache(cache_key_cols));if (input.checked) {if (!cacheCols.includes(item)) {cacheCols.push(item);}} else {cacheCols = cacheCols.filter(c => c !== item);}cache_manager.setCache(cache_key_cols, JSON.stringify(cacheCols))table_cols.forEach((col, index) => {if (cacheCols.includes(col.field) || col.field == "options") {col.hide = false;} else if (col.field === "id") {col.hide = true;} else {col.hide = true;}})layui.use(['table'], async function () {var table = layui.table;// 设置对应列的显示或隐藏table.hideCol('test', table_cols);});cms.reload();};let cache_manager = {setCache: function (key, value) {localStorage.setItem(key, value);},getCache: function (key) {return localStorage.getItem(key);},};</script><script>/*** >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*                layui组件* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/layui.use(['table', 'dropdown', 'laydate', 'laytpl', 'form'], async function () {var table = layui.table;var form1 = layui.form;var laydate = layui.laydate;var laytpl = layui.laytpl;var dropdown = layui.dropdown;//layui允许跨域$.ajaxSetup({xhrFields: {withCredentials: true}});//获取日期查询let wc_date = $("#wc_id").val();let date;if (wc_date) {let searchDate = wc_date.split(" ");date = 'BETWEEN \'' + searchDate[0].trim() + ' 00:00:00\' AND \'' + searchDate[2].trim() + ' 23:59:59\'';}// 创建渲染实例table.render({elem: '#test',url: `${baseURL}?class=ads&function=get_wx_customerinfos`, // 此处为静态模拟数据,实际使用时需换成真实接口method: "post",where: {p: 1,pmax: 20,u_name: `${localStorage.getItem('u_name')}`,wc_date: date,},scrollPos: 'fixed',  // 保持滚动条位置不变contentType: 'application/x-www-form-urlencoded',// toolbar: '#toolbarDemo',// defaultToolbar: ['filter'],cellExpandedMode: "tips",skin: "gird",// even: true,//隔行背景色// loading: true,//是否显示加载height: 'full-156', // 最大高度减去其他容器已占有的高度差lineStyle: 'height: 56px;',//行高css: [].join(''), //样式重设cellMinWidth: 80,response: {"code": 0,"msg": "",// "count": 1000,"data": []},parseData: function (res) { //res 即为原始返回的数据$("#pmax").val(res.psum)return {"code": 0, //解析接口状态"msg": "", //解析提示文本// "count": res.psum, //解析数据长度"data": res.data //解析数据列表};},// totalRow: true, // 开启合计行// page: true,cols: [table_cols],/*** 初始化完毕时*/done: function (res, curr, count) {//更新分页组件pagehelper.updateButtons();//渲染头部组件Object.keys(default_select_data).forEach(key => {cms.load_header_select(key, default_select_data[key])});// 日期时间选择器laydate.render({elem: '.bargain_time',type: 'datetime',done: function (value, date, endDate) {}});cache_data = res.data;first_load = false;},error: function (res, msg) {console.log(res, msg)}});// 触发单元格工具事件table.on('tool(test)', function (obj) { // 双击 toolDoublevar data = obj.data; // 获得当前行数据var id = data.id;var layEvent = obj.event; // 触发的事件名称var tr = obj.tr; //let to_update = {};if (layEvent === 'save') {to_update['id'] = id;//用户名to_update['u_name'] = `${localStorage.getItem('u_name')}`;//下拉数据select_fields.forEach(function (field) {to_update[field] = tr.find(`td[data-field=${field}] > div > select`).val();});//成交时间to_update["bargain_time"] = tr.find(`td[data-field=bargain_time] > div  > input`).val();//备注文本域to_update["memo1"] = tr.find(`td[data-field=memo1] > div  > textarea`).val() || tr.find(`td[data-field=memo1] > div`).text();to_update["c_name"] = tr.find(`td[data-field=c_name] > div  > input`).val() || tr.find(`td[data-field=c_name] > div`).text();to_update["c_phone"] = tr.find(`td[data-field=c_phone] > div  > input`).val() || tr.find(`td[data-field=c_phone] > div`).text();console.log("保存数据" + JSON.stringify(to_update));cms.in_item(to_update)}});// 行单击事件table.on('row(test)', function (obj) {let id = obj.data.id;console.log("单击的id" + id)});// 文本编辑table.on('edit(test)', function (obj) {var field = obj.field; // 得到字段var value = obj.value; // 得到修改后的值var data = obj.data; // 得到所在行所有键值console.log("edit的id" + obj.data.id);// 其他更新操作var to_update = {};to_update[field] = value;obj.update(to_update);});//下拉编辑// cms.addSelectListeners(select_fields, form1)});/*** >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*                layui组件* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
</script><script>/*** >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*                分页组件* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/let pagehelper = {/*** 跳转到哪一页*/goto_page: function (page) {let pmax = parseInt($("#pmax").val())if (page < 1 || page > pmax) {// alert('页码超出范围');return;}$("#p").val(page)console.log('跳转到第' + page + '页');// 更新按钮pagehelper.updateButtons();cms.reload();},/*** 点击上一页*/goto_previous: function () {let p = parseInt($("#p").val())if (p > 1) {pagehelper.goto_page(p - 1);}},/*** 点击下一页*/goto_next: function () {let p = parseInt($("#p").val())let pmax = parseInt($("#pmax").val())if (p < pmax) {pagehelper.goto_page(p + 1);}},/*** 生成五个页码*/generatePageNumbers: function (currentPage, totalPages) {// 计算要显示的页码范围let minPage = Math.max(1, currentPage - 2); // 至少从1开始let maxPage = Math.min(totalPages, currentPage + 2); // 最多到总页数// 如果总页数小于等于5,直接显示全部页码// if (totalPages <= 20) {//     minPage = 1;//     maxPage = totalPages;// }// 如果总页数允许且当前页接近两端,则调整最小或最大页码以包含足够的页码// 特别是当当前页是前几页或后几页时if (currentPage <= 3 && totalPages > 5) {maxPage = Math.min(totalPages, 5); // 确保不超过总页数} else if (currentPage >= totalPages - 2 && totalPages > 5) {minPage = Math.max(1, totalPages - 4); // 确保不小于1}// 生成页码数组let pageNumbers = [];for (let i = minPage; i <= maxPage; i++) {pageNumbers.push(i);}return pageNumbers;},/*** 重绘分页组件*/updateButtons: function () {let p = parseInt($("#p").val())let pmax = parseInt($("#pmax").val())var nav = document.getElementById('nav');nav.innerHTML = ''; // 清空nav的内容// 创建上一页按钮var prevButton = document.createElement('button');prevButton.onclick = function () {pagehelper.goto_previous();};prevButton.textContent = '上一页';if (p == 1) {// 如果当前是第一页,则不显示prevButton.style.display = 'none';}//创建五个页码let pages = pagehelper.generatePageNumbers(p, pmax);// 创建页码按钮var ul = document.createElement('ul');for (var i = 0; i < pages.length; i++) {var pageNum = pages[i];var li = document.createElement('li');var pageButton = document.createElement('button');pageButton.onclick = function (page) {return function () {pagehelper.goto_page(page);};}(pageNum); // 闭包确保正确的页码被传递pageButton.textContent = pageNum;if (pageNum == p) {// 如果不是当前页,则禁用pageButton.disabled = true;}li.appendChild(pageButton);ul.appendChild(li);}// 创建跳转输入框和下一页按钮var input = document.createElement('input');input.type = 'number';input.name = 'manual';input.placeholder = '最大页' + pmax;// 设置事件监听器input.onkeydown = function (event) {if (event.keyCode === 13) { // 只在按下回车键时验证let toPage = parseInt(this.value, 10);if (!isNaN(toPage) && toPage > 0 && toPage <= pmax) {pagehelper.goto_page(toPage);} else {pagehelper.goto_page(pmax);}}};var nextButton = document.createElement('button');nextButton.onclick = function () {pagehelper.goto_next();};nextButton.textContent = '下一页';nextButton.style.display = p < pmax ? '' : 'none'; // 如果当前是最后一页,则不显示// 将元素添加到nav中nav.appendChild(prevButton);nav.appendChild(ul);nav.appendChild(input);nav.appendChild(nextButton);}};/*** >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*                分页组件* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
</script></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3280876.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

面试经典算法150题系列-数组/字符串操作之多数元素

序言&#xff1a;今天是第五题啦&#xff0c;前面四题的解法还清楚吗&#xff1f;可以到面试算法题系列150题专栏 进行复习呀。 温故而知新&#xff0c;可以为师矣&#xff01;加油&#xff0c;未来的技术大牛们。 多数元素 给定一个大小为 n 的数组 nums &#xff0c;返回其…

“华数杯”全国大学生数学建模竞赛含金量如何?

“华数杯”全国大学生数学建模竞赛是由华中师范大学主办的一项全国性的大学生数学建模竞赛。该竞赛旨在提高大学生的数学建模能力和实践能力,增强大学生的创新意识和团队协作精神。 搜集一些评价,有人说该竞赛的含金量较高,但是也有一些人认为其认可度不高,报名费用较贵。…

javascript 构造函数

1.定义一个构造函数 命名是大驼峰 不需要显式得返回 this对象 构造函数已返回 2.使用这个构造函数构建对象

锅总浅析链路追踪技术

链路追踪是什么&#xff1f;常用的链路追踪工具有哪些&#xff1f;它们的异同、架构、工作流程及关键指标有哪些&#xff1f;希望读完本文能帮您解答这些疑惑&#xff01; 一、链路追踪简介 链路追踪技术&#xff08;Distributed Tracing&#xff09;是一种用于监控和分析分布…

代码随想录算法训练营day29 | 134. 加油站 、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列

碎碎念&#xff1a;加油 参考&#xff1a;代码随想录 134. 加油站 题目链接 134. 加油站 思想 局部最优&#xff1a; 一旦currentSum为负数&#xff0c;起始位置至少要是i1。 全局最优&#xff1a; 最后可以跑完一圈。 局部最优可以推出全局最优且找不到反例&#xff0c;所…

CST软件进行时域自适应网格设置步骤

这一期&#xff0c;我们回答一个大家非常关注的网格的问题。仿真软件的网格质量直接决定仿真的精度和效率&#xff0c;设置合理的网格才能将仿真做的又快有准。CST的微波工作室有多种求解器&#xff0c;如果用频域求解器&#xff08;F&#xff09;来仿真&#xff0c;有限元算法…

TCP的可靠机制

TCP的可靠机制 前言 要了解TCP的可靠机制&#xff0c;我们必须要先熟悉TCP的报文&#xff0c;在这篇文章中有详细介绍TCP的报文 &#xff1a; 并且确认应答机制也在该文章中提到&#xff0c;所以这篇文章就不会再介绍确认应答了。 超时重传 我们都知道&#xff0c;报文在网…

详解Qt 之QMdiArea 和 QMdiSubWindow

文章目录 前言QMdiArea概念作用为什么需要 QMdiAreaQMdiArea 的主要函数和成员函数列表 QMdiSubWindow概念作用为什么需要 QMdiSubWindowQMdiSubWindow 的主要函数和成员函数列表 示例代码 更多用法... 总结 前言 在复杂的应用程序中&#xff0c;尤其是那些需要同时管理多个子…

RabbitMQ快速入门(MQ的概念、安装RabbitMQ、在 SpringBoot 项目中集成 RabbitMQ )

文章目录 1. 补充知识&#xff1a;同步通讯和异步通讯1.1 同步通讯1.2 异步通讯 2. 同步调用的缺点2.1 业务耦合2.2 性能较差2.3 级联失败 3. 什么情况下使用同步调用4. 异步调用5. 异步调用的优点和缺点5.1 异步调用的优点5.1.1 解除耦合&#xff0c;拓展性强5.1.2 无需等待&a…

SQL必知必会

SQL必知必会 一些SQL知识&#xff0c;出自极客时间陈旸老师《SQL必知必会》 https://time.geekbang.org/column/intro/100029501 基础 视图 视图作为一张虚拟表&#xff0c;帮我们封装了底层与数据表的接口。它相当于是一张表或多张表的数据结果集。视图的这一特点&#x…

DMB,DSB,ISB三个指令区别

此部分说明三个指令的具体区别&#xff08;在指令流水线上说明&#xff09;&#xff0c;这三个指令主要目的在于确保程序在多处理器环境下的稳定性和一致性&#xff0c;避免由于指令乱序和内存操作重排引起的不可预测行为 一个简化的流水线&#xff0c;包含以下阶段&#xff1…

【git】git常用命令提交规范

Git 是程序员工作中不可或缺的版本控制工具&#xff0c;以下是一些优化后的常用 Git 命令列表&#xff0c;旨在帮助你更高效地使用 Git 进行版本控制。 基础操作 拉取代码 git clone xxx.git创建分支 git branch dev切换分支 git checkout dev # 或者 git switch dev创建并切换…

Mirror学习笔记(一) 简介

文章目录 一、常规学习&#xff1a;Mirror核心功能有服务器和主机 二、时间戳批处理时间戳 三、TCP和UDP四、CCU(同时在线人数)五、SyncDirection(同步方向)六、RTT&#xff08;往返时间&#xff09;七、Connection Quality&#xff08;连接质量&#xff09;八、Lag Compensati…

Android mLruProcesses的分布结构

AMS中的进程管理 final ArrayList<ProcessRecord> mLruProcesses new ArrayList<ProcessRecord>(); 在AMS的内部属性中使用mLruProcesses集合保存所有的进程信息&#xff0c;AMS将所有进程按照优先级从低到高的顺序保存着对应的ProcessRecord信息&#xff0c;即排…

25、Python之面向对象:私有属性是掩耳盗铃还是恰到好处

引言 声明&#xff0c;今天的文章中没有一行Python代码&#xff0c;更多的是对编程语言设计理念的思考。 上一篇文章中介绍了关于Python面向对象封装特性的私有属性的相关内容&#xff0c;提到了Python中关于私有属性的实现是通过“名称混淆”的方式来实现的&#xff0c;我们…

【Python体验】第五天:目录搜索、数据爬虫(评论区里写作业)

文章目录 目录搜索 os、shutil库数据爬虫 request、re作业&#xff1a;爬取案例的top250电影的关键信息&#xff08;名称、类型、日期&#xff09;&#xff0c;并保存在表格中 目录搜索 os、shutil库 os 模块提供了非常丰富的方法用来处理文件和目录。 os.listdir(path)&#x…

连环画:80、90后的童年记忆与副业项目的AI新玩法

在那个纯真的年代&#xff0c;当80、90后的孩子们还在为学业忙碌之余&#xff0c;一种名为连环画的读物成为了他们心中难以磨灭的记忆。 这些由一幅幅精美插图串联起来的故事&#xff0c;不仅满足了他们对知识的渴望&#xff0c;更在无形中丰富了他们的想象力和审美能力。在那…

智云-一个抓取web流量的轻量级蜜罐

智云-一个抓取web流量的轻量级蜜罐 安装环境要求 apache php7.4 mysql8 github地址 https://github.com/xiaoxiaoranxxx/POT-ZHIYUN 系统演示

Xilinx FPGA:vivado SPI实现FLASH通信

一、实验要求 要求使用SPI协议实现对flash芯片的页编程、读操作、页擦除等功能。 二、模块划分 大概的时序图&#xff1a; 三、程序设计 &#xff08;1&#xff09;接收端模块 timescale 1ns / 1ps module uart_rx(input sys_clk ,input …

ShardingSphere实战(2)- 水平分表

项目环境&#xff1a; JDK11 MySQL 8.0.30 Springboot 2.7.4 Mybatis ShardingSphere HikariCP 连接池 一、Maven 依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><versi…