Event appears to only fire sometimes? - javascript

The Code
I set up a jsFiddle at http://jsfiddle.net/6vd5C/1/
The JavaScript code in question:
var global_loggedOnUser = "User1";
$(function(){
var viewmodel = (function(){
this.feedbacktype = ko.observable("None");
this.currentPage = ko.observable(location.href);
this.currentUsername = global_loggedOnUser;
this.updateFeedbackType = function(item, event)
{
var newText = $(event.target).children("span").text();
feedbacktype(newText);
};
return{
pageUserIsOn : currentPage,
theUser : currentUsername,
feedbackType: feedbacktype
};
})();
ko.applyBindings(viewmodel);
});
The Goal
Whenever someone clicks on the button of the submission, I'd like to see the "Current Type" bullet point update to indicate caption on the clicked button.
The Problem
Sometimes the text updates to the correct words; sometimes it updates but is a null value.
I cannot find a pattern or rhyme/reason; sometimes after being blank, clicking another element and then clicking the element that previously returned null now returned the correct text.
What am I doing wrong?

Instead of using $(event.target) use $(event.currentTarget).
I'd like to expand a bit and explain the difference, when you use event.target you're getting the element that dispatched the event (the actual element literally) - like in your case, if you click on the <i></i> element which is nested within the button element, it will return the <i></i> notice that if you return the code to event.target and you click on the edge of your button it will work as expected.
In the case of event.currentTarget you're getting the element you're binding your listener to (which in your case is the actual button).

Related

Perform a action when checkbox is clicked Backbone

I basically want to know when the user has clicked the checkbox. If checkbox is clicked then I want the div to output a msg and once checkbox is not checked then output another msg but user has to check first. The checkbox gets created dynamically. But somehow I dont know what the value is.
There are 2 problems:
When checkbox is clicked, the check mark does not stay
If checkbox is clicked, a value does not output on the div
Here is a example:
http://jsfiddle.net/8GjdS/103/
Code:
var myView = Backbone.View.extend({
events: {
'click #check': 'checkboxHandler'
},
initialize: function() {
_.bindAll(this, 'checkboxHandler');
},
checkboxHandler: function(e) {
var filter = $('#check').is(':checked');
console.log(filter);
$('#out').append(filter);
return false;
},
});
var v = new myView({el: '#view-goes-here'});
v.render();
$('#view-goes-here').append('<div class=divs" align="right"><input id="check" type="checkbox" value=""><font size="4">check</font></input></div>');
There are a couple of issues.
First: When you return false from an event handler (or trigger event.preventDefault() you stop the event from bubbling up. That means, you handle the event yourself and it will never trigger the usual action -- in this case, it means the checkbox will never change. You should return true instead, in your checkbox handler.
Second: The value is not appended to your out div because you call the append function with a boolean as the argument. The easiest way in this case is probably to "cast" it to a string like so:
$('#out').append('' + filter);
Third: While it's a workable approach to listen for the click event, it could be argued that it's more correct to listen for the change event instead. From MDN:
The change event is fired for <input>, <select>, and <textarea> elements when a change to the element's value is committed by the user.
Here is an updated fiddle: http://jsfiddle.net/jzvzgdp4/

Too many click handlers being called

I am using the following function to dynamically populate a div with some text and a button using the array messages:
var populateMessages = function(messages){
for (var index in messages){
(function(){
var id = index;
$("#messages").append(messages[index]["title"])
$("#messages").append("<button>Open</button><br/>").click(function(){console.log(message["id"])})
}())
}
};
This code correctly populates the div with the text and the button. The problem is that if I click on ANY of the buttons, the click handlers for ALL of them fire. So with two buttons, it should log "0" if I click on the first one and "1" if I click on the second. Instead, if I click on either, it logs "0 1"
I'm not super up on Javascript so I don't know what the issue is.
The return value of
$("#messages").append("<button>Open</button><br/>")
is #messages, not the button that was added. So each time through the loop you're adding another click handler to #messages, not the button.
Try:
$.each(messages, function(index, message) {
$("#messages").append(message.title);
$("<button>Open</button>").click(function() {
console.log(message.id);
}).appendTo("#messages");
$("#messages").append("<br/>");
});
$("#messages").append("<button>Open</button><br/>")
Returns #messages not button so you are setting the click event to #message.
Try this:
$("#messages").append("<button>Open</button><br/>").find("button:last").click(/blabla/)

Jquery check box change function not working in IE 8

I have following jquery code, where on click of a check box I will show a popup value.
Except in IE,in all other browser it works as expected. That is, on change the check box will be checked and the popup will be opened.
However in IE8 its not getting checked, however popup is displayed properly.
Code :
$('#TAndC').change(function(){
if( $('input[name="TAndC"]').is(':checked'))
{
$('#TandCBox').show();
var termsandcondition = GetEnum().TermsandConditionsPageId;
var actionURL = '#Url.Action("ShowTAndC", "Account", new { isFromCheckBox = true })';
$('.popUpForm').load(actionURL);
var msgBox = $('#terms').attr('href');
MaskMsgPopUp(msgBox);
return false;
}
});
If your element is a checkbox and not a dropdown then use click anyway.
If your selector is referring to a dropdown use click if you need to support IE8 and older.
See why that is below.
According to the MSDN for change/onchange, the event is not triggered until the change is committed.
In addition the event is also not triggered when the value is changed programmatically.
To quote:
This event is fired when the contents are committed and not while the
value is changing. For example, on a text box, this event is not fired
while the user is typing, but rather when the user commits the change
by leaving the text box that has focus. In addition, this event is
executed before the code specified by onblur when the control is also
losing the focus. The onchange event does not fire when the selected
option of the select object is changed programmatically. Changed text
selection is committed.
To invoke this event, do one of the following:
Choose a different option in a select object using mouse or keyboard navigation.
Alter text in the text area and then navigate out of the object.
If you must support IE8 and older, you are probably better of to use the click event instead which get's triggered when you release the mouse and your new choice is selected.
instead of .change use below code and try
$(document).ready(function(){
$(document).on('click','#TAndC',click_function){
if( $('input[name="TAndC"]').is(':checked'))
{
$('#TandCBox').show();
var termsandcondition = GetEnum().TermsandConditionsPageId;
var actionURL = '#Url.Action("ShowTAndC", "Account", new { isFromCheckBox = true })';
$('.popUpForm').load(actionURL);
var msgBox = $('#terms').attr('href');
MaskMsgPopUp(msgBox);
return false;
}
});
});

