I'm not familiar with js, can you give me any tips. So basically I have calendar which generates dynamically. And I need to mark current day for example in "red". You can use my codepen for more detailed information.
When I try to execute value from this table I get the array which looks like this ~>
https://codepen.io/david_jons/pen/aPXeaK
<div id="calendar-container">
<div id="calendar-header">
<span id="calendar-month-year"></span>
</div>
<div id="calendar-dates">
</div>
</div>
JS:
window.onload = function(){
var d = new Date();
var month_name = ['January','February','March','April','May','June','July','August','September','October','November','December'];
var month = d.getMonth();
var year = d.getFullYear();
var first_date = month_name[month] + " " + 1 + " " + year;
var tmp = new Date(first_date).toDateString();
var first_day = tmp.substring(0, 3);
var day_name = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
var day_no = day_name.indexOf(first_day);
var days = new Date(year, month+1, 0).getDate();
var calendar = get_calendar(day_no, days);
document.getElementById("calendar-month-year").innerHTML = month_name[month]+" "+year;
document.getElementById("calendar-dates").appendChild(calendar);
var tr = document.getElementById("calendar-dates");
var tds = tr.getElementsByTagName("td");
var current_date = d.getDate();
}
function get_calendar(day_no, days){
var table = document.createElement('table');
var tr = document.createElement('tr');
//row for the day letters
for(var c=0; c<=6; c++){
var li = document.createElement('li');
li.innerHTML = "SMTWTFS"[c];
tr.appendChild(li);
}
table.appendChild(tr);
//create 2nd row
tr = document.createElement('tr');
var c;
for(c=0; c<=6; c++){
if(c == day_no){
break;
}
var td = document.createElement('td');
td.innerHTML = "";
tr.appendChild(td);
}
var count = 1;
for(; c<=6; c++){
var td = document.createElement('td');
td.innerHTML = count;
count++;
tr.appendChild(td);
}
table.appendChild(tr);
//rest of the date rows
for(var r=3; r<=7; r++){
tr = document.createElement('tr');
for(var c=0; c<=6; c++){
if(count > days){
table.appendChild(tr);
return table;
}
var td = document.createElement('td');
td.innerHTML = count;
count++;
tr.appendChild(td);
}
table.appendChild(tr);
}
return table;
}
You can iterate over an HTML collection using Array.prototype.filter called with the HTML collection as a context.
The following snippet may be of some help:
var cells = document.getElementById("calendar-dates").getElementsByTagName("td");
var current_date = d.getDate();
var matchingElement = Array.prototype.filter.call(cells, function(cell) {
return +current_date === +cell.textContent;
})[0];
matchingElement.style.backgroundColor = 'red';
Basically you got to check if the current date date that you are pasting is the same as today (new Date()).
function isToday(day, month, year){
const today = new Date();
return today.getDate() === day && today.getMonth() === month && today.getFullYear()===year;
}
https://codepen.io/kwiniarski97/pen/magPKV?editors=1111
it can be done in other ways this is just one
Related
I tried to append tr into a table with the 2 td elements already appended into my tr element. This is the code I used:
var month = 2;
var save = 0;
setInterval(function() {
month += 1;
alert("It is the next month.");
save = 0;
var tr = document.createElement("TR");
var td1 = document.createElement("TD");
var txt1 = document.createTextNode(month);
var td2 = document.createElement("TD");
var txt2 = document.createTextNode("$" + save);
var table = document.getElementById(table1);
td1.appendChild(txt1);
td2.appendChild(txt2);
tr.appendChild(td1);
tr.appendChild(td2);
table.appendChild(tr);
document.getElementById("howMuchSavings").innerHTML = "$0"
}, 30000);
function saveMore() {
save += 1;
document.getElementById("howMuchSavings").innerHTML = "$" + save;
}
I am working with Javascript where I've got a drop down list derived from an array (List of stream names) and whenever this array selection changes (onchange()) the details of the array( attributes and types) should be derived from two arrays (two 1d arrays- attributes, type) and displayed in a table form below the dropdown. I've written the function that displays the table within a division but it retrieves only the last data pair and appends it to the table. But I need all the data from the arrays to be displayed in each column so that they look as if they correspond each other.
JS Function to create the main array:
//Generate array to hold predefined Stream Definitions
function PredefinedStreams() {
var StreamArray = new Array(3);
for (var q = 0; q < 3; q++)
{
StreamArray[q] = new Array(4);
for (var w=1; w<3; w++)
{
StreamArray[q][w] = new Array(5);
}
}
StreamArray[0][0]="Stream1";
StreamArray[0][1][0]="1_attr1";
StreamArray[0][1][1]="1_attr2";
StreamArray[0][1][2]="1_attr3";
StreamArray[0][1][3]="1_attr4";
StreamArray[0][1][4]="1_attr5";
StreamArray[0][2][0]="1_type1";
StreamArray[0][2][1]="1_type2";
StreamArray[0][2][2]="1_type3";
StreamArray[0][2][3]="1_type4";
StreamArray[0][2][4]="1_type5";
StreamArray[0][3] = "define stream Stream1 (1_attr1 1_type1, 1_attr2 1_type2, 1_attr3 1_type3, 1_attr4 1_type4, 1_attr5 1_type5 );";
StreamArray[1][0]="Stream2";
StreamArray[1][1][0]="2_attr1";
StreamArray[1][1][1]="2_attr2";
StreamArray[1][1][2]="2_attr3";
StreamArray[1][1][3]="2_attr4";
StreamArray[1][1][4]="2_attr5";
StreamArray[1][2][0]="2_type1";
StreamArray[1][2][1]="2_type2";
StreamArray[1][2][2]="2_type3";
StreamArray[1][2][3]="2_type4";
StreamArray[1][2][4]="2_type5";
StreamArray[1][3] = "define stream Stream2 (2_attr1 2_type1, 2_attr2 2_type2, 2_attr3 2_type3, 2_attr4 2_type4, 2_attr5 2_type5 );";
StreamArray[2][0]="Stream3";
StreamArray[2][1][0]="3_attr1";
StreamArray[2][1][1]="3_attr2";
StreamArray[2][1][2]="3_attr3";
StreamArray[2][1][3]="3_attr4";
StreamArray[2][1][4]="3_attr5";
StreamArray[2][2][0]="3_type1";
StreamArray[2][2][1]="3_type2";
StreamArray[2][2][2]="3_type3";
StreamArray[2][2][3]="3_type4";
StreamArray[2][2][4]="3_type5";
StreamArray[2][3] = "define stream Stream3 (3_attr1 3_type1, 3_attr2 3_type2, 3_attr3 3_type3, 3_attr4 3_type4, 3_attr5 3_type5 );";
return StreamArray;
}
JS Function to retrieve individual stream data onto arrays:
var streams = '<select id="streamSelect" onchange="showStreamDef()">', streamtypes = PredefinedStreams();
var streamDef = streamtypes = PredefinedStreams();
var stream1_attr = streamtypes = PredefinedStreams();
var stream1_type = streamtypes = PredefinedStreams();
var stream2_attr = streamtypes = PredefinedStreams();
var stream2_type = streamtypes = PredefinedStreams();
var stream3_attr = streamtypes = PredefinedStreams();
var stream3_type = streamtypes = PredefinedStreams();
var PredefinedStreamComboDiv=document.createElement('div');
function createattr()
{
for (var q = 0; q < 3; q++)
{
streams += "<option value='"+streamtypes[q][0]+"'>"+streamtypes[q][0]+"</option>";
streamDef += streamtypes[q][3];
for (var w=0; w<3; w++)
{
for(var r=0; r<5;r++)
{
if(q==0 && w==1)
{
stream1_attr[r] = streamtypes[q][w][r];
}
if(q==0 && w==2)
{
stream1_type[r] = streamtypes[q][w][r];
}
if(q==1 && w==1)
{
stream2_attr[r]= streamtypes[q][w][r];
}
if(q==1 && w==2)
{
stream2_type [r]= streamtypes[q][w][r];
}
if(q==2 && w==1)
{
stream3_attr [r]= streamtypes[q][w][r];
}
if(q==2 && w==2)
{
stream3_type [r]= streamtypes[q][w][r];
}
}
}
}
streams += '</select>';
//streamDef += '</select>';
PredefinedStreamComboDiv.className="attr-combobox-style";
PredefinedStreamComboDiv.innerHTML= streams;
PredefinedStream.appendChild(PredefinedStreamComboDiv);
}
JS Function to create the table:
function showStreamDef()
{
alert("Displaying Stream Details");
var choice=document.getElementById("streamSelect");
var selectedStr = choice.options[choice.selectedIndex].text;
var myTableDiv = document.getElementById("streamDefDiv");
var table = document.createElement('TABLE');
var tableBody = document.createElement('TBODY');
table.border = '1';
table.appendChild(tableBody);
var tr = document.createElement('TR');
var td = document.createElement('TD');
td.appendChild(document.createTextNode("Attribute"));
tr.appendChild(td);
var td = document.createElement('TD');
td.appendChild(document.createTextNode("Type"));
tr.appendChild(td);
if(selectedStr=="Stream1")
{
for (var d = 0; d < stream1_attr.length; d++)
{
var tr = document.createElement('TR');
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream1_attr[d]));
tr.appendChild(td);
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream1_type[d]));
tr.appendChild(td);
}
}
else if(selectedStr=="Stream2")
{
for (var d = 0; d < stream1_attr.length; d++)
{
var tr = document.createElement('TR');
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream2_attr[d]));
tr.appendChild(td);
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream2_type[d]));
tr.appendChild(td);
}
}
else
{
for (var d = 0; d < stream1_attr.length; d++)
{
var tr = document.createElement('TR');
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream3_attr[d]));
tr.appendChild(td);
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream3_type[d]));
tr.appendChild(td);
}
}
tableBody.appendChild(tr);
myTableDiv.appendChild(table);
document.getElementById('streamDefDiv').style.display = "block";
}
The issue was only with the function where I dynamically generate the table.
As shown in the question, I've appended the row(tr) to the tablebody only at the end. This causes only the last saved data pair row to be appended to the table. So in order to get each row to be appended: once each table data(td) is appended to a row( tr), that particular tr needs to be appended to the tablebody.
function showStreamDef()
{
var choice=document.getElementById("streamSelect");
var selectedStr = choice.options[choice.selectedIndex].text;
var myTableDiv = document.getElementById("streamDefDiv");
var table = document.createElement('TABLE');
var tableBody = document.createElement('TBODY');
table.border = '1';
table.appendChild(tableBody);
var tr = document.createElement('TR');
var td = document.createElement('TD');
td.appendChild(document.createTextNode("Attribute"));
tr.appendChild(td);
var td = document.createElement('TD');
td.appendChild(document.createTextNode("Type"));
tr.appendChild(td);
tableBody.appendChild(tr);
if(selectedStr=="Stream1")
{
for (var d = 0; d < stream1_attr.length; d++)
{
var tr = document.createElement('TR');
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream1_attr[d]));
tr.appendChild(td);
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream1_type[d]));
tr.appendChild(td);
tableBody.appendChild(tr);
}
}
else if(selectedStr=="Stream2")
{
for (var d = 0; d < stream1_attr.length; d++)
{
var tr = document.createElement('TR');
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream2_attr[d]));
tr.appendChild(td);
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream2_type[d]));
tr.appendChild(td);
tableBody.appendChild(tr);
}
}
else
{
for (var d = 0; d < stream1_attr.length; d++)
{
var tr = document.createElement('TR');
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream3_attr[d]));
tr.appendChild(td);
var td = document.createElement('TD');
td.appendChild(document.createTextNode(stream3_type[d]));
tr.appendChild(td);
tableBody.appendChild(tr);
}
}
myTableDiv.appendChild(table);
document.getElementById('streamDefDiv').style.display = "block";
}
I need to generate year calendar with week numbers which should look like this image:
However it is not trivial to get week numbers in each month so they wouldn't overlap or be missing. I am using weekCount() function from this SO question. And for displaying calendar I have written this code:
var year = parseInt($(this).text());
var months = {1:'leden',2:'únor',3:'březen',4:'duben',5:'květen',6:'červen',7:'červenec',8:'srpen',9:'září',10:'říjen',11:'listopad',12:'prosinec'};
var calendar = $('<div id="summary_search_form_menu"></div>');
calendar.offset({top:$(this).offset().top + $(this).height() + 10}).css({right: '0px'});
var cur_week = 0;
for (var i=1;i<=12;i++) {
var row = $('<div class="row"></div>');
row.append('<div class="month button dark-blue">'+months[i]+'</div>');
var week_count = weekCount(year, i);
for (var week=1;week<week_count;week++) {
cur_week++;
row.append('<div class="week button blue">'+cur_week+'</div>');
}
calendar.append(row);
}
$('body').append(calendar);
Any way how to display week numbers correctly ?
OK, I have finally solved this on my own. In case somebody would find it helpful, I post my final code which works as I needed.
function weekCount(year, month_number) {
var firstOfMonth = new Date(year, month_number-1, 1);
var lastOfMonth = new Date(year, month_number, 0);
var used = firstOfMonth.getDay() + lastOfMonth.getDate();
return Math.ceil( used / 7);
}
Date.prototype.getWeekNumber = function(){
var d = new Date(+this);
d.setHours(0,0,0);
d.setDate(d.getDate()+4-(d.getDay()||7));
return Math.ceil((((d-new Date(d.getFullYear(),0,1))/8.64e7)+1)/7);
};
var year = parseInt($(this).text());
var months = {1:'leden',2:'únor',3:'březen',4:'duben',5:'květen',6:'červen',7:'červenec',8:'srpen',9:'září',10:'říjen',11:'listopad',12:'prosinec'};
var calendar = $('<div id="summary_search_form_menu"></div>');
calendar.offset({top:$(this).offset().top + $(this).height() + 10}).css({right: '15px'});
var cur_week = 0;
var col1 = $('<div id="summary_search_form_menu_col1"></div>');
var col2 = $('<div id="summary_search_form_menu_col2"></div>');
calendar.append(col1);
calendar.append(col2);
var col2_table = $('<div id="summary_search_form_menu_col2_table"></div>');
col2.append(col2_table);
for (var i=1;i<=12;i++) {
var row = $('<div class="row"></div>');
col1.append('<div class="month button dark-blue">'+months[i]+'</div>');
var week_count = weekCount(year, i);
var d = new Date(year, i-1, 1, 0,0,0);
var first_week_in_month = d.getWeekNumber();
for (var week=(cur_week == first_week_in_month ? 2 : 1);week<=week_count;week++) {
cur_week++;
row.append('<div class="week button blue">'+cur_week+'</div>');
}
col2_table.append(row);
}
$('body').append(calendar);
NOTE: Please no Jquery answers, need to get my head around Javascript first.
So I have added some rows to my table through insertRow(-1).
When I try to look up that table via getElementById and change the background color of a field, it works fine for the first added row:
"dates[4].style.backgroundColor = '#FF0000';"
But not for the second added row or thereafter, they just disappear:
"dates[7].style.backgroundColor = '#FF0000';
I am trying to highlight the current day (will replace the numbers 4/7 with a variable) I'm not sure whats happening, could anyone shed some light please?
Javascript
<script type="text/javascript">
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var hour = currentTime.getHours()
var min = currentTime.getMinutes()
//document.write(month + "/" + day + "/" + year)
var test = currentTime.getDay();
var day = currentTime.getDate()+1;
var month = currentTime.getMonth();
var full_year = currentTime.getFullYear();
var total_days = (daysInMonth(month,full_year));
var d=1;
function daysInMonth(month,year) {
return new Date(year, month, 0).getDate();
}
var temp = test+1;
for(i=0; i<5; i++){
var table = document.getElementById("calendar");
var row = table.insertRow(-1);
row.setAttribute("id", "rowClassName", 0);
for(c=1;c<8; c++){
if(d<test){
var newCell = row.insertCell(-1);
newCell.innerHTML = '0';
d++;
} else if ((temp-test)<=total_days){
var newCell = row.insertCell(-1);
newCell.innerHTML = (temp-test);
temp = temp+1;
if(temp==day){
var table1 = document.getElementById("rowClassName");
var dates = table1.getElementsByTagName('td');
dates[7].style.backgroundColor = '#FF0000';
}
}
}
}
HTML
<table id="calendar">
<tr>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
<td>Thu</td>
<td>Fri</td>
<td>Sat</td>
<td>Sun</td>
</tr>
</table>
Change:
var table1 = document.getElementById("rowClassName");
To:
var table1 = document.getElementById("calendar");
Explanation:
You are only getting the cells for the current row using "rowClassName". Each row only consists of 7 elements (Mon-Sun). [7] means you are selecting the 8th cell in that row, which doesn't exist (JavaScript arrays are 0-based - the first element starts from 0).
So now what you want to do is count the number of table cells from the start of the table, inclusive of those in the first row.
Also, if you do it this way, the table cell you are trying to reference may not been created by the loop yet. You should set the red color outside of the two loops, or set a class to the cell, and use CSS to style the background color.
Snippet:
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var hour = currentTime.getHours()
var min = currentTime.getMinutes()
//document.write(month + "/" + day + "/" + year)
var test = currentTime.getDay();
var day = currentTime.getDate() + 1;
var month = currentTime.getMonth();
var full_year = currentTime.getFullYear();
var total_days = (daysInMonth(month, full_year));
var d = 1;
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
var temp = test + 1;
for (i = 0; i < 5; i++) {
var table = document.getElementById("calendar");
var row = table.insertRow(-1);
row.setAttribute("id", "rowClassName"+1, 0);
for (c = 1; c < 8; c++) {
if (d < test) {
var newCell = row.insertCell(-1);
newCell.innerHTML = '0';
d++;
} else if ((temp - test) <= total_days) {
var newCell = row.insertCell(-1);
newCell.innerHTML = (temp - test);
temp = temp + 1;
if (temp == day) {
newCell.className = "current";
}
}
}
}
.current {
background-color: red;
}
<table id="calendar">
<tr>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
<td>Thu</td>
<td>Fri</td>
<td>Sat</td>
<td>Sun</td>
</tr>
</table>
I am trying to generate random numbers as well as the current minute into a table.
How do I have the script write into the table?
getElementbyClass()?
d = new Date();
var random=Math.floor(Math.random()*60)
document.writeln(random);
var Minutes = d.getMinutes();
document.writeln(Minutes);
You could do something like:
var d = new Date();
var random= Math.floor(Math.random()*60);
var td1 = document.createElement("td");
td1.innerHTML = random;
var Minutes = d.getMinutes();
var td2 = document.createElement("td");
td2.innerHTML = random;
var table = document.getElementById("tblResult");
var row = document.createElement("tr");
row.appendChild(td1);
row.appendChild(td2);
table.appendChild(row);
And int the HTML:
<table id="tblResult">
<tr>
<td>Random</td>
<td>Minutes</td>
</tr>
</table>
Result can be seen in this fiddle
Is there a set number of rows/column in the table? Do you need to update the table in run-time (e.g. will you change the contents in the columns after the page has been loaded)?
If you just want to create a table with those values when loading the page, you could create your table in JavaScript:
var table = document.createElement('table'),
row,
minCol,
ranCol;
function addRow(minutes, rand) {
row = document.createElement('tr');
minCol = document.createElement('td');
ranCol = document.createElement('td');
minCol.innerHTML = minutes;
ranCol.innerHTML = rand;
row.appendChild(minCol);
row.appendChild(ranCol);
table.appendChild(row);
}
for (var i = 0; i < 10; i++) {
addRow((new Date()).getMinutes(), Math.floor(Math.random() * 60));
}
document.body.appendChild(table);
Note that this script must be after the <body> tag for it to work.
If you need to add rows after the page has loaded (e.g. the user clicks a button) just call addRow().