Set text for table with double click - javascript

I have several tables with ajax loaded content. Sometimes I have to change the content of a td manually before exporting it to PDF, so I thought best way would be to create a trigger for each td on double-click using jQuery's .dblclick(). The trigger would open a modal with an input field and change the text of the double-clicked td when submitting the modal.
This works, but when I change the content of a second, third, etc td, each previously clicked td gets the new value too.
Check my fiddle: https://jsfiddle.net/fvoufq07/
My code so far:
$( ".sitename" ).dblclick( function() {
var sitename = $( this );
$( "#msgBox .modal-title" ).html("Change sitename");
$( "#msgBox .modal-body" ).html("Enter new sitename:<input type=\"text\" id=\"new_sitename\">");
$( "#msgBox" ).modal("show");
$( "#msgBox button.btn" ).click( function() {
sitename.text( $( "#new_sitename" ).val().trim() );
});
});

It's because you re-use the same button for the modal. So everytime the modal is opened, you add a new listener on the button, but you don't kill the previous one.
You can kill a previous listener with off :
$( ".sitename" ).dblclick( function() {
var sitename = $( this );
$( "#msgBox .modal-title" ).html("Change sitename");
$( "#msgBox .modal-body" ).html("Enter new sitename:<input type=\"text\" id=\"new_sitename\">");
$( "#msgBox" ).modal("show");
$( "#msgBox button.btn" ).off('click').click( function() {
sitename.text( $( "#new_sitename" ).val().trim() );
});
});

The problem you're seeing is that the click function you add to the button
$( "#msgBox button.btn" ).click( function() {
sitename.text( $( "#new_sitename" ).val().trim() );
});
is not removed. Because of this, every time you open the model anew, you change the text of any previously clicked .sitename as well as the newly clicked one.
In order to avoid this, you should remove the click event, or better yet use jQuery's .one() function which will only fire the callback on the first instance of an trigger event:
$( "#msgBox button.btn" ).one('click', function() {
sitename.text( $( "#new_sitename" ).val().trim() );
});
Updated fiddle: https://jsfiddle.net/fvoufq07/6/
Update: The above solution doesn't catch the problem of opening the modal then closing without clicking the "close" save button.
There are a couple of ways to fix this: either use .off() before adding the new .one() callback, or again use .off(), but conditionally upon the modal closing using bootstap's hidden.bs.modal trigger.
$( "#msgBox" ).one('hidden.bs.modal', function() {
$( "#msgBox button.btn" ).off('click');
});
You might also want to assign the 'click' listener to a variable so that you can remove that listener specifically, which will be useful if you have other 'click' listeners on the same element.
var updateText = $( "#msgBox button.btn" ).one('click', function() {
...
});
$( "#msgBox" ).one('hidden.bs.modal', function() {
$( "#msgBox button.btn" ).off('click', updateText);
});
Updated fiddle at https://jsfiddle.net/fvoufq07/7/ has an example.

Try this
var sitename;
$( ".sitename" ).dblclick( function() {
sitename = $(this);
$( "#msgBox .modal-title" ).html("Change sitename ");
$( "#msgBox .modal-body" ).html("Enter new sitename:<input type=\"text\" id=\"new_sitename\">");
$( "#msgBox" ).modal("show");
});
$( "#msgBox button.btn" ).click( function() {
$(sitename).text( $( "#new_sitename" ).val().trim() );
});
here is updated jsfiddle

try this
$( ".sitename" ).dblclick( function() {
sitename = $( this );
$( "#msgBox .modal-title" ).html("Change sitename");
$( "#msgBox .modal-body" ).html("Enter new sitename:<input type=\"text\" id=\"new_sitename\">");
$( "#msgBox" ).modal("show");
$( "#msgBox button.btn" ).click( function() {
sitename.text( $( "#new_sitename" ).val().trim() );
});
});
Krupesh Kotecha beat me too it ;)

Related

Why doesn't the hidden container reappear when I click on it?

