I'm new at programming and not experienced with JavaScript and I have an assignment to do for my school. I need to create a word search game, that has a form/button search that finds a word and highlights it in the grid. I have created the HTML/CSS layout, but I'm stuck linking it to JavaScript. I want to be able to search for the words "BANGKOK", "LONDON", "SINGAPORE", "HAVANA" AND "KYOTO", but I'm only able to search/highlight one letter/cell of the grid and I don't know how to make a string out of the letters from the grid so I could find those words. I'm stuck here. Really trying to understand. Can someone please help me/guide/explain to me how does it work? I have read a lot of things, but can't seem to find what I'm looking for. I would really appreciate it. I also need the highlighted word to stay highlighted, when it is found.
Here is what I have so far: https://jsfiddle.net/fwg8hequ/10/
function search() {
var text = document.getElementById("query").value;
var query = new RegExp("(\\b" + text + "\\b)", "gim");
var e = document.getElementById("searchtext").innerHTML;
var enew = e.replace(/(<span>|<\/span>)/igm, "");
document.getElementById("searchtext").innerHTML = enew;
var newe = enew.replace(query, "<span>$1</span>");
document.getElementById("searchtext").innerHTML = newe;
}
@charset "UTF-8";
/* CSS Document */
@font-face {
font-family: 'RobotoSlab';
src: url('RobotoSlab-bold.ttf');
}
@font-face {
font-family: 'RobotoMono';
src: url('RobotoMono-Regular.ttf');
}
.container {
position: relative;
width: 1000px;
height: 800px;
background: #ffcc78;
}
.header {
position: absolute;
left: 24.7%;
right: 26%;
top: 5.25%;
bottom: 86.75%;
overflow: auto;
}
.header img {
width: 58px;
height: 58px;
left: 247px;
top: 46px;
float: left;
}
.header h1 {
left: 33.8%;
right: 28.4%;
width: 378px;
height: 64px;
font-family: RobotoSlab;
font-style: normal;
line-height: normal;
font-size: 48px;
letter-spacing: -1px;
color: #E25C5C;
line-height: 5.28%;
float: right;
}
form {
position: absolute;
left: 24.7%;
right: 26%;
top: 18.75%;
bottom: 75%;
}
input[type=text] {
float: left;
left: 24.7%;
right: 35.8%;
top: 18.75%;
bottom: 75%;
width: 410px;
height: 50px;
background: #FFFFFF;
border: 1px solid #417505;
box-sizing: border-box;
border-radius: 5px;
}
button {
position: absolute;
left: 66.5%;
right: 27.3%;
top: 18.75%;
bottom: 75%;
background: linear-gradient(180deg, #76AD0C 0%, #417505 100%);
border-radius: 5px;
font-family: RobotoSlab;
font-style: normal;
line-height: normal;
font-size: 15px;
color: #FFFFFF;
float: right;
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
background-color: #E25C5C;
position: absolute;
left: 24.7%;
right: 26%;
top: 30.5%;
bottom: 7.88%;
padding: 2px;
border-radius: 5px;
}
.grid-item {
background-color: #ffcc78;
border: 2px solid #E25C5C;
left: 26.2%;
right: 27.2%;
font-family: RobotoMono;
line-height: 36px;
font-size: 36px;
letter-spacing: 2.9px;
font-style: normal;
font-weight: normal;
text-align: center;
padding: 2px;
}
#searchtext span {
background-color: #F5A623;
}
<div class="container">
<div class="header">
<img src="icon.png" alt="Icon" height="58" width="58">
<h1>WORD SEARCH</h1>
</div>
<form>
<input name="query" id="query" type="text">
</form>
<button type="button" onClick="search();">SEARCH</button>
<div class="grid-container" id="searchtext">
<div class="grid-item">W</div>
<div class="grid-item">S</div>
<div class="grid-item">I</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">C</div>
<div class="grid-item">E</div>
<div class="grid-item">O</div>
<div class="grid-item">I</div>
<div class="grid-item">V</div>
<div class="grid-item">V</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">B</div>
<div class="grid-item">A</div>
<div class="grid-item">N</div>
<div class="grid-item">G</div>
<div class="grid-item">K</div>
<div class="grid-item">O</div>
<div class="grid-item">K</div>
<div class="grid-item">U</div>
<div class="grid-item">T</div>
<div class="grid-item">L</div>
<div class="grid-item">O</div>
<div class="grid-item">N</div>
<div class="grid-item">D</div>
<div class="grid-item">O</div>
<div class="grid-item">N</div>
<div class="grid-item">O</div>
<div class="grid-item">I</div>
<div class="grid-item">U</div>
<div class="grid-item">S</div>
<div class="grid-item">I</div>
<div class="grid-item">N</div>
<div class="grid-item">G</div>
<div class="grid-item">A</div>
<div class="grid-item">P</div>
<div class="grid-item">O</div>
<div class="grid-item">R</div>
<div class="grid-item">E</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">C</div>
<div class="grid-item">O</div>
<div class="grid-item">G</div>
<div class="grid-item">E</div>
<div class="grid-item">E</div>
<div class="grid-item">U</div>
<div class="grid-item">V</div>
<div class="grid-item">R</div>
<div class="grid-item">H</div>
<div class="grid-item">A</div>
<div class="grid-item">V</div>
<div class="grid-item">A</div>
<div class="grid-item">N</div>
<div class="grid-item">A</div>
<div class="grid-item">T</div>
<div class="grid-item">L</div>
<div class="grid-item">A</div>
<div class="grid-item">A</div>
<div class="grid-item">A</div>
<div class="grid-item">B</div>
<div class="grid-item">I</div>
<div class="grid-item">S</div>
<div class="grid-item">S</div>
<div class="grid-item">N</div>
<div class="grid-item">O</div>
<div class="grid-item">R</div>
<div class="grid-item">I</div>
<div class="grid-item">S</div>
<div class="grid-item">N</div>
<div class="grid-item">K</div>
<div class="grid-item">Y</div>
<div class="grid-item">O</div>
<div class="grid-item">T</div>
<div class="grid-item">O</div>
<div class="grid-item">A</div>
<div class="grid-item">H</div>
<div class="grid-item">B</div>
<div class="grid-item">E</div>
<div class="grid-item">Z</div>
<div class="grid-item">M</div>
<div class="grid-item">P</div>
<div class="grid-item">T</div>
<div class="grid-item">R</div>
<div class="grid-item">E</div>
<div class="grid-item">S</div>
<div class="grid-item">J</div>
<div class="grid-item">R</div>
<div class="grid-item">L</div>
<div class="grid-item">F</div>
<div class="grid-item">P</div>
<div class="grid-item">E</div>
<div class="grid-item">K</div>
<div class="grid-item">T</div>
<div class="grid-item">A</div>
<div class="grid-item">M</div>
<div class="grid-item">L</div>
<div class="grid-item">O</div>
<div class="grid-item">J</div>
</div>
</div>
Let's try and decompose what your search function does:
So first you're extracting html code and trying to find text in this html code. But since you keep most of the tags (you only remove spans), you wont be able to find text only in the content of your divs (your search will be polluted with the div tags themselves).
We could do complicated things with replace but there has to be another way.
Let's now decompose the problem at hand: we would like to write a function that highlights the searched word in the grid according to the rules of this search word game (horizontaly, verticaly diagonaly).
There is no builtin javascript function to do that so we have to split the problem.
we can solve getSearchedWord:
Now in highlightText we need to find a word, that is being able to read letters given positions in the grid, compare them to the searched text, keep the list of the positions if the word is found and highlight these positions.
A position in the grid can be seen as coordinates x (index of the column of the letter), and y (index of the row of the letter).
In javascript we can define structured objects with braces
{}
so for instance the position 0,0 (first letter of the first row of the grid) will be{ x: 0, y: 0}
The first letter of your grid is in the first div (.grid-item) of your grid. Javascript gives you ways to retrieve elements based on their class name.
Documentation of getElementsByClassName
So we are able to list all your grid elements by writing
var items= document.getElementsByClassName('grid-item');
Lets define the function
getItems
:From this we can easily derive a new function:
with posToIndex being:
I'm going faster here to limit the size of the answer but the comments should help.
A way to highlight a position could be helpful too:
First define a css class doing the highlight (it easier to add or remove a class from an element than to wrap/unwrap its content in a span):
css:
Then javascript helper functions
js:
References:
split, indexOf and splice
Now to read words in the grid we have to find at least the positions of first letter of the searched text and then try to match each letters of the searched text:
with indexToPos being define as the reverse operation of posToIndex (takes an index, returns a pos):
For each found position we will need to try and match each letters of the searched text starting at this position and in a specified direction. For instance to the right (given the initial position of the first letter):
To sum it up the function to call when clicking the search button could be:
Fully working solution as a fiddle here
If you do want to understand programming I hope you'll appreciate this answer demonstrating how programing is mostly about splitting big problems into smaller problems until the problems are easily solvable (and understood) by the tools given by the language itself.
It was fun for me anyway! Cheers
(PS: as stated by Evochrome in the comments below the two helper functions addClass and removeClass are already solved by plain js this way
element.classList.add("mystyle")
andelement.classList.remove("mystyle")
)