Jquery .append() appends on every event - javascript

I have very minimal javascript and jquery knowledge, so the problem is, when click with mouse "li" tab and press ENTER jquery attach .append() on every mouse click event.
$(document).on("click", function(event){
let $ul_elem = $(event.target).parent().parent();
const $li = '<li><input type="text" name="geras"></li>'
if($(event.target).parent().prop("localName")=="li"){
console.log($(this.event))
$(window).on("keydown", function(event){
if(event.keyCode == 13) {
event.preventDefault();
$($ul_elem).append($li);
$($ul_elem).children().last().children().focus();
return false
}
})
}
else{
$(window).unbind("keydown");
}
})
in result if i click like 5 times with my mouse on the same li tab, it will create 5 new const $li elements and i dont want that.

You should avoid binding event handlers in context of another event handler. Your code currently rebinds the keydown handler on each click (when the if statements succeeds.) This is why the code appends several elements on each Enter. I guess you want to append li elements to ul elements conditionally. If yes this is one way of doing it:
$(document).on("click", "ul", function() {
$(this).toggleClass('active');
});
$(window).on("keydown", 'ul.active', function(event) {
if (event.keyCode == 13) {
const $ul_elem = $(this);
const li = '<li><input type="text" name="geras"></li>'
event.preventDefault();
$ul_elem.append(li);
$ul_elem.children().last().children().focus();
return false
}
})
This makes the keydown handler work conditionally by using event delegation. In case you want to listen to the keydown event of input elements you can just code $(document).on("keydown", 'input[type=text]', function(event) { ... and there is no need to use click handler. I'm still not sure what you are trying to achieve though.
what I want to do is after i put text in my default li > input field and press ENTER i want to create new li in ul
This should do it:
$(document).on("keyup", 'li input[type=text]', function(event) {
if (event.keyCode == 13) {
const $ul_elem = $(this).closest('ul');
const li = '<li><input type="text" name="geras"></li>'
event.preventDefault();
$ul_elem.append(li);
$ul_elem.children().last().children().focus();
}
})

Related

this.id on an Element Event Listener becomes an array of all id's of elements clicked

I have an event listener on all textboxes. When a textbox is clicked, I'd like to open a keyboard. On Enter of the keyboard I'd then like to use the id of the textbox which called it to do some logic. However the id (txtbxId in code) just becomes the first textbox I click, then the second textbox I click in an array.
E.g, the alert becomes 'textbox1' - after second textbox click alert is 'textbox1' 'textbox2'
I've tried to force the variable id to '', to delete it etc. to no avail,
Code snippet here:
$('.textbox').click(function() {
var txtbxId = this.id;
$("#Keyboard").show();
$(document).on('keydown', function(e) {
if (e.which === 13) {
alert(txtbxId);
}
});
});
});
The issue is because you're nesting events. Therefore as well as duplicating the keydown event when a click event happens, you're supplying each individual id to those events.
To fix this, use a single event handler for all the .textbox elements, and read their own id from the reference to the element which raised the event which is available through the this keyword:
$('.textbox').click(function() {
$("#Keyboard").show();
});
$(document).on('keydown', '.textbox', function(e) {
if (e.which === 13) {
alert(this.id);
}
});
The problem is that your on('keydown') function the first time you click a textbox never gets unassigned, so for every time you click a .textbox, you're making a NEW keydown callback, but not removing your old ones.
I would recommend making an object outside of your onClick callback which manages .keydown callbacks, so that you only have one at any time.
Something like this:
window.keydownmanager = {
init: () => {
$(document).on('keydown', function (e) {
window.keydownmanager.callback(e);
});
},
callback: () => {},
setCallback: (cb) => {
window.keydownmanager.callback = cb;
}
}
And inside your onClick callback, do this:
var txtbxId = this.id;
$("#Keyboard").show();
window.keydownmanager.setCallback(function(e) {
if (e.which === 13) {
alert(txtbxId);
}
})