What am i missing from jquery function in order to add value into a textarea

I am trying to add some content into a textarea after the user has clicked on the "Add" button but nothing is happening. Is there anything I am missing?
Below is the jquery code which adds the selected content:
$(".add").on("click", function(event) {
console.log("clicked");
//lets get our Question Text...
var theQuestion = $("td:first-child", $(this).parent()).text();
//the row is present, let's then make sure that the proper cell gets oru data.
if ($('.activePlusRow').length > 0) {
$('.activePlusRow').next('.textAreaQuestion').val(theQuestion);
$('.activePlusRow').removeClass('activePlusRow');
}
});
$(".plusrow").on("click", function(event) {
//adding a unique class for the purpose of the click.
$(this).addClass('activePlusRow');
});
Below is the textarea:
$('.questionTextArea').each( function() {
var $this = $(this);
var $questionText = $("<textarea class='textAreaQuestion'></textarea>").attr('name',$this.attr('name')+"[]")
.attr('value',$this.val());
});
EDIT:
You can use the application to see for yourself. Below is how to use app:
When you open the app click on the "Green Plus" button. A modal window will appear.
In the search box enter in "AAA", then click "Search".
Results of your search is displayed. Here is where the problem is. What I want is that when the user clicks on an "Add" button to add a "Question", it should close the modal window and add the "Question" into the top textarea, but it is not doing this.
Textareas unlike inputs don't use the value attribute to store there data, which is probably why attr('value', 'bla') is failing.
I believe the .val() method will automatically take this in to account and thus work anyway.
Try somthing like:
var $questionText = $("<textarea class='textAreaQuestion'></textarea>").attr('name',$this.attr('name')+"[]").val($this.val());

closed jscript for loop to switchstatement

replace for loop with a switch statement somehow?
You don't have to loop over all radio buttons to find the clicked one. You can pass the clicked element directly to your function:
function planeChoice(element) {
// element refers to the clicked radio button
var plane = element.value;
switch (plane) {
//...
}
}
For that to work, you have to pass this to your function:
<input type="radio" name="planeButton" value="152"
onclick="planeChoice(this)" />
this refers to the HTML element you attach the event handler to, so in this case it refers to the <input> element.
To learn more about events, I suggest to read the articles on http://quirksmode.org, starting with Introduction to Events and Early event handlers.
Two suggestions for further improvement:
(A) You can use a map (which is just an plain object in JavaScript) instead of a switch statement to determine the corresponding message:
var map = {
"152": "A small two-place-airplane for flight training",
"172": "The smaller of two four-place airplanes"
// ...
};
A map is also easier to maintain (to extend).
Once you have the value of the radio button, you can access the message with:
alert(map[plane]);
You are not limited to store only primitive values (like strings), you can also store functions and call them if you want to do some more complex things. But to learn more about functions and how you can use them, you should read a JavaScript guide.
(B) You can use event delegation instead of binding the same event handler to every element (this works through event bubbling). The click event handler is attached to the <form> element:
<form onclick="planeChoice(event)" ...>
Or even better, get a reference to the form element and attach the event handler via JavaScript:
document.getElementById("myForm").onclick = planeChoice;
The passed event object holds information about which element was clicked:
function planeChoice (event) {
event = event || window.event; // for IE
var target = event.target || event.srcElement; // for IE
if(target.type === "radio") { // if a radio button is clicked
var plane = target.value;
// ... further code
}
}
Can I suggest you try using jQuery? It's a useful (and popular) JavaScript library that will help reduce and simplify the code you need.
For example, the above code could be simplified to this in jQuery:
$('#myForm input:radio').click(function(){
switch (this.value) {
case "152":
alert("A small two-place-airplane for flight training");
break;
// More Options go here...
default:
alert("Error in JavaScript function planeChoice");
break;
}
});
It would also eliminate the need to use click handlers on each radio button.

Categories