AUTO-SUGGESTION keyboard use - javascript

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ajax Auto Suggest</title>
<script type="text/javascript" src="jquery-1.2.1.pack.js"></script>
<script type="text/javascript">
var stringcount = 0;
var st = "";
var vv = "f";
function lookup2(e,inpstring)
{
lookup1(e.keyCode,inpstring);
}
function lookup1(j,inputstring)
{
var x= inputstring.length;
st = inputstring ;
if (inputstring.charAt(parseInt(x,10)-1) == " ")
{
stringcount = stringcount + 1;
}
else
{
var mySplitResult = inputstring.split(" ");
var stringtemp = "" ;
var w = 0;
for (w =0 ; w < stringcount ;w++)
{
stringtemp = stringtemp+ " "+ mySplitResult[w];
}
st = stringtemp;
lookup(mySplitResult[stringcount],inputstring);
}
}
function lookup(inputString,i) {
if(inputString.length == 0) {
// Hide the suggestion box.
$('#suggestions').hide();
} else {
$.post("rpc.php", {queryString: ""+inputString+"" }, function(data){
if(data.length >0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}
});
}
} // lookup
function fill(thisValue) {
$('#inputString').val(st.substring(1,st.length)+" "+thisValue);
setTimeout("$('#suggestions').hide();", 200);
}
</script>
<style type="text/css">
body {
font-family: Helvetica;
font-size: 11px;
color: #000;
}
h3 {
margin: 0px;
padding: 0px;
}
.suggestionsBox {
position: relative;
left: 30px;
margin: 10px 0px 0px 0px;
width: 200px;
background-color: #212427;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border: 2px solid #000;
color: #fff;
}
.suggestionList {
margin: 0px;
padding: 0px;
}
.suggestionList li {
margin: 0px 0px 3px 0px;
padding: 3px;
cursor: pointer;
}
.suggestionList li:hover {
background-color: #659CD8;
}
</style>
</head>
<body>
<div>
<form>
<div>Type your county here:<br />
<input type="text" size="30" value="" id="inputString" onkeyup="lookup2(event,this.value);" onblur="" />
</div>
<div class="suggestionsBox" id="suggestions" style="display: none;">
<img src="upArrow.png" style="position: relative; top: -12px; left: 30px;" alt="upArrow" />
<div class="suggestionList" id="autoSuggestionsList"> </div>
</div>
</form>
</div>
</body>
</html>
This is the code i am using. The auto-suggestion box is accessed by clicking on the desired option. How can i scroll through the option by using the up/down keys of the keyboard and select an option by using enter?