I have a hidden container that contains comments, and a <div> with a <p> inside that says "Show all comments" that I click to show the comments. When I click the div it shows the hidden comments container perfectly, but when I click it again it doesn't hide the comments container. I am thinking there is something wrong with my jQuery code maybe?
var commentsHidden = $( ".comments-container" ).is( ":hidden" );
if (commentsHidden) {
$( ".see-all" ).click(function() {
$('.comments-container').show('slow');
$('.see_hide').text('Hide Comments');
});
} else {
$( ".see-all" ).click(function() {
$('.comments-container').hide();
});
};
When you initialize commentsHidden it is never updated so it always has its initial value. You need to check if its hidden on every click. So you don't need an if statement to attach the event. Just attach a single click event and check inside the event if its hidden and continue accordingly.
$(".see-all").click(function() {
var commentsHidden = $(".comments-container").is(":hidden");
if (commentsHidden) {
$('.comments-container').show('slow');
$('.see_hide').text('Hide Comments');
} else {
$('.comments-container').hide();
}
});
When you call on('click', ..) or its shortcut click(..), you install a new handler. What ends up happening is that you have multiple handlers on the same object, and they all get called. Instead, either install the handler only once:
// In global code or code that gets executed upon module load
// Only once!
$(".see-all").click(function() {
if ($( ".comments-container" ).is( ":hidden" )) {
$('.comments-container').show('slow');
$('.see_hide').text('Hide Comments');
} else {
$('.comments-container').hide();
}
});
or unbind the old handler:
$( ".see-all" ).off('click'); // Unbind all click handlers
var commentsHidden = $( ".comments-container" ).is( ":hidden" );
if (commentsHidden) {
$( ".see-all" ).click(function() {
$('.comments-container').show('slow');
$('.see_hide').text('Hide Comments');
});
} else {
$( ".see-all" ).click(function() {
$('.comments-container').hide();
});
};
You need to check the flag state inside the click function(). The way you have it now will only bind the click handler once on page load.
$( ".see-all" ).click(function() {
var commentsHidden = $( ".comments-container" ).is( ":hidden" );
if (commentsHidden) {
$('.comments-container').show('slow');
$('.see_hide').text('Hide Comments');
} else {
$('.comments-container').hide();
}
});
Try changing to
$( ".see-all" ).click(function() {
var commentsHidden = $( ".comments-container" ).is( ":hidden" );
if (commentsHidden) {
$('.comments-container').show('slow');
$('.see_hide').text('Hide Comments');
});
} else {
$( ".see-all" ).click(function() {
$('.comments-container').hide();
});
}
});
The click handler should only be bound once, and you need to check whether comments are hidden each time the p element is clicked.

jquery Replace DIV data and then track clicks on it

