Making table cells same row and make it look like buttons - javascript

I have this code below that alerts the value of the cell whenever the user clicks on the row. The problem is that i want try to make the cells look like button and put them on the same roll i'm not really too sure if this is possible to accomplish. Any help would be greatly appreciated thanks!
var obj2 = {};
var key3 = "Cars";
obj2[key3] = ['Toyota', 'Audi', 'Mercedes', 'Ferrari', 'Jeep', 'Honda', 'Nissan', 'Lamborghini'];
var myArray3 = [];
myArray3.push(obj2);
var bodyString = '';
var headString = '';
$.each(obj2[key3], function(index) {
bodyString += ('<tr><td>' + obj2[key3][index] + '</td></tr>');
});
headString += ('<tr><th>' + 'Cars' + '</th></tr>');
$('.carsclass tbody').html(bodyString);
$('.carsclass thead').html(headString);
$(document).ready(function() {
$("#carsid td").click(function() {
getval(this);
});
});
function getval(cel) {
alert(cel.innerHTML);
}
.class {
font-family: Open Sans;
}
.center{
display:flex;
justify-content:center
}
.skillsTable th{
border-left: 1px solid #AAA5A4;
border-right: 1px solid #AAA5A4;
}
table{
float: left;
border-collapse: collapse;
width:70%
}
td {
border-left: 1px solid #AAA5A4;
border-right: 1px solid #AAA5A4;
padding-top: 8px;
padding-left: 11px;
font-size: 15px;
}
th {
font-weight: normal;
border-bottom: 1px solid #AAA5A4;
padding-bottom: 5px;
}
div{
margin-bottom:50px;
}
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="//#" />
</head>
<body>
<div class="center">
<table id="carsid" class="carsclass skillsTable class">
<thead></thead>
<tbody></tbody>
</table>
</div>
</body>
</html>
This is what im trying to accomplish.

use blow code
td {
border-width: 1px;
border-radius: 50px;
border-color:black;
padding: 10px;
cursor:pointer;
font-size: 15px;
background-color: #9fc5e8;
}
th {
font-weight: normal;
border: 0;
padding: 10px 0;
}
div {
margin-bottom: 50px;
}
here is working example https://jsfiddle.net/deepakvaishnav/gfr36c1d/9/

I have changed some script and CSS to achieve your desired output but here you can't get an exact look like given image due to table
var obj2 = {};
var key3 = "Cars";
obj2[key3] = ['Toyota', 'Audi', 'Mercedes', 'Ferrari', 'Jeep', 'Honda', 'Nissan', 'Lamborghini'];
var myArray3 = [];
myArray3.push(obj2);
var bodyString = '<tr>';
var headString = '';
$.each(obj2[key3], function(index) {
bodyString += ('<td>' + obj2[key3][index] + '</td>');
});
bodyString += '</tr>';
headString += ('<tr><th colspan="' + obj2[key3].length + '">' + 'Cars' + '</th></tr>');
$('.carsclass tbody').html(bodyString);
$('.carsclass thead').html(headString);
$(document).ready(function() {
$("#carsid td").click(function() {
getval(this);
});
});
function getval(cel) {
alert(cel.innerHTML);
}
.class {
font-family: Open Sans;
}
.center {
display: flex;
justify-content: center
}
table {
float: left;
border-collapse: collapse;
width: 70%
}
td {
border: 0;
padding: 8px 10px;
padding-left: 11px;
font-size: 15px;
border-radius: 50px;
background-color: #007bff;
}
th {
font-weight: normal;
border: 0;
padding: 10px 0;
}
div {
margin-bottom: 50px;
}
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="//#" />
</head>
<body>
<div class="center">
<table id="carsid" class="carsclass skillsTable class">
<thead></thead>
<tbody></tbody>
</table>
</div>
</body>
</html>

use below css.
<style>
#carsid {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 100%;
}
#carsid td, #customers th {
border: 1px solid #ddd;
padding: 8px;
cursor: pointer;
}
#carsid tr:nth-child(even){background-color: #f2f2f2;}
#carsid tr:hover {background-color: #ddd;}
#carsid th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #4CAF50;
color: white;
}
</style>