Button with focus - run function on 'Enter'

I have my code below. It's doing what I want. What I want to also do is run this function when a user use their keyboard to tab to the .add-row button and then presses enter. How do I make that run?
$('body').on('click', '.add-row', function(e) {
$( this ).html('Hide').removeClass('add-row').addClass('hide-row');
$( this ).parent().parent().next().show();
});
My understanding is you want the button to have focus and the user to press enter to fire the event, yeah? If so, then using the :focus pseudo class selector on the .add-row should work with the keypress event
$("body").on("keypress", ".add-row:focus", function(e) {
var ENTER_KEY_CODE = 13;
if (e.keyCode === ENTER_KEY_CODE)
{
alert("Enter key pressed");
// perform hide row and other operations here
}
});

Trigger click event on DOM element

I tried to trigger a click event on an selected DOM element but my code won't work.
You can see my attempt on JSFiddle.
<ul class="list-group">
LG GOLA 8M
LG 5-6M
LP 5-6M
</ul>
$(document).ready(function() {
// I get the string tr from URL parameters
var tr = "fix_LG%20GOLA%208M";
if (tr !== null) {
var terminrahmen = $('.list-group-item').filter(function() {
return $(this).text() === decodeURI(tr).substring(4);
});
// Trigger click event on .list-group-item
terminrahmen.click();
}
// The function to be executed
$('.list-group-item').click(function() {
alert($(this).text());
});
});
When the DOM was loaded I collect some data from URL parameters and compare the data with DOM elements. This part works fine.
After that I get an element and I would like to trigger an click event. The click event should "execute" a specified function.
Have anyone a good solution for me? Thanks in advance.
http://jsfiddle.net/azg2R/2/
Put the click event on top in the ready event.. The click event needs to be triggered after registering the event. It was not happening before
$(document).ready(function() {
// The function to be executed
$('.list-group-item').click(function() {
alert($(this).text());
});
// I get the string tr from URL parameters
var tr = "fix_LG%20GOLA%208M";
if (tr !== null) {
var terminrahmen = $('.list-group-item').filter(function() {
return $(this).text() === decodeURI(tr).substring(4);
});
// Trigger click event on .list-group-item
terminrahmen.click();
}
});
The problem is that you are triggering click event before attaching event handler to it. So you just need to move click handler before triggering click and everything would work as you expected:
$(document).ready(function() {
// The function to be executed
$('.list-group-item').click(function() {
alert($(this).text());
});
// I get the string tr from URL parameters
var tr = "fix_LG%20GOLA%208M";
if (tr !== null) {
var terminrahmen = $('.list-group-item').filter(function() {
return $(this).text() === decodeURI(tr).substring(4);
});
// Trigger click event on .list-group-item
terminrahmen.click();
}
});
JSFiddle

when removing a child element I get an error that it may have already been removed in a "blur" event

I have a dynamic element added to a LI element. When I remove it in a "blur" event it works fine. But when I attempt to remove the element from the parent in a "keydown" event it throws an error that the child may already have been removed in a blur event.
The item is removed as expected and the flow continues but I get an error every time on the "keydown" event.
// I get the error in this event.
input.addEventListener('keydown', function (event) {
if (event.keyCode === 13) {
value = this.value;
this.parentElement.removeChild(this);
callBack.call(null,[value]);
}
});
//no error removing the element here
input.addEventListener('blur', function (event) {
value = this.value;
this.parentElement.removeChild(this);
callBack.call(null,[value]);
});
When you trigger the blur event on the input, only the blur event fires.
When you trigger the keydown event that removes the input, the blur event also fires as a consequence of that removal, and tries to remove an input that is already gone.
To see this in action, check out this example:
http://jsfiddle.net/nate/kDKVy/
var input = document.getElementById('foo');
var valueDisplay = document.getElementById('value');
var value;
input.addEventListener('keydown', function (event) {
if (event.keyCode === 13) {
value = this.value;
valueDisplay.value = value;
this.parentElement.removeChild(this);
}
});
input.addEventListener('blur', function (event) {
console.log('BLUR');
value = this.value;
valueDisplay.value = value;
this.parentElement.removeChild(this);
});
Open up your console. First, type something in the red box and then click away to trigger the blur event. Notice that it works nicely and you see "BLUR" in the console.
Run the fiddle again. Now, type something in the red box and hit enter. Notice that you get the "BLUR" message in your console before the error.
Make sense?

