Blank input adds short line to to-do list - javascript

When you click inside the input box of my to-do list and hit enter, a tiny line is added to the list. (When you enter text, the line height is regular height.) What could be causing this?
Please view my CodePen for my full code.
I'm not sure this is relevant, but here's my JavaScript:
$(function() {
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
// Inserts li as first child of ul
$('ul').prepend('<li>' + toAdd + '</li>');
// Clears input box after clicking '+'
$('input[name=listItem]').val('');
});
// Upon hitting enter, triggers button click and prevents page from refreshing and event bubbling and capturing/trickling
$('input[name=listItem]').keypress(function(e) {
if (e.which == 13) {
$('.button').click();
e.preventDefault();
};
});
$('ul').on('click', 'li', function() {
// Upon list item click, toggleClass() adds class 'strike' for it and fadeOut() completely hides it
$(this).toggleClass('strike').fadeOut('slow');
});
});

Just check on the value you are adding:
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
// Inserts li as first child of ul
if( toAdd == ""){
return false; // return on empty value
}
$('ul').prepend('<li>' + toAdd + '</li>');
// Clears input box after clicking '+'
$('input[name=listItem]').val('');
});

Both the below answers are right and hence upvoted but You can try and add validation to remove this situation
$(function() {
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
if (toAdd === '') {
alert("Input should not be blank");
$('input[name=listItem]').focus();
return;
}
// Inserts li as first child of ul
$('ul').prepend('<li>' + toAdd + '</li>');
// Clears input box after clicking '+'
$('input[name=listItem]').val('');
});
// Upon hitting enter, triggers button click and prevents page from refreshing and event bubbling and capturing/trickling
$('input[name=listItem]').keypress(function(e) {
if (e.which == 13) {
$('.button').click();
e.preventDefault();
};
});
$('ul').on('click', 'li', function() {
// Upon list item click, toggleClass() adds class 'strike' for it and fadeOut() completely hides it
$(this).toggleClass('strike').fadeOut('slow');
});
});
body {
text-align: center;
background: #dfdfdf;
font-family: Helvetica;
font-size: 14px;
color: #666;
background: linear-gradient(to left, #da4453, #89216b);
}
.container {
padding: 20px;
padding-top: 5px;
width: 400px;
/* 0 is for top and bottom and auto (set to equal values for each by browser) for left-right */
margin: 0 auto;
margin-top: 40px;
background: #eee;
border-radius: 5px;
}
form {
/* Needed to display button next to input box */
display: inline-block;
}
input[type="text"] {
border: 1px solid #ccc;
height: 1.6em;
width: 29em;
color: #666;
}
/* Sets appearance of input box boundaries when user clicks inside it */
input:focus {
border-color: #da4453;
/* L to R: horizontal offset, vertical offset, blur radius. A in RGBA is alpha parameter, a number between 0.0 (fully transparent) and 1.0 (fully opaque) */
box-shadow: 0 0 8px rgba(229, 103, 23, 0.6);
outline: 0 none;
}
button.button {
margin-left: -29.8px;
/* 2px added to account for default 1px padding of input box set by user agent (browser) stylesheet */
height: -webkit-calc(1.6em + 2px);
height: calc(1.6em + 2px);
width: 25px;
color: grey;
border: none;
}
.button:hover {
cursor: pointer;
opacity: 0.8;
color: #9a9797;
}
/* Remove margins and padding from list */
ul {
margin: 0;
padding: 0;
}
/* Applies styling to any li descendants of ul (descendant combinator) */
ul li {
text-align: left;
/* Prevents default bullet points */
list-style-type: none;
margin: auto;
cursor: pointer;
position: relative;
background-color: #eee;
/* First value sets top and bottom padding; second value sets right and left */
padding: 1.5px 0;
}
/* Set all odd list items to a different color (zebra stripes) */
ul li:nth-child(odd) {
background: #f9f9f9;
}
/* Sets darker background color on hover over list items */
ul li:hover {
background-color: #ddd;
}
.strike {
text-decoration: line-through;
}
<html>
<head>
<meta charset="UTF-8">
<title>To-Do List</title>
<link rel="stylesheet" href="styles.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="designs.js"></script>
</head>
<body>
<div class="container">
<h2>To Do</h2>
<form name="listForm">
<input type="text" name="listItem" placeholder="Add new">
<button type="button" class="button">+</button>
</form>
<br><br>
<ul>
<li>Work on projects for one hour</li>
<li>Go for a walk</li>
<li>Call parents</li>
</ul>
</div>
</body>
</html>
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
// Inserts li as first child of ul
if(toAdd == ""){
alert("Input Should no be blank");
return;
}
$('ul').prepend('<li>' + toAdd + '</li>');
// Clears input box after clicking '+'
$('input[name=listItem]').val('');
});