Here is the approach using flex-box instead of table.
HTML
<div id="cars-container"></div>
JavaScript with jQuery
let cars = [
'Toyota',
'Audi',
'Mercedes',
'Ferrari',
'Jeep',
'Honda',
'Nissan',
'Lamborghini',
'Hyundai'
];
let $carsContainer = $('#cars-container');
// Empty the container first
$carsContainer.html('');
// Loop through the car collection
$.each(cars, function(index, car) {
let $button = $('<button />', {
text: car,
value: car,
click: function() {
alert(this.value);
}
});
$carsContainer.append($button);
});
CSS
#cars-container {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
}
#cars-container button {
padding: .375rem 1.25rem;
border-radius: 1rem;
border: 1px solid #aaa5a4;
background-color: #9fc5e8;
margin: .25rem;
}
#cars-container button:hover {
cursor: pointer;
background-color: #8ab9e3;
}
Result
Here is the working example: https://jsfiddle.net/xpvt214o/233802/
Now reading from one of the comments, if the user of OP wants only 5 cars in a row, you can easily add a style to the button:
#cars-container button {
...
width: calc(100% / 5 - 2 * .25rem); <!-- Percentage - margin left - margin right -->
}
But I would highly not recommend to put a fixed width on the button element. That defeats the purpose of using flex-box - the flexibility and responsiveness it gives.
Instead, you can setup media breakpoints and do what works fine at that breakpoint (mobile-first approach). For example:
At extra small devices (portrait phones, less than 576px), I want the buttons to be vertically aligned. I can change the initial css flex-flow property to column instead of row.
#cars-container {
...
flex-flow: column nowrap;
...
}
Then on small devices (landscape phones, 576px and up), I might want only 2 items per row.
#media (min-width: 576px) {
#cars-container {
flex-flow: row wrap;
}
#cars-container button {
width: calc(100% / 2 - 2 * .25rem);
}
}
On Medium devices (tablets, 768px and up), I might want only 3 items per row.
#media (min-width: 768px) {
#cars-container {
width: calc(100% / 3 - 2 * .25rem);
}
}
You got the idea. You just need to change the divisor for the numbers of items you want per row.
Here is the working example with breakpoints: https://jsfiddle.net/rnvt689w/13/

Related

Div changes size once another div is loaded?

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.

Chrome extension State management

