Define a function globally in jQuery - javascript

I have some simple jQuery code, and it has a problem. The menu handler function doesn't work at all.
var clicked = false;
$(document).ready(function(){
$TemplateMenu= $('<p class="paragraph">texxt</p>');
$('.TemplateMaker').click();
this.menuhandler();
});
});
function menuhandler(){
if(clicked == false){
$(this).after($TemplateMenu);
clicked = true;
}
else{
$TemplateMenu.remove();
clicked = false;
}
For some reason, the function works if I put it directly inside click() like this:
$('.TemplateMaker').click(function(){
if(clicked == false){
$(this).after($TemplateMenu);
clicked = true;
}
else{
$TemplateMenu.remove();
clicked = false;
}
});
});
What is wrong with this code? Did I define the function wrong or do I need something special if the function contain jQuery elements?
Thanks for the help :-)
Edit:
I edit the code to include your guys suggestions, its stile doesn't seem to work.
code:
var clicked = false;
$(document).ready(function(){
$TemplateMenu= $('<p class="paragraph">texxt</p><p class="p2">texxt</p>');
$('.TemplateMaker').click(menuHandler($(this)));
});
function menuHandler(obj){
if(clicked == false){
$(obj).after($TemplateMenu);
clicked = true;
}
else{
$TemplateMenu.remove();
clicked = false;
}}
I notic now that the jquery throw this "event.returnValue is deprecated. Please use the standard event.preventDefault() instead. ", but I don't know how its contact to my script.

$('.TemplateMaker').click();
this.menuhandler();
});
Try replacing this.menuhandler(); with just menuhandler(); as shown below:
$('.TemplateMaker').click();
menuhandler();
});
Edit: In response to your comment. Try using this instead of $(this) in the menuhandler() of your original code.

You probably want the menuHandler function to fire when someone clicks on the button? Then you can simply change your code as follows:
$('.TemplateMaker').click(menuHandler);
Edit:
You basically have two options:
Option1:
You don't have to pass $(this) change your code to this (make sure you remove the parameter in the menuHandler function if you choose this approach):
$(document).ready(function(){
$TemplateMenu= $('<p class="paragraph">texxt</p><p class="p2">texxt</p>');
$('.TemplateMaker').click(menuHandler);
});
Option2:
Or if you want to pass $(this) you can do something like this (keep the parameter in the menuHandler function if you choose this approach):
$(document).ready(function(){
$TemplateMenu= $('<p class="paragraph">texxt</p><p class="p2">texxt</p>');
$('.TemplateMaker').click(function() {
menuHandler($(this));
});
});

Related

Show DIVs when page loads, not just 'on change' of drop down list

I currently have sections of a form which display based on the selection of a drop down list:
$('#Selection').on('change', function () {
if(this.value === "Section1"){
$("#Section1").show();
} else {
$("#Section1").hide();
}
if(this.value === "Section2"){
$("#Section2").show();
} else {
$("#Section2").hide();
}
if(this.value === "Section3"){
$("#Section3").show();
} else {
$("#Section3").hide();
}
if(this.value === "Section4"){
$("#Section4").show();
} else {
$("#Section4").hide();
}
if(this.value === "Section5"){
$("#Section5").show();
} else {
$("#Section5").hide();
}
});
This works well for my 'Add' function because the default drop down list selection is 'Please Select...' which means there is a 'change' which triggers my function.
For my 'Edit' function, a selection has already been made, and it's unlikely a change to this selection will be made. I've tried to change the .on('change') bit to .on('load') but that doesn't seem to work!
It feels like there is a simple change I need to make, but I'm rubbish at javaScript!
Thanks.
Try this one:
$( document ).ready(function() {
// Handler for .ready() called.
$("#Section1").show();
});
Try to trigger your code manually on document ready like so:
$(document).ready(function(){
$("#Selection").trigger("change");
});
If you are happy with the functionality inside your change handler;
I think Klikas solution is the correct one:
$(document).ready(function(){
if($('#Selection').value!=""){$('#Selection').trigger("change");}
});
You can simplify your long function with something like this:
$('#Selection').on('change', function(){
var p=["Section1", "Section2", "Section3", "Section4", "Section5"];
for(var i=0; i<p.length; i++){var n=p[i]; var t=$("#"+n); if(t){this.value===n?t.show():t.hide();}}
});

jQuery not executing code for new element with new id

