Implement the countdown timer that will be implemented in the portfolio. There is an article that says that jQuery is required to implement the timer, but this time I will proceed with the implementation without using jQuery.
As a specific procedure ① Create a deadline, which is a time limit column (2) Write HTML to display the timer on the screen. ③ I want to display the time limit, so write it using javascript
First, as always
$rails generate migration Add Column name To Table name Column name: Data type
Create a migration file with.
In this case, I want to display the time limit in the posting part, so I used deadline as the column name.
$rails generate migration AddDeadlineToMission deadline:datetime
And.
db/migrate/20200903084112_create_missions.rb
class CreateMissions < ActiveRecord::Migration[6.0]
def change
create_table :missions do |t|
t.integer :user_id
t.text :content
t.string :penalty
t.datetime :deadline
t.timestamps
end
end
end
Add `` `t.datetime: deadline``` to line 7 of the migration file above. And I saw it from the face of my parents
$ rails db:migrate
To save to the database.
To set a deficit timer like the one above
app/views/missions/new.html.erb
<p>
<%= f.hidden_field :deadline, :id => "deadline.id" %>
<input type="text" id="userYear" >Year
<input type="text" id="userMonth">Month
<input type="text" id="userDate" >Day
<input type="text" id="userHour" >Time
<input type="text" id="userMin" >Minutes
<input type="text" id="userSec" >Seconds
</p>
<p id="RealtimeCountdownArea" ></p> #The timer is displayed here
And. Here, `` `: id => deadline.id``` is described because it will be effective in the description of javascript later.
This time, I will write javascript in the script tag of app / views / missions / new.html.erb
.
It is as follows.
app/views/missions/new.html.erb
<script>
function set2fig(num) {
//If the number is 1 digit, return it as a 2-digit character string
var ret;
if( num < 10 ) { ret = "0" + num; }
else { ret = num; }
return ret;
}
function isNumOrZero(num) {
//If it is not a numerical value, set it to 0 and return it.
if( isNaN(num) ) { return 0; }
return num;
}
function showCountdown() {
//Numerical current date and time(1970-01-01 00:00:Milliseconds from 00)Conversion to
var nowDate = new Date();
var dnumNow = nowDate.getTime();
//Numerical value for the specified date and time(1970-01-01 00:00:Milliseconds from 00)Conversion to
var inputYear = document.getElementById("userYear").value;
var inputMonth = document.getElementById("userMonth").value - 1;
var inputDate = document.getElementById("userDate").value;
var inputHour = document.getElementById("userHour").value;
var inputMin = document.getElementById("userMin").value;
var inputSec = document.getElementById("userSec").value;
var targetDate = new Date( isNumOrZero(inputYear), isNumOrZero(inputMonth), isNumOrZero(inputDate), isNumOrZero(inputHour), isNumOrZero(inputMin), isNumOrZero(inputSec) );
var dnumTarget = targetDate.getTime();
//Prepare the display
var dlYear = targetDate.getFullYear();
var dlMonth = targetDate.getMonth() + 1;
var dlDate = targetDate.getDate();
var dlHour = targetDate.getHours();
var dlMin = targetDate.getMinutes();
var dlSec = targetDate.getSeconds();
var msg1 = "Deadline" + dlYear + "/" + dlMonth + "/" + dlDate + " " + set2fig(dlHour) + ":" + set2fig(dlMin) + ":" + set2fig(dlSec);
//Days after subtraction(millisecond)Calculate the difference between
var diff2Dates = dnumTarget - dnumNow;
if( dnumTarget < dnumNow ) {
//If the deadline has passed-Multiply by 1 to convert to positive value
diff2Dates *= -1;
}
//Divide the difference millisecond into days, hours, minutes, and seconds
var dDays = diff2Dates / ( 1000 * 60 * 60 * 24 ); //Days
diff2Dates = diff2Dates % ( 1000 * 60 * 60 * 24 );
var dHour = diff2Dates / ( 1000 * 60 * 60 ); //time
diff2Dates = diff2Dates % ( 1000 * 60 * 60 );
var dMin = diff2Dates / ( 1000 * 60 ); //Minutes
diff2Dates = diff2Dates % ( 1000 * 60 );
var dSec = diff2Dates / 1000; //Seconds
var msg2 = Math.floor(dDays) + "Day"
+ Math.floor(dHour) + "time"
+ Math.floor(dMin) + "Minutes"
+ Math.floor(dSec) + "Seconds";
//Creating a display string
var msg;
if( dnumTarget > dnumNow ) {
//If the deadline has not come yet
msg = msg1 + "Until" + msg2 + "is.";
}
else {
//When the deadline has passed
msg = msg1 + "Already" + msg2 + "It passed before.";
}
//Display the created character string
document.getElementById("RealtimeCountdownArea").innerHTML = msg;
document.getElementById("deadline.id").value = targetDate; #Most important description
}
//Run every second
setInterval('showCountdown()',1000);
</script>
Here, the previous : id => deadline.id
comes into play. Only by adding such a description
You can receive the result processed by javascript as value and display it on the screen. Now you can finally implement the timer.
It is also possible that you do not want to display the date and time entry field. If you want to display only the deadline and the remaining time of the timer as shown in the picture below,
app/views/missions/show.thml.erb
<p>Deadline<%= @mission.deadline %>
<br>
<input type="hidden" id="userYear" value = "<%= @mission.deadline.year %>" >
<input type="hidden" id="userMonth"value = "<%= @mission.deadline.month %>" >
<input type="hidden" id="userDate" value = "<%= @mission.deadline.day %>" >
<input type="hidden" id="userHour" value = "<%= @mission.deadline.hour %>" >
<input type="hidden" id="userMin" value = "<%= @mission.deadline.min %>" >
<input type="hidden" id="userSec" value = "<%= @mission.deadline.sec %>" >
</p>
<p id="RealtimeCountdownArea" ></p>
<script>
function set2fig(num) {
//If the number is 1 digit, return it as a 2-digit character string
var ret;
if( num < 10 ) { ret = "0" + num; }
else { ret = num; }
return ret;
}
function isNumOrZero(num) {
//If it is not a numerical value, set it to 0 and return it.
if( isNaN(num) ) { return 0; }
return num;
}
function showCountdown() {
//Numerical current date and time(1970-01-01 00:00:Milliseconds from 00)Conversion to
var nowDate = new Date();
var dnumNow = nowDate.getTime();
//Numerical value for the specified date and time(1970-01-01 00:00:Milliseconds from 00)Conversion to
var inputYear = document.getElementById("userYear").value;
var inputMonth = document.getElementById("userMonth").value - 1;
var inputDate = document.getElementById("userDate").value;
var inputHour = document.getElementById("userHour").value;
var inputMin = document.getElementById("userMin").value;
var inputSec = document.getElementById("userSec").value;
var targetDate = new Date( isNumOrZero(inputYear), isNumOrZero(inputMonth), isNumOrZero(inputDate), isNumOrZero(inputHour), isNumOrZero(inputMin), isNumOrZero(inputSec) );
var dnumTarget = targetDate.getTime();
//Prepare the display
var dlYear = targetDate.getFullYear();
var dlMonth = targetDate.getMonth() + 1;
var dlDate = targetDate.getDate();
var dlHour = targetDate.getHours();
var dlMin = targetDate.getMinutes();
var dlSec = targetDate.getSeconds();
var msg1 = "Deadline" + dlYear + "/" + dlMonth + "/" + dlDate + " " + set2fig(dlHour) + ":" + set2fig(dlMin) + ":" + set2fig(dlSec);
//Days after subtraction(millisecond)Calculate the difference between
var diff2Dates = dnumTarget - dnumNow;
if( dnumTarget < dnumNow ) {
//If the deadline has passed-Multiply by 1 to convert to positive value
diff2Dates *= -1;
}
//Divide the difference millisecond into days, hours, minutes, and seconds
var dDays = diff2Dates / ( 1000 * 60 * 60 * 24 ); //Days
diff2Dates = diff2Dates % ( 1000 * 60 * 60 * 24 );
var dHour = diff2Dates / ( 1000 * 60 * 60 ); //time
diff2Dates = diff2Dates % ( 1000 * 60 * 60 );
var dMin = diff2Dates / ( 1000 * 60 ); //Minutes
diff2Dates = diff2Dates % ( 1000 * 60 );
var dSec = diff2Dates / 1000; //Seconds
var msg2 = Math.floor(dDays) + "Day"
+ Math.floor(dHour) + "time"
+ Math.floor(dMin) + "Minutes"
+ Math.floor(dSec) + "Seconds";
//Creating a display string
var msg;
if( dnumTarget > dnumNow ) {
//If the deadline has not come yet
msg = "Until the end of the mission" + msg2 ;
}
else {
//When the deadline has passed
msg = msg1 + "Already" + msg2 + "It passed before.";
}
//Display the created character string
document.getElementById("RealtimeCountdownArea").innerHTML = msg;
document.getElementById("deadline.id").value = targetDate;
}
//Run every second
setInterval('showCountdown()',1000);
</script>
If you set input type =" hidden "
as above, the entry field will not be displayed on the screen, but the six `<input type = ・ ・ ・>`
will be deleted. This does not mean that it will start normally.
Also, <input type = "hidden" id = "userYear" value = "<% = @ mission.deadline.year%>">
`
value="<%= @mission.deadline.year %>"I will explain why the part of is such a description. This is because deadline is a column that takes a data type called datetime, but datetime stores date and time information such as year, month, day, hour, minute, and second. Therefore, with the above description, new.html.The date and time of the deadline described in the erb part can be retrieved.
# Summary
The difficulty was quite high, but the sense of accomplishment was amazing. I would appreciate it if you could refer to it as much as possible.
Reference article
https://www.nishishi.com/javascript-tips/realtime-countdown-deadline.html
Recommended Posts