I am currently making a chrome extension (This is my first chrome extension) that you can take small notes with and want to keep the user input. I am keeping the user input inside of input classes. How would I be able to store the chrome extension state so that when I reopen it, it will stay the same? Here is the code that I have written so far.
//selectors
const addbutton = document.querySelector(".add");
const addlist = document.querySelector(".note-list");
const noteList = document.querySelector(".note-list")
//event listners
addbutton.addEventListener('click', addNote);
//functions
function addNote(event){
//prevent page refresh
event.preventDefault();
//note div
const noteDiv = document.createElement('div');
noteDiv.classList.add('note');
//create li
const newNote = document.createElement('li');
newNote.classList.add('noteitem');
noteDiv.appendChild(newNote);
//create input
const newInput = document.createElement('input');
newInput.classList.add('noteInput')
newNote.appendChild(newInput);
//append to list
noteList.appendChild(noteDiv);
}
#import url('https://fonts.googleapis.com/css2?family=Montserrat:wght#500&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
outline: none;
}
body{
height: 500px;
width: 400px;
}
h1{
font-family: "Montserrat", sans-serif;
font-size: 20px;
font-weight: lighter;
padding-top: 10px;
padding-bottom: 10px;
}
main{
text-align: center;
}
.title{
box-shadow: 0 2px 2px -2px rgba(0, 0, 0, 0.685);
}
.mainpage{
padding-top: 20px;
}
.add{
font-family: "Montserrat", sans-serif;
font-size: 25px;
font-weight: 400px;
background-color: #00FF33;
width:40px ;
height: 40px;
border-radius: 10px;
border: none;
transition: ease 0.5s;
}
.add:hover{
background-color: #00c026;
}
.note-container{
display: flex;
justify-content: center;
align-items: center;
}
.note-list{
min-width: 30%;
list-style: none;
}
.note{
margin: 0.5rem;
background: whitesmoke;
font-size: 1.5rem;
display: flex;
justify-content: space-between;
border-radius: 7px;
}
.noteitem{
padding: 0.5rem 2rem;
}
.noteInput{
display: block;
margin-right: auto;
margin-left: auto;
border: none;
background-color: whitesmoke;
font-size: 20px;
max-height: 200px;
}
.note li{
flex: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mini Note</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<div class="title">
<h1>Mini note app</h1>
</div>
<section class="mainpage">
<button class="add">+</button>
<div class="note-container">
<ul class="note-list"></ul>
</div>
</section>
</main>
<script src="/popup.js"></script>
</body>
</html>
Thank you
// uses local storage
chrome.storage.local.set({key: value}, function() {
console.log('Value is set to ' + value);
});
// uses synced storage, hits Chrome backend when being set
chrome.storage.sync.set({key: value}, function() {
console.log('Value is set to ' + value);
});
// to retrieve the data, use 'sync' instead of 'local' if using sync
chrome.storage.local.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
});
You'll still need to figure out how you want to organize the note data. For example, you could store all of the notes in an array on the notes key that looks like the following:
{
notes: [
{ id: 1, body: 'First note' },
{ id: 2, body: 'Second note' }
]
}
you have two options :-
you can use localStorage just like in web page for more check here
you can use chrome.storage for more check here

A Notepad that keep the notes written even after refresh

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.

Stop underline from getting bigger

