javascript 练习 写一个简单 另类录入 电脑组装报价表 可打印

news2024/9/27 21:24:54

数据格式

(1代表cpu、2代表主板、3代表内存、。。。)

1@i3 12100 @630
2@H610 @480
3@DDR4 3200 16G @220
4@500G M.2  @299
5@300W电源 @150
6@小机箱 @85
7@GT 730G 4G @350
8@WD 2T @399
9@飞利浦 24Led @580

 主代码 Html + JS

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>电脑组装报价表</title>
  <link rel="stylesheet" href="./iconfont/iconfont.css">
  <link rel="stylesheet" href="css/index.css" />
</head>

<body>
  <h1>电脑组装报价表</h1>
    <form class="info no-print" autocomplete="off">
         <textarea placeholder="请输入内容" class="uname" name="uname" lay-verify="required" style="width: 500px;height: 100px;"></textarea>

          <button class="add">
            <i class="iconfont icon-tianjia"></i>录入
          </button>

    </form>
  
  

  <div class="title no-print">共有数据<span>0</span>条</div>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>类别</th>
        <th>配件名称</th>
        <th>数量</th>
        <th>单价</th>
        <th>金额</th>
        <th>录入时间</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <!-- 表格内容 -->
    </tbody>
  </table>
  <div class="title heji">大写: <strong>零</strong>&nbsp;&nbsp;&nbsp;    合计:<span>0</span>元</div>
  <div class="boot">
    <button class="printer no-print">
      <i class="iconfont icon-tianjia"></i>打印
    </button>
  </div>
  
  <script src="js/daxie.js"></script>
  <script>
    // 参考数据
    const initData = [
      {
        stuId: 1,
        bname: 'cpu',
        goods: 'i3 12100',
        sl: 1,
        dj: 630,
        je: 630,
        time: '2099/9/9 08:08:08'
      }
    ]
    // 1. 渲染业务
    // 1.1 先读取本地存储的数据
    // (1). 本地存储有数据则记得转换为对象然后存储到变量里面,后期用于渲染页面
    // (2). 如果没有数据,则用 空数组来代替
    let count = 0 //合计数据
    
    const arr = JSON.parse(localStorage.getItem('data')) || []
    console.log('数据arr:',arr)
    // 1.2 利用map和join方法来渲染页面
    const tbody = document.querySelector('tbody')
    function render() {
      // (1). 利用map遍历数组,返回对应tr的数组
      const trArr = arr.map(function (ele, index) {
        count +=parseInt(ele.dj)
        return `
          <tr>
            <td>${ele.stuId}</td>
            <td>${ele.bname}</td>
            <td>${ele.goods}</td>
            <td>${ele.sl}</td>
            <td>${ele.dj}</td>
            <td>${ele.je}</td>
            <td>${ele.time}</td>
            <td>
              <a href="javascript:" data-id="${index}">
                <i class="iconfont icon-shanchu"></i>
                删除
              </a>
            </td>
          </tr>
        `
        count +=ele.dj // 合计储存数据
      })

      console.log(trArr)
      // (2). 把数组转换为字符串 join
      // (3). 把生成的字符串追加给tbody 
      tbody.innerHTML = trArr.join('')
      // 显示共计有几条数据
      document.querySelector('.title span').innerHTML = arr.length
    }
    render()

    // 2. 新增业务
    const info = document.querySelector('.info')
    const uname = document.querySelector('.uname')
    


    // 2.1 form表单注册提交事件,阻止默认行为
    info.addEventListener('submit', function (e) {
      e.preventDefault()
      // 2.2 非空判断
      if (!uname.value) {
        return alert('输入内容不能为空')
      }
      const dataT = [] // 接收新的数据对像
      
      let lines = uname.value.split("\n");
      console.log(lines)
      // console.log(typeof(lines))
      // 2.3 给 arr 数组追加对象,里面存储 表单获取过来的数据
      for (let line of lines) {
                    let parts = line.split("@"); // 将每行分割成组件编号、名称和价格
                    console.log(parts)
                    let [number, name, price] = parts;
                    price = price.trim(); // 去除价格两侧的空格

                    // 根据组件编号创建对象,并添加到结果数组中
                    if (number === "1") {
                        dataT.push({ id: "1", lx: "cpu", pj: name, jg: price });
                    } else if (number === "2") {
                        dataT.push({ id: "2", lx: "主板", pj: name, jg: price });
                    } else if (number === "3") {
                        dataT.push({ id: "3", lx: "内存", pj: name, jg: price });
                    } else if (number === "4") {
                        dataT.push({ id: "4", lx: "固态硬盘", pj: name, jg: price });
                    } else if (number === "5") {
                        dataT.push({ id: "5", lx: "电源", pj: name, jg: price });
                    } else if (number === "6") {
                        dataT.push({ id: "6", lx: "机箱", pj: name, jg: price });
                    } else if (number === "7") {
                        dataT.push({ id: "7", lx: "外置显卡", pj: name, jg: price });
                    } else if (number === "8") {
                        dataT.push({ id: "8", lx: "机械硬盘", pj: name, jg: price });
                    } else if (number === "9") {
                        dataT.push({ id: "9", lx: "显示器", pj: name, jg: price });
                    }

                }

      for (let i = 0; i < dataT.length; i++){     
        arr.push({
        // 处理 stuId:数组最后一条数据的stuId + 1      
        stuId: arr.length ? arr[arr.length - 1].stuId + 1 : 1,
        bname: dataT[i].lx,
        goods: dataT[i].pj,
        sl: 1,
        dj: dataT[i].jg,
        je: dataT[i].jg,
        time: new Date().toLocaleString()
      })
      // 2.4 渲染页面和重置表单(reset()方法)
      render()
      }
      
      this.reset() // 重置表单

      // 2.5 把数组重新存入本地存储里面,记得转换为JSON字符串存储
      localStorage.setItem('data', JSON.stringify(arr))
      location.reload(); // 刷新显示储存数据 合计结果
    })

    // 3. 删除业务
    // 3.1 采用事件委托形式,给 tbody 注册点击事件
    tbody.addEventListener('click', function (e) {
      // 判断是否点击的是删除按钮  A 链接
      if (e.target.tagName === 'A') {
        // alert(11)
        // 3.2 得到当前点击链接的索引号。渲染数据的时候,动态给a链接添加自定义属性例如 data-id="0"
        console.log(e.target.dataset.id)

        // 确认框 确认是否要真的删除
        if (confirm('您确定要删除这条数据吗?')) {
          // 3.3 根据索引号,利用 splice 删除数组这条数据
          arr.splice(e.target.dataset.id, 1)
          // 3.4 重新渲染页面 
          render()
          // 3.5 把最新 arr 数组存入本地存储
          localStorage.setItem('data', JSON.stringify(arr))
          location.reload(); // 刷新显示储存数据 合计结果
        }
      }
    })
  
  // 显示小写合计
  console.log('数量:',count)
  document.querySelector('.heji span').innerHTML = count
   // 显示大写合计,用numberTochinese 函数转成大写
  let Num = numberToChinese(count)
  document.querySelector('.heji strong').innerHTML = Num
