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://www.rhkb.cn/news/387535.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【探索Linux】P.43(网络层 —— IP协议)

阅读导航 引言一、IP协议基本概念二、IP协议头格式三、网段划分1. 网络号和主机号2. 引入子网掩码&#xff08;1&#xff09;基本概念&#xff08;2&#xff09;默认子网掩码&#xff08;3&#xff09;子网掩码的作用&#xff08;4&#xff09;子网掩码与IP地址的结合&#xff…

国内NAT服务器docker方式搭建rustdesk服务

前言 如果遇到10054,就不要设置id服务器!!! 由于遇到大带宽,但是又贵,所以就NAT的啦,但是只有ipv4共享和一个ipv6,带宽50MB(活动免费会升130MB~) https://bigchick.xyz/aff.php?aff322 月付-5 循环 &#xff1a;CM-CQ-Monthly-5 年付-60循环&#xff1a;CM-CQ-Annually-60官方…

Prometheus安装部署

文章目录 1.Prometheus(普罗米修斯)安装部署1.1部署环境准备1.2部署prometheus1.3主机数据展示 2.Grafana安装部署2.1部署Grafana2.2配置Grafana数据源2.2配置Grafana仪表板 3.AlertManager安装部署3.1部署alertmanager3.2告警邮件发送配置3.3测试邮件告警效果3.4自定义邮件告警…

昇思25天学习打卡营第9天|RNN实现情感分类

第十天的不小心把第九天的覆盖了。现在重新补上。 情感分类是自然语言处理中的经典任务&#xff0c;是典型的分类问题。输入一句话&#xff0c;然后去语义理解这句话是褒义贬义还是中性的。不同的情感语境下理解的大基调是不同的。 RRN情感分类也是一个分类模型&#xff0c;是…

多态、接口、类练习题

代码&#xff1a; public static void main(String[] args) {Person2 personnew Person2("唐僧",new Horse());person.passRiver();person.onRoad();} 接口&#xff1a; interface Vehicles{public void work(); } lass Horse implements Vehicles{Overridepubli…

外星人入侵_计分

外星人入侵_计分 1添加Play按钮1.1创建Button类1.2在屏幕上绘制按钮1.3开始游戏1.4 重置游戏1.5 将Play按钮切换到非活动状态1.6隐藏光标 2提高等级2.1修改速度设置2.2重置速度 3计分3.1显示得分3.2创建记分牌3.3在外星人被消灭时更新得分3.4将消灭的每个外星人的点数都计入得分…

TortoiseSVN迁移到本地git

TortoiseSVN迁移到本地git 文章目录 TortoiseSVN迁移到本地git0 背景1 环境准备2 SVN库迁移到VisualSVN2.1 导出dump2.2 将dump文件灌入VisualSVN2.3 获取SVN仓最新URL 3 迁移到Git库中4 迁移分支到Git库 0 背景 之前在前东家工作都是采用git进行项目管理&#xff0c;高效便捷…

Redis实战篇(黑马点评)笔记总结

一、配置前后端项目的初始环境 前端&#xff1a; 对前端项目在cmd中进行start nginx.exe&#xff0c;端口号为8080 后端&#xff1a; 配置mysql数据库的url 和 redis 的url 和 导入数据库数据 二、登录校验 基于Session的实现登录&#xff08;不推荐&#xff09; &#xf…

Ruby、Python、Java 开发者必备:Codigger之软件项目体检

在编程的广阔天地里&#xff0c;Ruby、Python 和 Java 开发者们各自凭借着独特的语言特性&#xff0c;构建着精彩纷呈的应用世界。然而&#xff0c;无论使用哪种语言&#xff0c;确保项目的高质量始终是至关重要的目标。而 Codigger 项目体检则成为了实现这一目标的得力助手&am…

React——配置环境、ES6语法补充、Components

文章目录 架构设计前置知识DOM树 配置环境安装 create-react-app安装两个插件创建安装 nodejs仍然无法创建 下次需要创建新项目就使用这三行命令安装 bootstrap使用 bootstrap 包画图追求写 jsx短路原则绑定函数快捷键修改变量名箭头函数简写删除无用的文件写组件调用组件使用 …