I'm creating a currency converter app using html,css and javascript, and when text is entered into the <input> on the left, the converted value will appear in the input element on the right: <p id = "converted">.
I want to keep the underline(border-bottom) the same length on the <p id = "converted">. Currently, when you enter text into the input element on the left, the one on the right increases in size and makes the underline larger. I want the underline to stay the same as when there is no text in the element.
I am currently styling the <p id = "converted"> element like so:
padding-right: 40%;
border-bottom: 0.5vh solid white;
I do not think the API I am using will work correctly with the stack overflow snippets, but I will include a link to a codepen: https://codepen.io/oliknight/pen/XLvQow
let currlet currencyArr = [];
let ratesArr = [];
window.addEventListener("load", () => {
const api = "https://api.exchangeratesapi.io/latest?base=GBP";
fetch(api)
.then(response => {
return response.json();
})
.then(data => {
for (currency in data.rates) {
currencyArr.push(currency);
ratesArr.push(data.rates[currency]);
// create 'option' element here
var optionLeft = document.createElement("option");
var optionRight = document.createElement("option");
optionLeft.textContent = currency;
optionRight.textContent = currency;
document.querySelector("#left-select").appendChild(optionLeft);
document.querySelector("#right-select").appendChild(optionRight);
}
document.querySelector("#input").addEventListener("keyup", convert);
function convert() {
const input = document.querySelector("#input");
let leftSelectValue = document.querySelector("#left-select").value;
let convertedNumber = document.querySelector("#converted");
for (let i = 0; i < currencyArr.length; i++) {
if (leftSelectValue === currencyArr[i]) {
convertedNumber.textContent = ratesArr[i].toFixed(4) * input.value;
}
}
}
});
});
encyArr = [];
let ratesArr = [];
window.addEventListener("load", () => {
const api = "https://api.exchangeratesapi.io/latest?base=GBP";
fetch(api)
.then(response => {
return response.json();
})
.then(data => {
for (currency in data.rates) {
currencyArr.push(currency);
ratesArr.push(data.rates[currency]);
// create 'option' element here
var optionLeft = document.createElement("option");
var optionRight = document.createElement("option");
optionLeft.textContent = currency;
optionRight.textContent = currency;
document.querySelector("#left-select").appendChild(optionLeft);
document.querySelector("#right-select").appendChild(optionRight);
}
document.querySelector("#input").addEventListener("keyup", convert);
function convert() {
const input = document.querySelector("#input");
let leftSelectValue = document.querySelector("#left-select").value;
let convertedNumber = document.querySelector("#converted");
for (let i = 0; i < currencyArr.length; i++) {
if (leftSelectValue === currencyArr[i]) {
convertedNumber.textContent = ratesArr[i].toFixed(4) * input.value;
}
}
}
});
});
html {
font-family: "Lato", sans-serif;
font-weight: thin;
background-image: linear-gradient(to right top, #90d0ff, #008ef7);
color: white;
height: 100vh;
overflow: hidden;
}
h1 {
text-align: center;
font-size: 5em;
position: absolute;
left: 0;
right: 0;
margin: auto;
}
.container {
width: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.container p {
font-size: 8em;
display: inline-block;
padding-right: 40%;
border-bottom: 0.5vh solid white;
max-width: 50%;
}
.parent {
display: flex;
justify-content: center;
height: 100vh;
align-items: center;
}
.container select {
background: transparent;
color: white;
padding: 20px;
width: 80px;
height: 60px;
border: none;
font-size: 20px;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.5);
-webkit-appearance: button;
outline: none;
margin-left: 10%;
}
.original {
background: transparent;
border: none;
border-bottom: 0.5vh solid white;
font-size: 8em;
max-width: 50%;
outline: none;
font-family: "Lato", sans-serif;
font-weight: thin;
color: white;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Currency Converter</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="main.css" />
<link href="https://fonts.googleapis.com/css?family=Lato:300&display=swap" rel="stylesheet" />
</head>
<body>
<h1>Currency Converter</h1>
<div class="parent">
<div class="container">
<input type="text" class="original" id="input" />
<select id="left-select"> </select>
</div>
<div class="container" id="ctn">
<p id="converted">0</p>
<select id="right-select"> </select>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
Thanks!
If you replace max-width with width in your css, the percentage (e.g. 50%) width will stay the same, regardless of how long the converted number is. However this poses a problem regarding your overflow.
You could remove the padding, but you could still run into issues whereby only half a digit is showing at the end, depending on how big the device is:
So you may want to either reduce the font size or experiment with width percentages (maybe 49 or 51 .. ) , or both ..
If you knew exactly how many decimal digits there would be in the returned converted number, this would help determine an adequate size font.
Good luck, and hope this helps

MapBox API exclusive layer switcher

I have thoroughly searched MapBox support and Stack Overflow for an answer on how to create an exclusive layer switcher using the latest MapBox API (1.6.1 as of now). Exclusive in this case means that only 1 layer can be visible/active at a time. I do not want to use the Leaflet Layers Control for design reasons.
With a little help, I have come up with this example, which almost works:
http://bl.ocks.org/sarahkhank/0e5d81998d2d0876856c
For some reason, adding and removing the gridControl breaks the loop. If you use this structure to just add/remove the tileLayer with no gridLayer or gridControl, it works fine. But when you add the grid elements, the last element in the array doesn't show up and messes up the rest of the loop. (In this case 'far'.)
Does anyone have any idea why this is happening? This type of layer switcher is often asked about on MapBox support, so I'm sure many people would be happy to see this come to life. Thanks for your help!!
Posting full code here at the bottom in case my bl.ocks link ever breaks.
<html>
<head>
<title>DC Zoning Map</title>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src='http://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.js'></script>
<link href='http://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.css' rel='stylesheet' />
</head>
<body>
<style>
#zoning-map-container {
position:relative;
float: right;
display: inline;
}
#map_zoning {
position: relative;
float: left;
clear: both;
width:45%;
min-width: 500px;
height: 500px;
right:20px;
margin-top: 10px;
margin-right: 10px;
border: 1px solid #bbb;
}
#map-ui-zoning {
position:relative;
float: left;
list-style:none;
margin:0;padding:0;
left: -20px;
}
#map-ui-zoning a {
font-family: 'Carrois Gothic', sans-serif;
font-size: 12px;
font-weight: 400;
background:#FFF;
color:#5698D0;
float: left;
margin:0;
border:1px solid #BBB;
border-width: 1px 1px 1px 0;
max-width:100px;
padding:8px;
text-decoration:none;
}
#map-ui-zoning li {
display: inline;
}
#map-ui-zoning a:hover { background:#ECF5FA; }
#map-ui-zoning li:last-child a {
border-bottom-width:1px;
-webkit-border-radius:0 3px 3px 0;
border-radius:0 3px 3px 0;
}
#map-ui-zoning li:first-child a {
border-left-width: 1px;
-webkit-border-radius:3px 0 0 3px;
border-radius:3px 0 0 3px;
}
#map-ui-zoning a.active {
background:#5698D0;
border-color:#5698D0;
border-top-color:#BBB;
color:#FFF;
}
.map-tooltip .zone {
font-size: 10px;
line-height: 13px;
font-weight: bold;
}
.map-tooltip .desc {
font-size: 10px;
line-height: 13px;
padding-bottom: 3px;
}
.map-tooltip .focus {
font-size: 13px;
line-height: 16px;
font-weight: bold;
}
.map-tooltip .info {
font-size: 11px;
line-height: 16px;
}
</style>
<div id='zoning-map-container'>
<ul id='map-ui-zoning'>
<li>Maximum Stories</li>
<li>Maximum Height</li>
<li>Maximum FAR</li>
</ul>
<div id='map_zoning'></div>
</div>
<script type='text/javascript'>
var map = L.mapbox.map('map_zoning');
var stamenLayer = L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png', {
attribution: 'Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA.'
}).addTo(map);
map.setView([38.908, -77.029], 11);
var ui = document.getElementById('map-ui-zoning');
var stories = L.mapbox.tileLayer('sarah.28n6ogvi');
var storiesGrid = L.mapbox.gridLayer('sarah.28n6ogvi');
var storiesGridControl = L.mapbox.gridControl(storiesGrid, {follow: false});
var height = L.mapbox.tileLayer('sarah.ofjsv2t9');
var heightGrid = L.mapbox.gridLayer('sarah.ofjsv2t9');
var heightGridControl = L.mapbox.gridControl(heightGrid, {follow: false});
var far = L.mapbox.tileLayer('sarah.2w9x80k9');
var farGrid = L.mapbox.gridLayer('sarah.2w9x80k9');
var farGridControl = L.mapbox.gridControl(farGrid, {follow: false});
var layers = [{
'name': 'stories',
'layer': stories,
'gridLayer': storiesGrid,
'gridControl': storiesGridControl
},
{
'name': 'height',
'layer': height,
'gridLayer': heightGrid,
'gridControl': heightGridControl
},
{
'name': 'far',
'layer': far,
'gridLayer': farGrid,
'gridControl': farGridControl
}
];
$(document).ready(function(layer){
map.addLayer(stories);
map.addLayer(storiesGrid);
map.addControl(storiesGridControl);
});
$('#map-ui-zoning li a').on('click', function() {
$('#map-ui-zoning li a').removeClass('active');
var $el = $(this);
layers.forEach(function(layer) {
if ($el.data('name') !== layer['name']){
map.removeLayer(layer['layer']);
map.removeLayer(layer['gridLayer']);
map.removeControl(layer['gridControl']);
}
else {
map.addLayer(layer['layer']);
map.addLayer(layer['gridLayer']);
map.addControl(layer['gridControl']);
$el.addClass('active');
}
});
});
</script>
I think that when you call map.removeControl(layer['gridControl']) or more generally map.removeLayer you dont test if the layer is already added to the map because otherwise it mapboxjs will try to delete an element that does not exist and this is where your code gets broken .
if ($el.data('name') !== layer['name'])
needs to become
if ($el.data('name') !== layer['name'] && map.hasLayer(layer))
of course you need to change your else statement accordingly .
here is your example running
http://bl.ocks.org/radproject/31c48b1a7610e353d495

Categories