I have an image, and when I click on it I want it to change to a different image and change its ID as well. Then when I click on this new image, it reverts back.
$(document).ready(function(){
$("#name_edit").click(function(){
$(this).attr("src", "img/tick.png");
$(this).attr("id","name_confirm");
});
$("#name_confirm").click(function(){
$(this).attr("src", "img/edit.png");
$(this).attr("id","name_edit");
});
});
I have successfully done the first step, going from #name_edit to #name_confirm. However, not the reverse.
How do I go about solving this?
My suspicion is that since I'm using (document).ready, jQuery is preparing itself for elements already on the page. However, the element with the ID name_confirm does not exist until the image is clicked on.
Thanks.
The element that you are working on is always the same...
$(document).ready(function(){
// use just the first id value to find it in the DOM
$("#name_edit").click(function(){
var item = $(this);
var id = item.attr('id');
if(id === 'name_edit') {
return item
.attr("src", "img/tick.png")
.attr("id","name_confirm")
;
}
return item
.attr("src", "img/edit.png")
.attr("id","name_edit")
;
})
;
});
I think you have chosen bad solution for your problem.
1) Why your code doesn't work:
You bind 2 events only 1 time, whne your document loaded. So, jquery finds #name_edit element and bind onclick event on it. But jquery cannot find #name_confirm element, because it doesn't exists on document ready)
In your code you should bind 1 onclick event, but have some attr (for example class for checking your state).
Something like:
<img id="main_image" class="name_edit"/>
<script>
var img_paths = ["img/tick.png", "img/edit.png"]
var img_index = 0;
$("#main_image").click(function(){
if($(this).attr("class") == "name_edit"){
$(this).attr("src", "img/tick.png");
$(this).attr("class","name_confirm");
}
else{
$(this).attr("src", "img/edit.png");
$(this).attr("class","name_edit");
}
});
</script>
Other solutions: You can create 2 images and show/hide them.
Or use styles with background attr. With pseudoclasses or classes.
Also you can store image pathes in array and tick array index on click.
Something like:
var img_paths = ["/content/img1.png", "/content/img2.png"]
var img_index = 0;
$("#main_image").click(function(){
$(this).src = img_paths[img_index];
img_index = !img_index;
})
It is not working because you are referencing the same elements, try this:
(function(window, document, $, undefined){
$("#name_edit").on("click", function(){
var self = $(this);
if(self.attr("id") === "name_edit") {
self.attr("src", "img/tick.png");
self.attr("id", "name_confirm");
} else {
self.attr("src", "img/edit.png");
self.attr("id", "name_edit");
}
});
})(this, this.document, jQuery);
Also for easier to understand code you could use classes like this:
(function(window, document, $, undefined){
$(".name_edit").on("click", function(){
var self = $(this);
if(self.hasClass("name_edit")) {
self.attr("src", "img/tick.png");
self.removeClass("name_edit").addClass("name_confirm");
} else {
self.attr("src", "img/edit.png");
self.removeClass("name_confirm").addClass("name_edit");
}
});
})(this, this.document, jQuery);
To simplify replacing classes you could even add your own $.fn.replaceClass(); like this:
jQuery.fn.replaceClass = function(classA, classB) {
this.removeClass(classA).addClass(classB);
return this;
};
Then use it like this:
(function(window, document, $, undefined){
$(".name_edit").on("click", function(){
var self = $(this);
if(self.hasClass("name_edit")) {
self.attr("src", "img/tick.png");
self.replaceClass("name_edit", "name_confirm");
} else {
self.attr("src", "img/edit.png");
self.replaceClass("name_confirm", "name_edit");
}
});
})(this, this.document, jQuery);
I can confirm what the others said.. the jquery gets run on document ready, but doesn't get updated subsequently - so it basically gets the correct element from the dom, and assigns the click event. It has no event for the name_confirm.
so this code does nothing...
$("#name_confirm").click(function(){
$(this).attr("src", "img/edit.png");
$(this).attr("id","name_edit");
});
See it not work in this instructive jsfiddle
Of course does the id need to change? is it possible to use for example a specific class for the img? then you could make the second click bind on the class instead... for example see this working example, which still changes the src and id...
Try On method:
$(document).on('click', '#name_edit', function(){
$(this).attr("src", "img/tick.png");
$(this).attr("id","name_confirm");
});
$(document).on('click', '#name_confirm', function(){
$(this).attr("src", "img/edit.png");
$(this).attr("id","name_edit");
});

How can I preventDefault inside a callback inside an event handler?

