jQuery - Replacing HTML element multiple times - javascript

I want to replace a button with an input field, where the user enters something and presses the enter button. After that, the button from the beginning should appear again. My script works so far but I can't repeat this once it finished.
Update: The button should also appear again, if the input field is shown but the user don't want to enter anything and clicks somewhere else.
The code:
<button id="createButton">Create item</button>
/*
jquery stuff
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#createButton').click(function( event ) {
$(this).replaceWith('<input type="text" id="buttonInput" placeholder="e.g. books, movies" autofocus>');
});
$(this).on('keypress', function (event) {
if(event.which == '13'){ // If enter button is pressed
alert('You entered something');
$('#buttonInput').replaceWith('<button id="createButton">Create item</button>');
}
});
});
</script>
Update 2: I updated the code with hide() and show() to get the same result. But how can I let the input disappear, if the user clicks somewhere inside the body, without redundancy?
The new code:
<button id="createButton">Create item</button>
<input type="text" id="input" placeholder="e.g. books, movies" autofocus>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$('#input').hide();
$(document).on('click', '#createButton', function (event) {
$(this).hide();
$('#input').show().focus();
});
$('#input').on('keypress', function (event) {
if (event.which == '13') { // if enter button is pressed
$(this).hide().val('');
$('#createButton').show();
}
});
});
</script>

As the other answers say, you're replacing the element (createButton), which means the click handler is no longer bound.
You can either re-bind, or bind to the parent element, with the #createButton selector using on.
$(document).on('click','#createButton', function( event ) {
...
});
Don't actually use document - use whatever the parent element is, which doesn't get replace (a div, perhaps?)
Replacing DOM elements is a bad approach though -- you'd be better off leaving the elements on the page, and using show and hide.
http://jsfiddle.net/v03j8bns/
Updated Answer
Here's a fiddle showing the show/hide/ approach. To handle:
The button should also appear again, if the input field is shown but the user don't want to enter anything and clicks somewhere else.
When the button is clicked, I call focus() on the textbox. I've also hooked up a blur() event handler, so if the user clicks/tabs out, then it'll hide the textbox and show the button.

You have to bind the click event to newly created button again:
$(document).ready(function () {
$('#createButton').click(function (event) {
$(this).replaceWith('<input type="text" id="buttonInput" placeholder="e.g. books, movies" autofocus>');
});
$(this).on('keypress', function (event) {
if (event.which == '13') { // If enter button pressed
//Disable textbox to prevent multiple submit
alert('You entered something');
$('#buttonInput').replaceWith('<button id="createButton">Create item</button>');
}
$('#createButton').bind('click', function (event) {
$(this).replaceWith('<input type="text" id="buttonInput" placeholder="e.g. books, movies" autofocus>');
});
});
});

You have this issue because you replace DOM elements. It means that your new element button no longer has click handler.
I would recommend you to use something like show/hide or use jQuery delegate on/bind for handling click.

When you're changing DOM on the fly and want to automatically assign listeners to elements that may or may not exist at certain points of time, you need to use delegated event listeners.
$(document).on('click', '#createButton', function () { ... });
$(document).on('click', '#buttonInput', function () { ... });
These handlers will work however you scramble the DOM.

Related

How to tell what triggered jQuery focus()?

I have an input field and a button. It is necessary that when the button is clicked the input field gets focus.
I need the behaviour to be slightly different depending on whether the input field was focused manually by the user or if it was focused due the button being clicked.
It seems this would be relatively simple, but I couldn't come up with a solution so far. Any ideas very welcome.
$("button").click(function() {
target_input = $("input");
target_input.focus();
});
$("input").focus(function() {
// if focus done manually by user
// do something
// if focus done via button
// do something else
});
Here is a solution that uses no extra variables, instead it checks the event.
$("button").click(function() {
target_input = $("input");
target_input.focus();
});
$("input").focus(function(e) {
// if focus done manually by user
// do something
// if focus done via button
// do something else
if(e.originalEvent.relatedTarget){
// only from button events
}
// here is from all events
});
this e.originalEvent.relatedTarget will return null if we didn't use the button to originate the focus.
remember to add e to the function.
You should be able to use Event.isTrusted for this:
The isTrusted read-only property of the Event interface is a boolean
that is true when the event was generated by a user action, and false
when the event was created or modified by a script or dispatched via
dispatchEvent.
$("input").focus(function(e) {
if(e.isTrusted) {...} else {...}
});
As noted in the comments, neither IE nor Safari like this.
This works without global variables and it is cross-browser working solution:
$('button').click(function () {
$(this).prev('input').focus()
})
$('input').click(function (e) { // yes, listen to click instead
// original event exists only if input was clicked directly
if (e.originalEvent) {
console.log('manually triggered')
}
})
<div style="background-color: yellow;">
<input type="text">
<button>Focus input</button>
<br>
<input type="text">
<button>Focus input</button>
</div>
<script src="https://unpkg.com/jquery"></script>

toggling the focus from button to Text box using enter key to which an event is binding

$('#b').on('click', function() {
$('#in2').focus();
//setTimeout(function(){ $('#in2').focus(); },500);
});
$('#in2').on('keyup', function(event) {
console.log(event.which);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="b">focus</button>
<input type="text" id="in1" />
<input type="text" id="in2" />
I have a key up function bound to button where I am shifting my focus to text field #in2 in the above example.
And I also have a key down event bound for text field #in2.
Problem: When I am using the enter key on the button, event bound to the text field(#in2) is getting called.
Can someone suggest me some solution except setTimeout?
If I understand your problem correctly and you don't want the function on keyup on #in2 called when Enter is pressed, just check whether the pressed key is enter and only execute it if it isn't?
$('#in2').on('keyup', function(event) {
if(event.which != 13){
console.log(event.which);
}
});
Alternatively you could use onchange so that the function gets called when the content of the element changes (this would also work with copy-and-past for example)

Overlapping events from different elements double fire the same function in JQuery

I have a dead simple search form:
<div>
<input id="searchArea" type="text" value="" placeholder="Enter your search terms">
<button id="searchButton">Search</button>
</div>
and a snippet of Javascript controlling it:
function searchFunction() {
console.log("This is a POST request being send to the server");
}
$("#searchButton").on("click", function(e) {
e.preventDefault();
searchFunction();
})
$("#searchArea").on("change", function(e) {
e.preventDefault();
searchFunction();
});
The problem is that click and change overlap in functionality and so I get the following:
When I type something in the text box and then click elsewhere in the screen, searchFunction is fired properly but if "elsewhere" becomes the search button, then searchFunction double fires.
My question is this: Once inside the click handler, is there any way to cancel the change handler from firing as well which would otherwise cause searchFunction to double fire?
Mind that searchArea and searchButton don't have a parent-child relationship which means conventional methods like preventDefault and stopPropagation won't work.
You can see it in action in this fiddle.

Prevent clicking an anchor link while an input is focused?

I'm attempting to prevent a user from clicking a link and it going to another page while any input is focused. Sometimes the only available space around the input and the keyboard is a link and some users click the link accidentally. I'm trying to make it so when they click the link it blurs the input (closes the keyboard) and prevents the page from following the link. Then let them click the link again if they want to go to another page after the input is no longer in focus.
html
<input type="text">
Example
I've tried the following...
jQuery
$('a').on('click', function (event) {
if ($('input').is(":focus")) {
console.log('focused');
event.preventDefault();
}
});
(nothing gets logged)
Also tried this...
if ($('input').is(":focus")) {
$('a').on('click', function (event) {
event.preventDefault();
$('input').each(function(){
$(this).trigger('blur');
});
});
}
Neither one prevent the page from going to whatever link was clicked...
I don't think you can do this. You can disable the click event on the links while input is focused, and enable it back again when blur occurs on the input elements. However, while if user clicks on a link while focused on the input element blur event will occur first (which would enable clicking) then click even occurs and links acts as normal.
You could try disabling the links while input elements have focus, then you can enable them on the first click and restore normal operation.
$("input").on("focus", function() {
$("a").on("click", function (event) {
event.preventDefault();
$("a").off();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
example
I think I found a solution.
HTML
Example.com
jQuery
$('input').on('focus', function () {
$('a').each(function(){
$(this).addClass('cant-click');
});
});
$(document).on('touchend', function (e) {
if (!$(e.target).closest('input').length) {
$('a').each(function(){
$(this).removeClass('cant-click');
});
}
});
CSS
a.cant-click { pointer-events: none; }
When the input takes focus, every link gets this class. When anything on the page is clicked that is not an input, it removes this class from every link.

JQuery click of input button not firing

I've looked on the forum and my question is a duplicate of Button click event not firing in jQuery, except my code already matches the given answer.
I've stripped this down for you guys anyway, and can confirm that links with a class of disabled do not fire, so this proves the document ready and Jquery library are correct.
Javascript
$(document).ready(function () {
// Prevents links from firing
$('a.disabled').click(function (e) {
e.preventDefault();
});
// Handles search
$("#btnTreeSearch").click(function () {
alert("click search fool!");
});
});
Html
<input type="submit" value="btnTreeSearch" />
Any clues?
You need to assign id to input to use id selector
Live Demo
Html
<input type="submit" id="btnTreeSearch" value="btnTreeSearch" />
Javascript
$("#btnTreeSearch").click(function () {
alert("click search!");
});
Change value="btnTreeSearch" to id="btnTreeSearch".

Categories