jQuery keydown to create list - javascript

I'm trying to create a list where users can type text in a form field, and the next form field appears underneath it everytime user presses enter. This is my code:
HTML:
<body>
<form class="list">
<input type="text" name="list">
</form>
</body>
CSS:
.list {
margin-left: auto;
margin-right: auto;
margin-top: 230px;
width: 305px;
border-radius: 2px;
}
form input {
height: 40px;
width: 300px;
background-color: blue;
color: white;
font-size: 15px;
font-family: helvetica;
}
JS:
$(document).ready(function(){
$('form input').keydown(function(e){
if(e.keyCode == 13) {
var store = $(this).val();
$(this).parents().append($('input'));
};
});
})
This gives me 2 new unformatted boxes, instead of one formatted box underneath it. Pressing "enter" on the new unformatted boxes gives me newer unformatted boxes and messes up the page. What's wrong with the code?

You have a few issues.
You are using parents which will select all parents of the element. I believe you really just want the direct parent, so use just parent. (This is why 2 elements are created instead of one as the element has 2 parents in addition to the form, body and html).
By doing append($('input')) you are appending your existing input(s) and not creating a new input. You should instead do append($('<input/>')) to create a new input and append that.
With these changes made, you now need to use on for event delegation in order to have the keydown handler affect your dynamically created inputs. (more information on event delegation in the on documentation.)
With those changes you will end up with this:
$('form').on('keydown', 'input', function(e){
if(e.keyCode == 13) {
var store = $(this).val();
$(this).parent().append($('<input/>'));
};
});
http://jsfiddle.net/XjpG7/

Instead of appending, why don't you try having the box you want to show up already in your HTML, but just hidden by default, then use jQuery to show it, something like:
$(document).ready(function(){
$('.someOtherForm').hide();
$('form input').keydown(function(e){
if(e.keyCode == 13) {
var store = $(this).val();
$('.someOtherForm').show();
};
});
})
Just be sure to also include whatever other form you want in your html file to hide and show and you should be good to go.

Related

Return value of document.querySelectorAll("[value='a']") would not change after element value being modified [duplicate]

N.B.: I should note that the proper solution to this is to just use the 'placeholder' attribute of an input, but the question still stands.
Another N.B.: Since, as Quentin explains below, the "value" attribute stores the default value, and the input.value IDL attribute stores the current value, the JavaScript I used to "fix" the problem in my below example is non-conforming, as it uses the (non-IDL) value attribute to store current, rather than default, values. Besides, it involves DOM access on every key press, so it was always just a flawed demo of the problem I was having. It's actually quite terrible code and shouldn't be used ever.
CSS selectors made me think that I could make an input with a label that acts as a preview without any JS. I absolutely position the input at 0,0 inside the label (which is displayed as an inline-block) and give it a background of "none", but only if it's got a value of "" and isn't focussed, otherwise it has a background colour, which obscures the label text.
The HTML5 spec says that input.value reflects the current value of an input, but even though input.value updates as you type into an input, CSS using the input[value=somestring] selector applies based only on what was explicitly typed into the document, or set in the DOM by the JavaScript setAttribute method (and perhaps by other DOM-altering means).
I made a jsFiddle representing this.
Just in case that is down, here is an HTML document containing the relevant code:
<!doctype html>
<head>
<meta charset="utf-8" />
<title>The CSS Attribute selector behaves all funny</title>
<style>
label {
display: inline-block;
height: 25px;
line-height: 25px;
position: relative;
text-indent: 5px;
min-width: 120px;
}
label input[value=""] {
background: none;
}
label input, label input:focus {
background: #fff;
border: 1px solid #666;
height: 23px;
left: 0px;
padding: 0px;
position: absolute;
text-indent: 5px;
width: 100%;
}
</style>
</head>
<body>
<form method="post">
<p><label>name <input required value=""></label></p>
</form>
<p><button id="js-fixThis">JS PLEASE MAKE IT BETTER</button></p>
<script>
var inputs = document.getElementsByTagName('input');
var jsFixOn = false;
for (i = 0; i < inputs.length; i++) {
if (inputs[i].parentNode.tagName == 'LABEL') { //only inputs inside a label counts as preview inputs according to my CSS
var input = inputs[i];
inputs[i].onkeyup= function () {
if (jsFixOn) input.setAttribute('value', input.value);
};
}
}
document.getElementById('js-fixThis').onclick = function () {
if (jsFixOn) {
this.innerHTML = 'JS PLEASE MAKE IT BETTER';
jsFixOn = false;
} else {
this.innerHTML = 'No, actually, break it again for a moment.';
jsFixOn = true;
}
};
</script>
</body>
</html>
I could be missing something, but I don't know what.
The value attribute sets the default value for the field.
The value property sets the current value for the field. Typing in the field also sets the current value.
Updating the current value does not change the value attribute.
Attribute selectors only match on attribute values.
There are new pseudo classes for matching a number of properties of an input element
:valid
:invalid
:in-range
:out-of-range
:required
A required element with no value set to it will match against :invalid. If you insist on using the value instead of placeholder, you could simply add a pattern or a customValidity function to force your initial value to be counted as invalid.

