Separate Show/Hide button javascript - javascript

I'm trying to have 2 separate buttons so that when the first button is clicked there's a div that shows underneath it and then when the other button is pressed, another div pops out replacing/hiding the first div that came out when the first button was clicked.
Html:
<!-- Pre-Determined Button -->
<span class="tooltip">
<button style="border-top-right-radius: 13px; border-bottom-left-radius: 13px;border-bottom-right-radius: 20px;border-top-left-radius: 20px;" id="predetermine" onclick="javascript:predetermine();">Pre-Determined</button>
</span>
<!-- Auction Button -->
<span class="tooltip">
<button style="border-top-right-radius: 20px; border-bottom-left-radius: 20px;border-bottom-right-radius: 13px;border-top-left-radius: 13px;" id="auction" onclick="javascript:auction(); ">Auction</button>
</span>
</div>
<br>
<!-- Username Entry -->
<div class="username-entry" id="predetermineclick" style="visibility:hidden">
<label> Enter Username: </label>
<input class= "joe" type="text" id="uName" name="UserName">
</div>
<!-- Create code button -->
<div class="create" id="auctionclick" style="visibility:hidden">
<button class="button">Create Link</button>
</div>
For my javascript, I just wrote 2 seperate functions, but as you can see on the images the "create link" button goes on the bottom of the username spot. I know there's a way to put these 2 functions together and make the code cleaner.
Java script:
function predetermine() {
if (document.getElementById('predetermine').onclick) {
document.getElementById('predetermineclick').style.visibility='visible';
document.getElementById('auctionclick').style.visibility='hidden';
}
function auction() {
if (document.getElementById('auction').onclick) {
document.getElementById('auctionclick').style.visibility='visible';
document.getElementById('predetermineclick').style.visibility='hidden';
}

Use display: none to completely remove an element from the page.
function predetermine() {
if (document.getElementById('predetermine').onclick) {
document.getElementById('predetermineclick').style.display = 'block';
document.getElementById('auctionclick').style.display = 'none';
}
}
function auction() {
if (document.getElementById('auction').onclick) {
document.getElementById('auctionclick').style.display = 'block';
document.getElementById('predetermineclick').style.display = 'none';
}
}
<!-- Pre-Determined Button -->
<span class="tooltip">
<button style="border-top-right-radius: 13px; border-bottom-left-radius: 13px;border-bottom-right-radius: 20px;border-top-left-radius: 20px;" id="predetermine" onclick="javascript:predetermine();">Pre-Determined</button>
</span>
<!-- Auction Button -->
<span class="tooltip">
<button style="border-top-right-radius: 20px; border-bottom-left-radius: 20px;border-bottom-right-radius: 13px;border-top-left-radius: 13px;" id="auction" onclick="javascript:auction(); ">Auction</button>
</span>
<br>
<!-- Username Entry -->
<div class="username-entry" id="predetermineclick" style="display: none">
<label> Enter Username: </label>
<input class="joe" type="text" id="uName" name="UserName">
</div>
<!-- Create code button -->
<div class="create" id="auctionclick" style="display: none">
<button class="button">Create Link</button>
</div>

You can get the id of the clicked button by passing it in the javascript function. Try the code snippet below.
HTML:
<div>
<!-- Pre-Determined Button -->
<span class="tooltip">
<button
style="border-top-right-radius: 13px; border-bottom-left-radius: 13px;border-bottom-right-radius: 20px;border-top-left-radius: 20px;" id="predetermine" onclick="toggleState(this.id);">Pre-Determined</button>
</span>
<!-- Auction Button -->
<span class="tooltip">
<button
style="border-top-right-radius: 20px; border-bottom-left-radius: 20px;border-bottom-right-radius: 13px;border-top-left-radius: 13px;" id="auction" onclick="toggleState(this.id); ">Auction</button>
</span>
</div>
<br>
<!-- Username Entry -->
<div class="username-entry" id="predetermineclick" style="visibility:hidden">
<label> Enter Username: </label>
<input class="joe" type="text" id="uName" name="UserName">
</div>
<!-- Create code button -->
<div class="create" id="auctionclick" style="visibility:hidden">
<button class="button">Create Link</button>
</div>
Javascript:
function toggleState(clickedButtonId) {
const predetermineClick = document.getElementById('predetermineclick');
const auctionClick = document.getElementById('auctionclick');
if(clickedButtonId === 'predetermine') {
predetermineClick.style.visibility='visible';
auctionClick.style.visibility='hidden';
} else {
auctionClick.style.visibility='visible';
predetermineClick.style.visibility='hidden';
}
}
Another way of doing this is to pass the element itself instead of its id.
To make this work, change toggleState(this.id); to toggleState(this); in both the places in the above HTML code.
Then get the id of the triggered element like we've done in the code below.
function toggleState(clickedButton) {
const clickedButtonId = clickedButton.id;
const predetermineStyle = document.getElementById('predetermineclick').style;
const auctionStyle = document.getElementById('auctionclick').style;
if(clickedButtonId === 'predetermine') {
predetermineStyle.visibility = 'visible';
auctionStyle.visibility = 'hidden';
} else {
auctionStyle.visibility = 'visible';
predetermineStyle.visibility = 'hidden';
}
}
Also, I noticed there was a <div> element missing in your HTML code, which I'm sure you'd definitely have in your code file, but to make this answer self-sufficient, I took the liberty of adding a <div> element at the beginning.
I'd have chosen to remove the element instead of toggling its visibility, but I see that #Janned has already addressed that in his answer, so I won't go into it.

Related

can't find variable: function name in external js file

i have a problem with my website. I have couple of functions in java script that works in <body> <script> js code </script></body> but when i link external js file with exactly the same code functions that are called by onclick"function name" attribute stop working and I get error can't find variable: function name also it seems like it can't find some of ids for variables because i can't log them. this is my code
function onload() {
/* leaderboard variable */
let x = document.getElementById('boardw');
/* help popup variable*/
let y = document.getElementById('helpw');
/* settings popup variable*/
let z = document.getElementById('setw');
/* help button variable*/
let a = document.getElementById('help');
/* dropdown container variable*/
let dropdown = document.getElementById('dropdown');
/* footer popup display none*/
document.getElementById('card').style = "display: none;";
/* variable test */
console.log(x);
/* show footer popup */
function showCard() {
document.getElementById('card').style = "display: block;";
document.getElementById('footer').style = "display: none;";
}
/* hide footer popup */
function hide() {
document.getElementById('card').style = "display: none;";
document.getElementById('footer').style = "display: block;";
}
/* choose time in dropdown function */
function show(anything) {
document.getElementById('txt').value = anything;
}
/* show options in dropdown */
dropdown.onclick = function() {
dropdown.classList.toggle('active');
}
/* show leaderboard function*/
function menu1() {
x.classList.toggle('active');
}
/* show help popup function*/
function menu2() {
y.classList.toggle('active');
a.classList.toggle('active');
}
/* show settings function*/
function menu3() {
z.classList.toggle('active');
}
/* hide popups function*/
function remove() {
y.classList.remove('active');
z.classList.remove('active');
x.classList.remove('active');
dropdown.classList.remove('active');
}
}
<body id="bd" style="" onload="onload()">
<script src="script.js" charset="utf-8"></script>
<!-- dropdown select time window -->
<div class="dropdown" id="dropdown" onclick="">
<!-- dropdown textbox with chosen informations -->
<input type="text" class="textbox" id="txt" value="" placeholder=" select the test duration" readonly>
<!-- options for dropdown select -->
<div class="option">
<div onclick="show(' 1 minute')">1 minute</div>
<div onclick="show(' 2 minutes')">2 minutes</div>
<div onclick="show(' 3 minutes')">3 minutes</div>
<div onclick="show(' 5 minutes')">5 minutes</div>
<div onclick="show(' 10 minutes')">10 minutes</div>
</div>
</div>
<!-- checkboxes for charset in game -->
<div id="charset">
<!-- normal letters check -->
<div>
<label for="cka">a</label>
<input type="checkbox" id="cka" class="ck">
</div>
<!-- capital letters check -->
<div>
<label for="ckB">A</label>
<input type="checkbox" id="ckB" class="ck">
</div>
<!-- numbers check -->
<div>
<label for="ck1">1</label>
<input type="checkbox" id="ck1" class="ck">
</div>
<!-- special characters check -->
<div>
<label for="ck>">#</label>
<input type="checkbox" id="ck" class="ck">
</div>
</div>
<!-- about popup -->
<footer onclick="remove()">
<!-- show popup btn -->
<button id="footer" onclick="showCard();" style="">i</button>
<!-- popup container -->
<div id="card" class="card" style="">
<!-- close popup btn -->
<button id="close" onclick="hide()">x</button>
</div>
</footer>
<!-- menu -->
<menu>
<!-- leaderboard popup -->
<button class="menu" id="board" onclick="menu1()">L</button>
<div id="boardw" style="" class="menuw">
</div>
<!-- help popup -->
<button class="menu" id="help" onclick="menu2()">?</button>
<div id="helpw" style="" class="menuw">
</div>
<!-- settings pop -->
<button class="menu" id="settings" onclick="menu3()">S</button>
<div id="setw" style="" class="menuw">
</div>
</menu>
<!-- start game btn -->
<div id="gma">
<button id="start">Start</button>
</div>
<!-- frame for higher resolution screen-->
<div class="h"> </div>
</body>
You wrapped your functions in function onload() { ... } so the inner functions can't be reached from HTML.
Remove this wrapper.
Add defer attribute to the script
put functions and variables outside the onload function,
or use addEventListener to call listener
document.getElementById("cka").addEventListener("click", function(){
...
})

How to make multiple divs appear one after the other using javascript?

I'm trying to animate a chat. Every time the user clicks on the input field or "send" icon, I want the chat bubbles to appear one after the other. This is my part of my code so far. Right now, they all have "display: none." The picture below shows them without it.
<div class="messages">
<div class="message" id="msg1" style="display: none;">Hi! I'm looking for an old friend. She attended Martin Grove a few years ago.</div>
<div class="message" id="msg2" style="display: none;">Her name is Sam.<br>
<i>*insert pic of Sam and MC*</i></div>
<div class="message" id="msg3" style="display: none;">Did you know her or her last name by any chance? </div>
<div id="msg4" class="message-teacher" style="display: none;">Hello there!</div>
<div class="message-teacher" id="msg5" style="display: none;">Unfortunately, I did not have the pleasure of teaching Sam. Her last name and whereabouts are a mystery to me as well. </div>
<div class="message-teacher" id="msg6" style="display: none;">However, I do know she was in the photography club. I always saw her carrying a camera, always taking pictures. </div>
<div class="message-teacher" id="msg7" style="display: none;">In fact, I believe she won a contest for one of them. </div>
<div class="message-teacher" id="msg8" style="display: none;">She’s a super talented girl!</div>
<div class="message-teacher" id="msg9" style="display: none;">Best of luck on your search. I hope you two are reunited soon!</div>
</div>
<div class="input">
<div class="plus-icon" style="font-size: 25px; color: #2A84FF; margin: auto;">
<i class="fas fa-plus-circle"></i>
</div>
<div class="subinput" style="font-size: 25px; color: #2A84FF; margin: auto;">
<input type="text" placeholder="|" />
<i class="fas fa-smile"></i>
</div>
<div class="btn" style="font-size: 23px; color: #2A84FF; margin: auto;"><i class="fas fa-paper-plane"></i></div>
</div>
I would query for the required elements, create an array out of it, and shift() (aka remove the first element of the array - or you can use pop() to remove the last element, depending on your needs). When you pop or shift an element from an array, those functions return the removed element and we can remove the CSS class that hides those elements in the DOM.
const myHTMLCollection = document.getElementsByClassName("invisible");
const HTMLElementsArr = [...myHTMLCollection];
function showMessage() {
if (HTMLElementsArr.length > 0) {
HTMLElementsArr.shift().classList.remove('invisible');
}
}
.invisible {
display: none;
}
<p class="invisible">Some text 1 click</p>
<p class="invisible">Some text 2 clicks</p>
<p class="invisible">Some text 3 clicks</p>
<button onClick="showMessage()">Show a message</button>

jQuery not working on dynamically generated same divs

I am trying to make a comment reply section. I am loading the same div for reply which I use for commenting using $('#1').append($('.enterComment').html()); where 1 is the id of the div which will be displayed when reply is clicked.
.enterComment div contains a hidden submitPost button which will be displayed as soon as the user starts typing comment.
That div is loading properly but The problem for me is that when I loaded the same div in reply section and as I start typing anything in that it only displays the hidden div in the main comment div and not in the reply one.
My html is
<div class="enterComment">
<form id="insertComment">
<textarea name="comment" placeholder="comment here..."></textarea>
<div id="commentOptions">
<button type="button" class="btn btn-primary btn-sm">Comment</button>
</div>
</form>
</div>
For reply I have
<ul class="commentList">
<li>
<div class="commentData" id="1">
<p>The comment content will go here</p>
<p><span class="reply">Reply</span> <i class="fa fa-thumbs-up" aria-hidden="true" tabindex="1"></i> <i class="fa fa-thumbs-down" aria-hidden="true" tabindex="1"></i> </p>
</div>
</li>
</ul>
and script is
$("body").on('focus', 'textarea', function() {
$('#commentOptions').fadeIn(1000);
});
$("body").on('click', '#1 p .reply', function() {
$('#1').append($('.enterComment').html());
});
You need to fade in the following div of textarea so use .next().
Also, Identifiers in HTML must be unique, hence use CSS class. Here in the example I have used commentOptions CSS class.
$("body").on('focus', 'textarea', function() {
$(this).next('.commentOptions').fadeIn(1000);
});
$("body").on('click', '.commentData p .reply', function() {
var element = $('.enterComment').clone();
element.find('.commentOptions').hide();
$(this).closest('.commentData').append(element);
});
.commentOptions {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="enterComment">
<form id="insertComment">
<textarea name="comment" placeholder="comment here..."></textarea>
<div class="commentOptions">
<button type="button" class="btn btn-primary btn-sm">Comment</button>
</div>
</form>
</div>
<ul class="commentList">
<li>
<div class="commentData" id="1">
<p>The comment content will go here</p>
<p><span class="reply">Reply</span> <i class="fa fa-thumbs-up" aria-hidden="true" tabindex="1"></i> <i class="fa fa-thumbs-down" aria-hidden="true" tabindex="1"></i> </p>
</div>
</li>
</ul>
I've created an answer in one HTML file which works without dependencies apart from the jQuery and Bootstrap which you were using on your example:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style type="text/css">
body{
padding: 10px;
}
.wrapper{
width: 800px;
margin-right: auto;
margin-left: auto;
}
.submit-comment-btn-container {
display: none;
}
</style>
<script type="text/javascript">
$( document ).ready(function() {
$('#comment-textarea').on('focus', function() {
$('.submit-comment-btn-container').fadeIn('fast');
});
$('#submit-comment-btn').on('click', function() {
var text = $('#comment-textarea').val();
if(text != ''){
$('.submit-comment-btn-container').fadeOut();
$('#comment-textarea').val('');
// cloning the first child of the comments to use as a template
var comment = $('.comment-list').children().first().clone();
// replacing the content of the cloned comment with the new text
$(comment).html(text);
// appending the new comment to the comment list
$(comment).appendTo('.comment-list');
}
});
});
</script>
</head>
<body>
<div class="wrapper">
<div class="enterComment">
<form id="insertComment">
<div class="comment-text-container">
<textarea id="comment-textarea" placeholder="Comment here..."></textarea>
</div>
<div class="submit-comment-btn-container">
<button id="submit-comment-btn" type="button" class="btn btn-primary btn-sm">Comment</button>
</div>
</form>
</div>
<div class="comment-list-container">
<ul class="comment-list">
<li>
<div class="comment">
Comment goes here
</div>
</li>
</ul>
</div>
</div>
</body>
</html>

How to lower opacity on everything else on screen except the selected ng-repeat item?

I've looked everywhere on StackOverflow and there doesn't seem to be anyone else solving this issue or I'm just using the wrong wording or keywords which results in me not finding what I want. If that's the case and this is a duplicate, I would be glad if you could link me to a case like this. Thanks.
I have an HTML/CSS, AngularJS, PHP and MySQL project.
POST and GET requests work perfectly.
What I'm trying to do is similar to what is already done on Google Keep.
When the user clicks on the blue pencil, I want the opacity on the selected item to be 100% but all the parents divs and sibling divs at opacity value 0.3 or something.
I would like to try and avoid jQuery if possible.
I believe I read somewhere that it is bad practice to use a whole bunch of frameworks together and that when you use a framework, that you should stick with it.
I have no idea how to approach this problem.
I don't even know where to start.
Could you please also provide me with a working example JSFiddle or Plnkr please?
Any help or suggestion would be greatly appreciated!
Thanks in advance!
What I want
What I have
HTML
<body ng-app="myApp">
<font face="Source Sans Pro">
<div class="left">
<center>
<div ng-controller="insertController">
<h2> What I learned today </h2>
<form>
Date <br>
<input type="text" ng-model="date"><br><br>
Content <br>
<textarea rows="10" cols="50" ng-model="content"></textarea><br><br>
<input type="button" value="Submit" ng-click="insertdata()">
</form>
</div>
</center>
</div>
<div class="right">
<center>
<div ng-controller="fetchController"><br>
<span ng-repeat="item in results">
<div class="card">
<div class="theText">
<span class="bold-underline">{{item.date}}</span><br>
{{item.content}}
</div>
<div ng-controller="deleteController">
<input type="button" class="deleteButton" ng-click="deleteThisItem(item)" value="x">
</div>
<div ng-controller="editController">
<input type="button" class="editButton" ng-click="editThisItem(item)" value="✎">
</div>
</div>
<br><br>
</span>
</div>
</center>
</div>
</font>
</body>
EDIT
I just got it working.
New HTML
<div class="right">
<center>
<div ng-controller="fetchController"><br>
<span ng-repeat="item in results">
<div ng-controller="fadeController">
<div class="card" ng-class="cardFade">
<div class="theText">
<span class="bold-underline">{{item.date}}</span><br>
{{item.content}}
</div><!-- theText -->
<div ng-controller="deleteController">
<input type="button" class="deleteButton" ng-click="deleteThisItem(item)" value="x">
</div><!-- deleteController -->
<div ng-controller="editController">
<input type="button" class="editButton" ng-click="editThisItem(item)" value="✎">
</div><!-- editController -->
</div><!-- card -->
</div><!-- fadeController -->
<br>
</span><!-- ng-repeat -->
<div class="overlay"></div>
</div><!-- fetchController -->
</center>
</div><!-- right -->
New CSS
.someCSS {
background-color: white;
z-index: 200;
opacity: 1;
}
.noCSS {
}
.overlay {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: black;
opacity: 0.6;
z-index: 100;
pointer-events: none; /* required to be able to click buttons under overlay */
}
fadeController.js
app.controller("fadeController", function($scope, $http, resultsService) {
$scope.cardFade = "noCSS";
$scope.editThisItem = function(item) {
if($scope.cardFade === "noCSS") {
$scope.cardFade = "someCSS";
}
else if($scope.cardFade === "someCSS") {
$scope.cardFade = "noCSS";
}
else {
alert("FATAL ERROR!");
}
};
});
you can add a div as overlay
<div class="overlay"></div>
.overlay {
backgound-color: gray;
opacity: 0.5;
z-index: 100; //<= so the overlay with cover the page
}
next you will need to add a css class like this
.someCss {
z-index: 101; // <=so it would be on top on the overlay
}
and it will be added to the ng-repeat element when you click on the blue pencil.
I would even go and make the class as ng-class ng-class
so it would be something like this:
<span ng-repeat="item in results">
<div class="card" ng-class="{someCss : item.selected}">
<div class="theText">
<span class="bold-underline">{{item.date}}</span><br>
{{item.content}}
</div>
<div ng-controller="deleteController">
<input type="button" class="deleteButton" ng-click="deleteThisItem(item)" value="x">
</div>
<div ng-controller="editController">
<input type="button" class="editButton" ng-click="editThisItem(item)" value="✎">
</div>
</div>
<br><br>
</span>
and now on the blue pencil click you can add the property selected or change it

HTML Page search

I have a very long html file (20K+ lines) and I want to have a search that will find the search term and then scroll to the li class="page" data-name="XX". If more than one instance of the term is found we need a "next" result button.
Here is an excerpt from my HTML file I want to search:
<li class="page" data-name="11">
<div class="pageResizer" style="width:640px;height:960px;"> </div>
<div id="item690" class="pageItem" alt="Rectangle"> </div>
<div id="item728" class="pageItem" alt="Rectangle"> </div><button class="pageItem" alt="Home" id="item1426" data-id="1426" onclick="nav.to(5);"> </button><button class="pageItem" alt="prevBtn" id="item1423" data-id="1423" onclick="nav.back(this);"> </button><button class="pageItem" alt="nextBtn" id="item2550" data-id="2550" onclick="nav.next(this);"> </button><img src="assets/images/blank.gif" class="pageItem" alt="Rectangle" style="left:491px;top:11px;" data-src="assets/images/item_2757.png"/>
<div id="item2788" class="pageItem singleline" alt="Lafayette Chamber">
<p class="autoParaStyle1">Lafayette Chamber</p>
</div><button class="pageItem" alt="Share" id="item3136" data-id="3136"> </button>
<a href="javascript:nav.to(2);"><button class="pageItem" alt="Help" id="item2977" data-id="2977" onclick="nav.to(2);"> </button>
</a><img src="assets/images/blank.gif" class="pageItem" alt="Rectangle" style="left:1px;top:66px;" data-src="assets/images/item_4899.jpg"/><img src="assets/images/blank.gif" class="pageItem" alt="Rectangle" style="left:1px;top:707px;" data-src="assets/images/item_4901.jpg"/>
<div id="item4906" class="pageItem singleline" alt="lafayETTE ">
<p class="autoParaStyle13">lafayETTE<br />
</p>
</div>
<div id="item4937" class="pageItem singleline" alt="HISTORY">
<p class="autoParaStyle14">HISTORY</p>
</div>
<div id="item4982" class="pageItem" alt=" little more than a century ago, the first pioneers trickled into this region after a long journey across the Great P...">
<p class="Article-Body"> <span class="autoCharStyle5">little more than a century ago, the first pioneers trickled into this region after a long journey across the Great Plains. The gold rush attracted more and more adventurous fortune seekers who were closely followed by other settlers. The honeymoon of Lafayette and Mary E. Miller was spent crossing the plains and arriving in the Boulder region. In 1863, they started farming the Burlington (Longmont) area and soon moved south and settled in the present site of Lafayette. Lafayette Miller was an industrious man and besides farming, he operated the stage stop and ran several meat markets. His sudden death in 1878 left Mary Miller with six small children to raise. She did this and more…she raised a town!<br /></span> </p>
<p class="autoParaStyle8"><br /></p>
</div>
<div id="item27143" class="pageItem singleline" alt="A">
<p class="autoParaStyle15">A</p>
</div>
Here is the code I have so far:
<script>
function search() {
var name = document.getElementById("searchForm").elements["searchItem"].value;
var pattern = name.toLowerCase();
var targetId = "";
var divs = document.getElementsByClassName("page");
for (var i = 0; i < divs.length; i++) {
var para = divs[i].getElementsByTagName("p");
var index = para[0].innerText.toLowerCase().indexOf(pattern);
if (index != -1) {
targetId = divs[i].parentNode.id;
document.getElementById(targetId).scrollIntoView();
break;
}
}
}
</script>
<form id="searchForm" action="javascript:search();">
<div class="input-group">
<button id="go" type="button"
onclick="document.getElementById('searchForm').submit(); return false;">
Search</button>
<input type="text" id="searchItem" class="form-control" placeholder="Search" cols="50" rows="2">
</div>
</form>
Not sure what I need to do to my code to make this work and don't have a clue how to make a "next result" button.
I think this is what you are looking for:
HTML:
<body>
<form id="searchForm" action="javascript:search();" class="form">
<button id="nextButton" onclick="nextItem()" type="button" class="make-invisible">NEXT</button>
<div class="input-group">
<button id="go">Search</button>
<input type="text" id="searchItem" name="searchItem" class="form-control" placeholder="Search" cols="50" rows="2">
</div>
</form>
<ul>
<li class="page" data-name="foo">Has data-name = foo</li>
<li class="page" data-name="foo">Has data-name = foo</li>
...
</ul>
</body>
JavaScript:
var selectedItems;
var currentlySelectedItem;
var makeInvisibleClassName = "make-invisible";
var nextButton = document.querySelector("#nextButton");
function search() {
makeInvisible();
var searchPhrase = document.querySelector("#searchItem").value;
selectedItems = document.querySelectorAll(".page[data-name='" + searchPhrase + "']");
if (selectedItems.length === 0) {
return;
}
if (selectedItems.length > 1) {
makeVisible();
}
currentlySelectedItem = 0;
nextItem();
}
function nextItem() {
selectedItems[currentlySelectedItem].scrollIntoView();
currentlySelectedItem++;
if (currentlySelectedItem >= selectedItems.length) {
currentlySelectedItem = 0;
}
}
//////////
function makeInvisible() {
nextButton.classList.add(makeInvisibleClassName);
}
function makeVisible() {
nextButton.classList.remove(makeInvisibleClassName);
}
CSS:
.form {
position: fixed;
left: 0;
top: 0;
display: flex;
flex-direction: row;
justify-content: center;
width: 100%;
}
#nextButton {
margin-right: 10px;
}
.make-invisible {
display: none;
}
Here is the working Demo
Ok, let me explain what I did here.
When you have a form you don't actually need to this:
<button id="go" type="button" onclick="document.getElementById('searchForm').submit(); return false;">
Instead you can go very simple:
<button id="go">Search</button>
The default button type in a form is type="submit" which automatically triggers the event specified in the action attribute.
The next thing is the NEXT button. I hard-coded it and in order to show it and hide it, I will add or remove class make-invisible. Notice the button is invisible at the beginning. It also has a click event which will trigger nextItem()
<button id="nextButton" onclick="nextItem()" type="button" class="make-invisible">NEXT</button>
I also made 2 global variables: selectedItems, which will store the array of selected items and currentlySelectedItem that has the index of currently scrolled to item.
The search() function gets all elements that has the class name page and has attribute data-name with specified word. Then it checks if there is more then one result. If so, it makes the button visible.
The nextItem() function scrolls into selected element, and raises index by one. If the index value if bigger then there is matching elements, it will start a loop.

Categories

Resources