Real time agenda with javascript and json - javascript

I have a div on a website that needs to be a real time agenda for a list of events. I have the events loaded through a json file and am using javascript to populate the div with the data from the file.
The problem is that the data displays stacked item by item in one column within a div, I need to now split the div into three separate columns/divs. One for events happening now, next, and coming soon. Ex) one event is at 7am, next is 7:30, and coming soon is 8am.
But I am not able to select each item and move it using css since the code just populates by one item upon page load and I cannot see an index for each item (video side content item) over and over to display what events are necessary.
This would be a lot easier if I could just format the items being populated into three separate columns through css, but I can't figure out how to do this.
By the way this site is written using FlexBox, hence why there is a "row" in one of the divs.
Also can someone please point in the right direction as to how to get this to be real time? Or any other helpful solution that could achieve this?
Thanks in advance for any help.
picture of what I'm trying to do
Function to populate the data
function agendaRealTimeUpdate() {
if ($('.real-time-agenda').length !== 0) {
videoSideContentType = 'agenda';
$.getJSON("ac.json", function(data) {
var sessions = data.session;
var contentString = '';
var currentSessionIndex;
var currentSession;
var currentTime;
var currentDay;
var title;
var time;
var room;
var description;
var d;
var i = 0;
d = new Date();
//gets the current time and returns it in a string with 3-4 digits EX: "1000" = 10 am
currentTime = parseInt(d.getHours().toString() + ((d.getMinutes() < 10 ? '0' : '') + d.getMinutes()).toString());
currentDay = d.getDate();
// this loop runs as long as we haven't figured out which session matches the time
while (currentSessionIndex === undefined && i < sessions.length) {
//this takes the current time and compares it to the sessions start and end times
if ((currentTime >= sessions[i].startTime && currentTime <= sessions[i].endTime) &&
currentDay === sessions[i].day &&
sessions[i].track === "none")
{
currentSessionIndex = i;
}
i++;
}
if (currentSessionIndex === undefined) {
currentSessionIndex = 0;
}
// This function finds the sessions that come after the identified current session
function findNextSessions() {
var sessionsCopy = sessions.slice(); //make a copy of the sessions array so we aren't altering it when we remove indexes
for (var z = 0; z < 2; z++) {
var index = currentSessionIndex + z;
// breaks out of the loop if the next session is undefined
if (sessionsCopy[index] === undefined) {
z = 2;
}
currentSession = sessionsCopy[index];
// loops through the sessions and if the session has a track it is removed from the sessionsCopy array
while (currentSession.track !== "none") {
console.log('has a track: ' + currentSession.track);
sessionsCopy.splice(index, 1);
currentSession = sessionsCopy[index];
}
time = currentSession.timeString !== undefined ? "<div class='video-side-content__time'><b>Time:</b> " + currentSession.timeString + "</div>" : '';
room = currentSession.room !== undefined ? "<div class='video-side-content__room'><b>Room:</b> " + currentSession.room + "</div>" : '';
title = currentSession.title !== undefined ? "<div class='video-side-content__secondary-title'>" + currentSession.title + "</div>" : '';
description = currentSession.content !== undefined ? "<div class='video-side-content__content'>" + currentSession.content + "</div>" : '';
contentString += "<div class='video-side-content__item'>" + time + room + title + description + "</div>";
}
}
findNextSessions();
$('.real-time-agenda').html(contentString);
});
}
}
Div I'm working with
<div class="row__item">
<h2 class="video-side-content__title"><img src="img/agenda-icon.png"> Thursday. Sept. 22</h2>
<div class="row__flex-container">
<div class="row__item video-side-content__strip video-side-content__strip-left"> </div>
<div class="row__item video-side-content__row">
<div class="video-side-content">
<div class="video-side-content__items">
<div class="video-side-content__item">
<h2 class="count-down__sub-header"><br>
SHOWING NOW</h2><br>
<div class="real-time-agenda">
<!--data populates upon page load from the json file
It lays the data out as: Time, Title, Room, Description-->
</div>
<br>
</div>
</div>
</div>
</div>
</div>
</div>

Related

Using multiple checkboxes, all made by a javascript function, with Javascript