Try adding a check to see if there's nothing in the input box first:
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
if (toAdd === '') return;

Using ES6 Syntax
$('.button').on('click'() => {
let toAdd = $('input[name=listItem]').val();
toAdd === '' ? return : null

Related

"return false;" ignored when function is present even if function is empty

I have a click event handler for an anchor that grabs the selector's ID as a variable, has an if parameter and runs 2 functions with return false; at the end to prevent the window from refreshing:
function ItemNumberHistory(ItemNumber) {
var state = {ItemNumberHistory: ItemNumber};
var title = null;
var path = '/Inventory/' + ItemNumber;
history.pushState(state, title, path); // Add item number to URL/history
}
$(document).on('click', '.StoneLink', function(event) {
var ItemNumber = $(this).attr('id'); // Get item number from ID;
// Toggle nav on mobile
if($(navContent).is(':visible')) {
$(navContent).addClass('navHide'); // Hide nav on mobile
$('#navToggleIcon').toggleClass('mdi-close mdi-menu'); // Toggle nav menu icon
}
ItemNumberHistory(ItemNumber);
loadItem(ItemNumber);
return false;
});
For some reason though this still refreshes the window [although return false; is expected to prevent that], but when I comment out ItemNumberHistory(ItemNumber); (line 23) the return false; doesn't refresh the window.
return false; doesn't work when I delete the contents of ItemNumberHistory(ItemNumber); either. It seems that i'm having the issue simply because the function is inside the click event handler.
How do I run my click event handler without the window refreshing on click?!
CODE SNIPPET
var ItemNumberHistory = '';
function loadItem(ItemNumber) {
ItemNumberHistory = ItemNumber;
$('#pageRoot').css('overflow-y', 'hidden');
$('.LoadItem, #StonePage').show(); // Show modal and loader
$.ajax({
url: 'vendors/pages/Inventory/LandingPage/Item.php?number=' + ItemNumber,
method: 'POST',
data: {ItemNumber: ItemNumber},
async: true,
cache: false,
error:
function(jqXHR, strError) {
if(strError == 'timeout') {
// Do something. Try again perhaps?
alert('Seems like there was an error loading this stones information.');
}
},
success:
function(data) {
$('#StoneDetails').html(data);
},
timeout: 3000
});
}
function ItemNumberHistory(ItemNumber) {
var state = {ItemNumberHistory: ItemNumber};
var title = null;
var path = '/Inventory/' + ItemNumber;
history.replaceState(state, title, path); // Add item number to URL/history
}
$(document).on('click', '.StoneLink', function(event) {
var ItemNumber = $(this).attr('id'); // Get item number from ID;
// Toggle nav on mobile
if($(navContent).is(':visible')) {
$(navContent).addClass('navHide'); // Hide nav on mobile
$('#navToggleIcon').toggleClass('mdi-close mdi-menu'); // Toggle nav menu icon
}
ItemNumberHistory(ItemNumber);
loadItem(ItemNumber);
return false;
});
function closeModal() {
if($('#StonePage').is(':visible')) {
$('#StonePage').hide();
$('#pageRoot').css('overflow-y', 'auto');
history.replaceState(null, null, '/Inventory'); // Remove ItemNumber from URL path
}
}
// Hide modal when close button
$(document).on('click', '#CloseModal', function() {
closeModal();
});
// Hide modal on click away
$(document).on('click', '.head, #StonePage', function(event) {
// If clicked anywhere [on #StonePage] outside of .modal
if(!$('.modal').is(event.target) && $('.modal').has(event.target).length === 0) {
closeModal();
}
});
// Hide modal on esc key press
$(document).on('keydown', function(event) {
// keyCode 27 is esc key
if(event.keyCode == 27) {
closeModal();
}
});
.modalContainer {
display: none;
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0;
margin: 130px 0 0 0;
overflow: auto;
z-index: 2;
cursor: pointer;
outline: none;
background-color: rgba(0, 0, 0, .25);
}
.modal {
width: 700px;
height: 375px;
padding: 0;
margin: 20px auto;
box-shadow: 0 0 10px #000;
-webkit-box-shadow: 0 0 10px #000;
-moz-box-shadow: 0 0 10px #000;
-o-box-shadow: 0 0 10px #000;
-ms-box-shadow: 0 0 10px #000;
cursor: default;
background-color: #fff;
}
.StoneDetails {
}
/* .CloseModal height and width are 36px */
.CloseModal {
position: relative;
float: right;
color: #ff0000;
text-align: right;
cursor: pointer;
user-select: none; /* Standard syntax */
-webkit-user-select: none; /* Safari 3.1+ */
-moz-user-select: none; /* Firefox 2+ */
-ms-user-select: none; /* IE 10+ */
z-index: 9;
background-color: transparent;
}
.CloseModal:hover {
text-shadow: 1px 1px 10px rgba(150, 150, 150, 1);
}
.CloseModal:active {
color: #000;
}
/* Load Item */
.LoadItem {
display: none;
position: absolute;
width: 700px;
height: 375px;
margin: auto;
padding-top: 164px;
user-select: none; /* Standard syntax */
-webkit-user-select: none; /* Safari 3.1+ */
-moz-user-select: none; /* Firefox 2+ */
-ms-user-select: none; /* IE 10+ */
overflow: hidden;
z-index: 4;
border: 0px solid red;
background-color: #fff;
}
.noScroll {
position: fixed;
overflow-y: scroll;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Inventory">
<div id="StonePage" class="modalContainer" tabindex="0">
<div class="modal">
<div id="CloseModal" class="CloseModal" title="Close">
<span class="mdi mdi-36px mdi-close"></span>
</div>
<div id="StoneDetails" class="StoneDetails">
<!-- Content appends here -->
</div>
</div>
</div>
<div class="InventoryContent">
<!-- Stone listings -->
<div id="StoneContainer">
<div class="Stone" id="StoneIteration" data-listing="1" data-totalrows="1">
<!-- Stone's landing page -->
<a href="<?php $_SERVER['DOCUMENT_ROOT'] ?>/Inventory/Item Number" class="StoneLink" id="Item Number">
<!-- Image -->
<div class="StoneData StoneIMG">
<img src="image.jpg">
</div>
<!-- Weight -->
<div class="StoneData">
Weight
</div>
<!-- Type -->
<div class="StoneData">
Type
</div>
<!-- Enhancement -->
<div class="StoneData">
Enhancement
</div>
<!-- Dimensions -->
<div class="StoneData">
Dimensions
</div>
<!-- Item Number -->
<div class="StoneData">
#Item Number
</div>
</a>
</div>
</div>
</div>
</div>
I'm not sure if this is what you want.
'a href' is suspected.
change your tag
<a href="javascript:void(0);" class="StoneLink" id="<?php echo $row['number']; ?>">
(or <a href="#" class="StoneLink" id="<?php echo $row['number']; ?>">)
and change your event function
$('.StoneLink').on('click', function(event) {
var ItemNumber = $(this).attr('id'); // Get item number from ID;
// Toggle nav on mobile
if($(navContent).is(':visible')) {
$(navContent).addClass('navHide'); // Hide nav on mobile
$('#navToggleIcon').toggleClass('mdi-close mdi-menu'); // Toggle nav menu icon
}
ItemNumberHistory(ItemNumber);
loadItem(ItemNumber);
location.href = '/Inventory/'+ItemNumber; // '<a href="">' instead
return false;
});
I went through the code you posted and there are a bunch of small, semantic issues (not the culprit here though). I was able to run most of it successfully on my local machine. A couple things:
Make sure you're stopping propagation correctly i.e. event.preventDefault(), not event.preventDefault.
navContent isn't defined (at least within the snippet provided).
Do you need ItemNumberHistory both as a variable and function definition? It's confusing.
I think if you add this you'll be fine:
$('.StoneLink').on('click', function(event) {
event.preventDefault();
var ItemNumber = $(this).attr('id'); // Get item number from ID;
// Toggle nav on mobile
if($(navContent).is(':visible')) {
$(navContent).addClass('navHide'); // Hide nav on mobile
$('#navToggleIcon').toggleClass('mdi-close mdi-menu'); // Toggle nav menu icon
}
ItemNumberHistory(ItemNumber);
loadItem(ItemNumber);
location.href = '/Inventory/'+ItemNumber; // '<a href="">' instead
return false;
});

onmouseover not working in option [duplicate]

I am trying to show a description when hovering over an option in a select list, however, I am having trouble getting the code to recognize when hovering.
Relevant code:
Select chunk of form:
<select name="optionList" id="optionList" onclick="rankFeatures(false)" size="5"></select>
<select name="ranks" id="ranks" size="5"></select>
Manipulating selects (arrays defined earlier):
function rankFeatures(create) {
var $optionList = $("#optionList");
var $ranks = $("#ranks");
if(create == true) {
for(i=0; i<5; i++){
$optionList.append(features[i]);
};
}
else {
var index = $optionList.val();
$('#optionList option:selected').remove();
$ranks.append(features[index]);
};
}
This all works. It all falls apart when I try to deal with hovering over options:
$(document).ready(
function (event) {
$('select').hover(function(e) {
var $target = $(e.target);
if($target.is('option')) {
alert('yeah!');
};
})
})
I found that code while searching through Stack Exchange, yet I am having no luck getting it to work. The alert occurs when I click on an option. If I don't move the mouse and close the alert by hitting enter, it goes away. If I close out with the mouse a second alert window pops up. Just moving the mouse around the select occasionally results in an alert box popping up.
I have tried targeting the options directly, but have had little success with that. How do I get the alert to pop up if I hover over an option?
You can use the mouseenter event.
And you do not have to use all this code to check if the element is an option.
Just use the .on() syntax to delegate to the select element.
$(document).ready(function(event) {
$('select').on('mouseenter','option',function(e) {
alert('yeah');
// this refers to the option so you can do this.value if you need..
});
});
Demo at http://jsfiddle.net/AjfE8/
try with mouseover. Its working for me. Hover also working only when the focus comes out from the optionlist(like mouseout).
function (event) {
$('select').mouseover(function(e) {
var $target = $(e.target);
if($target.is('option')) {
alert('yeah!');
};
})
})
You don't need to rap in in a function, I could never get it to work this way. When taking it out works perfect. Also used mouseover because hover is ran when leaving the target.
$('option').mouseover(function(e) {
var $target = $(e.target);
if($target.is('option')) {
console.log('yeah!');
};
})​
Fiddle to see it working. Changed it to console so you don't get spammed with alerts. http://jsfiddle.net/HMDqb/
That you want is to detect hover event on option element, not on select:
$(document).ready(
function (event) {
$('#optionList option').hover(function(e) {
console.log(e.target);
});
})​
I have the same issue, but none of the solutions are working.
$("select").on('mouseenter','option',function(e) {
$("#show-me").show();
});
$("select").on('mouseleave','option',function(e) {
$("#show-me").hide();
});
$("option").mouseover(function(e) {
var $target = $(e.target);
if($target.is('option')) {
alert('yeah!');
};
});
Here my jsfiddle https://jsfiddle.net/ajg99wsm/
I would recommend to go for a customized variant if you like to ease
capture hover events
change hover color
same behavior for "drop down" and "all items" view
plus you can have
resizeable list
individual switching between single selection and multiple selection mode
more individual css-ing
multiple lines for option items
Just have a look to the sample attached.
$(document).ready(function() {
$('.custopt').addClass('liunsel');
$(".custopt, .custcont").on("mouseover", function(e) {
if ($(this).attr("id") == "crnk") {
$("#ranks").css("display", "block")
} else {
$(this).addClass("lihover");
}
})
$(".custopt, .custcont").on("mouseout", function(e) {
if ($(this).attr("id") == "crnk") {
$("#ranks").css("display", "none")
} else {
$(this).removeClass("lihover");
}
})
$(".custopt").on("click", function(e) {
$(".custopt").removeClass("lihover");
if ($("#btsm").val() == "ssm") {
//single select mode
$(".custopt").removeClass("lisel");
$(".custopt").addClass("liunsel");
$(this).removeClass("liunsel");
$(this).addClass("lisel");
} else if ($("#btsm").val() == "msm") {
//multiple select mode
if ($(this).is(".lisel")) {
$(this).addClass("liunsel");
$(this).removeClass("lisel");
} else {
$(this).addClass("lisel");
$(this).removeClass("liunsel");
}
}
updCustHead();
});
$(".custbtn").on("click", function() {
if ($(this).val() == "ssm") {
$(this).val("msm");
$(this).text("switch to single-select mode")
} else {
$(this).val("ssm");
$(this).text("switch to multi-select mode")
$(".custopt").removeClass("lisel");
$(".custopt").addClass("liunsel");
}
updCustHead();
});
function updCustHead() {
if ($("#btsm").val() == "ssm") {
if ($(".lisel").length <= 0) {
$("#hrnk").text("current selected option");
} else {
$("#hrnk").text($(".lisel").text());
}
} else {
var numopt = +$(".lisel").length,
allopt = $(".custopt").length;
$("#hrnk").text(numopt + " of " + allopt + " selected option" + (allopt > 1 || numopt === 0 ? 's' : ''));
}
}
});
body {
text-align: center;
}
.lisel {
background-color: yellow;
}
.liunsel {
background-color: lightgray;
}
.lihover {
background-color: coral;
}
.custopt {
margin: .2em 0 .2em 0;
padding: .1em .3em .1em .3em;
text-align: left;
font-size: .7em;
border-radius: .4em;
}
.custlist,
.custhead {
width: 100%;
text-align: left;
padding: .1em;
border: LightSeaGreen solid .2em;
border-radius: .4em;
height: 4em;
overflow-y: auto;
resize: vertical;
user-select: none;
}
.custlist {
display: none;
cursor: pointer;
}
.custhead {
resize: none;
height: 2.2em;
font-size: .7em;
padding: .1em .4em .1em .4em;
margin-bottom: -.2em;
width: 95%;
}
.custcont {
width: 7em;
padding: .5em 1em .6em .5em;
/* border: blue solid .2em; */
margin: 1em auto 1em auto;
}
.custbtn {
font-size: .7em;
width: 105%;
}
h3 {
margin: 1em 0 .5em .3em;
font-weight: bold;
font-size: 1em;
}
ul {
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>
customized selectable, hoverable resizeable dropdown with multi-line, single-selection and multiple-selection support
</h3>
<div id="crnk" class="custcont">
<div>
<button id="btsm" class="custbtn" value="ssm">switch to multi-select mode</button>
</div>
<div id="hrnk" class="custhead">
current selected option
</div>
<ul id="ranks" class="custlist">
<li class="custopt">option one</li>
<li class="custopt">option two</li>
<li class="custopt">another third long option</li>
<li class="custopt">another fourth long option</li>
</ul>
</div>

How to have two different bgcolor changing events

I'm trying to have a bgcolor change for an element on mouseover, mouseout, and onclick. The problem is Javascript overwrites my onclick with mouseout, so I can't have both. So is there any way to have mouseover reset after mouseout?
function init() {
document.getElementById('default').onmouseover = function() {
tabHoverOn('default', 'grey')
};
document.getElementById('default').onmouseout = function() {
tabHoverOff('default', 'yellow')
};
document.getElementById('section2').onmouseover = function() {
tabHoverOn('section2', 'grey')
};
document.getElementById('section2').onmouseout = function() {
tabHoverOff('section2', 'yellow')
};
document.getElementById('section3').onmouseover = function() {
tabHoverOn('section3', 'grey')
};
document.getElementById('section3').onmouseout = function() {
tabHoverOff('section3', 'yellow')
};
}
function tabHoverOn(id, bgcolor) {
document.getElementById(id).style.backgroundColor = bgcolor;
}
function tabHoverOff(id, bgcolor) {
document.getElementById(id).style.backgroundColor = bgcolor;
}
var current = document.getElementById('default');
function tab1Highlight(id) {
if (current != null) {
current.className = "";
}
id.className = "tab1highlight";
current = id;
}
function tab2highlight(id) {
if (current != null) {
current.className = "";
}
id.className = "tab2highlight";
current = id;
}
function tab3highlight(id) {
if (current != null) {
current.className = "";
}
id.className = "tab3highlight";
current = id;
}
window.onload = init();
body {
width: 900px;
margin: 10px auto;
}
nav {
display: block;
width: 80%;
margin: 0 auto;
}
nav > ul {
list-style: none;
}
nav > ul > li {
display: inline-block;
margin: 0 3px;
width: 150px;
}
nav > ul > li > a {
width: 100%;
background-color: #ffff66;
border: 1px solid #9b9b9b;
border-radius: 12px 8px 0 0;
padding: 8px 15px;
text-decoration: none;
font-weight: bold;
font-family: arial, sans-serif;
}
main {
display: block;
width: 80%;
margin: 0 auto;
border: 1px solid #9b9b9b;
padding: 10px;
}
main > h1 {
font-size: 1.5em;
}
.tab1highlight {
background-color: #339966;
color: white;
}
.tab2highlight {
background-color: #ff6666;
color: white;
}
.tab3highlight {
background-color: #6600ff;
color: white;
}
main img {
border: 5px solid #eeefff;
width: 80%;
margin-top: 20px;
}
<body>
<nav>
<ul>
<li>Section 1</li>
<li>Section 2</li>
<li>Section 3</li>
</ul>
</nav>
<main>
<h1>Exercise: Navigation Tab #5</h1>
<ul>
<li>
Combine the navigation tab exercises #1, #3, and #4 in one file, including <br>
<ul>
<li>temporarily change the background color of a tab when the cursor is hovering on it.</li>
<li>set the foreground and background color of the tab being clicked.</li>
<li>change the background color of the main element based on the selected tab.</li>
</ul>
<p>
To test, click on a tab and then move your mouse around. For example, the third tab is clicked, the tab background color is switched to blue. Then hover the mouse over the third tab, the background color of the tab should be switch to light green and then back to blue after the mouse moves out.
</p>
<img src="menu_tab5.jpg">
</li>
</ul>
</main>
It's generally a good idea to keep CSS out of JavaScript completely if you can help it. A better strategy for solving the hover problem is to use the CSS pseudo selector :hover rather than coding the color changes in JavaScript. If you give all your tabs the same class, you only have to write the CSS once:
.tab {
background-color: yellow;
}
.tab:hover {
background-color: grey;
}
Once you've done that, you can also relegate the click styling to CSS by creating an event handler that adds and removes a special class each time a tab is clicked.
In the CSS file:
.tab.clicked {
background-color: blue;
}
And then in JavaScript, something like:
var tabs = document.getElementsByClassName('tab');
for (i = 0; i < tabs.length; i ++) {
tabs[i].onclick = function (ev) {
for (i = 0; i < tabs.length; i ++) {
tabs[i].classList.remove('clicked');
}
ev.currentTarget.classList.add('clicked');
};
}
I've created a JSFiddle to illustrate.
Try updating a Boolean variable.
var Ele = document.getElementById('default');
var clicked = false;
Ele.onclick = function(){
clicked = true;
// add additional functionality here
}
Ele.onmouseover = function(){
clicked = false;
// add additional functionality here
}
Ele.onmouseout = function(){
if(!clicked){
// add additional functionality here
}
}

Trouble Removing One Child DIV At A Time

I am building a simple Grocery List App and I am having issues trying to remove a place holder div element.
HTML
<!DOCTYPE html>
<html>
<head>
<title>Grocery List App</title>
<link type="text/css" href="style/form.css" rel="stylesheet"/>
</head>
<body>
<div id="container">
<div id="left_side">
<div id="to_buy">To Buy:</div>
</div>
<div id="right_side">
<div id="in_cart">In Cart:</div>
</div>
</div>
<input type="text" id="item_body" placeholder="Type Item to Add">
<script src="scripts/jquery-1.11.2.min.js"></script>
<script src="scripts/grocery.js"></script>
<script src="scripts/jquery-ui/jquery-ui.js"></script>
</body>
</html>
JS
$(function () {
var rmv = false;
$('#item_body').keydown(function(e) {
if (e.keyCode == 13) {
var add = $('#item_body').val();
$("#to_buy").append('<div class="draggable_item">' + add + '</div>');
$("#in_cart").append('<div class="holder"></div>');
}
$(".draggable_item").draggable( {
axis: "x"
});
$(".draggable_item").dblclick(function() {
this.remove();
$('#in_cart > div:first').remove();
});
});
});
CSS
#to_buy {
float:left;
width: 50%;
height: 100%;
color: #00E5EE;
}
#in_cart {
float: left;
width: 49%;
height: 100%;
color: #00E5EE;
}
#container {
width:100%;
height: 100%;
}
#left_side {
height: 100%;
width: 50%;
float:left;
background: #5D5851;
}
#right_side {
height: 100%;
width: 50%;
float: left;
background: #6D5D4D;
}
#item_body {
float:left;
clear:both;
color: #326B62;
}
body {
background: #B1ADA5;
}
.draggable_item {
color: #FFF;
}
.holder {
height: 20px;
}
So the screen is split vertically between "to_buy" and "in_cart." When I add an item to "to_buy" I also add a "dummy" div to "in_cart" so that the two sides remain even. However, when I double click to remove an item, when
$('#in_cart > div:first').remove();
gets called, first one div is removed, then on the next double click two, then four etc etc. Apparently, it is getting called multiple times or something else wonky is going wrong.
This is because you bind event handlers for double click event on every Enter key press so they multiply on every item addition. Just move dblclick registration outside:
var rmv = false;
$('#item_body').keydown(function (e) {
if (e.keyCode == 13) {
var add = $('#item_body').val();
$("#to_buy").append('<div class="draggable_item">' + add + '</div>');
$("#in_cart").append('<div class="holder"></div>');
}
$(".draggable_item").draggable({
axis: "x"
});
});
$("#left_side").on("dblclick", ".draggable_item", function () {
this.remove();
$('#in_cart > div:first').remove();
});
Also note, that it makes sense to delegate double click event to the parent container #left_side so you don't have to worry about presence of elements at the time of event registration.
Here is a demo: http://jsfiddle.net/hx11gkcj/

