I have a div with a list of words from a file. I need help getting rid of the whitespace in the box using the CSS code below. Is it a margin error? I haven't text aligned to the centre either. I can't seem to figure out the CSS error. I'm hoping to keep the dimensions of the box the same just the words to fit in from the left but text-align: left doesn't solve it either. Please Help!
I reviewed your code and your list items were ul's so I changed them to li's and changed the parent ol to a ul and then styled list style none and removed the padding then fixed the width a bit.
The html won't be very responsive due to static widths so you might want to work more on that but I've fixed the issue you described.
#app {
display: table;
height: 80%;
font-size: 16px;
border: 1px solid black;
margin: 15px;
background: lightgray;
}
.search-header {
display: inline-flex;
}
#item-list {
height: 350px;
overflow: scroll;
border: 1px solid gray;
margin-left: 55px;
width: 240px;
background-color: white;
list-style: none;
padding: 0;
}
.search-text {
white-space: normal;
margin-left: 20px;
margin-right: 10px;
margin-top: 20px;
font-size: 15px;
height: 15px;
}
.search-box {
height: 15px;
width: 400px;
}
#search-box[placeholder] {
line-height: 20px;
font-size: 15px;
}
.allButtons{
height: 25px;
margin-left: 10px;
margin-top: 10px;
margin-right: 10px;
}
<!DOCTYPE html>
<html>
<head>
<title>JS search filter</title>
</head>
<body>
<div id="app">
<div class="search-header">
<div class="search-text"> Find:
<input id="search-box" />
<button type="button" class="allButtons" span onclick="var input = this.previousElementSibling; input.value = ''; input.focus();"> Clear </button></span>
</div>
</div>
<div>
<ul id="item-list"></ul>
</div>
</div>
</body>
<script type="text/javascript">
var itemList = [
"a",
"able",
"about",
"account",
"acid",
"across",
"act",
"addition",
"adjustment",
"advertisement",
"after",
"again",
"against",
"agreement",
];
const itemContainer = document.getElementById("item-list");
const searchInput = document.getElementById("search-box");
// Trigger function every time search text is changed
searchInput.onkeyup = (event) => {
filterBySearch(event.target.value);
};
// String to render HTML list item
const itemHTML = (item) => `<li>${item}</li>`;
// Function to render filtered list
const filterBySearch = (query = "") => {
var renderHTML = ``;
// Generate HTML for filtered List
itemList.forEach((item) => {
if (item.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
renderHTML += itemHTML(item);
}
});
// Display updated HTML on screen
itemContainer.innerHTML = renderHTML;
};
// Load the list of items
filterBySearch();
</script>
</html>
Related
Situation: I'm trying to create a dynamic input box where I can add words to a box to have them display individually in bubbles. To build up to that, I'm trying to have a div container ( ) side by side with an input field (), so when a user adds an element it drops it in the div container displaying both side by side. If you're confused on what I'm trying to achieve I posted a jsfiddle for reference.
My Issue: When I add an element to the div container, it expands the size of the container past the maximum size I tried to allocate for it. I set a specific size to the parent div containing everything. I think my issue lies in that, using width=100% for the input box references the parent div which does not change despite adding new elements side by side. How can I make the input text box dynamically resize itself to fill in the left over space and no more?
My goal: Figure out how to make the input box dynamically resize to fit the parent container when sibling elements are added side by side to it.
Any help would be greatly appreciated.
Code Snippet:
$('.emotionsInput').keypress(function (e) {
var key = e.which;
if (key == 13)
{
var inputWord = $(this).val();
var currentCell = $(this);
createTag(currentCell);
}
})
function createTag(currentCell)
{
var parentCell = currentCell.parent()
var inputWord = currentCell.val();
currentCell.val("");
var newTagHTML = '<span class="emotionTag">' + inputWord + '</span>';
parentCell.children(".emotionTagsDiv").append(newTagHTML);
}
#testTagBox > span > span {
border-color:transparent;
box-shadow:0 0 0 2px #000;
border-radius: 40px;
padding:5px;
background-color: white;
width: 100%;
display:flex; /* changed this here, it was inline*/
}
#testTagBox > span {
padding: 0.67rem 0.5rem;
width: 100%;
display:flex; /* changed this here, it was inline-block */
}
#testTagBox {
width: 30rem;
padding-right:1.8rem;
}
.emotionsDiv {
display: flex; /* changed this here, it was inline-block */
width: 100%;
white-space: nowrap;
}
.emotionTagsDiv {
flex: 1 1 auto; /* added this here */
white-space: nowrap;
}
.emotionTag {
display: inline-block;
padding-right: 1em;
}
input {
font-family: Arial;
display: flex; /* changed this here */
flex: 20 1 auto; /* added this so that it prioritizes shrinking this element.*/
width: 100%;
}
input:focus {
outline: none;
}
<html lang="en">
<body>
<div id="testTagBox">
<span>
<span>
<div class="emotionsDiv">
<div class="emotionTagsDiv">
</div>
<input class="emotionsInput" placeholder="type and press enter here" type="text" value="">
</div>
</span>
</span>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/#popperjs/core#2/dist/umd/popper.min.js"></script>
<script src="https://unpkg.com/tippy.js#6/dist/tippy-bundle.umd.js"></script>
<script src="testapp.js" type="text/javascript" ></script>
</body>
</html>
As you can see, when you add an element the entire container resizes when I'm trying to make the input box be fixed on the right side and reduce size on the left so the container stays the same size and everything fits in.
Width if the input can be adjusted by changing the display property of .emotionTagsDiv to flex
$('.emotionsInput').keypress(function (e) {
var key = e.which;
if (key == 13)
{
var inputWord = $(this).val();
var currentCell = $(this);
createTag(currentCell);
}
})
function createTag(currentCell)
{
var parentCell = currentCell.parent()
var inputWord = currentCell.val();
currentCell.val("");
var newTagHTML = '<span class="emotionTag">' + inputWord + '</span>';
parentCell.children(".emotionTagsDiv").append(newTagHTML);
}
#testTagBox > span > span {
border-color:transparent;
padding:5px;
background-color: white;
width: 100%;
}
#testTagBox > span {
padding: 0.67rem 0.5rem;
width: 100%;
}
#testTagBox {
max-width: 30rem;
padding-right:1.8rem;
}
.emotionsDiv {
display: flex;
width: 100%;
box-shadow:0 0 0 2px #000;
padding: .5rem;
border-radius: 40px;
}
.emotionTagsDiv {
display: inline-block;
white-space: nowrap;
}
.emotionTag {
display: inline-block;
padding-right: 1em;
}
input {
/* border-style: hidden; */
font-family: Arial;
display: inline-block;
width: 100%;
min-width: 50px;
}
input:focus {
outline: none;
}
<html lang="en">
<body>
<div id="testTagBox">
<span>
<span>
<div class="emotionsDiv">
<div class="emotionTagsDiv">
</div>
<input class="emotionsInput" placeholder="type and press enter here" type="text" value="">
</div>
</span>
</span>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/#popperjs/core#2/dist/umd/popper.min.js"></script>
<script src="https://unpkg.com/tippy.js#6/dist/tippy-bundle.umd.js"></script>
<script src="testapp.js" type="text/javascript" ></script>
</body>
</html>
So, i am having an issue with a div, when another div is generated (via javascript) below it, it is changing the size of the div.
// for the side nav message list
const chatList = function(list) {
let br = document.createElement("br")
for (let index in list) {
try {
let chat = list[index]
let chatBodyParent = document.createElement("div")
chatBodyParent.onclick = function() {
$("#message-list").empty()
api.listMessages(chat.chat.id)
document.getElementById("message-list").channelId = chat.chat.id
}
chatBodyParent.id = `chat-body-${chat.chat.id}`
let chatBody = document.createElement("div")
chatBody.className = "chat-body"
let chatImg = document.createElement("img")
chatImg.src = chat.chat.cover
if (!chat.chat.cover && chat.chat.type == 1) {
chatImg.src = "/dump/pfp.svg"
}
if (!chat.chat.cover && chat.chat.type == 3) {
chatImg.src = "/dump/public.png"
}
chatImg.className = "chat-img"
chatImg.setAttribute("align", "left")
chatBody.appendChild(chatImg)
let chatInfoContainer = document.createElement("div")
chatInfoContainer.className = "chat-info-container"
let chatName = document.createElement("span")
chatName.className = "chat-name"
chatName.innerText = chat.chat.title
chatInfoContainer.appendChild(chatName)
chatInfoContainer.appendChild(br.cloneNode(true))
let chatMessageContent = document.createElement("span")
chatMessageContent.className = "chat-message-content"
chatMessageContent.id = `chat-message-content-${chat.chat.id}`
let messageContent
if (chat.message) {
let long = false;
if (chat.message.text.length >= 30) {
long = true
}
messageContent = chat.message.text.substring(0, 30)
if (long) {
messageContent += "..."
}
} else if (chat.type == "file") {
messageContent = chat.user.nick + " sent a file"
}
chatMessageContent.innerText = messageContent
chatInfoContainer.appendChild(chatMessageContent)
chatBody.appendChild(chatInfoContainer)
chatBodyParent.appendChild(chatBody)
document.getElementById("chat-list").appendChild(chatBodyParent)
} catch {
console.log(list[index])
}
}
}
.sidenav {
height: 100%;
width: 15%;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: var(--lightish-grey);
overflow-x: hidden;
padding-top: 20px;
}
.sidenav a {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
}
.sidenav a:hover {
color: #f1f1f1;
}
.main {
margin-left: 15%;
padding: 0px 10px;
overflow-x: hidden;
}
#media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}
::-webkit-scrollbar {
color: var(--grey);
}
::-webkit-scrollbar-corner {
color: var(--grey);
}
::-webkit-scrollbar-track {
color: var(--grey);
}
.menu {
width: 90%;
min-width: 90%;
height: 200px;
margin-left: 5%;
margin-right: 5%;
background-color: var(--menu-grey);
padding-top: 10px;
padding-bottom: 5px;
font-family: "FontRegular";
}
.chat-bar {
position: fixed;
bottom: 1%;
width: 50%;
height: 3.5%;
padding: 0px 5px;
margin: 8px 0;
display: inline-block;
border-top: hidden;
border-left: hidden;
border-right: hidden;
border-bottom: solid var(--light-grey);
box-sizing: border-box;
background-color: var(--grey);
color: var(--light-grey);
font-family: "FontRegular";
}
.chat-bar:focus {
outline-width: 0;
}
.chat-body {
width: 90%;
height: 50px;
margin-left: 5%;
border: 3px;
border-top: hidden;
border-left: hidden;
border-right: hidden;
/*border-bottom: solid var(--light-grey);*/
padding-top: 10px;
padding-bottom: 5px;
font-family: "FontRegular";
}
.chat-body:hover {
opacity: 0.8;
cursor:pointer;
}
.chat-body:focus {
opacity: 0.8;
}
.chat-img {
height: 50px;
width: auto;
border-radius: 50%;
}
.chat-info-container {
position:relative;
top: 10%;
}
<!DOCTYPE html>
<html>
<head>
<title>iFChat - Dashboard</title>
<link rel="stylesheet" href="/css/index.css">
<link rel="stylesheet" href="/css/dashboard.css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="/js/utils.js"></script>
<script type="text/javascript" src="/js/api.js"></script>
<script type="text/javascript" src="/js/dashboard.js"></script>
</head>
<div class="sidenav">
<div id="menu" class="menu">
</div>
<div>
</div> <br><br>
<div id="chat-list">
</div>
</div>
<div class="main" id="main">
<div id="message-list" class="message-list">
</div>
<input type="text" name="chat..." id="chat-bar" class="chat-bar" placeholder="chat..." maxlength="500">
</div>
</html>
Here is an image before the chat list is loaded
Then menu is loaded with the correct size and margin
pre-load
after the chat list loads, it changes the width or margin of the div above some how, and im not sure how or why its doing that, but i cant figure it out, heres an image of after the chat list is loaded post-load
i have tried different margins and positioning settings but cant seem to get it to work, any help is greatly appreciated :)
edit: One possible solution may be to change the css with javascript every time the chat list is loaded, but i would like to avoid that if at all possible.
OK, so i figured out the issue, the issue occurs when enough elements pop up to trigger the scrollbar, so the fix for me was this
::-webkit-scrollbar {
display: none;
}
Because i want a user to beable to scroll, but i dont want there to be a scrollbar, My next plan is to make this static, so that it doesnt move on scroll at all. Still the issue was arising when my (invisible scroll bar, that still had a width) was appearing. Gotta watch out for hidden elements.
First of all i want to point out that i saw that there are similar posts about tracking event listeners but in my case i just couldn't figure it out. I am familliar with event.target property but in my case i just couldn't make it.
So this is my code snippet:
const taskListSection = document.querySelector('.task-list-section');
const taskListAddModal = document.querySelector('.task-list-add-modal');
const confirmTaskAddBtn = document.getElementById('add-list');
const cancelTaskAddBtn = document.getElementById('cancel-add-list');
const addTaskBtn = document.getElementById('add-task');
const titleInput = document.getElementById('title');
const descriptionInput = document.getElementById('description');
const timeInput = document.getElementById('time');
const clearUserInput = () => {
titleInput.value = '';
descriptionInput.value = '';
timeInput.value = '';
};
const taskListAddModalHandler = () => {
const taskList = taskListSection.querySelectorAll('li');
taskListAddModal.classList.toggle('visible');
addTaskBtn.classList.toggle('visible');
taskList.forEach((list) => {
list.classList.toggle('visible');
});
clearUserInput();
};
const confirmAddTask = () => {
const newTask = document.createElement('li');
const taskList = taskListSection.querySelectorAll('li');
const titleInputValue = titleInput.value;
const descriptionInputValue = descriptionInput.value;
const timeInputValue = timeInput.value;
if(titleInputValue.trim() === ''){
alert('Please enter a title of your task!');
return;
}
newTask.className = 'visible';
newTask.innerHTML =
`<button class="check-task">C</button>
<button class="remove-task">X</button>
<h4>Title:</h4>
<p>${titleInputValue}</p>
<h4>Description:</h4>
<p>${descriptionInputValue}</p>
<h4>Time:</h4>
<p>${timeInputValue}</p>`;
taskListSection.append(newTask);
taskListAddModal.classList.remove('visible');
taskList.forEach((list) => {
list.classList.add('visible');
});
addTaskBtn.classList.toggle('visible');
clearUserInput();
};
addTaskBtn.addEventListener('click', taskListAddModalHandler);
cancelTaskAddBtn.addEventListener('click', taskListAddModalHandler);
confirmTaskAddBtn.addEventListener('click', confirmAddTask);
body{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main-wrapper{
width: 70rem;
margin: 0 auto;
border: 2px solid black;
position: relative;
}
.main-wrapper #add-task{
display: none;
}
.main-wrapper #add-task.visible{
position: absolute;
top: 150px;
right: 100px;
width: 50px;
height: 50px;
font-size: 50px;
display: flex;
justify-content: center;
align-items: center;
}
ul{
border: 1px solid black;
width: 40rem;
height: 40rem;
margin: 10rem auto;
padding: 0;
background-color: red;
overflow-x: scroll;
}
ul form{
flex-direction: column;
width: 100%;
height: 40rem;
background-color: white;
display: none;
}
ul form input[type=button]{
display: block;
margin: 10px auto;
}
ul form.visible{
display: flex;
}
ul li{
display: none;
}
ul li.visible{
display: block;
width: 80%;
list-style: none;
border: 2px solid black;
margin: 10px;
position: relative;
}
ul li .check-task{
position: absolute;
width: 30px;
height: 30px;
top: 30px;
right: 30px;
}
ul li .remove-task{
position: absolute;
width: 30px;
height: 30px;
bottom: 30px;
right: 30px;
}
ul li.checked{
background-color: green;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section class="main-wrapper">
<button id="add-task" class="visible">+</button>
<ul class="task-list-section">
<form class="task-list-add-modal">
<label for="title">Title:</label>
<input type="text" id="title">
<label for="description">Description:</label>
<textarea type="text" id="description" maxlength="100"></textarea>
<label for="time">Time:</label>
<input type="text" id="time">
<div class="to-do-list-confirmation">
<input type="button" id="add-list" value="ADD">
<input type="button" id="cancel-add-list" value="CANCEL">
</div>
</form>
</ul>
</section>
<script src="app.js"></script>
</body>
</html>
I have a problem to track which button 'C' on which 'li' element was clicked. So the logic behind this would be that when i click on 'C' button on certain li element that was created i want THAT 'li' element to get class named 'checked' (class 'checked' will provide green background to that 'li' element). You create 'li' element by clicking a "+" button on your top right corner than filling input elements and then by clicking ADD button. Sorry about lousy design i made it really fast just to try and explain what is my problem. I would like you to give me solution using pure JS. Thanks in advance.
Since you asked for an example, the following example is simplified to show how you can use an event parameter in your handler function to be used on the element that is being triggered in your listener. This is over simplified to show you how it is done. You will need to apply this functionality to your code, it is rather easy once you understand the concept.
Further notes in the code snippit below...
// here I am querying all the buttons in the dom
let el = document.querySelectorAll("button");
// I am running them through a loop and applying an event listner with a handler function on click
for(let i = 0; i < el.length; i++){
el[i].addEventListener('click', handler);
}
// the function passes a parameter "event" => e.
// we use the e.target to get the element being pressed
// I use a data attribute in the element being pressed
// to locate an id and affect its background color
function handler(e){
let handler = e.target.getAttribute("data-handler");
let target = document.getElementById(handler);
target.style.backgroundColor = '#d4d4d4';
}
<div id="one">Div One</div>
<div id="two">Div Two</div>
<div id="three">Div Three</div>
<div id="four">Div Four</div>
<button data-handler="one">This btn handles div one</button>
<button data-handler="two">This btn handles div two</button>
<button data-handler="three">This btn handles div three</button>
<button data-handler="four">This btn handles div four</button>
Yeah my problem was that my 'li' elements were not premade so to say, like in your example. They were created with JS so i couldnt figure out how to 'connect' button and his li element and then use target property (like you did with data-handler and id of div element). But i found a way by giving random id to my li element by using Math.random and then i used that same number as data-handler value on my button and then rest was easy. Thanks a lot you gave me a little push so i made it. It works. Here is a code snippet may be useful to someone.
const taskListSection = document.querySelector('.task-list-section');
const taskListAddModal = document.querySelector('.task-list-add-modal');
const confirmTaskAddBtn = document.getElementById('add-list');
const cancelTaskAddBtn = document.getElementById('cancel-add-list');
const addTaskBtn = document.getElementById('add-task');
const titleInput = document.getElementById('title');
const descriptionInput = document.getElementById('description');
const timeInput = document.getElementById('time');
const clearUserInput = () => {
titleInput.value = '';
descriptionInput.value = '';
timeInput.value = '';
};
const taskListAddModalHandler = () => {
const taskList = taskListSection.querySelectorAll('li');
taskListAddModal.classList.toggle('visible');
addTaskBtn.classList.toggle('visible');
taskList.forEach((list) => {
list.classList.toggle('visible');
});
clearUserInput();
};
const confirmAddTask = () => {
const newTask = document.createElement('li');
const taskList = taskListSection.querySelectorAll('li');
const titleInputValue = titleInput.value;
const descriptionInputValue = descriptionInput.value;
const timeInputValue = timeInput.value;
if(titleInputValue.trim() === ''){
alert('Please enter a title of your task!');
return;
}
newTask.className = 'visible';
let newTaskId = newTask.id = Math.random().toString();
newTask.innerHTML =
`<button data-handler = '${newTaskId}' class="check-task">C</button>
<button data-handler = '${newTaskId}' class="remove-task">X</button>
<h4>Title:</h4>
<p>${titleInputValue}</p>
<h4>Description:</h4>
<p>${descriptionInputValue}</p>
<h4>Time:</h4>
<p>${timeInputValue}</p>`;
taskListSection.append(newTask);
taskListAddModal.classList.remove('visible');
taskList.forEach((list) => {
list.classList.add('visible');
});
const checkTaskBtn = document.querySelectorAll('.check-task');
for(const btn of checkTaskBtn){
btn.addEventListener('click', taskCheck);
}
addTaskBtn.classList.toggle('visible');
clearUserInput();
};
const taskCheck = (e) => {
let handler = e.target.getAttribute("data-handler");
let target = document.getElementById(handler);
target.classList.toggle('checked');
}
addTaskBtn.addEventListener('click', taskListAddModalHandler);
cancelTaskAddBtn.addEventListener('click', taskListAddModalHandler);
confirmTaskAddBtn.addEventListener('click', confirmAddTask);
body{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main-wrapper{
width: 70rem;
margin: 0 auto;
border: 2px solid black;
position: relative;
}
.main-wrapper #add-task{
display: none;
}
.main-wrapper #add-task.visible{
position: absolute;
top: 150px;
right: 100px;
width: 50px;
height: 50px;
font-size: 50px;
display: flex;
justify-content: center;
align-items: center;
}
ul{
border: 1px solid black;
width: 40rem;
height: 40rem;
margin: 10rem auto;
padding: 0;
background-color: red;
overflow-x: scroll;
}
ul form{
flex-direction: column;
width: 100%;
height: 40rem;
background-color: white;
display: none;
}
ul form input[type=button]{
display: block;
margin: 10px auto;
}
ul form.visible{
display: flex;
}
ul li{
display: none;
}
ul li.visible{
display: block;
width: 80%;
list-style: none;
border: 2px solid black;
margin: 10px;
position: relative;
}
ul li .check-task{
position: absolute;
width: 30px;
height: 30px;
top: 30px;
right: 30px;
}
ul li .remove-task{
position: absolute;
width: 30px;
height: 30px;
bottom: 30px;
right: 30px;
}
ul li.checked{
background-color: green;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<section class="main-wrapper">
<button id="add-task" class="visible">+</button>
<ul class="task-list-section">
<form class="task-list-add-modal">
<label for="title">Title:</label>
<input type="text" id="title">
<label for="description">Description:</label>
<textarea type="text" id="description" maxlength="100"></textarea>
<label for="time">Time:</label>
<input type="text" id="time">
<div class="to-do-list-confirmation">
<input type="button" id="add-list" value="ADD">
<input type="button" id="cancel-add-list" value="CANCEL">
</div>
</form>
</ul>
</section>
<script src="app.js"></script>
</body>
</html>
I have just found a set of codes that fits my need right now for my blog.
Here I'll attach the code and a glimpse of what it looks like. Although It's still very simple.
What I want to ask is if it's possible to tweak these code possible using JS localstorage, so that it will keep all the saved text even after the user refresh the page, or even better if it stays there even after a user closed the window and reopened it later?
Here's what it looks like right now
and here is the code:
$(document).ready(function(){
var noteCount = 0;
var activeNote = null;
$('.color-box').click(function(){
var color = $(this).css('background-color');
$('notepad').css('background-color', color);
$('#title-field').css('background-color', color);
$('#body-field').css('background-color', color);
})
$('#btn-save').click(function(){
var title = $('#title-field').val();
var body = $('#body-field').val();
if (title === '' && body === '') {
alert ('Please add a title or body to your note.');
return;
}
var created = new Date();
var color = $('notepad').css('background-color');
var id = noteCount + 1;
if (activeNote) {
$('#' + activeNote)[0].children[0].innerHTML = title;
$('#' + activeNote)[0].children[1].innerHTML = created.toLocaleString("en-US");
$('#' + activeNote)[0].children[2].innerHTML = body;
$('#' + activeNote)[0].style.backgroundColor = color;
activeNote = null;
$('#edit-mode').removeClass('display').addClass('no-display');
} else {
var created = new Date();
$('#listed').append('<div id="note' + id + '" style="background-color: ' + color + '"><div class="list-title">' + title + '</div> <div class="list-date">' + created.toLocaleString("en-US") + '</div> <div class="list-text">' + body + '</div> </div>');
noteCount++;
};
$('#title-field').val('');
$('#body-field').val('');
$('notepad').css('background-color', 'white');
$('#title-field').css('background-color', 'white');
$('#body-field').css('background-color', 'white');
});
$('#btn-delete').click(function(){
if (activeNote) {
$('#' + activeNote)[0].remove();
activeNote = null;
$('#edit-mode').removeClass('display').addClass('no-display');
}
$('#title-field').val('');
$('#body-field').val('');
$('notepad').css('background-color', 'white');
$('#title-field').css('background-color', 'white');
$('#body-field').css('background-color', 'white');
});
$('#listed').click(function(e){
var id = e.target.parentElement.id;
var color = e.target.parentElement.style.backgroundColor;
activeNote = id;
$('#edit-mode').removeClass('no-display').addClass('display');
var titleSel = $('#' + id)[0].children[0].innerHTML;
var bodySel = $('#' + id)[0].children[2].innerHTML;
$('#title-field').val(titleSel);
$('#body-field').val(bodySel);
$('notepad').css('background-color', color);
$('#title-field').css('background-color', color);
$('#body-field').css('background-color', color);
})
})
header {
text-align: left;
font-weight: 800;
font-size: 28px;
border-bottom: solid 3px #DEDEDE;
display: flex;
justify-content: space-between;
}
footer {
display: flex;
flex-flow: row-reverse;
padding: 5px 20px;
}
.headers {
margin-top: 20px;
margin-bottom: -10px;
font-size: 20px;
}
#list-head {
margin-left: 2.5%;
width: 30.5%;
display: inline-block;
text-align: center;
}
#note-head {
width: 60%;
margin-left: 5%;
display: inline-block;
text-align: center;
}
noteList {
margin-top: 20px;
display: inline-block;
margin-left: 2.5%;
width: 30.5%;
height: 400px;
overflow: scroll;
border: solid 3px #929292;
border-radius: 5px;
background-color: #DEDEDE;
}
.within-list {
cursor: pointer;
}
.list-title {
font-weight: 600;
font-size: 20px;
padding: 5px 5px 0 5px;
}
.list-date {
font-weight: 200;
font-style: italic;
font-size: 12px;
padding: 0 5px 0 5px;
}
.list-text {
padding: 0 5px 5px 5px;
border-bottom: solid 1px black;
}
notePad {
display: inline-block;
border: solid 3px black;
border-radius: 10px;
height: 400px;
overflow: scroll;
width: 60%;
margin-left: 5%;
margin-top: 0;
}
#note-title {
font-size: 24px;
padding: 0 0 5px 5px;
border-bottom: solid 2px #DEDEDE;
}
#note-body {
padding: 5px;
}
#body-field, #title-field {
width: 100%;
border: none;
outline: none;
resize: none;
}
#title-field {
font-size: 18px;
font-weight: 600;
}
#body-field {
font-size: 14px;
font-weight: 500;
height: 400px;
}
#color-select {
display: flex;
flex-flow: row-reverse nowrap;
padding: 5px 10px 0 0;
}
.color-box {
border: solid 2px #929292;
height: 10px;
width: 10px;
margin-left: 5px;
}
.display {
display: visible;
}
.no-display {
display: none;
}
button {
margin: 5px;
border: solid 3px grey;
border-radius: 10%;
font-size: 22px;
font-weight: 800;
text-transform: uppercase;
color: #DEDEDE;
}
button:hover, .color-box:hover {
cursor: pointer;
}
#listed:nth-child(odd):hover {
cursor: pointer;
}
#btn-save {
background-color: #2F5032;
}
#btn-delete {
background-color: #E41A36;
}
.white {
background-color: white;
}
.orange {
background-color: #FFD37F;
}
.banana {
background-color: #FFFA81;
}
.honeydew {
background-color: #D5FA80;
}
.flora {
background-color: #78F87F;
}
.aqua {
background-color: #79FBD6;
}
.ice {
background-color: #79FDFE;
}
.sky {
background-color: #7AD6FD;
}
.orchid {
background-color: #7B84FC;
}
.lavendar {
background-color: #D687FC;
}
.pink {
background-color: #FF89FD;
}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title></title>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<header>
The Note Machine
<div id='color-select'>
<div class='color-box white'></div>
<div class='color-box orange'></div>
<div class='color-box banana'></div>
<div class='color-box honeydew'></div>
<div class='color-box flora'></div>
<div class='color-box aqua'></div>
<div class='color-box ice'></div>
<div class='color-box sky'></div>
<div class='color-box orchid'></div>
<div class='color-box lavendar'></div>
<div class='color-box pink'></div>
</div>
</header>
<main>
<div class="headers">
<div id="list-head">
<b>Your Notes</b> <i>(click to edit/delete)</i>
</div>
<div id="note-head">
<b>Your Notepad</b>
<span id="edit-mode" class="no-display">
<i> (edit mode) </i>
</span>
</div>
</div>
<noteList>
<div id='listed'>
</div>
</noteList>
<notepad>
<div id="note-title">
<input id="title-field" type="text" placeholder="title your note">
</div>
<div id="note-body">
<textarea id="body-field"></textarea>
</div>
</notepad>
</main>
<footer>
<button id="btn-save">Save</button>
<button id="btn-delete">Delete / Clear </button>
</footer>
</body>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js'></script>
<script type='text/javascript' src='app.js'></script>
</html>
I tried searching in the net for other notepads, but they aren't working on my blog, and here's the one that is finally working. I would really appreciate any kind of suggestions and assistance. T
If all you want to do is save to LocalStorage when save is clicked, then it would be as simple as saving the title and body variables to LocalStorage in the $('#btn-save').click() handler.
Assuming that (as #Nawed Khan guessed) you want to have the note saved without the user having to click save, then you'll want to make three changes:
In the main body of your $(document).ready() function, check for existing LocalStorage values, and if they exist, then set them on your $('#title-field') and $('#body-field') elements.
Add two new change handlers to your $('#title-field') and $('#body-field') elements. When these change handlers fire, get the title and body values from the elements and save them to LocalStorage.
In the $('#btn-save').click() and $('#btn-delete').click() handlers, reset the LocalStorage values of the active note.
You should find these links useful:
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
https://api.jquery.com/change/
P.S. The information stored in LocalStorage can be lost if the user chooses to clear their browser data. If preservation of the data is vital, then implementing a solution using AJAX to connect to a database as #The Rahul Jha suggested would guarantee preservation of the data.
Yes , You can save the data in localStorage and fetch the data on page load. To set the localStorage item add below function in your script which is setting the item on keyup of textarea in localstorage.
$(document).on("keyup","#body-field",function(){
var text = $("#body-field").val();
localStorage.setItem("savedData", text);
});
Add below method to fetch the data from local storage
function loadDataFromLocalStorage(){
if (localStorage.getItem("savedData") !== null) {
$("#body-field").val(localStorage.getItem("savedData"))
}
}
And at last call the above method in $(document).ready() or page load to set the data back in text area after page load.
Put this inside the $(document).ready block:
$(“#title-field”).val(window.localStorage.getItem(“title”) || “”);
$(“#body-field”).val(window.localStorage.getItem(“body”) || “”);
$(“#title-field, #body-field”).change(function() {
var title = $(“#title-field”).val();
var body = $(“#body-field”).val();
window.localStorage.setItem(“title”, title);
window.localStorage.setItem(“body”, body)
})
The 2 first lines will load the text from the localStorage and sets the data on the corresponding inputs
The rest of the code is the part where the data is being saved to localStorage every time the value of #title-field OR #body-field changes.
I'm working on a Q/A bare bones todolist app and notice that when a list item that is really long is added to the list, it pushes the button out.
Is there a way I can make the LI element larger when the textnode hits the button margin instead of pushing the button out of the LI element. Below is a screenshot. I'll post my source code below, but maybe this is a question that is a quick fix?
My source code can be found here - Issue with floating buttons right of my to do list
A) If I understood you well, you can easily fix it with CSS-Grid:
li {
display: grid;
grid-template-columns: 3fr 100px;
grid-template-areas: 'text button';
}
li > span {
grid-area: text;
}
li > button {
grid-area: button;
height: 30px;
}
https://jsfiddle.net/axqwhj29/
Play with the example linked above resizing the result area to check if that's what you are looking for.
B) Also, but I don't recommend you, if you really don't wanna change your li hight and you have a maximum text width (ex: 25 characters), you can clip parts of your message in a phone vertical view and if the user flips to horizontal show the whole text automatically.
https://jsfiddle.net/qfy3mz01/
Hope this help :)
Okay I have wrapped the text inside the li with span element and and added I add grid display to li and give every element inside the li a width and then I have added word-break: break-word; so the line will break when the text of the span reach the width limit and don't affect the delete button and I've deleted height from li so the li will grow with the lines on it
var addItemButton = document.getElementById('addItem')
var onEnter = document.getElementById('newNote')
//below event listener adds an item to the list on click
addItemButton.addEventListener('click', function() {
let item = document.getElementById('newNote').value
let node = document.createElement("li")
let span = document.createElement("span")
let textnode = document.createTextNode(item)
span.appendChild(textnode)
node.appendChild(span)
if (item) {
document.getElementById('list-body').appendChild(node)
}
let node2 = document.createElement('BUTTON')
let textnode2 = document.createTextNode('Delete')
node2.appendChild(textnode2)
node.appendChild(node2)
node2.addEventListener('click', function() {
node2.parentNode.parentNode.removeChild(node)
});
document.getElementById('newNote').value = ''
});
onEnter.addEventListener('keyup', function(event) {
if (event.keyCode === 13) {
// Cancel the default action, if needed
event.preventDefault();
// Trigger the button element with a click
addItemButton.click();
}
})
function applyButton() { //onload for dummy data or data from db
let getListObjects = document.querySelectorAll("li")
for (let i = 0; i < getListObjects.length; i++) {
let node2 = document.createElement('BUTTON')
let textnode2 = document.createTextNode('Delete')
node2.appendChild(textnode2)
getListObjects[i].appendChild(node2)
let y = getListObjects[i].querySelector('button')
y.addEventListener('click', function() {
y.parentNode.parentNode.removeChild(getListObjects[i])
});
}
}
.container {
height: 100%;
width: 40%;
margin: 0 auto;
}
.container2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
background-color: grey;
border: 1px solid grey;
}
#main-grid {
width: 100%;
}
#newNote {
height: 25px;
}
#inputIdForGrid {
justify-content: left;
align-items: center;
display: flex;
padding-left: 0.3em;
padding-top: 0.5em;
padding-bottom: 0.5em;
}
button {
padding: 10px 18px;
background-color: green;
border: none;
color: white;
font-size: 14px;
align-self: center;
justify-self: end;
}
#addItem {
margin-left: 1em;
padding: 0.5em;
color: white;
font-size: 1.5em;
float: right;
}
ul {
list-style-type: none;
padding: 0px;
margin: 0px;
}
li {
padding: 5px 15px;
display: grid;
grid-template-columns: 2.5fr .5fr;
}
span {
word-break: break-word;
grid-column: 1 / 2;
display: flex;
align-items: center;
}
li:nth-child(2n) {
background-color: grey;
}
li>button {
background-color: red;
}
h1 {
text-align: center
}
<body onload="applyButton()">
<h1>Vanilla JS ToDo List - No Jquery, No Bootstrap</h1>
<div class='container'>
<div id='main-grid'>
<div class="container2">
<div id='inputIdForGrid'>
<input type='text' placeholder="Enter List Items Here" id='newNote'>
</div>
<div>
Hi
</div>
</div>
<ul id='list-body'>
<li><span>run all around town. walk all around town. drive all around town</span></li>
<li><span>Buy Apples</span></li>
<li><span>Hit Gym and Lift Bro</span></li>
<li><span>Stretch</span></li>
</ul>
</div>
</div>
</body>
P.S. I've edited your js code so it will generate span and add the text inside it