How to pick up the input value by asynchronous communication and output the desired data from the server

background

I am co-developing a baseball scorebook using Rails. Regarding the pre-registered player data, I was asked to have a function that displays the player's grade and name in conjunction with the player's grade when I entered the number, so I will describe how to make it.

I think it's hard to understand, so To give a concrete example, if you enter the employee number in the personnel salary system, the company name and name will be linked and automatically displayed, and you want the data to be linked at the time of registration.

Complete image

It will be in the form below. Image from Gyazo

Way of thinking to realize the desired function

I decided to first consider the procedure in terms of selecting the technology required for the function.

  1. After entering the uniform number form, get the value with Javascript
  2. Send the acquired data as a parameter to the server side
  3. Extract the player table data from the sent data and return it to the client in json format
  4. Insert the contents (grade, name) of the returned data into each form

In a nutshell It fetches the values, extracts the data, and if there is one that applies, inserts it where it is needed.

Implementation method

We will explain in the flow of advance preparation → way of thinking.

Advance preparation

Create an action for data extraction. Create a new search_member action in the batting_order controller file.

batting_orders_controller.rb


    def create
    end
    
    def search_member
    end

Set the routing when creating a new action.

routes.rb


Rails.application.routes.draw do
    resources :batting_orders
    collection do
      get 'search_member'
    end
  end
end

1. After entering the uniform number form, get the value with Javascript

search_member.js


function searchMember() {
  //Get all the elements to enter the uniform number and the HTML elements to insert the data, and also get the number of acquired HTML elements
  const uniformNumber = document.querySelectorAll(".input-game-uniform-number");
  const memberGrade = document.querySelectorAll(".input-game-grade");
  const memberId = document.querySelectorAll(".input-member-id");
  const fullName = document.querySelectorAll(".input-game-full-name");
  const uniformNumberLength = uniformNumber.length;

  for(let i=0; i<=uniformNumberLength - 1; i++){
    //When there is an input in the form to enter a specific uniform number, asynchronous processing is executed and the input value is acquired.
    uniformNumber[i].addEventListener("keyup", (e) => {
      const formResult = uniformNumber[i];
      const formData = Math.floor(formResult.value);
    });
  };
}
window.addEventListener("load", searchMember);
Supplementary information

querySelectorAll() Get all HTML elements that apply in parentheses. Class name, ID name, etc. can be specified Assuming that it is stored in the variable a with querySelectorAll Get the first element of the HTML element obtained with a [0], get the second element with a [1], etc ... It is also possible to specify the nth HTML element with a [n-1].

__ Variable name.addEventListener ("keyup", (e) => {Processing}) __ Event handler that executes processing when the key is pressed and released This time, the for statement is set so that the event is fired for all the uniform number input forms.

2. Send the acquired data as a parameter to the server side

search_member.js


uniformNumber[i].addEventListener("keyup", (e) => {
  const formResult = uniformNumber[i];
  const formData = Math.floor(formResult.value);
  //To send an HTTP request, you need to create an XMLHttpRequest object, open the URL and send the request.
  const XHR = new XMLHttpRequest();
  XHR.open("GET", '/games/search_member?keyword=' + encodeURIComponent(formData), true);
  XHR.responseType = "json";
  XHR.send(null);
  });
Supplementary information

__GET parameter __ At the end of the URL? The value described below. When adding parameters, add? Set key and value and send to server side. This time, key is the keyword and value is the character entered in the target uniform number.

In addition, since data is sent only for one form of text type, it is set in the GET parameter. When sending data for multiple forms, use the POST parameter.

encodeURIComponent It says that it encodes a URI (Uniform Resource Identifier) ​​component by replacing certain characters with one to four escape sequences represented in UTF-8 character encoding. In short, a function that encrypts characters into a machine-readable form. An image that converts line breaks to characters \ n if it is easy to understand.

3. Extract the player table data from the sent data and return it to the client in json format

batting_orders_controller.rb


def search_member
    target = Member.find_by(uniform_number: params[:keyword], team_id: current_team.id)
    render json:{ member: target }
end
Supplementary information

As a typical example of the function to display data asynchronously, the following incremental search is a major and many reference materials can be found, so I referred to it. Test.where('title LIKE(?)', "%#{search}%") This time, I'm using the find_by method because I want the data and want a unique value that exactly matches. Perhaps the data is stored in the form of target = {id: 1, uniform_number: 2}.

4. Insert the contents (grade, name) of the returned data into each form

search_member.js