Can't hide other elements while clicking on another

I'm trying to make a toggle which works, but every element I click on creates a stack of these showed elements. Instead I'm trying to hide everything and display only element that I clicked on. Now I can only hide it when I click on the same element twice, which is not what I want. I want to click on one and hide previous ones that were showing.
.totalpoll-choice-image-2 is a bunch of images that always has to be shown. They are what the user clicks on to display hidden description under each image. That description shows up when I click on .totalpoll-choice-image-2. There are 5 images with that class. The next image I click on, I want to hide the previous description box.
My code:
jQuery(document).ready(function() {
var element = document.getElementsByClassName("totalpoll-choice-image-2");
var elements = Array.prototype.slice.call(Array.from( element ) );
console.log(elements);
jQuery(element).each(function(item) {
jQuery(this).unbind('click').click(function(e) {
e.stopPropagation();
var id = jQuery(this).attr("data-id");
console.log(this);
//jQuery("#" + id).css({"display": 'block !important'});
//document.getElementById(id).style.setProperty( 'display', 'block', 'important' );
var descriptionContainer = document.getElementById(id);
var thiss = jQuery(this);
console.log(thiss);
console.log(jQuery(descriptionContainer).not(thiss).hide());
jQuery(descriptionContainer).toggleClass("show");
});
})
})
You can attach event handlers to a group of DOM elements at once with jQuery. So in this case, mixing vanilla JS with jQuery isn't doing you any favors - though it is possible.
I threw together this little example of what it sounds like you're going for.
The script itself is very simple (shown below). The classes and IDs are different, but the idea should be the same:
// Assign click handlers to all items at once
$('.img').click(function(e){
// Turn off all the texts
$('.stuff').hide();
// Show the one you want
$('#' + $(e.target).data('id')).show();
})
https://codepen.io/meltingchocolate/pen/NyzKMp
You may also note that I extracted the ID from the data-id attribute using the .data() method, and attached the event listener with the .click() method. This is the typical way to apply event handlers across a group of jQuery objects.
From what I understood based on your comments you want to show only description of image that has been clicked.
Here is my solution
$('.container').on('click', 'img', function() {
$(this).closest('.container').find('.image-description').addClass('hidden');
$(this).siblings('p').removeClass('hidden');
});
https://jsfiddle.net/rtsj6r41/
Also please mind your jquery version, because unbind() is deprecated since 3.0
You can use event delegation so that you only add your event handler once to the parent of your images. This is usually the best method for keeping work the browser has to do down. Adding and removing classes is a clean method for show and hide, because you can see what is happening by looking at your html along with other benefits like being easily able to check if an item is visible with .hasClass().
jsfiddle: https://jsfiddle.net/0yL5zuab/17/
EXAMPLE HTML
< div class="main" >
<div class="image-parent">
<div class="image">
</div>
<div class="image-descr">
Some text. Some text. Some text.
</div>
</div>
<div class="image-parent">
<div class="image">
</div>
<div class="image-descr">
Some text. Some text. Some text.
</div>
</div>
<div class="image-parent">
<div class="image">
</div>
<div class="image-descr">
Some text. Some text. Some text.
</div>
</div>
<div class="clear">
</div>
</div>
EXAMPLE CSS
.image-parent{
height: 100px;
width: 200px;
float: left;
margin: 5px;
}
.image-parent .image{
background: blue;
height: 50%;
width: 100%;
}
.image-descr{
display: none;
height: 50%;
width: 100%;
}
.show-descr{
display: block;
}
.clear{
clear: both;
}
EXAMPLE JQUERY
$(".main").on("click", ".image-parent", ShowDescription);
function ShowDescription(e) {
var $parent = $(e.target).parent(".image-parent");
var $desc = $parent.find(".image-descr");
$(".image-descr").removeClass("show-descr");
$desc.addClass("show-descr");
}

