I'm trying to use the basic .js countdown timer from Keith Wood but am running into troubles when trying to adjust the layout. Because I cannot inspect the element (every time I inspect it it reloads and vanishes so I can't work out what CSS needs to be adjusted).
I want it to output as : XX days XX hours xx minutes
I tried adding a layout code to the script but it does nothing.
<script type="text/javascript">
$(function () {
var austDay = new Date();
austDay = new Date(austDay.getFullYear() + 1, 1 - 1, 26);
$('#defaultCountdown').countdown({until: austDay});
$('#year').text(austDay.getFullYear());
$('#textLayout').countdown({until: liftoffTime,
layout: '{sn} {sl}, {mn} {ml}, {hn} {hl}, and {dn} {dl}'});
});
</script>
This part in particular apparently should make it output as I want but it doesn't
$('#textLayout').countdown({until: liftoffTime,
layout: '{sn} {sl}, {mn} {ml}, {hn} {hl}, and {dn} {dl}'});
});
Here is the live site: username is admin password is gogogo
http://www.francesca-designed.me/fyp/
What you need is to define "liftoffTime".
Example of missing code:
<script>
var liftoffTime = new Date();
liftoffTime.setDate(liftoffTime.getDate() + 5); /* 5 days countdown */
</script>
*I think in Your case You need to replace "liftoffTime" by "austDay" (since You've defined austDay)
<div id="defaultCountdown" class="hasCountdown">
<span class="countdown_row countdown_show4">
<span class="countdown_section">
<span class="countdown_amount">366</span><br>Days</span>
<span class="countdown_section">
<span class="countdown_amount">6</span><br>Hours</span>
<span class="countdown_section">
<span class="countdown_amount">57</span><br>Minutes</span>
<span class="countdown_section">
<span class="countdown_amount">39</span><br>Seconds</span>
</span>
</div>
There you go!
All you do if you get this problem (and assuming you are using google chrome) is righ-click -> inspect
Then get the parent container and right click -> copy as HTML and then paste into an editor
EDIT
To address your code giving the wrong output (and not the CSS layout part -
layout: '{mn} {ml}, {hn} {hl}, and {dn} {dl}'
just remove the
{sn} {sl}
Related
I have a picture with the word "NEW" over it to designate a new document that has been posted to our website. I would like to have jQuery remove the picture after 6 hours of it being posted. How would I go about doing this?
Here is the element:
<tr class="pointer">
<td>
<img class="germ" src="~/Image" width="40px" />
<i class="created" hidden="hidden">April 3, 2020 13:13:00</i>
Document Title
</td>
<td>PDF</td>
<td>March 2020</td>
</tr>
As you can see, I have a hidden <i> element that designates when the document was posted to the website. I need to remove the <img> tag 6 hours from the time in the <i> tag.
How can I do this using jQuery or JavaScript?
This would be better done server-side. The way you want to do it assumes that the user will have this same page up for 6+ hours, or come back to this page in the same state, which is pretty unlikely.
What I would do is add a property to the post for created and have it set a default time of Date.now(), and then have front end code look for whether that created value was less than 6 hours ago (1000 * 60 * 60 * 6 miliseconds).
If so, show the 'New' graphic. If not, don't.
Another way to do it so that you don't have to update server-side stuff that might be more set in stone is to have the default display for the "New" graphic to be true, then:
let createdTime = new Date(document.queryselector('i.hidden').textContent);
if (Date.now() - createdTime > (1000 * 60 * 60 * 6)){
//code to hide the "New" graphic
}
A little extra two cents for free: I would add an id attribute to that hidden i element to make sure you're selecting only that and not something else that may have the same class
Since you asked how to do this with JavaScript or JQuery, this is how.
I also included a 3-second example to show that it does work.
window.setTimeout(function() {
document.getElementById('sixHours').outerHTML = '';
}, 2160000);
window.setTimeout(function() {
document.getElementById('threeSeconds').outerHTML = '';
}, 3000);
<div id="sixHours">This will be removed after six hours</div>
<div id="threeSeconds">This will be removed after three seconds</div>
Keep in mind, that as soon as the page is refreshed, the timer will start over. If you want to avoid this and still have JavaScript handle it, you could have it removed at a definite time.
Edit
The snippet below will parse the date in expiration and find the milliseconds from that till now. Then like the snippet above, the remove element will get removed when the timer expires. 6 hours are added to the timer to make it expire 6 hours from the given time.
var expiration = Date.parse(document.getElementById('expiration').innerHTML);
var diff = expiration - Date.now();
window.setTimeout(function() {
document.getElementById('remove').outerHTML = '';
}, diff + 2160000);
//2160000ms = 6 hours
<div id="expiration">April 3, 2020 20:00:00</div>
<div id="remove">Will be removed by the date above</div>
Use setTimeout(), but bear in mind that people aren't likely going to sit at a single page for 6 hours meaning this will fail as soon as they navigate away. You'll have to change the time sent over every time they refresh.
const testing = true;
if (testing) {
// BEGIN - Fake date for testing
const tmpNow = new Date();
document.querySelector("i.created").innerHTML = tmpNow.toUTCString();
// END - Fake date for testing
}
const d = document.querySelector("i.created").innerHTML;
const dd = new Date(d);
if (testing) {
dd.setSeconds(dd.getSeconds() + 3);
} else {
dd.setHours(dd.getHours() + 6);
}
const ddd = dd.getTime();
const now = Date.now();
if (ddd < now) {
console.log("Too late");
}
const dt = Math.max(ddd - now, 0);
setTimeout(() => {
const img = document.querySelector("img.germ");
img.parentNode.removeChild(img);
}, dt);
<tr class="pointer">
<td>
<img class="germ" src="~/Image" width="40px" />
<i class="created" hidden="hidden">April 3, 2020 13:13:00</i> 03.21.2020 GOA - Alaska Businesses Now Eligible for SBA Economic Injury Disaster Loans (2)
</td>
<td>PDF</td>
<td>March 2020</td>
</tr>
You don't understand the problem here.
As R Greenstreet said it needs to be done server-side. You need a Create Post Date to be sent to UI.
Let's assume you have a JSON coming from a server where you can add createDate property of a post form bata base.
{createDate: date, name......}
You need to compare that date with Date.now()
Pseodu Code here:
if(createDate + 6 hours >= Date.now()) then hide your Icon.
You will need to use Date to convert the String into a Date Object:
new Date("April 3, 2020 13:13:00");
This will create a Date Object, yet since there is no Timezone Offset, the script might assume UTC. Your result might be:
"2020-04-03T13:13:00.000Z"
So consider specifying a Time Zone. Some browsers will assume the Users local Timezone.
$(function() {
function getDate(cObj, tz) {
if (tz == undefined) {
tz = "GMT-07:00";
}
var str = cObj.text().trim() + " " + tz;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
var nDt = new Date(str);
console.log(str, nDt);
return nDt;
}
function getHoursPast(thn) {
// https://stackoverflow.com/questions/19225414/how-to-get-the-hours-difference-between-two-date-objects/19225463
var now = new Date();
return Math.floor(Math.abs(now - thn) / 36e5);
}
var hours = getHoursPast(getDate($(".created")));
console.log(hours + " have passed since", getDate($(".created")));
if (hours > 5) {
$(".germ").remove();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class="pointer">
<td>
<img class="germ" src="~/Image" width="40px" />
<!--
Would advise better format
Example: 2020-04-03T13:00.000-7:00
-->
<i class="created" hidden="hidden">April 3, 2020 13:13:00</i> Document Title
</td>
<td>PDF</td>
<td>March 2020</td>
</tr>
</table>
References
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
How to get the hours difference between two date objects?
Getting the client's timezone offset in JavaScript
I'm using Shopify and am trying to sort blog posts by a different date than the publish date. Shopify Community Forums says the only real way to do it is using liquid to plug in the information and alter it via client side Javascript. I'm doing that by taking the div and the new date and placing it into an object in an array. The object is structured to have a div value and a date value like so:
0:
date: "1563681600"
div: " <div class="article-image">
<a href="/blogs/upcoming/dog-days-of-summer">
<div class="rimage-outer-wrapper" style="max-width: 750px"><div class="rimage-wrapper lazyload--placeholder" style="padding-top:60.0%"><img class="rimage__image lazyload fade-in " data-src="//cdn2.shopify.com/s/files/1/0152/7041/2388/articles/84th_2019-0721_slider_{width}x.jpg?v=1561562008" data-widths="[180, 220, 300, 360, 460, 540, 720, 900, 1080, 1296, 1512, 1728, 2048]" data-aspectratio="1.6666666666666667" data-sizes="auto" alt="DOG DAYS OF SUMMER"><noscript><img src="//cdn2.shopify.com/s/files/1/0152/7041/2388/articles/84th_2019-0721_slider_1024x1024.jpg?v=1561562008" alt="DOG DAYS OF SUMMER" class="rimage__image"></noscript></div></div>
</a>
</div>
<div class="meta">
<span class="meta-item date">1563681600</span>
<span class="meta-item" id="time">1-3pm</span>
<span class="meta-item location">84th Street Location</span>
</div>
<h2>DOG DAYS OF SUMMER</h2>
<div class="rte article-excerpt"><b>Books of Wonder</b><span> </span><span>is excited to host a picture book event: DOG DAYS OF SUMMER. Please join us on Sunday, July 21st at our 84th Street Store to celebrate four amazing picture books about dogs!</span></div>
<p class="fullarticle"><a class="cta-link" href="/blogs/upcoming/dog-days-of-summer">Read more</a></p>
"
The trouble I'm having now after sorting the array by date is how to take all these div elements and display them in the DOM. AppendChild throws an error even though these DIVS are captured using innerHTML. Here is the code:
function storeid() {
var divName = document.getElementsByClassName('pullup');
var className = document.getElementsByClassName('date');
var classnameCount = className.length;
var IdStore = new Array();
for (var j = 0; j < classnameCount; j++) {
var obj = {};
var div = divName[j].innerHTML;
var dateString = className[j].innerText;
obj["div"] = div;
obj["date"] = dateString;
IdStore.push(obj);
}
console.log(IdStore);
IdStore = IdStore.sort(function(a, b) {
return b.date - a.date
});
IdStore.forEach(el => {
document.body.appendChild(el.div);
})
}
storeid();
However despite specifying it only take the div I'm still getting the following error. TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'
Is appendChild not able to append this much? Or is there a better way of solving this?
When you do this:
var div = divName[j].innerHTML;
You're no longer dealing with a Node, it's a string. Remove the .innerHTML from the line and it should work.
I am trying to output an estimated time based off the number of items (people) within my database (this is a wait list). Currently I save a value in the quick form called countNumber. This is just set to 1 everytime. I then get the count of all the items by finding the all items that have countNumber = 1 (all of them). I then try updating the html using getElementById().
The problem I am having is that when I add a person to the database the estimated time will go up appropriately. However when I refresh the page the html resets to 0 like the initial html that is put in.
How do I fix this so that the html will always display the appropriate time even when the page is refreshed?
Html code:
<head>
<title>Wait List</title>
</head>
<template name= "home">
<body>
<h2 id="insert">Approximate Wait Time: 0 Minutes</h2>
<div class="col-lg-6 col-lg-offset-3">
{{>quickForm id="studentForm" collection="Students" type="insert" template="bootstrap3-horizontal" label-class="col-sm-3" input-col-class="col-sm-9"}}
</div>
</body>
</template>
js code:
AutoForm.hooks({
studentForm:
{
onSuccess: function (insert,result) {
var totalCount = Students.find({countNumber:1}).count();
var waitTime = "Approximate Wait Time: " + totalCount*15 +" Minutes";
document.getElementById("insert").innerHTML = waitTime;
...
},
}
});
You should put this into a helper instead of a hook.
Template.home.helpers({
waitTime: function(){
var totalCount = Students.find({countNumber:1}).count();
var waitTime = totalCount*15;
return waitTime;
}
});
and change the <h2> line in the html to this.
<h2 id="insert">Approximate Wait Time: {{waitTIme}} Minutes</h2>
I am using rateit plugin by http://gjunge.github.io/rateit.js/examples/
Every thing works fine until i load content with starts on page dynamically after page load. Stars simply don't appear.
My dynamically generated content which is appended to the page looks likes this(form ajax request):
<div class="caption">
<p id="productNameInFeeds"><a href="https://youlense.com/view/IPHONE">
<b>IPHONE</b></a> - I PHONE 6S</p>
<div class="rateit" data-rateit-value="3.00"
data-rateit-ispreset="true" data-rateit-readonly="true" data-rateit-max="10">
</div>
<div>
3.00 Stars | 2 Reviews | 10 Views | 1 Followers
</div>
</div>
my js file looks likes this
$(document).ready(function() {
var page = 1;
$("#load_more_feeds").click(function(){
$.post("my/feeds/more",
{
page: page
},
function(data, status){
if(data != ''){
$("#feedHolder").append(data);
page = page + 1;
}
});
$('div.rateit, span.rateit').rateit();
});
});
Can anyone tell me the solution?
Thanks in advance
Found this: https://stackoverflow.com/a/33071447/3499595
Just after you append the new content, call this:
$('div.rateit, span.rateit').rateit();
This initializes all the rateit elements.
I'm working on a Business Catalyst site (Adobe). I need to insert a placeholder div after each row of items which another script later appends info to. This is working fine on most browsers but does nothing on IE 11.
The script looks for the last item in a row to insertAfter, ie. rows contain 4 items but if the last row only has 1 or 2 it inserts it after the last one.
I was using Jquery 1.1 but just switched to 1.7 and it seems to make no difference.
My markup:
<div class="roller col-md-3" id="roller001">
<div class="roller-type">
<div class="roller-image">
{tag_small image_nolink}
</div>
<a class="roller-btn" onclick="appendRoller{tag_itemid}('{tag_itemid}')" href="javascript:void(0);">{tag_name_nolink}</a>
</div>
</div>
<div class="roller col-md-3" id="roller002">
<div class="roller-type">
<div class="roller-image">
{tag_small image_nolink}
</div>
<a class="roller-btn" onclick="appendRoller{tag_itemid}('{tag_itemid}')" href="javascript:void(0);">{tag_name_nolink}</a>
</div>
</div>
Script:
<script type="text/javascript">
$(document).ready(function(){
var rollerItems = document.getElementsByClassName('roller');
for (n=0; n<rollerItems.length; n++) {
if(n%4 == 0) {
var rowEnd = rollerItems[n];
if(document.contains(rollerItems[n+1])) { rowEnd = rollerItems[n+1]; }
if(document.contains(rollerItems[n+2])) { rowEnd = rollerItems[n+2]; }
if(document.contains(rollerItems[n+3])) { rowEnd = rollerItems[n+3]; }
$('<div class="popup-row"></div>').insertAfter(rowEnd);
}
}
});
</script>
I've realised the problem was not with the 'insertAfter' command at all but with 'document.contains'. Apparently IE does not regard 'document' as a node and I needed to use 'document.body.contains' to determine items at the end of the row.
Eg.
if(document.body.contains(rollerItems[n+1])) { rowEnd =
rollerItems[n+1]; }
Went through everything line by line but glossed over that! Not sure if this is the best solution but it works now at least.