create stackoverflow tagging system?

I am trying to create a tagging system just like SO has.
I have added the tags,now I want to remove them.
MyQuestion:
How do I remove the tags appended?
how do I make the cross button(a span) look identical to that in SO tagging system?
SO TAGGING
var tags = [];
$("#textBox").keypress(function (e) {
if (e.which === 13) {
$(".target").append("X</span>'+ "");
function remove_tag(){
//what to do here?
}
tags.push(this.value);
this.value = "";
}
});
Here's my JSFiddle: http://jsfiddle.net/Wky2Z/11/
Basically, listen on the .cross to be clicked, and then remove from array and delete element
//enter something in textbox and press enter....
var tags = [];
$("#textBox").keypress(function (e) {
if (e.which === 13) {
$(".target").append("X</span>'+ "");
tags.push(this.value);
this.value = "";
}
});
$('body').on('click','.cross',function(){
tags.splice($(this).parent('a').html(), 1);
$(this).parent('a').remove();
});
As for the look of the cross, SO use a CSS Sprite, so you can do the same by making a png or gif or jpeg of the two states, off(grey) and hover(red) and switch the background-position to red with css eg: .cross:hover { background-position:0px -20px }
You can delete elements making use of remove().
Also, i would recommend you to make use of jQuery events instead of using inline events. (if you take a look at the source code of stackoverflow you will notice there are no inline javascript calls)
In this case you would need to add an event handler to the document object as you want to assign the events to elements which are not loaded in the DOM from the start.
$(document).on('click', '.tag span', function(){
$(this).parent().remove();
});
Living example: http://jsfiddle.net/Wky2Z/7/
Update
I updated the example removing the element from the list of tags too:
http://jsfiddle.net/Wky2Z/8/
Added a data-value for the tag links:
$(".target").append("X</span>'+ "");
And modified the click event:
$(document).on('click', '.tag span', function(){
$(this).parent().remove();
var removeItem = $(this).parent().data('value');
tags = $.grep(tags, function(value) {
return value != removeItem;
});
});
For a full jQuery solution you can remove the inline remove_tag function and use jQuery on function. it works for dynamically created elements too.
Attach an event handler function for one or more events to the
selected elements.
Here you can get the parent element of the deleted element and remove it from the DOM using remove.
To "sync" the array with the current situation you can use grep to delete the item from the array; note the removedItem variable used to get the text only of the parent excluding the children from the text.
Code:
//enter something in textbox and press enter....
var tags = [];
$(document).ready(function () {
$('body').on('click', 'span.cross', function () {
var removedItem = $(this).parent().contents(':not(span)').text();
$(this).parent().remove();
tags = $.grep(tags, function (value) {
return value != removedItem;
});
});
$("#textBox").keypress(function (e) {
if (e.which === 13) {
$(".target").append("X</span>' + "");
tags.push(this.value);
this.value = "";
}
});
});
Demo: http://jsfiddle.net/IrvinDominin/pDFnG/
Here's the updated link: http://jsfiddle.net/Wky2Z/6/
Move remove_tag outside of keypress event handle and pass a this pointer to it for quick solution:
//enter something in textbox and press enter....
var tags = [];
function remove_tag(x) {
$(x).parent('a').remove();
}
$(function () {
$("#textBox").keypress(function (e) {
if (e.which === 13) {
$(".target").append("X</span>' + "");
tags.push(this.value);
this.value = "";
}
});
});

Categories

Resources