jQuery .change() only fires once - javascript

I have a DropDownList called "ddlCaseFiles".
I then have a script which I import that contains the jQuery .change() function to capture the event. Then I have 3 radio buttons which sorts the dropDownList. When the default radio button is loaded, then the event fires. But as soon as I select another radio button, then the event doesn't fire anymore.
Here is my DropDownList:
<asp:DropDownList runat="server" ID="ddlCaseFiles" DataSourceID="dsMyCaseFiles"
DataTextField="Display" DataValueField="FileID" OnPreRender="ddl_PreRender" />
and here is my jQuery .change():
$('#ddlCaseFiles').change(function () {
debugger;
$('#lblNextExhibitNumber').text('');
var temp = $(this).val();
});
Here is a snipper of what the radio buttons do:
protected void rbByFileName_CheckedChanged(object sender, EventArgs e)
{
ddlCaseFiles.DataSourceID = "dsCaseFilesReverse";
ddlCaseFiles.DataTextField = "Display";
ddlCaseFiles.DataValueField = "FileID";
}
protected void rbByFileID_CheckedChanged(object sender, EventArgs e)
{
ddlCaseFiles.DataSourceID = "dsCaseFiles";
ddlCaseFiles.DataTextField = "Display";
ddlCaseFiles.DataValueField = "FileID";
}
I have never used the .change() before. So maybe I am missing something

Looks like your CheckedChanged events of the radio buttons don't trigger the dropdown change event. The JS change event fires when the selected value of a drop down changes. This doesn't necessarily happen when you change the DataSourceID, does it?
I'm not sure how to trigger this in ASP. Perhaps ddlCaseFiles.SelectedIndexChanged()?
Otherwise, you could add a click event handler to the radios:
$('input[type="radio"].someCssClass').click(function(){
$('#ddlCaseFiles').trigger('change');
});
EDIT:
This is just a guess, but it looks like the CheckedChanged might be modifying the <select> element on the page. For example, is it reinserted every time DataSourceID changes?
Try changing your dropdown change event handler like this using the .on() function:
$('body').on('change', '#ddlCaseFiles', function () {
debugger;
$('#lblNextExhibitNumber').text('');
var temp = $(this).val();
});
Note: for better performance change $('body') to some container closer to the dropdown.
The .change() function attaches the change handler to an element on a page. If ASP removes an element and re-adds it later then the handler is gone.
A handler attached using the .on() function persists even if the element is removed. Read more here.

A more modern answer using jquery 3.6
$(document).on('change', "#ddlCaseFiles", function (e) {
debugger;
$('#lblNextExhibitNumber').text('');
var temp = $(this).val();
});

Related

Javascript button click has no effect

I have a asp button that I want to be clicked by a javascript function when I click a regular html button. However when it gets to the button.click() there is no effect whatsoever. If I look in the debugger, everything else in the function acts as normal, and if I click on the asp button myself it runs the code I expect it to or if I call the joingameBtn_Click in the console it also properly clicks the button. I created the buttons dynamically on page load in a loop so that each has an onclick function that passes an id unique to it.
function joinGameBtn_Click(campaignid) {
var temp = document.getElementById('CampaignID');
temp.value = campaignid;
var button = document.getElementById("CampaignBtn");
button.click();
}
function createFunction(id) {
return function() { joinGameBtn_Click(id); };
}
//Where the button is created
var hoverbutton = document.createElement('button');
hoverbutton.id = 'hoverbutton';
var func = createFunction(campId);
hoverbutton.onclick = func;
After reading some other posts I saw that sometimes the dynamically created buttons could be the problem in that the event listener isn't tied to them. Some suggestions mentioned making sure the document was ready so I tried this as well to no avail.
$(document).ready(function() {
$(document).on('click', '#hoverbutton', function () {
$("#CampaignBtn").click();
});
});
EDIT: Here is the asp.net button in question.
<asp:Button ID="CampaignBtn" runat="server" Text="Button" style="display:none;" OnClick="joinGame_Click" ClientIDMode="Static"/>
Here is the server side button click function:
public void joinGame_Click(object sender, EventArgs e)
{
Session["campaignid"] = int.Parse(CampaignID.Value);
Response.Redirect("CampaignSession.aspx");
}
I changed my asp button to a regular html button which seemed to resolve the issue
<button onserverclick="joinGame_Click" runat="server" id="CampaignBtn" ClientIDMode="Static">Button</button>
Not sure if fixing the issues with duplicate id's played a role in it as well.

