jQuery Click Event for Dynamically Created Links Not Working - javascript

I am displaying a list of users in a table. Then, I have a button to allow a user to view more details about a specific user. However, I am having a hard time getting the ID for the user that is clicked on. I am not sure why it's not working. What am I doing wrong? I tried several options, and none of them work.
Partial code of how data the links are generated in my view.
if (Model != null) {
if (Model.Count() > 0) {
foreach (var item in Model) {
<tr>
<td><div class="centerText">#item.UserID</div></td>
<td><div class="centerText">#item.FirstName</div></td>
<td><div class="centerText">#item.LastName</div></td>
<td><div class="centerText">Details</div></td>
</tr>
}
}
}
My jQuery function
$(function () {
$('.Detail').on('click', function (event) {
var dt = $(this).attr('id');
console.log('dt');
});
});
I also tried it this way:
if (Model != null) {
if (Model.Count() > 0) {
foreach (var item in Model) {
<tr>
<td><div class="centerText">#item.UserID</div></td>
<td><div class="centerText">#item.FirstName</div></td>
<td><div class="centerText">#item.LastName</div></td>
<td><div class="centerText">Details</div></td>
</tr>
}
}
}
Here is the Javascript function that I created. It kept giving
function test(e){
console.log(e);
};
I get this error:
0x800a1391 - JavaScript runtime error: 'test' is undefined
updated on 11/21/15 #7:53 AM EST
I removed the for loop and created a single cell with 1 click button. The click event is not registered. I tried it with 'on', 'live', and 'delegate' with no success.
<div class="table table-responsive" style="width:100%;height:100%;">
<table class="table table-bordered table-condensed table-striped">
<thead>
<tr>
<th><div class="centerText">Date Created</div></th>
<th colspan="2"></th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="6"><div class="centerText">Detail</div></td>
</tr>
</tbody>
</table>
</div>
#section Scripts {
<script type="text/javascript">
$('.table tbody tr td div').delegate('.Detail','click', function ()
{
console.log('you click me');
});
</script>
}