人工智能与机器学习原理精解【11】

文章目录 广义线性模型基础理论泊松分布的基本公式一、基本公式二、泊松分布的特点三、泊松分布的应用场景四、泊松分布与二项分布的关系五、总结 泊松回归例子1例子背景模型设定数据收集模型拟合结果解释预测应用场景 泊松回归例子2背景数据准备模型设定模型拟合结果解释预测 …

Prometheus-部署

Prometheus-部署 Server端安装配置部署Node Exporters监控系统指标监控MySQL数据库监控nginx安装grafana Server端安装配置 1、上传安装包&#xff0c;并解压 cd /opt/ tar xf prometheus-2.30.3.linux-amd64.tar.gz mv prometheus-2.30.3.linux-amd64 /usr/local/prometheus…

TypeScript 简介及安装

文档 typeScript官网中文文档&#xff1a;https://www.tslang.cn/index.html中文文档(简洁点)&#xff1a;https://typescript.bootcss.comMDN 概述 TypeScript 是以JavaScript为基础构建的语言。 TypeScript 是一个为 JavaScript 添加静态类型检查的编程语言。 TypeScrip…

自动化测试与手动测试的区别!

自动化测试与手动测试之间存在显著的区别&#xff0c;这些区别主要体现在以下几个方面&#xff1a; 测试目的&#xff1a; 自动化测试的目的在于“验证”系统没有bug&#xff0c;特别是在系统处于稳定状态时&#xff0c;用于执行重复性的测试任务。 手工测试的目的则在于通过…

git配置环境变量

一.找到git安装目录 打开此git安装目录下的bin文件&#xff0c;复制此文件路径 二.配置环境变量 2.1 右键点击此电脑的属性栏 2.2 点击高级系统配置 2.3 点击环境变量 2.4 按图中步骤进行配置 三.配置完成 win r 输入cmd打开终端 终端页面中输入 git --version 如图所示…

如何将WordPress文章中的外链图片批量导入到本地

在使用采集软件进行内容创作时&#xff0c;很多文章中的图片都是远程链接&#xff0c;这不仅会导致前端加载速度慢&#xff0c;还会在微信小程序和抖音小程序中添加各种域名&#xff0c;造成管理上的麻烦。特别是遇到没有备案的外链&#xff0c;更是让人头疼。因此&#xff0c;…

kafka高性能的底层原理分析

目录 1.磁盘顺序写 2.零拷贝 3.数据压缩 4.消息批量处理 5.pageCache 6.稀疏索引 总结 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。那么他是如何做到高性能的呢&#xff0c;本篇文章从宏观上分析一下&#xff…

alibabacloud学习笔记12

Docker介绍和使用场景 讲解阿里云ECS服务安装Docker实战 遇到这个报错可以执行&#xff1a; 执行这个docker info出这个就证明docker关闭成功。 快速掌握Dokcer基础知识 掌握Docker容器常见命令 查看本地已有镜像&#xff1a; 拉取镜像&#xff1a; 可以查到刚才拉取的镜像。 …

028-GeoGebra中级篇-脚本的初步的探索

GeoGebra 的脚本功能允许用户通过不同的触发机制&#xff08;如点击、更新、输入框变化、拖动结束&#xff09;和全局 JavaScript 自定义图形和交互行为&#xff0c;实现动态数学模型和用户交互&#xff0c;同时 ggbOnInit() 函数可在应用初始化时设置默认状态&#xff0c;提供…

构建基于数据驱动的应用程序与Llamaindex——理解大型语言模型

如果你在阅读这本书&#xff0c;你可能已经探索过大型语言模型&#xff08;LLMs&#xff09;的领域&#xff0c;并且已经认识到它们的潜在应用以及它们的缺陷。本书旨在解决LLMs所面临的挑战&#xff0c;并提供一本实用指南&#xff0c;教你如何使用LlamaIndex构建数据驱动的LL…