How to determine if an Element was created dynamically

I have an existing system built using jQuery, Backbone.js and a REST-ish back-end written in C#. The application is an SPA with forms to fill and navigation. My job is to build a "Navigation Interceptor" to connect on the application so the system detects whether a field was modified in the current view so that when the user navigates, he will be warned that fields were modified and be requested to save or cancel the changes.
The way I designed it is using jQuery. To make it short, I use a selector on input, select, etc.. and bind a change event to it. Then I use a selector on links and buttons, unbind all click events, bind my "interceptor" (if a field has changed, ask before navigating) and then rebind all click events after my interceptor. I use stopImmediatePropagation() to cancel the regular navigation events, resulting in a kind of wrapper around the events.
By doing so, I have 2 problems:
Calling .val() on a field does not trigger the change event which is fine since I populate the fields dynamically. The problem is that the bootstrap date pickers does not seem to be setting the value using .val() resulting in all date fields having the "changed" state when initialized.
Elements dynamically created (e.g.: field in accordion panel created after the page has loaded) don't accept the events resulting in forms not firing the change event of my navigation interceptor.
My question is regarding the 2 above elements:
Is there a way to determine if a specific field is a date picker and bind the change event on that field so that when I populate it, the change event does not fire, but when the users do, it does (I tried binding on the changeDate event but the setDate method seems to be firing the changeDate event also)?
Is there a way to determine if the element was dynamically created (e.g.: $(''))? The problem is that I do not have a specific selector for a single field, so I think I cannot use delegation ($(document).on('change', 'someFieldSelectorICannotKnow', function () {});). All I have is a handle on the jQuery element ($(this) in a .each(fn) iteration).
#2 Solved using event delegation on all fields and skipping the handler if the field is not a form field
Solution of #2:
NavigationInterceptor.prototype.bindChangeEventOnAllEditableFields = function () {
var self = this;
var fieldsSelector = $(this.configuration.selectors.formFields.join(', '));
$(fieldsSelector).each(function () {
var isFormField = !self.searchClassFromArrayInElement(self.configuration.classes.nonFormFieldClasses, $(this));
if (isFormField && self.configuration.debug.highlight.fields.unchanged && $(this).attr('type') === 'radio') {
$(this).parent().css('background-color', self.configuration.debug.highlight.fields.unchanged);
} else if (isFormField && self.configuration.debug.highlight.fields.unchanged) {
$(this).css('background-color', self.configuration.debug.highlight.fields.unchanged);
}
});
$(document).on('change', fieldsSelector, function (event) {
var field = $(event.target);
var isFormField = !self.searchClassFromArrayInElement(self.configuration.classes.nonFormFieldClasses, field);
if (isFormField) {
self.hasFieldChanged = true;
if (self.configuration.debug.highlight.fields.changed) {
if (field.attr('type') === 'radio') {
field.parent().css('background-color', self.configuration.debug.highlight.fields.changed);
} else {
field.css('background-color', self.configuration.debug.highlight.fields.changed);
}
}
}
});
return this;
}
var unchangeable_classes = ['decorative', 'constant'];
$(document).on('change', 'input,select,textarea', function () {
var $this=$(this);
for(var i =0;i<unchangeable_classes.length;++i){
if($this.hasClass(unchangeable_classes[i]))
return;
}
global_changed = true;
});
Why doesn't this work, it should? (Edited in response to comment.)
My thoughts>>
1)A way to stop calling changeDate() after calling setDate(), you could just call event.stopPropogation(), it will prevent the event from bubbling up
2)while creating a dynamic element, you could add any property of your wish. For eg
var iDiv = document.createElement('div');
iDiv.isDynamic = true;
then while iterating through the element, check for isDynamic property
Why not add a benign class tag to the element
$('#foo').addClass('bar');
then you can check for the class to see if it was created
if ($('#foo').hasClass('bar'))
alert('was created');
Note that when you add elements you have to re-attach the events. So if you have a global document event and then add an element, that element won't be included unless you explicitly attach the new element.
I'm posting the answer for my question #1.
What I did is modify bootstrap's source. When calling setDate like so:
$('#myDateInput').datepicker('setDate', new Date());
The code goes through the function setDates which calls update and setValue, the first one resulting in the date being set in the datepicker itself, the second one setting only the value in the input text field. What I did is remove the call to 'change' which triggers the change event on the field and left the custom event 'dateChange'. This results in my code not firing the change event when I call setDate, but calls it when the user sets a date using the picker itself.