You are trying to get the attribute id which doesn't exist. Use below to get data-id
$(function () {
$('.Detail').on('click', function (event) {
var dt = $(this).data('id');
console.log(dt);
});
you can also use
var dt = $(this).attr("data-id");
Second one (remove var):
function test(e){
console.log(e);
};

Partial code of how data the links are generated in my view. change id instead of data-id.
if (Model != null) {
if (Model.Count() > 0) {
foreach (var item in Model) {
<tr>
<td><div class="centerText">#item.UserID</div></td>
<td><div class="centerText">#item.FirstName</div></td>
<td><div class="centerText">#item.LastName</div></td>
<td><div class="centerText">Details</div></td>
</tr>
}
}
}
My jQuery function
$(function () {
$('.Detail').on('click', function (event) {
var dt = $(this).attr('id');
console.log('dt');
});
});
I also tried it this way:
if (Model != null) {
if (Model.Count() > 0) {
foreach (var item in Model) {
<tr>
<td><div class="centerText">#item.UserID</div></td>
<td><div class="centerText">#item.FirstName</div></td>
<td><div class="centerText">#item.LastName</div></td>
<td><div class="centerText">Details</div></td>
</tr>
}
}
}
Here is the Javascript function that I created. It kept giving. (Remove var before function).
function test(e){
console.log(e);
};

Here is how I reproduced your problem with JavaScript runtime error: 'test' is undefined.
Scenario
I guess that you've defined the function test probably in your jQuery DOM ready function $(function(){...}.
If so, the function test is undefined because by the time the DOM is loading, AND the event handlers on DOM elements are being registered (in your case the onclick in the link), the function test is not yet known to the document, and therefore undefined.
Solution
Try to move your test function's declaration outside of jQuery's DOM ready function. That is,
$(function(){
//code that has to run once the DOM is ready
});
function test(e){
console.log(e);
}
DEMO

I found what was causing the problem. I had a modal popup within the form. I was looking to add a textarea, so I added this code '
<textarea name="reasonForArchiveText" id="reasonForArchiveText" />
That's the code that was preventing me from getting the click event. As I was playing around with the code, I commented out the modal popup, and things started to work. Then, I commented section of the modal until I finally found the culprit. The minute that I commented it out, the code works.

Related

Uncaught ReferenceError: Function is not defined using external js file

I have a table of rows with contact details and a call button in every row, which when clicked should call the customer.
I am using onclick on call the function defined in external js file (I know not the best practice and potentially due to outside scope, but I am passing the phone number as well)
I am getting error Uncaught Referenceerror: function is not defined
https://jsfiddle.net/e1z25y3w/3/
<table>
<th>
<td>#</td>
<td>Name</td>
<td>City</td>
<td>Phone Number</td>
<td>Call</td>
</th>
<tr>
<td>1</td>
<td>John</td>
<td>Melbourne</td>
<td>+61123456789</td>
<td><a role="button" onclick="callPhone('+61123456789')">Call</a></td>
</tr>
<tr>
<td>2</td>
<td>Tanya</td>
<td>Sydney</td>
<td>+61987654321</td>
<td><a role="button" onclick="callPhone('+61987654321')">Call</a></td>
</tr>
</table>
Jquery 3.4.1 included at the bottom of the page
javascript file also included after jquery
$(function () {
//const phoneNumberInput = document.getElementById("phone-number");
function callPhone(phonenumber) {
alert(here);
log("calling phone number " + phonenumber.value);
//e.preventDefault();
phoneNumberInput = phonenumber;
makeOutgoingCall();
}
});
What is the best way to execute this?
because the "callPhone" function isn't in the global scope, so when you to try call it, will give "callPhone is not defined".
1- first solution is to write it on the global scope.
function callPhone(phonenumber) {
console.log('running')
}
https://jsfiddle.net/mena234/rakeopg2/9
2- The second solution is to store it in a global variable.
let referanceStore = null
$(function () {
//const phoneNumberInput = document.getElementById("phone-number");
function callPhone(phonenumber) {
// any code here...
console.log('running')
}
referanceStore = callPhone
});
and use referancecStore to call your function
ex:
referanceStore('+61987654321')
https://jsfiddle.net/mena234/z391euhm/7
3- Third solution is to use the javascript click event and dataset instead.
https://jsfiddle.net/mena234/z391euhm/22/
That is one of the reasons why you shouldn't use an inline event handler (onclick="callPhone('+61123456789')")
Your inline event handler can't find the function callPhone(phonenumber) because it is defined within the anonymous callback function passed to your $( ... ) so it is only visible in it.
So the first idea of how to solve it would be to make the callPhone globally visible. This however is a bad idea as it pollutes the global namespace.
You instead should get rid of your inline event handlers and attach the event handler within the scope where callPhone is defined, using e.g. event delegation and data attributes:
$(function() {
function callPhone(phonenumber) {
console.log("calling phone number " + phonenumber);
}
// use event delegation to listen a click on elements with the data-action attribute beeing callPhone
$(document).on('click', '[data-action="callPhone"]', function(evt) {
// get the contents of the data attribute phone-number
// and pass it to the callPhone function
callPhone($(evt.target).data().phoneNumber)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>#</td>
<td>Name</td>
<td>City</td>
<td>Phone Number</td>
<td>Call</td>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>Melbourne</td>
<td>+61123456789</td>
<td><a role="button" data-phone-number="+61123456789" data-action="callPhone">Call</a></td>
</tr>
<tr>
<td>2</td>
<td>Tanya</td>
<td>Sydney</td>
<td>+61987654321</td>
<td><a role="button" data-phone-number="+61987654321" data-action="callPhone">Call</a></td>
</tr>
</table>

jquery within a javascript function not working

I am calling a javascript function from within my razor code..but the jquery code within my javascript function doesnot get executed..
what is the correct way of doing it.
function getPosition(id) {
var c = '#' + id;
return $c.index();
}
My HTML Table
<tbody>
<tr>
<td>
#foreach(Result geResults in Model.results)
{
#:
<script>
{
getPosition(#geResult.assessmentId);
}
</script>
}
</td>
</tr>
<\tbody>
UPDATE
As everybody is getting confused i am posting more detail
<table>
<thead>
<tr>
#foreach (Assessment geAssessment in Model.assessments)
{
<th id=#geAssessment.AssessmentID>#geAssessment.Name</th>
}
</thead>
<tbody>
<tr>
#{
// add a td for each assessment in body
foreach(Assessment geAssessment in Model.assessments)
{
<td>
#foreach (ShortResult geResult in Model.results)
{
#:
<script>
{ getPosition(#geResult.assessmentId);
}
</script>
}
</td>
}
}
</tr>
</tbody>
i want to return the column index in getPosition function and then print it in the td..hope this clears out any confusions
currently it says getPosition is out of context whereas intellisense shows me getPosition when i code
Just put c in brackets. It will be like this:
function getPosition(id) {
var c = '#' + id;
return $(c).index();
}
If it doesnt throw
$ Undefind error
first of all check that your passing the values means getPosition("") is not null secondly write in JavaScript
function getPosition($id) {
var c = '#' + $id +;
return $(c).index();
}

jQuery - Can not select a dynamic created element

Here is my HTML structure:
<table id="items" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<td> </td>
<td>Name</td>
<td>Description</td>
<td>Location</td>
</tr>
<tr>
<td>
<button type="button" class="btn btn-default btn-lg">
<span class="glyphicon glyphicon-plus"></span>
</button>
</td>
<td><input type="text" id="addName"></td>
<td><input type="text" id="addDescription"></td>
<td></td>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
</tfoot>
</table>
And here is my jQuery code:
function getTable(){
var args = new Object();
args.op = "getTable";
$.post("./service.php", args , function(data)
{
var dataObj = JSON.parse(data);
for(var i = 0; i<dataObj.length; i++){
$('table#items tbody').append("<tr class=\"items_tr\" id=\"item"+dataObj[i].sn+"\"><td>"+dataObj[i].sn+"</td><td>"+dataObj[i].name+"</td><td>"+dataObj[i].description+"</td><td>"+dataObj[i].belonged+"</td></tr>");
}
});
}
getTable();
$('tbody').children("tr").hide();
$("tbody tr").hide();
$("tr.items_tr").hide();
The Last 3 statements do not work at all.
Cannot select created <tr>s.
Why and how can I select them?
$("tr").hide();
This one hides only <tr>s inside <thead>, things that have already been created.
more questions - How about .each() function?
I want to bind a click event on each td tag, and I failed again..
How to iterate all new added <td>s?
For the last three statements to work, the elements have to exist. You are executing those methods before the Ajax response was received. Move the calls inside the $.get callback, after you added the elements (i.e. after the loop).
Kind of related (because they explain how async stuff works):
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
How do I return the response from an asynchronous call?
If you are trying to hide these elements on an event, add them to an event handler for example:
$(document).ready( function () {
getTable();
$(element).on('click', function () {
$('tbody').children("tr").hide();
$("tbody tr").hide();
$("tr.items_tr").hide();
});
)};
If you are trying to hide these elements right after call the getTable function then add the 3 functions to the $.post success function
code should look like:
function getTable(){
var args = new Object();
args.op = "getTable";
$.post("./service.php", args , function(data)
{
var dataObj = JSON.parse(data);
for(var i = 0; i<dataObj.length; i++){
$('table#items tbody').append("<tr class=\"items_tr\" id=\"item"+dataObj[i].sn+"\"><td>"+dataObj[i].sn+"</td><td>"+dataObj[i].name+"</td><td>"+dataObj[i].description+"</td><td>"+dataObj[i].belonged+"</td></tr>");
}
$('tbody').children("tr").hide();
$("tbody tr").hide();
$("tr.items_tr").hide();
});
}
getTable();
Hi jquery binds events on document.ready if there are elements which are created after document.ready then you need to register those elements for those events using .bind() function of jquery. But be sure first unregister alredy attached elements. using unbind();
Refer bind and unbind functions.

Open link when doubleclicking on table row with jQuery

I have a table that looks like this:
<table id="table">
<thead>
<tr class='tablehead'>
<th>Test</th>
</tr>
</thead>
<tbody>
<tr class='tablecell'>
<td>
</td>
</tr>
</tbody>
</table>
I want to be able to double click on a row and then trigger a link.
An ID has to be transmitted somehow. Where should I define this? This allows me to edit the selected row afterwards.
Any idea how to do this?
Do you have any jQuery you've written yet? Here's a headstart...
Define your ID in the row:
<tr id="something">...</tr>
Then use something like this:
$('tr').dblclick(function(){
var id = $(this).attr('id');
//do something with id
})
This may help you:
jQuery(function($) {
$('#table tr').click(function() {
return false;
}).dblclick(function() {
window.location = url;
return false;
});
});
Do you mean something like this:
$(document).ready(function() {
$('.tablecell').click(function() {
return false;
}).dblclick(function() {
window.open("your_url");
return false;
});
});
and you could create a hidden field and populate that field with the id when double clicked.
Working demo: http://jsfiddle.net/Xr7LC/ (created from the sample code you provided)
Use dblclick api http://api.jquery.com/dblclick/
You can use $(this).attr('id') to get the id, and obviously you will define the id in a tag.
jQuery code for dblclick:
$(document).ready(function() {
$('#table >thead > tr').dblclick(function() {
alert('Row dblclicked');
alert($(this).attr('class'));
});
});​

jQuery remove elements after creation

I'm building a jQuery sortable list where the user can add items from a table, drag and sort and/or remove them. I can add and sort no problem, but I can't work out how to remove an item element after it has been added. I'm relatively new to js / jQuery, so I have a feeling there's something new to learn here about how it works!
I'll leave out the ui.sortable stuff here as I'm only concerned with removing items..
<table>
<tr>
<td><a class="addrelease" href="#" cat_id="1">add</a></td>
<td>Item 1</td>
</tr>
<tr>
<td><a class="addrelease" href="#" cat_id="2">add</a></td>
<td>Item 2</td>
</tr>
</table>
<div id="list"></div>
<script>
$("a.addrelease").click(function (e) {
e.preventDefault();
cat_id = $(this).attr('cat_id');
remove_str = " remove";
str = cat_id + remove_str;
$(str).appendTo("#list").hide().fadeIn();
});
$("a.remove").click(function (e) {
alert("This function doesn't seem to be called");
$(this).parent().remove(); //Doesn't happen..
});
</script>
I'm guessing that javascript doesn't recognize the new generated items - but I'm not sure, so I'm not sure where to start fixing it
Cheers
You should use live function to attach events to dynamically added elements.
Try this to bind click event to a.remove elements:
$("a.remove").live("click", function (e) {
alert("This function doesn't seem to be called");
$(this).parent().remove(); //Doesn't happen..
});
You're absolutely right, javascript won't recognise new items.
jQuery selectors will normally only match against elements currently in the document. When you use $("a.remove").function(), jQuery builds a list of nodes matching "a.remove", then calls function() on each of them.
The .live() function is special, and doesn't attach events directly to elements - instead, events bubbling up to the top of the DOM are evaluated to see if they match the selector.
IMHO, the best approach is to bind the remove handler when you create the new list entry:
str = cat_id + remove_str;
var remove = $(str);
remove.appendTo("#list").hide().fadeIn();
remove.click(function(e) { .... })
Disclaimer: Typed late at night & not tested!
Here is my answer of how I think you should modify your code:
http://jsfiddle.net/RY5CP/
<table>
<tr>
<td><a class="addrelease" href="#" rel="1">add</a></td>
<td>Item 1</td>
</tr>
<tr>
<td><a class="addrelease" href="#" rel="2">add</a></td>
<td>Item 2</td>
</tr>
</table>
<div id="list"></div>
<script type="text/javascript">
$("a.addrelease").click(function(e) {
e.preventDefault();
var catId = $(this).attr('rel');
var itemName = $(this).closest('td').next('td').text();
var newItem = '<p>' + catId + ' ' + itemName + ' remove';
$(newItem).appendTo('#list').hide().fadeIn();
});
$("a.remove").live('click', function(e) {
$(this).parent('p').remove();
});
</script>
It's not valid to use cat_1, cat_2 as HTML attributes. You can use the rel attribute if you need to have a specific value to be associated to your items
Use the live() method to have the click event handler automatically attached to items dynamically created

Categories