For example I have something like
$('div').on('click', '.button', function(event){
$('.showdiv').show('fast', function(){
var myvar = someFunction();
if(myvar == 1){
event.preventDefault();
}
});
});
I want to prevent the Default behaviour of the click button inside the callback of the show function (to ensure that the show div is shown before runnin the myvar function). IBut I can't make the preventDefault() works. How can I make it happen? Thanks!
Please check below updates code, I think you need also need to define event in show function.
$('div').on('click', '.button', function(event){
$('.showdiv').show('fast', function(event){
var myvar = someFunction();
if(myvar == 1){
event.preventDefault();
}
});
});
Hope this will work for you.
It should not be inside the callback.
If you put it inside the callback the default behavior would have been already fired :
$('div').on('click', '.button', function(event)
event.preventDefault();{
$('.showdiv').show('fast', function(){
var myvar = someFunction();
if(myvar == 1){
}
});
});
in the code you are not passing event as parameter.
change to
$('.showdiv').show('fast', function(){
var myvar = someFunction(event); // pass parameter
if(myvar == 1){
event.stopPropagation();
event.preventDefault();
}
});

Jquery rename content insite a tag and confirm it

The User should be able to change the Name and then confirm the change. I'm not able to archive it with this code as when I click confirm, it returns like before.
What am I missing?
Any better way to put this together (which I'm sure there's one) ?
Please check the demo where you can also see the changeElementTypefunction
http://jsfiddle.net/dLk6E/
js:
$('.replace').on('click', function () {
$("h2").changeElementType("textarea");
$('.replace').hide();
$('.confirm').show();
//Confermation of the change
$('.confirm').bind('click', function () {
$('.replace').show();
$('.confirm').hide();
$("textarea").changeElementType("h2");
});
if ($('textarea:visible')) {
$(document).keypress(function (e) {
if (e.which == 13) {
alert('You pressed enter!');
$("textarea").changeElementType("h2");
$('.replace').css('opacity', '1');
}
});
}
});
Here are your updated code and working fiddle http://jsfiddle.net/dLk6E/
(function($) {
$.fn.changeElementType = function(newType) {
var attrs = {};
$.each(this[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
this.replaceWith(function() {
return $("<" + newType + "/>", attrs).append($(this).contents());
});
}
})(jQuery);
$('.replace').on('click', function (){
$("h2").changeElementType("textarea");
$('.replace').hide();
$('.confirm').show();
//Confermation of the change
$('.confirm').on('click', function(){
$('.replace').show();
$('.confirm').hide();
// you are missing this
$('.replaceble').html($("textarea").val());
$("textarea").changeElementType("h2");
});
if ($('textarea:visible')){
$(document).keypress(function(e) {
if(e.which == 13) {
alert('You pressed enter!');
$("textarea").changeElementType("h2");
$('.replace').css('opacity','1');
}
});
}
});
updated
jsfiddle.net/dLk6E/1
I think your code is right but you need to use the value you're entering when replacing it. So the confirmation binding would be something like this (fetching it, and then using it to update the textarea before "transforming" it into an h2 tag.
$('.confirm').bind('click', function(){
var valueEntered = $('textarea').val();
$('.replace').show();
$('.confirm').hide();
$("textarea").html(valueEntered).changeElementType("h2");
});
You could be using .on for this as well as of jQuery 1.7 is prefered to .bind.
Another thing I would suggest is whenever you struggle with something like this just put in google (or whatever...) exactly what you want, in this case "jquery get value of input" will get asw first result the jquery documentation
This way you won't forget it ;)
Update: Maybe a small detail but in the binding I use it would be more efficient to just hit $('textarea') once, so it would be something like this. Something that you may keep in mind (not really an issue here), better to store in a variable than hit the DOM several times.
$('.confirm').on('click', function(){
var $textarea = $('textarea');
$('.replace').show();
$('.confirm').hide();
$textarea.html($textarea.val()).changeElementType("h2");
});
jsfiddle

Toggle State Incorrect in jQuery

I am using jQuery to show / hide lists, but it takes two clicks on a link instead of just one to show the list. Any help?
jQuery.showList = function(object) {
object.toggle(function(){
object.html("▾");
object.siblings("ul.utlist").show("fast");
}, function(){
object.html("▸");
object.siblings("ul.utlist").hide("fast");
});
}
$(document).ready(function() {
$("#page").click(function (e){
e.preventDefault();
var target = $(e.target);
var class = target.attr("class");
if(class == "list")
$.showList(target);
});
});
It's probably because toggle thinks the object is already visible, and executes the 'hide' clause.
edit:
Eh.. quite circular logic; how else would a user be able to click on it :-)
PS. You changed the logic from is-object-visible? to is-list-visible? in your own reply.
Not sure if this will fix everything but stop using reserved keywords.
Change variable class to something like c. And Change object variable to at least obj.
Doing the following worked well
jQuery.showList = function(obj) {
var list = obj.siblings("ul.utlist");
if(list.is(":visible")){
obj.html("▸");
list.hide("fast");
} else {
obj.html("▾");
list.show("fast");
}
}

Categories