A function uses Google Maps API results to create a list of places (hotels etc.) besides each one there is a checkbox:
if(place['rating']) {
LocationName = place['name'];
LocationString += `<div class="input-group" id="Location-checkbox-${[i]}">
<span value=${[i]} class="input-group-addon">
<input type="checkbox" name="choice"
id="checkboxes" aria-label="..." onclick="chooseSelection(${[i]})">
</span>
<li id="Location-${[i]}" class="list-group-
item"><strong id="locationName-${[i]}">${LocationName}</strong><br>`;
if(place['rating']) {
var LocationRating = place['rating'];
LocationString += `rating: <span
id="locationRating-${[i]}">${LocationRating}</span><br>`;
} else {
var LocationRating = 'This place has no rating';
LocationString += LocationRating;
}
if(place['user_ratings_total']) {
var LocationUsers = place['user_ratings_total'];
LocationString += `based on ${LocationUsers} reviews</li></div>`;
} else {
var LocationUsers = '</li></div>';
LocationString += LocationUsers;
}
htmlString += LocationString;
I then need to add the ones the user chooses into an temporary array:
var temporarySelection = "";
var placeSelection = "";
var hotelSelection = "";
var restaurantSelections = "";
var sightSelections = "";
function chooseSelection(resultIndex) {
var locationName = document.getElementById('locationName-' + resultIndex);
temporarySelection += `<div class="input-group" id="Hotel-chosen">
<li class="list-group-item">
<strong>${locationName.innerHTML}</strong><br>`;
var locationRating = document.getElementById('locationRating-' +
resultIndex);
temporarySelection += `rating: ${locationRating.innerHTML}</li></div>`
}
Lastly, I need to move the temporary selection into ANOTHER array.
My problem is that, at the moment, the checkboxes are just working like buttons. Every time you click it, it just adds another one to the array. I want to only add the ones to the array that are ticked when the Next button is clicked (not shown in the code).
Any advice?

Display and delete multiple cookies in Javascript

I want to display the last three search values on the website using javascript cookies. I store last three values but when I display in view it displays everything together. I have two question.
I want to display the values separately inside the href. So the user can click and search again.
Actual output
1=Dubai; 2=India; 3=SriLanka <span class='rmvcookie'>x</span>
Expecting output
<a href='abc.com?location=Dubai'>Dubai</a><span class='rmvcookie'>x</span>
<a href='abc.com?location=India'>India</a><span class='rmvcookie'>x</span>
<a href='abc.com?location=SriLanka'>SriLanka</a><span class='rmvcookie'>x</span>
I created removeCookies function but it removes all the cookies at once. I want to remove the cookies individually.
This website does the same. makemytrip.ae/holidays-india Search by any destination. It stores the values and you can remove it individually.
I tried last two days and couldn't get the right code. Can anyone help me? Please.
JavaScript
var num = 1;
function addCookie() {
var searchvalue = document.getElementsByClassName("cookiename")[0].value;
document.cookie = num + "=" + searchvalue;
if (num >= 3) { //Limit for last three search value
num = 1;
} else {
num++;
}
var result = document.cookie;
document.getElementById("list").innerHTML = "<a href='abc.com?location=" + result + "'>" + result + "</a> <span class='rmvcookie' onclick='removeCookies()'>x</span>";
}
function listCookies() {
var result = document.cookie;
document.getElementById("list").innerHTML = "<a href='abc.com?location=" + result + "'>" + result + "</a> <span class='rmvcookie' onclick='removeCookies()'>x</span>";
}
window.onload = function() {
listCookies();
};
function removeCookies() {
var res = document.cookie;
var multiple = res.split(";");
for (var i = 0; i < multiple.length; i++) {
var key = multiple[i].split("=");
document.cookie = key[0] + "=; expires=Thu, 28 May 2030 00:00:00 UTC";
}
}
HTML
<input type="text" id="searchTxt" class="cookiename" name="asd">
<button onclick='addCookie()'>ADD</button><br>
<button onclick='removeCookies()'>REMOVE</button>
<h1>Cookies List</h1>
<p id="list"></p>
View
I wrote a solution on codepen - https://codepen.io/darius9171/pen/JBBRaz
Stackoverflow does not allow you to work in snippets with cookies, but requires you to write code when you specify a link to codepen. So don't pay attention to the snippet :D
//set cookies
const cookies = ['Dubai', 'India', 'SriLanka'];
cookies.forEach((name, i) => document.cookie = `${i+1}=${name};`);
//render
const list = document.querySelector('.list');
document.cookie.split('; ').forEach(cookie => {
const pair = cookie.split('=');
list.innerHTML += `<div class="cookie" data-name="${pair[0]}">${pair[1]} <span class='rmvcookie'>x</span></div>`
})
document.querySelectorAll('.rmvcookie').forEach(span => {
span.addEventListener('click', (event) => {
const parent = event.currentTarget.parentNode;
document.cookie = `${parent.dataset.name}=; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
parent.parentNode.removeChild(parent);
})
})
span {
color: blue;
cursor: pointer;
}
<div class="list">
</div>

Keep vertical scroll position when clicking horizontal carousel button

I have a long page with lots of patient data inside an accordion container. At the top of the page there is a carousel with the 7 days of the week. If you click on the left or right arrow, either the previous or following week will show, which in turn, will show the applicable data below in the accordion.
What I need to do is when a user clicks on the left or right arrow, hold the page position on the current accordion section, but still allow the data to be updated. The data currently updates, but the container location may change. That particular container may not have data for one week, but the next week may have data.
I would like to click the arrow and still show the previous container heading.
Ex. I'm on the Hematology container and I click on the right arrow. I want the Hematology container to still be in view, even if there is no content inside.
Here is a screenshot of my page with the carousel and containers.
I know how to do this with anchor tags when dealing with links to different pages, but this is a bit different.
This project uses Angular to asynchronously get the new data for the containers. You can see it below. Thanks
Here is my code for the carousel:
<div id="myCarousel" class="carousel slide russ" data-ride="carousel" data-interval="false">
<div class="carousel-inner" role="listbox"></div>
<a class="left carousel-control" href=".russ" role="button" data-slide="prev">
<span class="fa fa-chevron-left" aria-hidden="true"></span>
</a>
<a class="right carousel-control" href=".russ" role="button" data-slide="next" onclick="stopVerticalScrolling()">
<i class="fa fa-chevron-right" aria-hidden="true"></i>
</a>
</div>
My first crack at this:
<script>
function stopVerticalScrolling() {
var scroll = $(window).scrollTop();
$("html").scrollTop(scroll);
//javascript: alert($(window).scrollTop());
}
</script>
AngularJS Code:
function get_sticky_popup_data(timeline, patientMRN, patientSiteid, start, end) {
$http
.get('/API/data/patientdetails/Titlebar/get_admission_data/' + patientSiteid + '?MRN=' + patientMRN)
.success(function(data) {
$scope.carouseldata = data;
build_sticky_table(timeline, $scope.carouseldata, start, end);
var carouselItemTop = $('.displayTableContainer').position();
$('.displayTableContainer').attr('data-offset-top', carouselItemTop.top);
}).error(function(e) {
console.log('error in Ajax call get_admission_data: ' + e.message);
});
}
function build_sticky_table(timeline, items, start, end) {
var startDate = new Date(start.toString());
var endDate = new Date(end.toString());
var dtRotate = new Date(startDate);
var firstWeeksDataObject = new Array(7);
var datediff = ((endDate - startDate) / (1000 * 60 * 60 * 24)) + 1;
var weeks = (datediff % 7 === 0 ? parseInt((datediff / 7)) + 1 : parseInt((datediff / 7))); // you need this many tables
$('.item').remove();
items.push({
'admit': timeline.admission_range_start,
'datetime': timeline.event_start_date,
'diagnosis': '',
'discharge': timeline.admission_range_end,
'location': timeline.location,
'room_bed': timeline.roombed
});
var isActive = false;
var starting_month_from_query_string = $('#workflow_header_month').val();
var starting_year_from_query_string = $('#workflow_header_year').val();
var match_weekly_data_from_query_string_month_and_year = false;
var previous_match_found = false;
var current_event_start_date = timeline.event_start_date;
if (starting_month_from_query_string !== "0" && starting_year_from_query_string !== "0") {
match_weekly_data_from_query_string_month_and_year = true;
}
for (var i = 0; i <= weeks; i++) {
var name = 'stickytbl' + i.toString();
$('.carousel-inner').append(buildtable(name, i)); //inserts a new table
var hcells = $('#' + name + ' > thead > tr > td');
var brows = $('#' + name + ' > tbody> tr');
$.each(hcells, function (index, item) {
if (index > 0) {
var cell = $(brows[0]).children('td');
var cell2 = $(brows[1]).children('td');
var cell3 = $(brows[2]).children('td');
//set the column data
var currentColumnHeaderDate = dtRotate.getMonth() + 1 + '/' + dtRotate.getDate() + '/' + dtRotate.getFullYear();
var currentColumnHeaderDateWithTime = new Date(currentColumnHeaderDate.toString() + ' 23:59:59');
firstWeeksDataObject[index] = currentColumnHeaderDate;
$(item).text((dtRotate.getMonth()) + 1 + '/' + dtRotate.getDate() + '/' + dtRotate.getFullYear());
//set the row data
if (dtRotate <= currentColumnHeaderDateWithTime) {
var arrayReturn = getDaysData(items, start, end, dtRotate, currentColumnHeaderDate);
//set table row data
$(cell[index]).html(arrayReturn[0]);
$(cell2[index]).html(arrayReturn[1]);
$(cell3[index]).html(arrayReturn[2]);
}
//increment the date
dtRotate.setDate(dtRotate.getDate() + 1);
}
});
}

How to Change color of a text after a time period?

I have created a notice board. I want to show the notices in Red color for the first 48 hours. After 48 hour the color of the Notices will be changed. Now what should i change or add in my code?
HTML body for the notice board -
<div class="col-md-4">
<div class="widget-item" style="padding-top:0px;margin-top:0px;">
<div class="widget-main-title">
<h4 class="widget-title">Notice Board</h4>
</div> <!-- /.widget-main-title -->
<marquee id="dvNotice" FACE="courier" BEHAVIOR="SCROLL" height="247px" onmouseout="this.setAttribute('scrollamount', 2, 0);" onmouseover="this.setAttribute('scrollamount', 0, 0);" scrollamount="2" direction="up" style="text-align: left;">
<%--<div class="widget-inner" id="dvNotice">
</div> --%><!-- /.widget-inner -->
</marquee>
<!-- /.request-information -->
</div> <!-- /.widget-item -->
</div>
JQuery/JavaScript -
$(document).ready(function () {
PageMethods.loadNotice('', loadNoticeSuccess);
});
function loadNoticeSuccess(result) {
$("#dvNotice").html('');
var html = "";
for (var i = 0; i < result.length; i++) {
var month_value = result[i].PublishedDate.getMonth();
var day_value = result[i].PublishedDate.getDate();
html += "<div class=\"event-small-list clearfix\">";
html += "<div class=\"calendar-small\"><span class=\"s-month\">" + months[month_value] + "</span><span class=\"s-date\">" + day_value + "</span></div>";
//html += "<div class=\"event-small-details\"><h5 class=\"event-small-title\">" + result[i].Title + "</h5><p class=\"event-small-meta small-text\">" + result[i].Description + "</p></div></div>";
html += "<div class=\"event-small-details\"><h5 class=\"event-small-title\">" + result[i].Title + "</h5><p class=\"event-small-meta small-text\"></p></div></div>";
}
html += "<div class=\"event-small-list clearfix\" style=\"text-align:right;padding:0;\">More</div>";
$("#dvNotice").append(html);
}
C# Code Behind for loading the notice board -
[WebMethod]
public static List<Notice> loadNotice(string value)
{
IList<Notice> notice = NoticeManager.GetTopPublishedNotice();
if (notice == null)
{
notice = new List<Notice>();
}
return notice.ToList();
}
I assume you are using some CMS to add these notices. One option is to check difference between notice/content creation time and now on page load. This can be done easily through javascript get Time function.
If you don't have such value then simply add it to you CMS, to store metadata of creation date and time. Most CMS I have encountered have such possibilities.
Hope this theory will help.
Can you please try this code after appending the html to the div dvNotice ,
setTimeout(function () {
$('#dvNotice').css('color','yellow');
}, 172800000);
I'm leveraging the function from this answer to calculate the difference of two dates, based on the assumption that 48 hours == 2 days
var _MS_PER_DAY = 1000 * 60 * 60 * 24;
// a and b are javascript Date objects
function dateDiffInDays(a, b) {
// Discard the time and time-zone information.
var utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
var utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
return Math.floor((utc2 - utc1) / _MS_PER_DAY);
}
// tweaked OP code
function loadNoticeSuccess(result) {
$("#dvNotice").html('');
var html = "";
for (var i = 0; i < result.length; i++) {
var isPast48Hours = dateDiffInDays(new Date(), result[i].PublishedDate) > 2;
if (isPast48Hours) { /*setup html for default color*/ }
else { /*setup html for red color */ }
// rest of code, using the html you setup above for the variable color
}
}
What's missing here is a real-time verification (and reaction, switching the colors) of the age of the entry: if the page is loaded 47 hours and 59 minutes after the published date, the entry will be red and stay red.

Measure actual activity time

Fiddle: http://jsfiddle.net/qfn04xzj/
var a, b;
$('input:not([type=password]), textarea, select').on('focus', function(event) {
a = performance.now();
});
$('input:not([type=password]), textarea, select').on('blur', function(event) {
b = performance.now();
$('#console').append( $(this).attr('name') + ' took ' + (b - a) + ' ms.' + "<br/>");
});
... works but it measures time between focus and blur.
Is there any way I could measure the actual time — the time it took to type or time between two value changes?
You should first define what actual time means. If you mean the time between the first and last keystroke, then the following code should work. It creates an object for each time the user focuses on the input and listens for every keystroke, keeping record of the first and last keystrokes. When the input is blurred, it computes the difference between the two.
Of course, the user can still type a couple of characters, go for a cup of coffee and then return and type the others, which will result in a very long time of activity. There is no way to know how much time the user has spent actually staring at the input. You could, however, define a "timeout" or period of inactivity after which you assume that the user is idle.
Fiddle
$('input:not([type=password]), textarea, select').on('focus', function() {
new EditingSession($(this));
});
/**
* Represents the period of time during which the user is focused on
* the input.
*/
function EditingSession(input){
var firstKeydownTime = null;
var lastKeydownTime = null;
var sessionId = makeRandomId();
input.on("keydown." + sessionId, function(){
// User typed something
var time = performance.now();
lastKeydownTime = time;
if(firstKeydownTime === null){
firstKeydownTime = time;
}
});
input.on("blur." + sessionId, function(){
// Editing session finished.
// Detach all handlers
input.off("." + sessionId);
// Print time between first and last keydown
var time;
if(firstKeydownTime === null){
time = 0;
} else {
time = lastKeydownTime - firstKeydownTime;
}
$('#console').append(input.attr('name') + ' took ' + time + ' ms.' + "<br/>");
});
}
// Borrowed from http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript
function makeRandomId() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
Instead of getting the time difference between keydown and keyup (which is silly :)) you need to simply get one single performance.now() timestamp and store it into a b variable for a later "input" event time-difference comparison.
var $fields = $('input:not([type=password]), textarea, select'),
$console = $("#console"),
$total = $("#totTime"),
tot=0, a=0, b=0;
$fields.on('input', function() {
a = performance.now();
var diff = (a - b)|0; // |0 prevents floated results (happens in FF)
$console.append( this.name +" took "+ diff +" ms"+ this.value +"<br>");
$total.text("Total time: "+ (tot+=diff) +" ms");
b = a; // Store a into b for later use.
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="totTime"></div>
<input type="text" name="" id="">
<div id="console"></div>
Performance-wise (since you're dealing with hopefully time accuracy) cache your Elements selectors into variables, that way you'll prevent parsing again the DOM in the search for your elements on every input event.
Also "input" as event is quite enough to handle all you need from copy-paste, change etc...
This will give you total time typing: Fiddle
<input type="text" name="" id="">
<div id="total"></div>
<div id="console"></div>
JS
$('input:not([type=password]), textarea, select').on('input change keyup', function (event) {
if (event.type == 'input') {
$('#console').append("input: " + $(this).val() + "<br/>");
}
if (event.type == 'change') {
$('#console').append("change: " + $(this).val() + "<br/>");
}
});
var a, b, total = 0;
$('input:not([type=password]), textarea, select').on('keydown', function (event) {
a = performance.now();
});
$('input:not([type=password]), textarea, select').on('keyup', function (event) {
b = performance.now();
var net = (b - a);
$('#console').append($(this).attr('name') + ' took ' + net + ' ms.' + "<br/>");
var final = total += net;
$('#total').text('Total time typing: ' + final + ' ms.');
});

Categories

Resources