// 打印
  function printPage() {
    window.print();
  }
  // 监听打印按钮
  const pr = document.querySelector('.printer')
  pr.addEventListener('click',function(){
    printPage();
  })

  

  </script>
</body>

</html>

注1:其中数据转换:

let parts = line.split("@"); // 将每行分割成组件编号、名称和价格

// 根据组件编号创建对象,并添加到结果数组中

                    if (number === "1") {

                        dataT.push({ id: "1", lx: "cpu", pj: name, jg: price });

                    } else if (number === "2") {

                        dataT.push({ id: "2", lx: "主板", pj: name, jg: price });

                    } else if (number === "3") {

                        dataT.push({ id: "3", lx: "内存", pj: name, jg: price });

                    } else if (number === "4") {

                        dataT.push({ id: "4", lx: "固态硬盘", pj: name, jg: price });

                    } else if (number === "5") {

                        dataT.push({ id: "5", lx: "电源", pj: name, jg: price });

                    } else if (number === "6") {

                        dataT.push({ id: "6", lx: "机箱", pj: name, jg: price });

                    } else if (number === "7") {

                        dataT.push({ id: "7", lx: "外置显卡", pj: name, jg: price });

                    } else if (number === "8") {

                        dataT.push({ id: "8", lx: "机械硬盘", pj: name, jg: price });

                    } else if (number === "9") {

                        dataT.push({ id: "9", lx: "显示器", pj: name, jg: price });

                    }