It looks like (because you have not quoted the really important code) that your server side ajax endpoint returns an HTML unordered list and this is pasted into the suggestionList div. That's going to be my assumption. Your CSS allows for the hover pseudo-selector so mouse support looks good.
For keyboard support, you are going to have add an event handler for the keypress event, probably on the document. Add the handler when the suggestion box is displayed, remove it when it is dismissed.
The event handler will have to track the up and down arrow keys as well as enter. You will have to add and remove a special class (or maybe an id) on the li element that is currently selected, which means you will have to track how many elements there are to scroll through, and which one is the currently highlighted one. So, if you see the down arrow key, add one to the current index (if you're at the last one, ignore the key). Remove the special class from the li element you just left and add it to the new one (obviously style the class accordingly in your CSS). When the enter key is pressed you know which element is selected, so return it, or do what you want with it.

Related

JavaScript modal is unable to open

I'm making a note taker app that gives you the option to view said note in a modal whenever the button is clicked. The HTML for the note and modal is dynamically generated by event listeners. There are two ways the close the modal, by clicking the "X" button or by clicking outside of the modal. The program has full functionality whenever only one note is generated, but once I generate a second note the code breaks down. Once this happens only I'm able to open the modal of the first note generated, but not close it. And the second one won't open whatsoever. How could I fix this issue?
class Input {
constructor(note) {
this.note = note;
}
}
class UI {
addNote(input) {
// Get table body below form
const content = document.querySelector(".content");
// Create tr element
const row = document.createElement("tr");
// Insert new HTML into div
row.innerHTML = `
<td>
${input.note}
<br><br>
<button class="modalBtn">View Note</button>
</td>
`;
content.appendChild(row);
// Event listener to make modal
document.querySelector(".modalBtn").addEventListener("click", function(e) {
// Get container div
const container = document.querySelector(".container");
// Create div
const div = document.createElement("div");
// Assign class to it
div.className = "modal";
// Insert HTML into div
div.innerHTML = `
<div class="modal-content">
<span class="closeBtn">×</span>
<div>
<p>${input.note}</p>
</div>
</div>
`;
// Append the new div to the container div
container.appendChild(div);
// Get modal
const modal = document.querySelector(".modal");
// Event listener to close modal when "x" is clicked
document.querySelector(".closeBtn").addEventListener("click", function() {
container.removeChild(modal);
});
// Event listener to close when the window outside the modal is clicked
window.addEventListener("click", function(e) {
if (e.target === modal) {
container.removeChild(modal);
}
});
});
}
// Clear input field
clearInput() {
note.value = "";
}
}
// Event listener for addNote
document.getElementById("note-form").addEventListener("submit", function(e) {
// Get form value
const note = document.getElementById("note").value;
// Instantiate note
const input = new Input(note);
// Instantiate UI
const ui = new UI();
// Validate form (make sure input is filled)
if (note === "") {
// Error alert
alert("Please fill in text field!");
}
else {
// Add note
ui.addNote(input);
// Clear input field
ui.clearInput();
}
e.preventDefault();
});
h5 {
color: green;
}
.modal {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-content {
background-color: #fff;
margin: 20% auto;
padding: 30px;
width: 70%;
box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.17);
animation-name: modalopen;
animation-direction: 1s;
}
.closeBtn {
color: #aaa;
/* float: right; */
font-size: 30px;
margin-bottom: 1rem;
padding-bottom: 1rem;
}
.closeBtn:hover,
.closeBtnBtn:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.closeBtn + div {
margin-top: 2rem;
}
#keyframes modalopen {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.css" integrity="sha512-5fsy+3xG8N/1PV5MIJz9ZsWpkltijBI48gBzQ/Z2eVATePGHOkMIn+xTDHIfTZFVb9GMpflF2wOWItqxAP2oLQ==" crossorigin="anonymous" />
<link rel="stylesheet" href="style.css">
<title>Note Taker</title>
</head>
<body>
<div class="container">
<h1>Note Taker</h1>
<h5>Add A New Note:</h5>
<form id="note-form">
<div>
<label>Note:</label>
<textarea name="Note" id="note" class="u-full-width"> </textarea>
</div>
<div>
<button type="submit" class="button-primary">Add Note</button>
</div>
</form>
<table>
<tbody class="content"></tbody>
</table>
</div>
<script src="app.js"></script>
</body>
</html>
Fist of all.. I love your syntaxt!! Best I've seen so far! second.. you do a general query Selector and don't handle them separately. Can that be an issue?
EDIT:
Because of reasons I'll reformulated my answer..
document.querySelector('class') returns an Html-Collection with DOM element references containing the specified html class and should be handled separately.

Save contentEditable into html file with javascript

How can I save contenteditable element with javascript(no PHP) into actual HTML code? So I can edit content whenever even in offline mode.
Like when you click "save button" it replace old file with new one(text with changes).
If there is a way to make this work in offline mode with any other programming lang please suggest.
I found a few examples but they were all made with PHP.
Also, I will post code. In this code, you are able to edit the file with javascript and save it. But problem is that it does not save into actual HTML code.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
</head>
<style type="text/css">
body{
font-family: "Dosis";
font-size: 1.3em;
line-height: 1.6em;
}
.headline{
font-size: 2em;
text-align: center;
}
#wrapper {
width: 600px;
background: #FFF;
padding: 1em;
margin: 1em auto;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
border-radius: 3px;
}
button {
border: none;
padding: 0.8em;
background: #F96;
border-radius: 3px;
color: white;
font-weight: bold;
margin: 0 0 1em;
}
button:hover, button:focus {
cursor: pointer;
outline: none;
}
#editor {
padding: 1em;
background: #E6E6E6;
border-radius: 3px;
}
</style>
<body>
<div id="wrapper">
<section>
<h1 class="headline">contentEditable Demonstration</h1>
<button id="editBtn" type="button">Edit Document</button>
<div id="editDocument">
<h1 id="title">A Nice Heading.</h1>
<p>Last Edited by <span id="author">Monty Shokeen</span>
</p>
<p id="content">You can change the heading, author name and this content itself. Click on Edit Document to start editing. At this point, you can edit this document and the changes will be saved in localStorage. However, once you reload the page your changes will be gone. To fix it we will have to retrieve the contents from localSotrage when the page reloads.</p>
</div>
</section>
</div>
<script>
var editBtn = document.getElementById('editBtn');
var editables = document.querySelectorAll('#title, #author, #content');
if (typeof(Storage) !== "undefined") {
if (localStorage.getItem('title') !== null) {
editables[0].innerHTML = localStorage.getItem('title');
}
if (localStorage.getItem('author') !== null) {
editables[1].innerHTML = localStorage.getItem('author');
}
if (localStorage.getItem('content') !== null) {
editables[2].innerHTML = localStorage.getItem('content');
}
}
editBtn.addEventListener('click', function(e) {
if (!editables[0].isContentEditable) {
editables[0].contentEditable = 'true';
editables[1].contentEditable = 'true';
editables[2].contentEditable = 'true';
editBtn.innerHTML = 'Save Changes';
editBtn.style.backgroundColor = '#6F9';
} else {
// Disable Editing
editables[0].contentEditable = 'false';
editables[1].contentEditable = 'false';
editables[2].contentEditable = 'false';
// Change Button Text and Color
editBtn.innerHTML = 'Enable Editing';
editBtn.style.backgroundColor = '#F96';
// Save the data in localStorage
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables[i].getAttribute('id'), editables[i].innerHTML);
}
}
});
</script>
</body>
</html>
You'll want to use something like the downloadInnerHtml function as described here. Ideally you'll probably also want to strip out the script tag and content editable attribute before exporting because you won't want the final html page to be editable

