php + js实现便捷成绩录入功能

php基础

浏览数:562

2019-10-30

AD:资源代下载服务

在最近的《微课堂》项目中,有教师录入学生成绩的需求,为了使录入成绩的功能更加便捷,采用了js,现在就和大家分享一下。

效果

在进行构思编写之前,我们首先要做的就是知道自己想要达成什么效果。先来看一下我们想要的效果吧(由于最后实现了想要的效果,就用成品展示一下)

这是录入成绩界面的控制按钮,点击后进入录入成绩的界面。


这是录入成绩的界面,教师在这里输入平时成绩和期末成绩后,平时成绩、期末成绩、总成绩都会保存到数据表中。


点击方框后,便可以进行编辑,点击方框之外的地方,编辑完成,立刻进行保存,而且立刻计算出总成绩。


考虑到不同的老师会按照不同的权重给平时成绩和考试成绩的分数,所以添加了选择权重的功能,又因为权重的比例一般没有个位数,所以提供给用户选择的功能,而并非输入权重,相比之下,选择更加省时、省心、省力。

实现

一、失去焦点后执行方法和对表单进行编辑


要想实现点击时进行编辑,离开后进行保存的功能,我们需要用到一个方法“onblur()”
下面是它的用法:

onblur使用方法
一般情况下,表单内容是无法进行编辑的,为了保证整体的美观性和实用性,我们采用对表单进行编辑,而非采用<input>输入框,在这我们对其属性进行了编辑,即:“contenteditable=”true””

修改属性后,便可以进行编辑了。

二、执行方法后进行保存

在我的代码中,对平时成绩和考试成绩的保存分别采用了autoSave()、 finalSave()两个方法,当然这两个方法是自己任意命名的。

平时成绩

<td style="color: white"  class="list usual" contenteditable="true" onblur="autoSave(event);" id="{$score-> id}">{$score->usual_score}</td>

考试成绩

<td style="color: white"  class="list exam" contenteditable="true" onblur="finalSave(event);" id="{$score-> id}">{$score->exam_score}</td>

下面来看一下js的方法

成绩的保存

  function autoSave(event) {
    const id = event.target.id;
    const usualValue = event.target.textContent;
    $.post("/index/teacher/usualScore?", { id: id, usualvalue: usualValue }, function(result) {
      totalAchievements(id);
    });
                         }
event


event接口

id 和 value 都是要传输给后台的参数值,post指的是用post方法进行传值,路径为“/index/teacher/usualScore”,所以我们要在后台构建“usualScore()”这个方法,“?”后面的都是要传输的参数。

我们再来看一下后台的方法

   public function usualScore()
   {
   $data = Request::instance()->param();
   $id = $data['id'];
   $value = $data['usualvalue'];
   $Score = Score::get($id);
   $Score->usual_score = $value;
   $Score->save();
   }

$data 接收所有的参数,然后找到id所对应的对象,赋值后进行保存。

考试成绩和总成绩的写法与平时成绩的写法相同,在此也就不一一介绍了。

三、权值的选择与计算
<label   class="option" style="color: white">请选择平时成绩所占权重</label>
  <select name="usual" id="usual" lay-search style="height: 4%;"  onchange="reload();">
   <option value="0.3">30%</option>
   <option value="0.1">10%</option>
   <option  value="0.2">20%</option>
   <option value="0.4">40%</option>
   <option  value="0.5">50%</option>

 </select>

“onchange()”方法指的是一经改变,就执行方法,此处执行的是”reload()”方法。

   function reload()
   {
     obtainWeight();
     init();
   }
   

“reload()”方法又调用”obtainWeight()”、”init()”两个方法。

function obtainWeight(event) {
    let usual = document.getElementsByClassName('usual');

    let weightNode = document.getElementById("usual");
    let examNode = document.getElementById('exam');
    let index = weightNode.selectedIndex;
    let value = weightNode.options[index].value;
    //利用url跳转将term节点的值传到后台
    let url = "/index/teacher/getWeight?usualScore=" + value;


    ajaxGet(url, function(response) {
      console.log(response);
      clear(examNode);
      createOption(examNode, response);
      totalAchievements();
    });
    //调用creatOption方法
  }

document.getElementsByClassName()”是通过Class的名字获取节点,“document.getElementsById()”是指通过id获取节点,用“value”表示获取到的节点的值,之后定义url,标明方法和参数,用”ajaxGet()”方法进行跳转传值。

function ajaxGet(url, callback) {
    $.ajax({
      url: url,
      type: "get",
        //成功后调用success后面的语句
        success: function(response) {
          callback(response);
        },
        //失败后调用error后面的语句
        error: function(xhr) {
          console.log('server error');
        }
      });

url 指的是用户定义的url,如果没有参数,只写明路径即可,type指的是传值的方式,一般有“post”和“get”两种,success()和error()指的是传回的数据,如果成功,就返回参数,如果未成功,就在控制台上显示“error”中的内容。

 //获取前台传入的平时成绩的权重值,计算出考试成绩的权重值后返回给前台
    public function getWeight()
    {
    $usualScore = Request::instance()->param('usualScore');
    $examScore = 100-($usualScore*100).'%';    
    return $examScore;
    }

现在我们再来看一下后台的代码,$usualScore表示的是平时成绩的权重,计算出考试成绩的权重后返回给前台。

function createOption(node, inners, values) {
    let examScore = document.createElement('option');
    examScore.name = node;
    examScore.innerHTML = inners;
    node.appendChild(examScore);
  }

在图中我们可以发现,考试成绩所占权重是没有<option>的,那么它是怎么得到的option呢?

由上面的命名可以知道,我们要用js创建一个<option>,“document.createElement()”,指的是创建节点,后面的内容便是对节点进行赋值,从而生成节点。

  function init() 
  {
    let usual = document.getElementsByClassName('usual');
    for (var i = 0; i < usual.length; i++)
    {

      totalAchievements(usual[i].id);


     }
   }

通过Class的名字获取节点,然后用for循环生成id,以区分不同的usualScore的值,然后调用”totalAchievements()”方法。

 function totalAchievements(id)
 {
    let index;
    let usual = document.getElementsByClassName('usual');
    let exam = document.getElementsByClassName('exam');
    let total = document.getElementsByClassName('total');
    let usualWeight = document.getElementById("usual").value;

    for (var i = 0; i < usual.length; i++) {
      if (usual[i].id === id) {
        index = i;
        break;
      }
    }
    usualScore = usual[index];
    examScore = exam[index];
    totalScore = total[index];
    if (usualScore && examScore && totalScore) {
      let response = usualWeight * usualScore.innerText + (1 - usualWeight) * examScore.innerText;
      totalScore.innerText = (Math.round(response*10)/10);
     totalSave(id,  (Math.round(response*10)/10));
    }
  }

获取到节点,然后取各节点的值,之后便是根据各值的含义进行运算,再把值赋予总成绩。

 function clear(node) {
    node.length = 0;
  }

定义”clear()”方法,清除上一次的取值,否则会造成数值积累。

总结

以上便是思路以及实现的步骤,在最后要提醒大家,在权值选择改变后,要执行计算另一个权值以及计算总成绩的方法,还有就是在点击“录入”按钮跳转到录入成绩的界面时,要执行计算另一权重的方法,一般情况下,初始权重默认为是<select>标签下的第一个<option>。
这是第一次接触js,不得不说js真的挺神奇的,这次接触的不是很深,相信在日后的接触中,我会好好的掌握它。

作者:锦城