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.
I decided to first consider the procedure in terms of selecting the technology required for the function.
In a nutshell It fetches the values, extracts the data, and if there is one that applies, inserts it where it is needed.
We will explain in the flow of advance preparation → way of thinking.
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
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);
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.
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);
});
__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.
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
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}.
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;
}
}
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.
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.
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