I have a <div id="myContainer"></div> .
I also have a button: <input type="button" value="Send" id="sendButton">
While clicking at the button: it replaces the DIV with another:
$( "#sendButton" ).click(function() {
$( "#myContainer" ).replaceWith("<div id='calc'><input type=\"text\" id=\"screen\" value=0><button id=\"add\">+</button><button id=\"mul\">*</button><button id=\"settings\">settings</button><button id=\"clear\">clear</button></div>");
});
I want to activate another function after click on a new button I've just put (<button id=\"mul\">*</button>):
$( "#mul" ).click(function() {
console.log(' mul clicked!');
});
Which doesn't work, the fact that I'm waiting for a click on a div that just created have something to do with it?
You need to attach event to #mul. Because it is appended dynamically, $("#mul").click() will not work.
.on() attaches event handlers to the currently selected set of elements.
Try:
$("body").on("click","#mul",function(){
console.log("mul clicked!");
});
More information here.
When you call $( "#mul" ).click(), you're attaching an event handler to #mul as it exists at that point. To fix this, just call $( "#mul" ).click() after you create #mul.
$( "#sendButton" ).click(function() {
$( "#myContainer" ).replaceWith("<div id='calc'><input type=\"text\" id=\"screen\" value=0><button id=\"add\">+</button><button id=\"mul\">*</button><button id=\"settings\">settings</button><button id=\"clear\">clear</button></div>");
$( "#mul" ).click(function() {
console.log( ' mul clicked!' );
});
});
You could also use jQuery's .on method with the optional selector, called a delegated event handler according to the documentation. Take a look at the API for jQuery if that's what you want: jQuery API documentation. The basic usage would be something like
$( document ).on( "click", "#mul", function( ) {
console.log( ' mul clicked!' );
});
use this
$(document).on("click","#mul",function() {
instead of
$( "#mul" ).click(function() {
or
$( "#sendButton" ).click(function() {
$( "#myContainer" ).replaceWith("<div id='calc'><input type=\"text\" id=\"screen\" value=0><button id=\"add\">+</button><button id=\"mul\">*</button><button id=\"settings\">settings</button><button id=\"clear\">clear</button></div>");
$( "#mul" ).click(function() {
console.log(' mul clicked!');
});
});
$( "#sendButton" ).click(function() {
$( "#myContainer" ).replaceWith("<div id='calc'><input type=\"text\" id=\"screen\" value=0><button id=\"add\">+</button><button id=\"mul\">*</button><button id=\"settings\">settings</button><button id=\"clear\">clear</button></div>");
// add listener here
$( "#mul" ).click(function() {
console.log(' mul clicked!');
});
$( "#mul" ).trigger("click"); // add this to your code
});
http://api.jquery.com/trigger/ see detail of trigger()
http://jsfiddle.net/tnnj5/ here is a demo
you must add listener after the new content has insert into dom
You can use .live() method to bind event with dynamically added content.
Try this:
$("#mul").live("click", function() {
console.log(' mul clicked!');
});
Try in fiddle
You can also use jquery .on(), But here you add dynamic content. So you need to use event delegation to register the event handler like:
$(document).on("click","body #mul", function() {
console.log(' mul clicked!');
});
Try in jsfiddle with on

Jquery codes does not work on external loaded html file

I have index.php and will load index-edit.php with a button click into index.php in a <div class="edit-wrapper"> </div>. I have some input in index.php and some input in index-edit.php. I want to add .active class to them on focus out, but jQuery does not add .active class to the ones in index-edit.php, but rest of them (which are not index-edit.php) works fine.
Look at my script.js.
$( input ).focusout( function() {
$( this ).addClass('active');
});
$( document ).on( "click", ".btn", function() {
$('.edit-wrapper').load('index-edit.php');
});
Since the inputs are added dynamically, you need to use event delegation to register the event handler
// New way (jQuery 1.7+) - .on(events, selector, handler)
$(document).on('focusout', 'input', function(event) {
$(this).addClass('active');
});
Where are you loading script.js ? Try this :
$(document).ready(function(){
$( input ).focusout( function() {
$( this ).addClass('active');
});
$( document ).on( "click", ".btn", function() {
$('.edit-wrapper').load('index-edit.php');
});
});
need to use event delegation
$( document).on('focusout', 'input ', function() {
$( this ).addClass('active');
});

JQuery button each click, show/hide forms

Guess I'm just starting out here, so might as well look for any kind of help since I'm quite frustrated with this novice question...
I have a button that shows a form I created, with 1 click, but the problem comes when I want to show another form that comes with another button.
What I want, basically is that buttonA shows formA, but when I click buttonB, I want to hide formA and show formB. Now what's happening is that it's overlaying formA and formB.
Here's my current code..
function runEffect() {
$( "#effect" ).show( "drop");
};
function runEffect2() {
$( "#effect2" ).show( "drop");
};
//callback function to bring a hidden box back
function hideEffect() {
$( "#effect:visible" ).hide( "drop");
};
// set effect from select menu value
$( "#button" ).each(function(index) {
$(this).click(function(){
runEffect();
});
});
$( "#button2" ).each(function(index) {
$(this).click(function(){
runEffect2();
});
});
$( "#effect" ).hide();
$( "#effect2" ).hide();
I know this is easy, but I can't seem to find the answer to it.
Thanks!
try this
function runEffect() {
$( "#effect" ).show( "drop");
$( "#effect2" ).hide( "drop");
};
function runEffect2() {
$( "#effect2" ).show( "drop");
$( "#effect" ).hide( "drop");
};
$('#buttonB').click(funciton()(
$('#formA').hide();
$('#formB').show();
});
something like this?
I haven't tested it, but maybe you want to a more dynamic function.
Button class must be something like "formButton" and the id like "form1Button", the form id then should be "form1" and so on..
(Form 2 would have a button with class "formButton", id like "form2Button" and form 2 needs id "form2"
$(".formButton").click(function(e) {
e.preventDefault(); //prevent default action
var id = $(this).attr('id');
var formId = id.replace('Button', '');
$('#' + formId).show();
$('form').not(document.getElementById(formId)).hide();
});
When a formButton is clicked, the form will be shown. All other forms, wich do not have the requested ID, will be hidden.

jquery bind an event to a class, or something to the same effect?

I'd like to bind an event to a class, or any alternative to the redundant code I posted below. Any ideas?
thanks,
mna
(function(){
$( "button", "body" ).button();
var submenu=false;
$( "#about" ).click(function() {
$( "#content" ).fadeOut(1000);
$( "#content" ).load('about.html');
$( "#content" ).fadeIn(1000);
});
$( "#community" ).click(function() {
$( "#content" ).fadeOut(1000);
$( "#content" ).load('community.html');
$( "#content" ).fadeIn(1000);
});
$( "#store" ).click(function() {
$( "#content" ).fadeOut(1000);
$( "#content" ).load('store.html');
$( "#content" ).fadeIn(1000);
});
$( "#projects" ).click(function() {
$( "#content" ).fadeOut(1000);
$( "#content" ).load('projects.html');
$( "#content" ).fadeIn(1000);
});
});
Either use the multiple selector
$("#about, #community, #store, #projects").click(function() {
$("#content").fadeOut(1000)
.load(this.id + '.html')
.fadeIn(1000);
});
or give these elements the same class and use
$('.classname').click(...);
Update:
I've seen that #pointy had a good point, but he deleted his answer: You probably want for fadeOut, load, fadeIn to occur one after another. Then you have to put them in callbacks:
$("#content").fadeOut(1000, function() {
$(this).load(this.id + '.html', function() {
$(this).fadeIn(1000);
})
});
See their documentation for more information.
How about this?
Set the class load-content to all of the elements that you want to bind the click event to.
(function(){
$("button, body").button();
var submenu=false;
$(".load-content").click(function() {
$("#content").fadeOut(1000).load(this.id+'.html').fadeIn(1000);
});
});

Categories