Adding a newline character and display input from a textarea

I have a text are in a form. I used this code
$('textarea').keypress(function (event) {
if (event.which == 13) {
event.preventDefault();
var s = $(this).val();
$(this).val(s + "<br />");
}
});
to allow users to go the next line using the enter button. I tried using both and \n
In the form, the user is able to go to a new line. However, when the input is displayed on a page, the new line doesn't show, and any text after the new line does not appear. However, it is still there- if you go to edit the form it stills shows the text typed after you click enter. I added
white-space: pre-wrap;
into the css for text boxes in my css file trying to resolve the issue. However, it still did not work. Any suggestions/ input on how to resolve this?
You don't want to insert the <br/> tag as they type. You really don't want to do anything to their text as they type. If you want to maintain their line breaks, you can convert them to <br/> tags before you inject them into an element.
$('#text').keyup(function(event) {
var text = $("#text").val();
text = text.replace(/(?:\r\n|\r|\n)/g, '<br />');
$("#result").html(text);
});
textarea {
min-width: 200px;
min-height: 200px;
float: left;
}
#result {
float: left;
border: 1px solid red;
padding: 10px;
margin-left: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="text" placeholder="Type in here"></textarea>
<div id="result"></div>

Gallery. Display divs corresponding to clicked <li> item. Javascript

I'm trying to build a basic gallery which displays a large image [div] depending on which image is clicked. The thumbnail images are stored in a basic unordered list.
I'm a javascript noob, I could use getElementById to change display class etc but I'd prefer not to have a separate function for each image, of which they're may be 100 or so.
Is there a way to call the same function to display a different div depending on which image is clicked [a larger version of that image]?
So:
If img1 is clicked display divA,
If img2 is clicked display divB,
If img3 is clicked display divC...
Many thanks.
The event passed to the onclick method has a target parameter, which refers to the element that was clicked.
Please post your code, preferably in a working JsFiddle, to get a more targeted answer.
Here is a general example of what you want to achieve:
document.onclick = function(e) {
// e.target is the img that was clicked, display the corresponding div
// Get the image number from the id
var number = e.target.id.substr(3)
// Display the corresponding div
document.getElementById('div' + number).style.visibility = 'visible';
}
Please note that the last line will most likely be different in your implementation - I don't know how you are displaying these divs.
You could try as follows
Assign id to all images in such a manner when they will be clicked we
could generate the corresponding div's id with some logical
manipulation.
Such as
images would have id like img_divA,img_divB and when they will be clicked , get there id and do some stuff like substring and you will get divA , divB and so on .. Finally show that by javascript ..
You could do something like this. Here actually a function is created per clickable dom element, but they are programmatically created. I use the num attribute to make the correspondence between the images to show and the images to click but there is many other (good) ways to do it.
// retrieve the divs to be clicked
var toClicks = document.querySelectorAll(".img-to-click");
[].forEach.call(toClicks, function(node){
// retrieve the target image
var num = node.getAttribute("num");
var target = document.querySelector(".img-to-show[num=\"" + num + "\"]");
// create the click listener on this particular dom element
// (one of the image to click)
node.addEventListener('click', function(){
// hide any currently displayed image
var current = document.querySelector(".img-to-show.shown");
if(current) current.classList.remove("shown");
// set the new current
target.classList.add("shown");
});
});
#to-display {
position: relative;
width: 100%;
height: 50px;
}
#to-click {
position: relative;
margin-top: 20px;
}
.img-to-show {
position: absolute;
width: 100%;
height: 100%;
display: none;
}
.img-to-show.shown {
display: block;
}
.img-to-click{
display: inline-block;
background-color: gray;
width: 50px;
color:white;
text-align: center;
line-height: 50px;
vertical-align: middle;
height: 50px;
cursor:pointer;
}
<div id="to-display">
<div class="img-to-show" num="1" style="background-color:blue;"></div>
<div class="img-to-show" num="2" style="background-color:red;"></div>
</div>
<div id="to-click">
<div class="img-to-click" num="1">1</div>
<div class="img-to-click" num="2">2</div>
</div>