注2:两条内存 未解决 可以当 双条 合成 1套  

注3:打印 只是用CSS 隐藏 不打印的

CSS代码 index.css

* {
  margin: 0;
  padding: 0;
}

a {
  text-decoration: none;
  color: #721c24;
}

h1 {
  text-align: center;
  color: #333;
  margin: 20px 0;

}

.title {
  width: 933px;
  height: 50px;
  line-height: 50px;
  padding-right: 15px;
  border: 1px solid #ebebeb;
  margin: 10px auto;
  background-color: #f2f2f2;
  text-align: right;
}

.title span {
  display: inline-block;
  vertical-align: middle;
  height: 20px;
  margin: -3px 5px 0;
  text-align: center;
  line-height: 20px;
  color: #f26934;
  font-weight: 700;
}

table {
  margin: 0 auto;
  width: 950px;
  border-collapse: collapse;
  color: #3c3637;
}

th {
  padding: 10px;
  background: #f2f2f2;
  font-size: 18px;
  text-align: left;
}

td,
th {
  border: 1px solid #bbbaba;
  padding: 15px;
}

td {

  color: #080808;
  font-size: 16px;

}

tbody tr {
  background: #fff;
}

tbody tr:hover {
  background: #fbfafa;
}

tbody a {
  display: inline-block;
  width: 80px;
  height: 30px;
  text-align: center;
  line-height: 30px;
  color: #fff;
  background-color: #f26934;
}

.info {
  width: 900px;
  margin: 50px auto;
  text-align: center;
}

.info input,
.info select {
  width: 100px;
  height: 30px;
  outline: none;
  border: 1px solid #ebebeb;
  padding-left: 5px;
  box-sizing: border-box;
  margin-right: 10px;
}

.info button {
  width: 70px;
  height: 30px;
  background-color: #5dbfd8;
  outline: none;
  border: 0;
  color: #fff;
  cursor: pointer;
  font-size: 14px;
}

.info button:hover {
  background-color: #52abc1;
}

.printer {
  width: 70px;
  height: 30px;
  background-color: #5dbfd8;
  outline: none;
  border: 0;
  color: #fff;
  cursor: pointer;
  font-size: 14px;
}

.printer:hover {
  background-color: #52abc1;
}

.boot {
  margin: 0 auto;
  width: 950px;
  padding-bottom: 20px;
  text-align: center;
}

/* 对打印机进行样式设置 */
@media print {
  .no-print {
    display: none; /* 在打印时隐藏带有no-print类的元素 */
  }
  td,th {
    border: 1px solid #1a1a1a;
    padding: 15px;
  }
}

@media print {
  @page {
    margin-top: 0;
    margin-bottom: 0;
  }
  header, footer {
    display: none;
  }
}

小写转大写 JS代码 daxie.js