last button of dynamic list not always firing click event with jQuery

I have a simple div that I dynamically append buttons to, now all the the button click events fire except for the last element in the list, which sometimes it does fire sometimes it doesn't. If I click on the left or right icon in the button it works just fine, if I click on the text or middle of the button sometimes it fires sometimes it doesn't.
<div id="btn-list"></div>
on page load after my dom is loaded I append a random number of buttons and I add the on click event listener to the buttons.
$( function () {
for (var i=0;i<arr.length;i++) {
var item = arr[i];
var btn = $(document.createElement('button'));
btn.text(item['description']);
btn.attr('id', i);
$("#btn-list").append(btn);
}
$('#btn-list').on('click', 'button', function (e) {
e.preventDefault();
e.stopPropagation();
window.location.replace('blah.html');
});
}
I'm using jQuery 2.0.
Without extra code, this snippet shouldn't fail. Have in mind that a reference to the last button added is kept in btn, thus if at some other part of the code the element or its events are modified it will alter the expected behavior.
Have you added some debug output to confirm the click event is not fired? http://jsfiddle.net/AstDerek/gKJNe/
$('#btn-list').on('click', 'button', function (e) {
e.preventDefault();
e.stopPropagation();
alert('blah.html');
})
Added a simple test, it doesn't fail at the browser I tested, maybe its limited to your browser? http://jsfiddle.net/AstDerek/gKJNe/1/
Now, what happens if you encapsulate the button creation into its own function?
function create_button (index,properties) {
var btn = $(document.createElement('button'));
btn.text(properties.description);
btn.attr('id',index);
$("#btn-list").append(btn);
return btn;
}
for (var i=0;i<arr.length;i++) {
create_button(i,arr[i]);
}
Finally, just as a workaround, why not add a hidden button as last step?
for (var i=0;i<arr.length;i++) {
create_button(i,arr[i]);
}
create_button(-1,{description:''}).hide();

Getting the name of a hyperlink when it's clicked using jQuery

Is there a way to get the hyperlink name when you click on it using jQuery? I have the following code, I need some jQuery direction:
<a href="#" id="imageClick" name='<%# Eval("fileName1") %>'><asp:Image ID="myImage" name='<%# Eval("fileName1") %>' runat="server" ImageUrl='<%#"~/Image/" + Eval("fileName") %>' /></a>
Basically I would like to return the value of whatever <%# Eval("fileName1") %> is.
Thanks.
EDIT: To be more clear, I have a popup page which contains a listView which that has images and radio buttons. The requirement is if you click on the radio button, it should get the value of that specific choice and close the popup. I'm also passing a value back to the parent window. So this is what I have:
$(document).ready(function () {
$("#form1").change(function () {
var val = "";
if ($('input:radio[name=myRadio]:checked').val()) {
val = $('input:radio[name=myRadio]:checked').val();
}
if (val != "") {
$(window.opener.document).find('#txtLogos').val(val);
// Close the window
window.close();
}
});
});
This works fine when I click on one of the radio buttons. But now they added another requirement that if they click on the images they want the same result (Obviously without disrupting the functionality that the radio button has).
You can just access it using this.name inside your click handler. this here is the Dom element (Don't need jquery to retrieve the element attribute value), so just directly access the name attribute of the element.
$('#imageClick').click(function(){
alert(this.name);
});
Edit
Form change will not be triggered if you click on an image; unlike input, select, textarea etc. So you need to trigger form change manually on image click event (to simulate a radio button click triggering the form change event).
Bind a click handler to your images to add class:
$('yourimageselector').click(function(){
$(this).toggleClass('checkedImage'); // Add a class on first click and again clicked on it remove the class to say it is turned off. If you dont want a turn off functionality simply say :
//$(this).addClass('checkedImage'); //or if this is the only class then this.className = 'checkedImage' classList is not yet supported in all browsers.
$('yourform').change(); //as this is image it wont trigger form change event so you need to manually trigger form's change event (only for input, select, textarea etc form change will be triggered).
});
And in your form event:
$("#form1").change(function () {
var imgNames= $('.checkedImage')
.map(function(){return this.name; })
.get(); // Will get you all the image names in an array.
//if it is just one image then simply do if($('.checkedImage').length > 0) $('.checkedImage')[0].name,
//Code follows
});
Fiddle
this can also work in the event handler of your click :
document.getElementById("new-answer-activity").name

Javascript confirm without code in code behind

I have a page with dynamically added imagebuttons, and i want them to send a confirm when you click them(for deletion).
Since they are dynamic i cant code anything in a .click event.
Hows the best way to do this? check if true or false and then send it to a delete function in code behind with the control as parameter? or any other way?
Thanks
If you want to be able to cancel the submission, set the OnClientClick property to the string "Return" and the function name. The client script can then cancel the submission by returning false.
check imagebutton clientclick property.
void Button1_Click(Object sender, EventArgs e)
Label1.Text = "Server click handler called.";
End Sub
your dynamic generated imagebutton should be somewhat like this:
Create commman event hadler for all imagebuttons and set the id of these imagebutton to the primary key value.
check Respond to Button Web Server Control Events in Client Script for details:
You can create a custom imagebutton usercontrol that will provide the delete functionality on click event. On ItemRowCreated or GridView RowCreated events assign event hadler to these dynamically added control.
If they are not in any databind control then simple assign there properties at run time.
protected void Page_Init(object sender, EventArgs e)
{
ImageButton btn = new ImageButton();
btn.ID = "1";
btn.ImageUrl = "http://icons.iconarchive.com/icons/deleket/button/256/Button-Fast-Forward-icon.png";
btn.OnClientClick = "return confirm('Ready to submit.')";
btn.Click += new ImageClickEventHandler(btn_Click);
this.form1.Controls.Add(btn);
}
check the control id in event handler.
private void btn_Click(object sender, ImageClickEventArgs e)
{
ImageButton btn = (ImageButton)sender;
Response.Write("<script>alert('Image button with id = " + btn.ID + "clicked');</script>");
}
and then perfom delete operation
It's easy to do with jQuery (a javascript framework), even if want to do with pure JavaScript, you need to add a class to all your delete image button and add an handler to it
Using jQuery, just use this:
$(".deleteImageButton").bind("click", function() {
var res = confirm("Are you sure you want to delete?");
return res;
});
Objects that fire .click and other functions are "collected" at load, if you add any elements after that, you need to either use .delegate or .bind to make the new elements also fire an event.
Events bubble up the DOM, ie. they'll get triggered for the element it happened on, as well as all of it's parents (up to the document node itself). This make it easy to solve your problem: just attach a click handler to the container of the buttons. jQuery makes it even easier to do it through it's delegate function, here's some example code:
$('#buttons').delegate('.delete_control', 'click', function(e) {
e.preventDefault();
e.stopPropagation(); // maybe you don't need these 2, you can remove them if so
if (confirm('Are you sure you want to delete that element?')) {
// make an ajax request to delete the image. alternatively you can submit
// a hidden form, with the controlid in an input, but this is way simpler.
$.post('/url/to/delete/control/by/id/' + e.target.id, function() {
$(e.target).remove(); // to delete the button when the request is done.
});
}
});
And here's a JSFiddle page showing the whole thing working: http://jsfiddle.net/8d7D4/

Categories

Resources