XHR.onload = () =>{
  if (XHR.status != 200) {
    alert(`Error ${XHR.status}: ${XHR.statusText}`);
    return null;
  }
  //Since the value is passed by the key of member in 3, store it in the variable called member on javascript. Then store each column in a variable.
  const member = XHR.response.member;
  const gradeForm = memberGrade[i];
  const memberIdForm = memberId[i];
  const fullNameForm = fullName[i];

  //If member data cannot be extracted in 3, undefind will be returned, so conditional branching
  if(member === undefined || member === null){
    gradeForm.value = "";
    memberIdForm.value = "";
    fullNameForm.value = "";
  }else{
    const grade = member.grade;
    const memberNumber = member.id;
    //When I registered as a player, I registered my first and last name separately, so I stored it as my full name.
    const name = member.first_name + " " + member.last_name;
    gradeForm.value = grade;
    memberIdForm.value = memberNumber;
    fullNameForm.value = name;
  }
}
Supplementary information

About i such as __memberGrade [i] __ Since the event is triggered in the element number [i] th jersey number input form, it is necessary to insert it in the form that stores the element number [i] th grade, name, and ID number. Therefore, the position is specified by the variable i in which the numerical value is stored.

__ About the returned data __ As a result of checking the behavior with the verification tool, it was found that undefind is stored in each variable when there is no matching data. Therefore, we applied a branch condition depending on whether the variable member is undefind or null and when it is not.

in conclusion

Thank you for watching till the end.

Pick up the data on a particular form, send it to the server, and extract the data. After that, the extracted value is returned to the client and some operation is performed. By doing this asynchronously, I think the range of implementation recipes could be greatly improved.

Also, even if the language and framework are different, the JavaScript part can be used, so I want to study so that I can handle it better.

If you have any comments or questions, please let us know.

JavaScript (full text)

search_member.js



function searchMember() {
  const uniformNumber = document.querySelectorAll(".input-game-uniform-number");
  const memberGrade = document.querySelectorAll(".input-game-grade");
  const memberId = document.querySelectorAll(".input-member-id");
  const fullName = document.querySelectorAll(".input-game-full-name");
  const uniformNumberLength = uniformNumber.length;

  for(let i=0; i<=uniformNumberLength - 1; i++){
    uniformNumber[i].addEventListener("keyup", (e) => {
      const formResult = uniformNumber[i];
      const formData = Math.floor(formResult.value);
      // const formData = new FormData(formResult);
      const XHR = new XMLHttpRequest();
      XHR.open("GET", '/games/search_member?keyword=' + encodeURIComponent(formData), true);
      XHR.responseType = "json";
      XHR.send(null);
      XHR.onload = () =>{
        if (XHR.status != 200) {
          alert(`Error ${XHR.status}: ${XHR.statusText}`);
          return null;
        }
        const member = XHR.response.member;
        const gradeForm = memberGrade[i];
        const memberIdForm = memberId[i];
        const fullNameForm = fullName[i];
        if(member === undefined || member === null){
          gradeForm.value = "";
          memberIdForm.value = "";
          fullNameForm.value = "";
        }else{
          const grade = member.grade;
          const memberNumber = member.id;
          const name = member.first_name + " " + member.last_name;
          gradeForm.value = grade;
          memberIdForm.value = memberNumber;
          fullNameForm.value = name;
        }
      }
    });
  };
}

window.addEventListener("load", searchMember);

Recommended Posts

How to pick up the input value by asynchronous communication and output the desired data from the server
The value is taken out from the double hash and output by the getter.
[Java] How to get and output standard input
[Java] How to get the key and value stored in Map by iterative processing
[ruby] How to assign a value to a hash by referring to the value and key of another hash
[Ruby On Rails] How to search and save the data of the parent table from the child table
[Ruby] How to get the value by specifying the key. Differences between hashes, symbols and fetch
I tried to implement the like function by asynchronous communication
How to display 0 on the left side of the standard input value
How to output the value when there is an array in the array
How to place and share SwiftLint config files on the server
How to get and add data from Firebase Firestore in Ruby
[Swift5] How to communicate from ViewController to Model and pass a value
[Java] How to convert from String to Path type and get the path
[Ruby] How to use is_a? Differences from kind_of? and instance_of ?. How to check the type and return a boolean value.
How to output the sum of any three numbers, excluding the same value
How to return a value from Model to Controller using the [Swift5] protocol
[Java] How to retrieve the parameters passed from html on the server side
Add the date to the GC statistics acquired by gcutil and output it.
How to change the maximum and maximum number of POST data in Spark
How to get the setting value (property value) from the database in Spring Framework
How to create your own annotation in Java and get the value
[Java] How to output and write files!
How to set up and use kapt
How to find the tens and ones
How to pass the value to another screen
From terminal to Ruby (standard input / output)
How to connect to lcalhost from your smartphone and use the app under development
[swift5] How to transition from the app to an external site by specifying the URL
[JDBC ③] I tried to input from the main method using placeholders and arguments.
[Ruby] How to use the map method. How to process the value of an object and get it by hash or symbol.
How to build a Jenkins server with a Docker container on CentOS 7 of VirtualBox and access the Jenkins server from a local PC
An application that acquires the value of the accelerometer by UDP communication between C # and Android
Construction of authorization server using Authlete and communication from OAuth client (Web application)