function numberToChinese(num) {
    const digit = {
      0: '零',
      1: '壹',
      2: '贰',
      3: '叁',
      4: '肆',
      5: '伍',
      6: '陆',
      7: '柒',
      8: '捌',
      9: '玖',
    };
    const unit = ['', '拾', '佰', '仟', '万', '亿'];
   
    const moneyStr = String(num.toFixed(2));
    const moneyArr = moneyStr.split('.');
    const integralPart = Number(moneyArr[0]);
    const decimalPart = Number(moneyArr[1]);
   
    const toChinese = (num) => {
      const numArr = String(num).split('');
      const len = numArr.length;
      const resultArr = [];
   
      for (let i = 0; i < len; i++) {
        const digitIndex = Number(numArr[i]);
        if (i !== len - 1 && digitIndex !== 0) {
          resultArr.push(digit[digitIndex], unit[len - i - 1]);
        } else {
          resultArr.push(digit[digitIndex]);
        }
      }
      return resultArr.join('');
    };
   
    if (num === 0) {
      return '零元整';
    }
   
    const result = toChinese(integralPart);
    if (decimalPart === 0) {
      return result + '元整';
    } else {
      return result + '元' + toChinese(decimalPart) + '角';
    }
  }
   
  console.log(numberToChinese(123456789.12)); // 壹亿贰仟叁佰肆拾伍万陆仟柒佰捌拾玖元壹角贰分

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

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

相关文章

Unity之ShaderGraph入门简介与配置

前言 ShaderGraph是Unity的一个可视化着色器编辑工具,它允许开发者在不编写代码的情况下创建复杂的着色器效果。ShaderGraph提供了一个直观的图形界面,用户可以通过拖拽节点并连接它们来构建自定义的着色器。用户可以在ShaderGraph中使用各种节点,如数学运算、纹理采样、颜…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(五)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 继续接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 在下面的图片中&#…

「 网络安全常用术语解读 」通用配置枚举CCE详解

1. 背景介绍 NIST提供了安全内容自动化协议&#xff08;Security Content Automation Protocol&#xff0c;SCAP&#xff09;为漏洞描述和评估提供一种通用语言。SCAP组件包括&#xff1a; 通用漏洞披露(Common Vulnerabilities and Exposures, CVE)&#xff1a;提供一个描述…

K8S 哲学 - 服务发现 services

apiVersion: v1 kind: Service metadata:name: deploy-servicelabels:app: deploy-service spec: ports: - port: 80targetPort: 80name: deploy-service-podselector: app: deploy-podtype: NodePort service 的 endPoint &#xff08;ep&#xff09; 主机端口分配方式 两…

LeetCode 234.回文链表

题目描述 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为 回文链表 。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff…

学习笔记:【QC】Android Q - IMS 模块

一、IMS init 流程图 二、IMS turnon 流程图 三、分析说明 1、nv702870 不创建ims apn pdp 2、nv702811 nv702811的时候才创建ims pdp&#xff1a; ims pdp 由ims库发起&#xff0c;高通没有开放这部分代码&#xff1a; 10-10 11:45:53.027 943 943 E Diag_Lib: [IMS_D…

开源im即时通讯app源码系统/php即时聊天im源码/php+uniapp框架【终身使用】

摘要 随着开源文化的蓬勃发展&#xff0c;即时通讯(IM)系统作为现代通信不可或缺的一部分&#xff0c;其开源实现正变得越来越普遍。本文将深入探讨基于PHP的全开源即时通讯源码系统&#xff0c;并结合UniApp开源框架&#xff0c;从理论基础到代码实现&#xff0c;再到实际应用…

SpringCloudAlibaba:4.1云原生网关higress的搭建

概述 简介 Higress是基于阿里内部的Envoy Gateway实践沉淀、以开源Istio Envoy为核心构建的下一代云原生网关&#xff0c; 实现了流量网关 微服务网关 安全网关三合一的高集成能力&#xff0c;深度集成Dubbo、Nacos、Sentinel等微服务技术栈 定位 在虚拟化时期的微服务架构…

微信小程序之搜索框样式(带源码)

一、效果图&#xff1a; 点击搜索框&#xff0c;“请输入搜索内容消失”&#xff0c;可输入关键字 二、代码&#xff1a; 2.1、WXML代码&#xff1a; <!--搜索框部分--><view class"search"><view class"search-btn">&#x1f50d;&l…

kettle从入门到精通 第五十六课 ETL之kettle Microsoft Excel Output