Make contents of div scroll down with overflow

I have created a small chat system for a project I am making. The chat is functioning well. However, I cannot figure out how to make it so the div stays at the bottom of the chat, rather than having to scroll down to read the last thing someone said.
I am referring to another similar question posted on here for guidance. How to keep a div scrolled to the bottom as HTML content is appended to it via jquery, but hide the scroll bar?
But it still will not work for me. The chat is then stored in a chat.txt file. Each line is surrounded in tags. The following is the code I am using.
js in header:
$container = $('#chat-area');
$container[0].scrollTop = $container[0].scrollHeight;
$('#sendie').keypress(function (e) {
if (e.which == 13) {
$container = $('#chat-area');
$container.append('<p>' + e.target.value + '</p>');
$container.animate({ scrollTop: $container[0].scrollHeight }, "slow");
}
});
chat.php:
<script type="text/javascript">
// strip tags
name = name.replace(/(<([^>]+)>)/ig,"");
// display name on page
$("#name-area").html("You are: <span>" + name + "</span>");
// kick off chat
var chat = new Chat();
$(function() {
chat.getState();
// watch textarea for key presses
$("#sendie").keydown(function(event) {
var key = event.which;
//all keys including return.
if (key >= 33) {
var maxLength = $(this).attr("maxlength");
var length = this.value.length;
// don't allow new content if length is maxed out
if (length >= maxLength) {
event.preventDefault();
}
}
});
// watch textarea for release of key press
$('#sendie').keyup(function(e) {
if (e.keyCode == 13) {
var text = $(this).val();
var maxLength = $(this).attr("maxlength");
var length = text.length;
// send
if (length <= maxLength + 1) {
chat.send(text, name);
$(this).val("");
} else {
$(this).val(text.substring(0, maxLength));
}
}
});
});
</script>
<p id="name-area"></p>
<div id="chatWrap"><div id="chat-area"></div></div>
<form id="send-message-area">
<p>Your message: </p>
<textarea id="sendie" maxlength = '100' ></textarea>
</form>
</div>
css:
#pageWrap
{
position: fixed;
display: block;
right: 0;
bottom: 0;
background: #8B1918;
box-shadow: 0px 0px 12px #333;
transition: height .5s;
}
#pageWrap p
{
color: white;
font-family: arial;
margin-left: 5px;
margin-bottom: 4px;
}
#chatWrap
{
width: 200px;
height: 200px;
overflow: scroll;
overflow-x:hidden;
box-shadow: 1px 1px 10px #333 inset;
color: white;
font-family: arial;
font-size: 14px;
}
#chat-area
{
padding-left: 11px;
}
#sendie
{
resize: none;
display: block;
width: 92%;
margin-left: auto;
margin-right: auto;
margin-bottom: 6px;
}
I got it (partially) working for you. Here are the issues I discovered:
Try not to name variables starting with $ - it creates unnecessary confusion.
You didn't declare $container as var, so you're using a variable before declaring it.
jQuery supports 99% of everything you can do with plain Javascript, but makes it better. Wherever possible, I changed your code to use jQuery instead.
I'm not sure about e.target.value, but $('#sendie').val() works just as well.
You definitely needed to wrap this in the body onload function.
You want to add e.preventDefault(); in the event handler so that it doesn't put a return character in the box.
You didn't clear the input textarea (with jQuery it's just $('#sendie').val('');).
The font color of the chat message area was white (at least on JSFiddle it was). Messages were invisible due to this.
Here's a fiddle demonstrating everything working (as far as I know) - http://jsfiddle.net/U9XAv/
And here's the updated Javascript:
$(function()
{
var container = $('#chat-area');
container.css('scrollTop', container.css('scrollHeight'));
$('#sendie').keydown(function (e)
{
if (e.which == 13)
{
container.append('<p>' + $(this).val() + '</p>')
.animate({ scrollTop: container[0].scrollHeight) }, "slow");
$(this).val('');
e.preventDefault();
}
});
});
And the CSS I changed:
#chat-area
{
padding-left: 11px;
color: black;
}

Categories

Resources