dynamically update css content using javascript

There is a need to update css to dynamic value and I am not sure what's the best approach to it.
<div id="app" style="zoom: 0.XX;">
...
</div>
The zoom level will trigger based on window resize and the app will zoom according. I loaded this app into cordova and have it run within iPAD, then I realize the font-size needs to be adjusted to the same as zoom level using "-webkit-text-size-adjust" in order for it to not break the design layout.
My challenge is to set the css dynamically like this:
#app * {
-webkit-text-size-adjust : nn%
}
Where nn is the zoom X 100 + '%'
I have tried:
1) Set the style on the app div, but this doesn't help to apply to inner elements
<div id="app" style="zoom: 0.XX; -webkit-text-size-adjust: XX%">
2) Use javascript to set to all inner nodes, but not only I think this is less efficient, but it won't get trigger if my window doesn't resize, that means if I navigate to other pages, this logic won't get called.
REF: https://stackoverflow.com/questions/25305719/change-css-for-all-elements-from-js
let textSizeAdjust = function(zoom) {
let i,
tags = document.getElementById("app").getElementsByTagName("*"),
total = tags.length;
for ( i = 0; i < total; i++ ) {
tags[i].style.webkitTextSizeAdjust = (zoom * 100) + '%';
}
}
3) I tried using javascript, and most likely they are technically incorrect because querySelector return null.
document.querySelector('#app *').style.webkitTextSizeAdjust = zoom *100 + '%';
document.querySelector('#app').querySelector('*').style.webkitTextSizeAdjust = zoom * 100 + "%";
Ultimate, I believe I need to dynamically create the css, for the browser to apply this setting to the DOM:
#app * {
-webkit-text-size-adjust: nn
}
Please let me know if this is the right, or how to use javascript to create the above css and change the value dynamically?
CSS Variables
Requirements
HTML
Each form control that has numerical data should have:
value={a default, don't leave it blank}
class='num'
data-unit={unit of measurement or a single space}
The select/option tag should have the selected attribute
CSS
CSS Variable Signature: propertyName: var(--propertyValue)
// Declare CSS Variables at the top of a stylesheet
:root {
--mx0: 50px;
--my0: 50px;
--rz0: 1.0;
--zm0: 1.0;
--sp0: 360deg;
}
JavaScript
There's step by step details commented in the JavaScript Demo. Here's the most important statement in the code:
CSSStyleDeclaration CSS Variable
🢃 🢃
`ele.style.setProperty(`--${node.id}`,
${node.valueAsNumber}${node.dataset.unit})
🢁 🢁
HTMLInputElement DataSet API
Demo 1
// Reference form#UI
var ui = document.forms.UI;
// Register form#UI to change event
ui.addEventListener('change', setCSS);
// Callback passes Event Object
function setCSS(e) {
// Collect all form controls of form#UI into a NodeList
var fx = ui.elements;
// Reference select#pk0
var pk0 = fx.pk0;
// Get select#pk0 value
var pick = pk0.options[pk0.selectedIndex].value
// if the changed element has class .num...
if (e.target.className === 'num') {
// Reference Event Target
var tgt = e.target;
// Then reference is by its #id
var node = document.getElementById(tgt.id);
// DOM Object to reference either html, square, or circle
var ele;
/* Determine which tag to test on: html (affects everything),
|| #sQ<uare> and #ciR<cle> shapes.
*/
switch (pick) {
case "rT":
ele = document.documentElement;
break;
case "sQ":
ele = document.getElementById('sQ');
break;
case "cR":
ele = document.getElementById('cR');
break;
default:
break;
}
/* Sets a target element's Transform:
|| translateXY, scale, and rotate
*/
ele.style.setProperty(`--${node.id}`, `${node.valueAsNumber}${node.dataset.unit}`);
}
}
/* Declare CSS Variables on the :root selector at the top of sheet
All CSSVar must be prefixed with 2 dashes: --
*/
:root {
--mx0: 50px;
--my0: 50px;
--rz0: 1.0;
--sp0: 360deg;
}
.set {
border: 3px ridge grey;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
padding: 5px;
}
/* The var() function's signature is:
propertyName: var(--propertyValue)
*/
#sQ {
position: relative;
background: rgba(0, 100, 200, 0.3);
width: 50px;
height: 50px;
transform: translateX(var(--mx0)) translateY(var(--my0)) scale(var(--rz0)) rotate(var(--sp0));
border: 3px ridge grey;
z-index: 1;
transition: all 1s ease;
}
#cR {
position: relative;
background: rgba(200, 100, 0, 0.3);
width: 50px;
height: 50px;
transform: translateX(var(--mx0)) translateY(var(--my0)) scale(var(--rz0)) rotate(var(--sp0));
border: 3px ridge grey;
border-radius: 50%;
transition: all 1s ease;
}
#sQ::before {
content: '\1f504';
text-align: center;
font-size: 2.25rem;
transform: translate(1px, -8px)
}
#cR::after {
content: '\1f3b1';
text-align: center;
font-size: 2.25rem;
}
input,
select {
display: inline-block;
width: 6ch;
font: inherit;
text-align: right;
line-height: 1.1;
padding: 1px 2px;
}
select {
width: 9ch
}
.extension {
overflow-y: scroll;
overflow-x: auto;
min-height: 90vh;
}
/* For debugging on Stack Snippets */
/*.as-console-wrapper {
width: 25%;
margin-left: 75%;
min-height: 85vh;
}*/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style></style>
</head>
<body>
<!--
HTML Requirements
Each form control that has numerical data should have:
1. value={a default, don't leave it blank}
2. class='num'
3. data-unit={unit of measurement or a single space}
4. The select/option tag should have the selected attribute
-->
<form id='UI'>
<section class='set'>
<label>X: </label>
<input id='mx0' class='num' type='number' min='-350' max='350' value='50' step='10' data-unit='px'>
<label>Y: </label>
<input id='my0' class='num' type='number' min='-350' max='350' value='50' step='10' data-unit='px'>
<label>Size: </label>
<input id='rz0' class='num' type='number' min='0' max='5' value='1' step='0.1' data-unit=' '>
<label>Spin: </label>
<input id='sp0' class='num' type='number' min='0' max='1440' value='360' step='180' data-unit='deg'>
<label>Pick: </label>
<select id='pk0' class='num'>
<option value='rT' selected>Root</option>
<option value='sQ'>Square</option>
<option value='cR'>Circle</option>
</select>
</section>
</form>
<section class='set extension'>
<div id='sQ' class='test shape' width="50" height="50"></div>
<div id='cR' class='test shape' width="50" height="50"></div>
</section>
</body>
</html>
Update
This update is specifically for OP, so this may be of help or not for other users.
Deno 2
:root {
--opc: 0;
--zoom: 1;
}
.fc {
display: inline-block;
width: 18ch;
margin:0 0 10px 0
}
#app * {
opacity: var(--opc);
transform: scale(var(--zoom));
}
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<form id='app' action='https://httpbin.org/post' method='post' target='view'>
<fieldset class='sec'>
<legend>App of Mystery</legend>
<input id='A0' name='A0' class='fc' type='text' placeholder='User Name'>
<input id='A1' name='A1' class='fc' type='password' placeholder='Password'>
<input type='submit'>
<input type='reset'>
<input id='zBtn' type='button' value='Zoom'>
<iframe name='view' frameborder='1' width='100%'></iframe>
</fieldset>
</form>
<script>
var node = document.querySelector('#app *');
var zBtn = document.getElementById('zBtn');
var flag = false;
document.addEventListener('DOMContentLoaded', function(e) {
node.style.setProperty("--opc", "0.5");
});
document.addEventListener('click', function(e) {
node.style.setProperty("--opc", "1");
});
zBtn.addEventListener('click', function(e) {
if (flag) {
flag = false;
node.style.setProperty("--zoom", "1");
} else {
flag = true;
node.style.setProperty("--zoom", "1.25");
}
});
</script>
</body>
</html>
I don't have much knowledge about -webkit-text-size-adjust
However, this should work for creating a dynamic stylesheet and inserting it:
I have added code to dynamically update it as well
const form = document.getElementById('colorChooser');
form.addEventListener('submit', (e) => {
e.preventDefault();
color = document.getElementById('colorInput').value;
const style = document.getElementById('colorStyle');
style.innerHTML = `#app * {
background-color: ${color};
}`;
});
const style = document.createElement('style');
style.id = 'colorStyle';
style.type = 'text/css';
style.innerHTML = `#app * {
background-color: red;
}`;
document.head.appendChild(style);
#app {
margin-bottom: 10px;
}
#inner {
width: 50px;
height: 50px;
background-color: black;
}
<div id="app">
<div id="inner"></div>
</div>
<form id="colorChooser">
<input id="colorInput" type="text" placeholder="red" />
<input type="submit" value="Update color"/>
</form>

AppendTo but each new append is unique but still uses the same jquery

I'm wondering if it's possible to on each appendTo make the new div unique but still use the same jquery.
As you can see in the mark-up below, each new div shares the same jquery so doesn't work independently.
Within my Javascript i'm selecting the ID to fire each function.
I've tried just adding + 1 etc to the end of each ID, but with that it changes the name of the ID making the new created DIV not function.
I've thought of using DataAttribues, but i'd still have the same issue having to create multiple functions all doing the same job.
Any ideas?
Thanks
$(function() {
var test = $('#p_test');
var i = $('#p_test .upl_drop').length + 1;
$('#addtest').on('click', function() {
$('<div class="file-input"><div class="input-file-container upl_drop"><label for="p_test" class="input-file-trigger">Select a file...<input type="file" id="p_test" name="p_test_' + i + '" value=""class="input-file"></label></div><span class="remtest">Remove</span><p class="file-return"></p></div>').appendTo(test);
i++;
});
$('body').on('click', '.remtest', function(e) {
if (i > 2) {
$(this).closest('.file-input').remove();
i--;
}
});
});
var input = document.getElementById( 'file-upload' );
var infoArea = document.getElementById( 'file-upload-filename' );
input.addEventListener( 'change', showFileName );
function showFileName( event ) {
// the change event gives us the input it occurred in
var input = event.srcElement;
// the input has an array of files in the `files` property, each one has a name that you can use. We're just using the name here.
var fileName = input.files[0].name;
// use fileName however fits your app best, i.e. add it into a div
textContent = 'File name: ' + fileName;
$("#input-file-trigger").text(function () {
return $(this).text().replace("Select a file...", textContent);
});
}
/*
#### Drag & Drop Box ####
*/
.p_test{
display: inline-block;
}
.upl_drop{
border: 2px dashed #000;
margin: 0px 0px 15px 0px;
}
.btn--add p{
cursor: pointer;
}
.input-file-container {
position: relative;
width: auto;
}
.input-file-trigger {
display: block;
padding: 14px 45px;
background: #ffffff;
color: #1899cd;
font-size: 1em;
cursor: pointer;
}
.input-file {
position: absolute;
top: 0; left: 0;
width: 225px;
opacity: 0;
padding: 14px 0;
cursor: pointer;
}
.input-file:hover + .input-file-trigger,
.input-file:focus + .input-file-trigger,
.input-file-trigger:hover,
.input-file-trigger:focus {
background: #1899cd;
color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="p_test" id="p_test">
<div class="file-input">
<div class="input-file-container upl_drop">
<input class="input-file" id="file-upload" type="file">
<label tabindex="0" for="file-upload" id="input-file-trigger" class="input-file-trigger">Select a file...</label>
</div>
<div id="file-upload-filename"></div>
</div>
<button class="btn--add" id="addtest">
Add
</button>
</div>
I'd advise against using incremental id attributes. They become a pain to maintain and also make the logic much more complicated than it needs to be.
The better alternative is to use common classes along with DOM traversal to relate the elements to each other, based on the one which raised any given event.
In your case, you can use closest() to get the parent .file-input container, then find() any element within that by its class. Something like this:
$(function() {
var $test = $('#p_test');
$('#addtest').on('click', function() {
var $lastGroup = $test.find('.file-input:last');
var $clone = $lastGroup.clone();
$clone.find('.input-file-trigger').text('Select a file...');
$clone.insertAfter($lastGroup);
});
$test.on('click', '.remtest', function(e) {
if ($('.file-input').length > 1)
$(this).closest('.file-input').remove();
}).on('change', '.input-file', function(e) {
if (!this.files)
return;
var $container = $(this).closest('.file-input');
$container.find(".input-file-trigger").text('File name: ' + this.files[0].name);
});
});
.p_test {
display: inline-block;
}
.upl_drop {
border: 2px dashed #000;
margin: 0px 0px 15px 0px;
}
.btn--add p {
cursor: pointer;
}
.input-file-container {
position: relative;
width: auto;
}
.input-file-trigger {
display: block;
padding: 14px 45px;
background: #ffffff;
color: #1899cd;
font-size: 1em;
cursor: pointer;
}
.input-file {
position: absolute;
top: 0;
left: 0;
width: 225px;
opacity: 0;
padding: 14px 0;
cursor: pointer;
}
.input-file:hover+.input-file-trigger,
.input-file:focus+.input-file-trigger,
.input-file-trigger:hover,
.input-file-trigger:focus {
background: #1899cd;
color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="p_test" id="p_test">
<div class="file-input">
<div class="input-file-container upl_drop">
<input class="input-file" type="file">
<label tabindex="0" for="file-upload" class="input-file-trigger">Select a file...</label>
</div>
<div class="file-upload-filename"></div>
</div>
<button class="btn--add" id="addtest">Add</button>
</div>
Note that I've made a couple of other optimisations to the code. Firstly it now makes a clone() of the last available .file-input container when the Add button is clicked. This is preferred over writing the HTML in the JS file as it keeps the two completely separate. For example, if you need to update the UI, you don't need to worry about updating the JS now, as long as the classes remain the same.
Also note that you were originally mixing plain JS and jQuery event handlers. It's best to use one or the other. As you've already included jQuery in the page, I used that as it makes the code easier to write and more succinct.
Finally, note that you didn't need to provide a function to text() as you're completely over-writing the existing value. Just providing the new string is fine.

Set font-weight back if another li is selected

On another question I asked if I could set the font-weight to bold on a text element when that text is selected. This has been completed much to the avail of #Eric ! But currently, when you click a text, you can happily click another one and both of the text will be bold.
How can I prevent more than one text element from being bold?
Here is my code on JSFiddle: http://jsfiddle.net/6XMzf/ or below:
CSS:
html,body {
margin: 0;
padding: 0
}
#background {
width: 100%;
height: 100%;
position: absolute;
left: 0px;
top: 0px;
z-index: 0;
color: white;
}
.stretch {
width:100%;
height:100%;
}
.navigationPlaceholder {
width:100px;
height: 400px;
left: 100px;
top: 100px;
position: absolute;
}
#navigation {
background-color: #000000;
}
#navigationText ul {
font-family: "Yanone Kaffeesatz";
font-weight: 100;
text-align: left;
font-size: 25px;
color: #b2b2b2;
left: 25px;
top: 50px;
position: absolute;
line-height: 40px;
list-style-type: none;
}
.noSelect {
-moz-user-select: none; /* mozilla browsers */
-khtml-user-select: none; /* webkit browsers */
}
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Max Kramer | iOS Developer</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz" />
</head>
<body>
<div id="background" />
<div id="navigation" class="navigationPlaceholder">
<div id="navigationText">
<ul>
<li>iOS</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</div>
</div>
<script type="text/javascript">
var nav = document.getElementById('navigationText');
var navItems = nav.getElementsByTagName('li');
for (var i = 0; i < navItems.length; i++) {
navItems[i].addEventListener('click', function() {
this.style.fontWeight = '400';
}, false);
}
</script>
</body>
</html>
If you don't have a selector engine handy like jQuery and really have to do this in plain Javascript, I would do it like this:
function addClass(elem, className) {
if (elem.className.indexOf(className) == -1) {
elem.className += " " + className;
}
}
function removeClass(elem, className) {
elem.className = elem.className.replace(new RegExp("\\s*" + className), "");
}
var lastSelected = null;
function initNavClickHandler() {
var nav = document.getElementById('navigationText');
var navItems = nav.getElementsByTagName('li');
for (var i = 0; i < navItems.length; i++) {
navItems[i].addEventListener('click', function() {
addClass(this, "selected");
if (lastSelected) {
removeClass(lastSelected, "selected");
}
lastSelected = this;
}, false);
}
}
initNavClickHandler();
Then, add a CSS rule that controls the selected look:
.selected {font-weight: 800;}
This is a lot more flexible for styling because you can add as many CSS rules as you want to the .selected class to change/modify it without ever touching your code.
You can see it work here: http://jsfiddle.net/jfriend00/rrxaQ/
If you can use things like jQuery then this is a much simpler problem. Let me show you the jQuery solution for both highlighting and unhighlighting.
$("#navigationText li").click( function() {
$("#navigationText li").css("fontWeight", "100");
$(this).css("fontWeight", "400");
});
Now you can achieve the same thing yourself without jQuery. You either need to create a global that holds the currently bolded item and remove the fontWeight or just remove the fontWeight from all items (brute force).
//untested with global to store currently selected
var nav = document.getElementById('navigationText');
var activeItem = null;
var navItems = nav.getElementsByTagName('li');
for (var i = 0; i < navItems.length; i++) {
navItems[i].addEventListener('click', function() {
if (activeItem) {activeItem.style.fontWeight = '100'; }
this.style.fontWeight = '400';
activeItem = this;
}, false);
}
//sorry I don't feel like writing a brute force one for you!

Categories

Resources