My idea is to hide some sections based on visitor sport. He would see a popup display when he enters the site for the first time. This popup has multiple buttons that should determine what content he will see further on. When he clicks on a button all the content with the selected sport would continue to be shown and all other sports content would hide. Also when data-sport="all" the function should not hide this section affecting all the other sports.
I used a localStorage() for saving this setting in the device preventing the user to be click the preferred sport everytime. The js is supposed to be a loop for always have a localStorage() item "stSport" and when the device doesn't have this item it launches the popup to capture the sport.
I've got this but it's not working presuming that some little thing is wrong.
Could you help me out?
Thanks in advance! :)
HTML:
<section data-sport="soccer"></section>
<section data-sport="basketball"></section>
<section data-sport="all"></section>
<div id="sportsModal">
<div id="sportsModal-group">
<button onclick="sportRemove()" class="sportsModal-sport">All</button>
<button onclick="sportExecute(soccer)" class="sportsModal-sport">Soccer</button>
<button onclick="sportExecute(futsal)" class="sportsModal-sport">Futsal</button>
<button onclick="sportExecute(basketball)" class="sportsModal-sport">Basketball</button>
<button onclick="sportRemove()" class="sportsModal-sport">Other</button>
</div>
</div>
CSS:
#sportsModal {
background-color: rgba(255,255,255,0.15);
position: fixed;
width: 100%;
height: 100%;
display: none;
justify-content: center;
align-items: center;
top: 0;
z-index: 99999;
left: 0;
}
#sportsModal-group {
display: flex;
flex-direction: column;
}
.sportsModal-sport {
margin-bottom: 10px;
}
JS:
function sportFunnel() {
$("#sportModal").css("display", "fixed");
}
function sportExecute(n) {
localStorage.removeItem("stSport");
localStorage.setItem("stSport", n);
var vstSports = localStorage.getItem("stSport");
$("*[data-sport]").hide();
var dataSport = "*[data-sport='" + vstSports + "']";
var dataSportAll = "*[data-sport='all']";
$(dataSportAll).show();
$(dataSport).show();
}
$(document).ready( function() {
if(!localStorage.getItem("stSport")){
sportFunnel();
var vstSports = localStorage.getItem("stSport");
}
else {
var stSportChosen = localStorage.getItem("stSport");
$("*[data-sport]").hide();
var dataSport = "*[data-sport='" + stSportChosen + "']";
var dataSportAll = "*[data-sport='all']";
$(dataSportAll).show();
$(dataSport).show();
}
});
function sportRemove() {
localStorage.removeItem("stSport");
var vstSportsValue = localStorage.getItem("stSport");
sportFunnel();
};
Welcome to SO.
I've created a simple fiddle using your example: https://jsfiddle.net/Dganenco/vxja4kb1/ When I've tried to run your code, I received an error msg in console that says: Uncaught ReferenceError: soccer is not defined
Fix for your issue is straight-forward - add quotes!
<button onclick="sportExecute('soccer')" class="sportsModal-sport">Soccer</button>
<button onclick="sportExecute('futsal')" class="sportsModal-sport">Futsal</button>
<button onclick="sportExecute('basketball')" class="sportsModal-sport">Basketball</button>
Related
I'm trying to add a popup with javascript which is triggered by a query string of the URL. I want the popup to stay hidden unless the query string is attached to the URL. I'll be using the popup mostly for redirects and any messaging that I want to display relating to the redirect.
I've tried using a combination of different functions I've used previously and can't get it to work, so I was just wondeirng if someone could take a look through and tell me where I'm going wrong.
The redirect with query string will be something like this:
https://www.example.com/?fromoldsite
SCRIPT
<script>
var fromOldURL = window.location.href;
if (fromOldURL.indexOf('fromoldsite') !== -1) {
function PopUp(hideOrshow) {
if (hideOrshow == 'hide') document.getElementById('redirectPopUp').style.display = "none";
else document.getElementById('redirectPopUp').removeAttribute('style');
window.onload = function () {
setTimeout(function () {
PopUp('show');
}, 3000);
}
}
}
</script>
CSS
<style>
#redirectPopUp {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,.6);
z-index: 1001; }
#popUpContent{
padding: 100px;
width: 50%;
height: 50%;
background-color: #FFF;
background-size: cover
position: relative;
margin: 200px auto; }
</style>
HTML
<div id="redirectPopUp">
<div id="popUpContent">
<h2>Popup Content Here</h2>
<h6>Popup Message Here</h6>
<input type="submit" name="submit" value="Submit" onClick="PopUp('hide')" />
</div>
</div>
I want the popup to show up only if the url contains "fromoldsite" and to pop up after 3 seconds. At the moment, the popup is showing up automatically regardless of the URL.
Any help would be appreciated.
At the moment your popup is displaying simply because you didn't call PopUp("hide"); yet.
Furthermore the function definition of PopUp is inside the if block that evaluates the query string. Move it above, outside of the if block.
Lastly the setTimout function should just be triggered if the query string is present.
Your corrected code should look like this:
<script>
function PopUp(hideOrshow) {
if (hideOrshow == 'hide')
document.getElementById('redirectPopUp').style.display = "none";
else
document.getElementById('redirectPopUp').removeAttribute('style');
}
var fromOldURL = window.location.href;
if (fromOldURL.indexOf('fromoldsite') !== -1) {
setTimeout(function() {
PopUp('show');
}, 3000);
}
PopUp("hide");
</script>
I have been tasked to take some pre-existing code which has a float event on an org chart. When you hover over an individual on the org chart a picture pops up and displays all the employees under them.
They don't like that and would like it changed to a click event. I've listed the code for the float event but what would be an example of taking the contentFloating and making it a click event? Looking for the proper syntax please.
}
.orgContainer .contentStable .contentFloating img {
height: 720px;
width: 960px;
}
/* Float content */
.orgContainer .contentFloating {
border: 2px solid black;
display: none;
position: fixed;
}
.orgContainer .contentStable:hover .contentFloating {
display: block;
top: 7%;
left: 15%;
}
<div class="contentStable">
<img title="Scott Plemmons Director Supplier Quality Compliance" src="/sites/scm/utas_supp_qual/Home_Pictures/scott_plemmons.jpg" />
<p>
Scott Plemmons<br/> Director
<br/> Supplier Quality
</p>
<div class="contentFloating">
<img src="/sites/scm/utas_supp_qual/Home_Pictures/Org_Charts/Scott_Plemmons_Chart.jpg" />
</div>
</div>
This is an example of how to add a click event handler to a dom element, and then make another div appear when you click on it.
html
<div class="orgchart">click for details</div>
<div id="details">details</div>
css
#details {
position:absolute;
}
javascript
let elements = document.getElementsByClassName("orgchart");
for(var i = 0; i < elements.length; i++)
{
elements[i].addEventListener("click", function(e){
// get the position of the element that was clicked
let clickedItem = e.target;
var rect = clickedItem.getBoundingClientRect();
// set the details div to that position and fill it with content
let details = document.getElementById("details");
details.innerHTML = "Joe Average";
details.style.left = (rect.left + 10) + "px";
details.style.top = (rect.top + 20) + "px";
});
}
Check a jsfiddle example here
Here is the important part of the code that executes.
Im trying to click on one element with a particular ID that relates to bookmarking the message but the element keeps triggering another click event that hides every div with the class 'messageCase' while at the same time attaching class messageOpen2 to the bookmark images ID which is very odd
the 'hidden' classes just hide all other message instances that contain
The messageCase class.
var openMessageAnimationStrategy = function () {
var openMessage = $(document).ready(function () {
var divTarget = $("div.messageCase");
$(divTarget).click(function (e) {
var target = $(e.target);
target.toggleClass('messageOpen2');
divTarget.addClass('hidden');
target.removeClass('hidden');
});
});
};
Here is what the HTML looks like
<div class="messageCase">
<div class="messageImageBox">
<div id="messageImage">
</div>
</div>
<div id="subjectLine">
Subject Line Text
</div>
<div id="bookMarkImage">
<img id="bookmarkStatus" class="savedMessage" src="notbookMarked64.png" />
</div>
<div class="activeBookmarks">
{38} <br />
Bookmarks <br />
<br />
9:53am
</div>
<div id="bodyPreview">
Body Preview Text is light
</div>
</div>
Every Time I use the Click event on bookmarkStatus to change the src of the image it causes the first click event to execute making everything disappear & the class messageOpen2 to be added to bookmarkStatus. I can include the CSS if necessary but ill list the code for the bookmarking function below
var bookmarkedStrategy = function () {
var bookmarkedStrategy = $(document).ready(function () {
var bookmarkStatus = $("#bookmarkStatus");
var divTarget = $('messageCase');
//below trying to remove the Class that was attached by the initial function while also changing the image SRC for the class bookmark
$(divTarget).click(function (e) {
var target = $(e.target);
divTarget.removeClass('messageCase2');
bookmarkStatus.toggleClass('savedMessage');
});
});
};
I Think the main problem has to do with the initial function but I don't know what else could be wrong any ideas?
edit Here is the CSS that matters.
.savedMessage {
background-image: url("bookmarked64.png");
}
.messageOpen2 {
height: 250px;
}
.messageCase {
margin: 5px;
border-radius: 5px;
background-color: aliceblue;
height: 70px;
}
#bookMarkImage {
float:right;
height:64px;
width:64px;
z-index:9999;
}
.hidden {
display:none;
max-height: inherit;
}
.activeBookmarks {
float: right;
text-align: center;
font-size: 13px;
font-weight: 700;
text-decoration: solid;
}
Calling code
var bookmarkedthings = new MessageHandling(bookmarkedStrategy);
bookmarkedthings.greet();
var openMessage = new MessageHandling(openMessageAnimationStrategy);
openMessage.greet();
There is a missing . in your bookmarkedStrategy function code var divTarget = $('.messageCase'); Add dot and try again
I'm building a basic real-time messaging app in Meteor and currently every time a message is created it is appended to the list of messages on the page & everything is working correctly. However once the contents of the messagesList div overflow (I've set it to scroll) I can no longer see the latest messages without scrolling down manually each time.
What is the 'Meteor way' of using callbacks to skip to the bottom automatically (e.g. with Jquery scrolltop) every time the messages list rerenders? I had a go at it in the messages list template helpers but I'm not getting a value returned on scrollTop and I can't figure out if it's my selectors or something to do with Meteor, i.e. where I am putting the code. So I'd really appreciate some pointers.
Here's what I have:
messagesList.html
<template name="messagesList">
<div class="pure-g-r content" id="layout">
<div class="pure-u-1" id="list">
{{#each messages}}
{{> messageItem}}
{{/each}}
</div>
</div>
</template>
messagesList.js:
Template.messagesList.helpers({
messages: function() {
return Messages.find();
}
});
Template.messagesList.rendered = function () {
console.log("scrolltop is " + $('#list').scrollTop);
// $('#list').scrollTop( $('#list').height() )
};
messageItem.html:
<template name="messageItem">
<div class="email-item email-item pure-g">
<div class="pure-u-3-4">
<p>
<strong>{{sentBy}}</strong><br>
{{msgText}}
</p>
</div>
</div>
</template>
MessageSubmit.html:
<template name="messageSubmit">
<form class="pure-form">
<input type="text" name="msg" class="pure-input-rounded">
<button type="submit" class="pure-button">Speak!</button>
</form>
</template>
messageSubmit.js:
Template.messageSubmit.events({
'submit form': function(e) {
e.preventDefault();
console.log('new comment created')
var user = Meteor.user();
var message = {
msgText: $(e.target).find('[name=msg]').val(),
sentBy: user.profile.name,
userId: user._id
}
message._id = Messages.insert(message);
$('.pure-input-rounded').val("");
}
});
main.css:
html, body {
height: 100%;
}
#layout {
max-height: 60%;
left: 20px;
top: 60px;
position: relative;
overflow: scroll;
padding-bottom: 60px;
}
h1 {
font-size: 2em !important;
}
.pure-form {
position: absolute;
left: 10px;
bottom: 20px;
}
I don't think there is a particularly meteor way of doing this, but with this minor fix to your code it should work:
Template.messagesList.rendered = function () {
console.log("scrolltop is " + $('#list').scrollTop());
$('#list').scrollTop( $('#list').prop("scrollHeight") );
};
I like the notification bars used in stackoverflow. I have found a jQuery plugin which makes the notification bar possible with just a few lines, but this plugin does not seem to stack multiple notifications bars when required.
Does anyone know of a better plugin or how to get the plugin below to stack bars as more notifications become available?
http://www.dmitri.me/blog/notify-bar/
...
<body>
<div id="notificationArea"></div>
<!-- rest of your website -->
</body>
</html>
Then to create notifications just do this in jquery:
$('#notificationArea').prepend('<div class="notification">This is my notification</div>');
its a bit basic, but this should do the trick, and because you are "prepending" you will get the stacking you are looking for. You can use append() too, but I was assuming you'd want the most recent notifications on the top.
To get the "X" (close) button just have a link in the notification with a class of notifcationClose and do:
$('.notificationClose').click(function(){ $('this').parents('.notification').remove(); })
I know that you are looking only for bar plugin, but I write my opinion. Imagine that you have more than 2 notifications in this bar. It grows and it could fill more space than you would like to. Instead of viewing results of action, user will see only notifications to half display of monitor :)
Try to consider using bar notifications, if you know that you will have more than one notification in time often.
I recommend jGrowl which is similar to the way that in OS X works. It is simple, good-looking and ready for many notifications in time.
good luck.
I wrote this piece of Javascript that does just that.
// Show a message bar at the top of the screen to tell the user that something is going on.
// hideAfterMS - Optional argument. When supplied it hides the bar after a set number of milliseconds.
function AdvancedMessageBar(hideAfterMS) {
// Add an element to the top of the page to hold all of these bars.
if ($('#barNotificationContainer').length == 0)
{
var barContainer = $('<div id="barNotificationContainer" style="width: 100%; margin: 0px; padding: 0px;"></div>');
barContainer.prependTo('body');
var barContainerFixed = $('<div id="barNotificationContainerFixed" style="width: 100%; position: fixed; top: 0; left: 0;"></div>');
barContainerFixed.prependTo('body');
}
this.barTopOfPage = $('<div style="margin: 0px; background: orange; width: 100%; text-align: center; display: none; font-size: 15px; font-weight: bold; border-bottom-style: solid; border-bottom-color: darkorange;"><table style="width: 100%; padding: 5px;" cellpadding="0" cellspacing="0"><tr><td style="width: 20%; font-size: 10px; font-weight: normal;" class="leftMessage" ></td><td style="width: 60%; text-align: center;" class="messageCell"></td><td class="rightMessage" style="width: 20%; font-size: 10px; font-weight: normal;"></td></tr></table></div>');
this.barTopOfScreen = this.barTopOfPage.clone();
this.barTopOfPage.css("background", "transparent");
this.barTopOfPage.css("border-bottom-color", "transparent");
this.barTopOfPage.css("color", "transparent");
this.barTopOfPage.prependTo('#barNotificationContainer');
this.barTopOfScreen.appendTo('#barNotificationContainerFixed');
this.setBarColor = function (backgroundColor, borderColor) {
this.barTopOfScreen.css("background", backgroundColor);
this.barTopOfScreen.css("border-bottom-color", borderColor);
};
// Sets the message in the center of the screen.
// leftMesage - optional
// rightMessage - optional
this.setMessage = function (message, leftMessage, rightMessage) {
this.barTopOfPage.find('.messageCell').html(message);
this.barTopOfPage.find('.leftMessage').html(leftMessage);
this.barTopOfPage.find('.rightMessage').html(rightMessage);
this.barTopOfScreen.find('.messageCell').html(message);
this.barTopOfScreen.find('.leftMessage').html(leftMessage);
this.barTopOfScreen.find('.rightMessage').html(rightMessage);
};
this.show = function() {
this.barTopOfPage.slideDown(1000);
this.barTopOfScreen.slideDown(1000);
};
this.hide = function () {
this.barTopOfPage.slideUp(1000);
this.barTopOfScreen.slideUp(1000);
};
var self = this;
if (hideAfterMS != undefined) {
setTimeout(function () { self.hide(); }, hideAfterMS);
}
}
To use it you must use jQuery and ensure there are no margins or padding on the body of your page.
The parameter that the AdvancedMessageBar takes is optional. If provided it will cause the bar to disappear after a certain amount of time in milliseconds.
var mBar = new AdvancedMessageBar(10000);
mBar.setMessage('This is my message', 'Left Message', 'Right Message');
mBar.show();
If you want to stack these then just create more AdvancedMessageBar objects and they'll automatically stack.