Opening a javascript dialog box to store to the complete file location into a var

I need your help.
I would like to design a javascript function, such that when I call it, it will open up a dialog box asking me to navigate to the selected file, once I click on the "open" button, it will then save the file's path into a var.
How do you do this? I would NOT like to the input type="file" method, as I dont require that particular input to be on my page.
ie:
function getlocation() {
var x = popup the open file dialog box and let the user select a file
}
The only way to allow the user to select a file is to use an <input type="file" />1. You don't have to have this element visible, just on the page.
When a user selects a file, all you can get from it is its name. You cannot get its path. Also, note that file upload elements are asynchronous. You need to use the onchange event (callback) to get the name.
You can hide the upload element using display: none, and then just have another JavaScript function programmatically trigger it. (NOTE: This method doesn't work in Opera, and possibly other browsers. It was tested in Chrome, Firefox, and IE 8/9)
<style>
#getFile{
display: none;
}
</style>
<input type="file" id="getFile" />
<button id="openFile" type="button">Click Me</button>
<script>
var uploadElement = document.getElementById('getFile'),
uploadTrigger = document.getElementById('openFile'),
openFileUpload = function(){
uploadElement.click();
},
alertValue = function () {
alert(uploadElement.value);
};
if (window.addEventListener) {
uploadTrigger.addEventListener('click', openFileUpload);
uploadElement.addEventListener('change', alertValue);
} else {
uploadTrigger.attachEvent('onclick', openFileUpload);
uploadElement.attachEvent('onchange', alertValue);
}
</script>
DEMO: http://jsfiddle.net/rJA7n/3/show (Edit it at: http://jsfiddle.net/rJA7n/3/)
Another method that should work in most browsers (including Opera) is to make the file upload element "invisible" and put an element on top of it. So, when you click on what you think is a button, you're really clicking on the upload element. AJAX uploaders (like http://fineuploader.com/) use this method to allow you to "style" upload buttons.
<style>
#getFile{
width: 100px;
opacity: 0;
filter: alpha(opacity = 0);
}
#openFile{
display: inline;
margin-left: -100px;
background-color: red;
height: 30px;
width: 100px;
padding: 10px;
color: white;
text-align: center;
}
</style>
<input type="file" id="getFile" />
<div id="openFile">Click Me</div>
<script>
var uploadElement = document.getElementById('getFile'),
alertValue = function(){
alert(uploadElement.value);
};
if(window.addEventListener){
uploadElement.addEventListener('change', alertValue);
}
else{
uploadElement.attachEvent('onchange', alertValue);
}
</script>
DEMO: http://jsfiddle.net/cKGft/4/show/ (Edit it at: http://jsfiddle.net/cKGft/4/)
1 Well, you can use drag and drop if you want to be really fancy. I made a quick demo of that here: http://jsfiddle.net/S6BY8/2/show (edit it at: http://jsfiddle.net/S6BY8/2/)

Categories