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

8次阅读

共计 4461 个字符,预计需要花费 12 分钟才能阅读完成。

在最近的《微课堂》项目中,有教师录入学生成绩的需求,为了使录入成绩的功能更加便捷,采用了 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 真的挺神奇的,这次接触的不是很深,相信在日后的接触中,我会好好的掌握它。

正文完
 0