php + js to realize convenient score entry function

Keywords: PHP

In the recent "micro classroom" project, there is a need for teachers to enter students' scores. In order to make the function of entering scores more convenient, js is adopted. Now I'll share it with you.

Effect

The first thing we need to do before we start to write ideas is to know what we want to achieve. Let's take a look at the desired effect first (since the desired effect is finally achieved, let's show it with the finished product)

This is the control button in the score entry interface. Click it to enter the score entry interface.


This is the interface for entering grades. After entering the usual grades and final grades, the usual grades, final grades and total grades will be saved in the data table.


After clicking the box, you can edit it. Click outside the box, edit it, save it immediately, and calculate the total score immediately.


Considering that different teachers will give scores of usual and test scores according to different weights, the function of selecting weights is added. Because the proportion of weights generally does not have single digits, the function of selecting weights is provided to users instead of inputting weights. In contrast, selecting is more time-saving, heart-saving and labor-saving.

Realization

I. execution method and form editing after losing focus


To achieve the function of editing when clicking and saving after leaving, we need to use a method "onblur()"
Here's how it works:

How to use onblur
Generally, the form content cannot be edited. To ensure the overall aesthetics and practicability, we use the form to edit, rather than the < input > input box. Here we edit its attributes, that is, "contentable =" true "

After you modify the properties, you can edit them.

II. Save the method after implementation

In my code, autoSave() and finalSave() are used to save the usual and exam scores respectively. Of course, these two methods are named arbitrarily.

Usual performance

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

Examination results

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

Let's take a look at the js method

Preservation of achievements

  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 interface

Both id and value are parameter values to be transferred to the background. Post means to transfer values with the post method. The path is "/ index/teacher/usualScore". Therefore, we need to build the "usualScore()" method in the background. The latter are all parameters to be transmitted.

Let's take a look at the backstage approach.

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

$data receives all the parameters, finds the object corresponding to the id, assigns a value and saves it.

The writing method of examination results and total scores is the same as that of usual scores, so I will not introduce them one by one here.

III. selection and calculation of weights
<label   class="option" style="color: white">Please select the weight of your usual performance</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()" means to execute a method once it has been changed, and "reload()" method is executed here.

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

The "reload()" method also calls "obtainWeight()" and "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;
    //Using url jump to transfer the value of term node to the background
    let url = "/index/teacher/getWeight?usualScore=" + value;


    ajaxGet(url, function(response) {
      console.log(response);
      clear(examNode);
      createOption(examNode, response);
      totalAchievements();
    });
    //Call the createoption method
  }

"document.getElementsByClassName()" is to obtain a node by the name of Class, "document.getElementsById()" is to obtain a node by the id, and use "value" to represent the value of the acquired node, then define the url, indicate the method and parameter, and use "ajaxGet()" to jump to the value.

function ajaxGet(url, callback) {
    $.ajax({
      url: url,
      type: "get",
        //After success, call the statement after success.
        success: function(response) {
          callback(response);
        },
        //After failure, call the statement after error.
        error: function(xhr) {
          console.log('server error');
        }
      });

url refers to the user-defined url. If there is no parameter, just write the path. type refers to the way of value transfer. Generally, there are two ways: "post" and "get". success() and error() refer to the returned data. If it is successful, the parameter will be returned. If it is unsuccessful, the content in "error" will be displayed on the console.

 //Get the weight value of the usual score from the front desk, calculate the weight value of the test score and return it to the front desk
    public function getWeight()
    {
    $usualScore = Request::instance()->param('usualScore');
    $examScore = 100-($usualScore*100).'%';    
    return $examScore;
    }

Now let's take a look at the code in the background. The $usualScore represents the weight of the usual scores. After calculating the weight of the test scores, it will return to the front desk.

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

In the figure, we can see that there is no < option > in the weight of test scores, so how does it get the option?

As can be seen from the above naming, we need to create a < option >, "document.createElement()", which means to create a node. The next content is to assign a value to the node to generate a node.

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

      totalAchievements(usual[i].id);


     }
   }

Get the node through the name of Class, and then generate id with the for loop to distinguish the values of different usualScore, and then call the totalAchievements() method.

 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));
    }
  }

Get the node, then take the value of each node, then calculate according to the meaning of each value, and then assign the value to the total score.


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

Define the "clear()" method to clear the last value, otherwise it will cause value accumulation.

summary

The above is the thinking and implementation steps. At the end of the article, I want to remind you that after the weight selection changes, you need to perform another method of calculating the weight and the total score. Also, when you click the "enter" button to jump to the interface of entering the score, you need to perform another method of calculating the weight. In general, the default initial weight is the first < opti under the < Select > tab. On>.
This is the first time to contact js. I have to say that js is really amazing. This time, it's not very deep. I believe that in the future, I will master it well.

Posted by srhino on Fri, 25 Oct 2019 07:06:43 -0700