1、9.4 版本的kettle中有两个Excel输出&#xff0c;Excel输出和Microsoft Excel输出。前者只支持xls格式&#xff0c;后者支持xls和xlsx两种格式&#xff0c;本节课主要讲解步骤Microsoft Excel输出&#xff0c;如下图所示&#xff1a; 1&#xff09;、步骤【生成记录】生成两条…

VUE v-for 数据引用

VUE 的数据引用有多种方式。 直接输出数据 如果我们希望页面中直接输出数据就可以使用&#xff1a; {{ pageNumber }}双括号引用的方式即可。 在 JavaScript 中引用 如果你需要直接在代码中使用&#xff0c;直接使用变量名就可以了。 上面这张小图&#xff0c;显示了引用的…

「 网络安全常用术语解读 」通用安全通告框架CSAF详解

1. 简介 通用安全通告框架&#xff08;Common Security Advisory Framework&#xff0c;CSAF&#xff09;通过标准化结构化机器可读安全咨询的创建和分发&#xff0c;支持漏洞管理的自动化。CSAF是OASIS公开的官方标准。开发CSAF的技术委员会包括许多公共和私营部门的技术领导…

Ubuntu 域名解析出现暂时性错误

Ubuntu 域名解析出现暂时性错误 问题描述解决方案 问题描述 由于在Ubuntu系统里面经常切换网络导致&#xff0c;系统一直处于有线网络连接但是没网状态&#xff0c;尝试ping网络也无法完成&#xff0c;尝试了很多方法均不能解决 解决方案 点击”虚拟机“ 按照要求设置好即可…

Grafana:云原生时代的数据可视化与监控王者

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Grafana&#xff1a;让数据说话的魔术师》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Grafana简介 2、Grafana的重要性与影响力 …

GPT-3

论文&#xff1a;Language Models are Few-Shot Learners&#xff08;巨无霸OpenAI GPT3 2020&#xff09; 摘要 最近的工作表明&#xff0c;通过对大量文本进行预训练&#xff0c;然后对特定任务进行微调&#xff0c;在许多NLP任务和基准方面取得了实质性进展。虽然这种方法…

WPF应用程序XAML

当WPF应用程序创建好后&#xff0c;系统会自动添加一个Grid控件到窗体上&#xff0c;通过Grid控件能够方便地对界面进行布局.下面代码中为Grid控件添加了两行两列&#xff0c;分别用RowDefinitions属性ColumnDefinitions属性表示行的集合和列的集合&#xff0c;集合中有RowDefi…

【短剧在线表格搜索-附模板】

短剧在线表格搜索-附模板 介绍电脑界面手机界面送附加功能&#xff1a;反馈缺失短剧送&#xff1a;资源更新源头获取 介绍 你好&#xff01; 这是你第一次使用 金山在线文档 所生成的短剧搜索表格&#xff0c;支持批量导入自己转存的短剧名字和链接&#xff0c;实现在线搜索&a…

Java八股文系列之四(JVM)

什么是Java虚拟机&#xff1f;为什么Java被称作是“平台无关的编程语言”&#xff1f; Java虚拟机是一个可以执行Java字节码的虚拟机进程。 Java 实现跨平台的主要原因在于它的编译和执行方式。Java 程序首先被编译成中间代码&#xff08;bytecode&#xff09;&#xff0c;然…

【白话机器学习系列】白话特征向量

白话特征向量 一个方阵 A A A 与列向量 v v v 的乘积会生成一个新的列向量。这个新向量通常与原向量有着不同的方向&#xff0c;矩阵在这里代表一个线性变换。然而&#xff0c;某些向量会保持其原始方向。我们称这种向量为矩阵 A A A 的特征向量&#xff08;eigenvector&…

论文阅读_使用有向无环图实现流程工程_AgentKit

英文名称: AgentKit: Flow Engineering with Graphs, not Coding 中文名称: AgentKit&#xff1a;使用图而非编码进行流程工程 链接: https://arxiv.org/pdf/2404.11483.pdf 代码: https://github.com/holmeswww/AgentKit 作者: Yue Wu, Yewen Fan, So Yeon Min, Shrimai Prabh…