This is my first post as I usually find answers (or similar ones) to my questions easily via Google and StackExchange sites. However, I've tried researching various methods, but I am not finding one that meets what I am trying to do. Hopefully someone smarter than me can help me figure this out.
My main page has a "InitiativeContainer" DIV. This DIV loads content into sub DIV containers ListDetails and InitiativeDetails. These sub containers are separate pages loaded into the sub DIVs so that the entire main page is not reloaded, only these content containers. The mainpage loads with the ListDetails DIV populated and is a seperate page with a DataTable named tblDetails. I want to grab the ID of the row that is clicked on in the Datatable, and return that ID as a variable to the parent page so that it can be passed to the InitiativeDetails page.
Right now, I can achieve an alert with getKeyValue, but only after 2 clicks. The 1st click does nothing, but the second and following clicks provide the ID in an alert. The 2 clicks is not user friendly and has to be corrected. It is as if the ListDetails container is not being "initialized" or the "focus" set and the first click initializes/sets the focus of the DIV and the second click does what it is supposed to. Code Below:
Main Page snippet:
<div class="InitiativeContainer">
<div id="ListDetails"></div>
<div id="InitiativeDetails"></div>
</div>
<script type="text/javascript">
$(document).ready(function() {
ListDetails.onload=ListLoad();
});/*End (document).ready*/
</script>
<script>
function ListLoad() {
var urlListDetails = './cfm/Initiative_List.cfm';
var ListDetails = $('#ListDetails');
$.ajax({
beforeSend: function() {
ListDetails.html('<b>Loading...</b>');
},
success: function(html) {
ListDetails.html(html);
},
url: urlListDetails
}); /*End Ajax*/
}; /*End ListLoad*/
ListLoad();
function DetailLoad(InitiativeID) {
var InitiativeID = 1
var urlInitiativeDetails = './cfm/Initiative_Info.cfm?InitiativeID=' + InitiativeID;
var InitiativeDetails = $('#InitiativeDetails');
$.ajax({
beforeSend: function() {
InitiativeDetails.html('<b>Loading...</b>');
},
success: function(html) {
InitiativeDetails.html(html);
},
url: urlInitiativeDetails
}); /*End Ajax*/
} /*End DetailsLoad*/
function getKeyValue(key){
var keyValue = key
alert('key Value: '+keyValue)
}
$('#ListDetails').on('click',function(event) {
// Get project_key
$('#tblDetail tbody tr').on('click',function(event){
var k2 = $(this).find('td').first().text();
event.stopPropagation();
getKeyValue(k2);
return false;
});
return false;
});
</script>
Initiative_List.cfm page Snippet:
<div id="ListDetails" align="center" style="width:100%;">
<table id="tblDetail" class="title display compact cell-border dataTable_pointer" cellpadding="0" cellspacing="0" border="0">
<thead>
<tr>
<th>ID</th>
<th>Prospect</th>
<th>Status</th>
<th>ClientType</th>
<th>Effective</th>
<th>Approved</th>
<th>Consultant</th>
<th>Audit Request</th>
<th>Completed</th>
</tr>
</thead>
<tbody>
<cfoutput query="qryListDetails">
<tr>
<td>#qryListDetails.ID#</td>
<td>#qryListDetails.Prospect#</td>
<td>#qryListDetails.ProspectStatus#</td>
<td>#qryListDetails.ClientType#</td>
<td>#dateFormat(qryListDetails.EffectiveDate,"yyyy-mm-dd")#</td>
<td>#qryListDetails.Approved#</td>
<td>#qryListDetails.Consultant#</td>
<td>#dateFormat(qryListDetails.AuditRequestDate,"yyyy-mm-dd")#</td>
<td>#qryListDetails.Completed#</td>
</tr>
</cfoutput>
</tbody>
</table>
</div>
Is the issue that I have a nested click event inside of a click event? If so how could I handle this better? I am looking to understand what I am doing wrong in addition to a better code solution. Thank you in advance.
The #tblDetail tbody tr click handler should be defined outside of your ListDetails click handler. That is likely causing the click-twice issues.
I don't see what the ListDetails handler is supposed to be doing, maybe we can just omit that and have the end of your code snippet look something like this:
function getKeyValue(key){
var keyValue = key
alert('key Value: '+keyValue)
}
$('#ListDetails').on("click", "#tblDetail tbody tr", function(event) {
var k2 = $(this).find('td').first().text();
event.stopPropagation();
getKeyValue(k2);
return false;
});
</script>
It seems you were on the right track, the nesting of click handlers caused the inner handler to be defined only after the outer click handler had fired. After the first click, the inner handler starts working.
Related
I am working with Ajax and jQuery, I am working on sorting (without data tables), I am getting correct result but just want to display sorting icons (up, down), I want whenever I click on any column (name or symbol) for sort then "down" icon should display and after click on "down" icon should replace with "up" and whenever I click on another column both icons should remove and display on another
column for sort like previous. How can I do this ? I tried with following code but icons appending (showing multiple times), where I am wrong?
Here is my html:
<table border='1' width='100%' style='border-collapse: collapse;' id='postsList'>
<thead>
<tr>
<th>S.no</th>
<th class="column_sort" id="name" data-order="desc" href="#">Title</th>
<th class="column_sort" id="symbol" data-order="desc" href="#">Symbol</th>
</tr>
</thead>
<tbody></tbody>
</table>
And here is my script code:
$(document).ready(function(){
var timesClicked = 0;
$(document).on('click', '.column_sort', function(event){
event.preventDefault();
var column_name = $(this).attr("id");
timesClicked++;
if (timesClicked % 2 == 1) { // after first click(even clicks)
$('#'+column_name+'').append('<img src="<?=base_url()?>/assets/img/DownArrow.png"/>');
$('#'+column_name+'').remove('<img src="<?=base_url()?>/assets/img/UpArrow.png"/>');
var order = "ASC";
}else{
var order = "DESC"; // after second click(odd clicks)
$('#'+column_name+'').remove('<img src="<?=base_url()?>/assets/img/DownArrow.png"/>');
$('#'+column_name+'').append('<img src="<?=base_url()?>/assets/img/UpArrow.png"/>');
};
var arrow = '';
var PageNumber= $("#pagination").find("strong").html();
$(".column_sort").removeClass("active");
$.ajax({
url:'<?=base_url()?>/Main/fetch_details/',
method:"POST",
data:{column_name:column_name, order:order ,PageNumber:PageNumber},
success:function(data) {
$("#postsList tr:not(:first)").remove();
$("#postsList2").show();
$('#'+column_name+'').addClass('active');
return false;
}
})
});
});
If you check your browser's devtools console, I think you will see errors.
If you check the docs for .remove(), it removes the matched element - in your case, it is trying to remove the whole <th>. If you pass a parameter, it should be a selector (not HTML), and it will filter the matched elements, not find nested elements. Because you are passing HTML, the .remove() call is generating an error and failing, so the img is never removed. Next time you click, a new one is added to the one that is already there.
So you really want something like:
$('#' + column_name + ' img').remove();
This will match the <img> element inside the <th>, and remove it.
Next problem - the order you add and remove elements is important. Eg: for the first click, you add a down arrow. If we now do the removal, the selector will match any image. That means we'll remove both the old and the newly added images!
So we need to take care to 1) Remove the old image first; 2) Add a new image.
Here's a working snippet - click the Run button to see it in action. I don't have your images of course, so instead of <img> elements I used <span>s, but the idea is exactly the same.
I also removed your AJAX code as that is not relevant to the problem.
$(document).ready(function(){
var timesClicked = 0;
$(document).on('click', '.column_sort', function(event){
event.preventDefault();
var column_name = $(this).attr("id");
timesClicked++;
if (timesClicked % 2 == 1) {
$('#' + column_name + ' span').remove();
$('#' + column_name).append('<span> v</span>');
} else {
$('#' + column_name + ' span').remove();
$('#' + column_name).append('<span> ^</span>');
};
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border='1' width='100%' style='border-collapse: collapse;' id='postsList'>
<thead>
<tr>
<th>S.no</th>
<th class="column_sort" id="name" data-order="desc" href="#">Title</th>
<th class="column_sort" id="symbol" data-order="desc" href="#">Symbol</th>
</tr>
</thead>
<tbody></tbody>
</table>
PS: as an alternative to adding and removing elements on every click, it might be a neater solution to simply toggle visibility of elements already on the page. Eg both arrow images are already on the page on page load, but with a "hidden" class. Every click then just toggles that class on/off. Maybe something like:
$('#' + column_name + ' img').toggleClass('hidden');
How you display the arrow icons is up to you, for my example I simply used html entities. Wrap the up and down arrows into separate tags (span in my example) and include those within the TH tags for each column header.
<th class="column_sort" id="name" data-order="desc" href="#">
Title
<span>↑</span><span>↓</span>
</th>
Hide all the spans by default and we'll target the others specifically by toggling between two other classes we'll add to the TH that already has column_sort class.
.column_sort{cursor:pointer}
.column_sort span{display:none;}
.sort_asc span:first-child{display:inline;}
.sort_desc span:nth-child(2){display:inline;}
Then for the javascript:
$(document).on('click', '.column_sort', function(event){
var $x = $(event.target);
var ascending = $x.hasClass('sort_asc') ? true : false;
// Remove arrows from any columns currently displaying them
$('.column_sort.sort_asc').removeClass('sort_asc');
$('.column_sort.sort_desc').removeClass('sort_desc');
// Show the appropriate arrow
if (ascending){
$x.addClass('sort_desc');
}else{
$x.addClass('sort_asc');
}
});
https://jsfiddle.net/176hj8s0/
Since you already have logic in place to handle ascend and descend order, you can just piggyback off that to determine which class is added.
You can also use fontawesome icons instead of img for display of up and down arrows. Here's a working example of how I do:
Step 1. Use tag after column name
<tr>
<th>S.no</th>
<th class="column_sort" id="name" data-order="desc" href="#">
Title <i class="fas fa-angle-down rotate-icon pr-10"></i>
</th>
<th class="column_sort" id="symbol" data-order="desc" href="#">
Symbol <i class="fas fa-angle-down rotate-icon pr-10"></i>
</th>
2.Jquery : First check which column is clicked and find class of icon tag and toggle it.
<script type="text/javascript">
$(document).on('click', '.column_sort', function(event) {
event.preventDefault();
if ($(this).find(".fas").hasClass('fa-angle-down')) {
$(this).find(".fas").removeClass('fa-angle-down');
$(this).find(".fas").addClass('fa-angle-up');
} else {
$(this).find(".fas").removeClass('fa-angle-up');
$(this).find(".fas").addClass('fa-angle-down');
}
});
I'm creating a button through JavaScript and am trying to assign it to an onclick event. At runtime the button is created but the onclick event isn't firing when I click it. Also in Chrome's Inspector, no error is generated when I click the button.
Here's my code:
function truncator(){
$.each($('td.rawdata-field').not(':empty'), function(i,v){
var count = parseInt($(v).text().length);
var maxChars = 650;
if(count > maxChars){
var str = $(v).text();
var trimmed = str.substr(0, maxChars - 2);
$(v).text(trimmed + '...');
var btn = document.createElement('button');
btn.setAttribute('content', 'test content');
btn.setAttribute('class', 'show-full-text-button');
btn.innerHTML = 'Show Full Log';
btn.onclick = function() {
alert("assd");
};
$(v).append(btn);
}
});
};
v is the parent container, which in this case is a td element.
What's the problem here?
EDIT:
One additional detail I can offer is that the above is being executed many times over a page, which is have something to do with why it isn't working. All the buttons are being created fine, but the alert's aren't working when done through the above method.
The container already exists when the above code is executed.
EDIT 2:
I've updated the code above to include more of what is going on. The function truncator basically is supposed to go through all td elements with class rawdata-field that are not empty, and check if the text mentioned in it is longer than 650 characters. If it is, it truncates the text to 650 characters and then puts a button there to showing the complete log if the user wishes to do so.
The table on which the above function operates already exists when truncator is called.
Your code work fine here: https://jsfiddle.net/dusfqtr9/
$(document).ready(function() {
var btn = document.createElement('button');
btn.setAttribute('content', 'test content');
btn.setAttribute('class', 'show-full-text-button');
btn.innerHTML = 'Show Full Log';
btn.onclick = function() {
alert("Hello !");
};
$("#container").append(btn);
});
Maybe your script is run before the parent container created, so $(v).append(btn) do nothing.
onclick only works with the elements that already exist at the time when the script (containing your onclick handler) is loaded. As such, elements that get created after that, are no longer bound to the onclick event that you specified in the loaded script.
I'm not sure what your full code set is, but I'm guessing that your button is regenerated probably several times after the script is loaded. This is the most likely reason why the onclick event does not fire.
As such, what you would want to do is to "attach" the event handler to a higher level in the DOM tree (highest being your html) that you are sure won't get 'programmatically' regenerated, then you'd want to check if the element in question, which is inside the DOM, exists. You then run your function when this element is found.
Below is a JQuery implementation of this logic using the .on :
EDIT1: I've edited the code based on your latest comment. You'll notice that I've separated the function that handles the click of your buttons. I urge you to try doing this in your original code set, and you'll see that the onclick event will always be bound to your buttons regardless of when your buttons are created, or even how many times you regenerate them.
EDIT2: I just noticed in the comments that you wanted to show the full text in the alert. Edited the code to show one way of doing that.
function truncator(){
$.each($('td.rawdata-field').not(':empty'), function(i,v){
var origContent = $(v).text();
$(v).attr('orig-content',origContent);
var count = parseInt($(v).text().length);
var maxChars = 10;
if(count > maxChars){
var str = $(v).text();
var trimmed = str.substr(0, maxChars - 2);
$(v).text(trimmed + '...');
var btn = document.createElement('button');
btn.setAttribute('content', 'test-content');
btn.setAttribute('class', 'show-full-text-button');
btn.innerHTML = 'Show Full Log';
$(v).append(btn);
}
});
};
$('html').on('click', '.show-full-text-button', function(){
content = $(this).closest('td').attr('orig-content');
alert(content);
});
truncator();
table td {
border:1px solid black;
padding:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td class="rawdata-field"> this is a very long text </td>
<td class="rawdata-field"> another long text </td>
<td class="rawdata-field"> this is getting out ofhand </td>
</tr>
<tr>
<td class="rawdata-field"> okay another longtext </td>
<td class="rawdata-field"> more content here, and there's another one here </td>
<td class="rawdata-field"> what am i doing here </td>
</tr>
</table>
I have a page setup for a presentation layout:
+------------------------+
|prev next|
|+----------------------+|
|| page ||
|| dynamic content ||
|| ||
|+----------------------+|
+------------------------+
In the example above, next/prev are nav buttons that control the dynamic content using $("page").load(url);
On one of the pages I have a popup that has buttons in it that are linked to an ajax call which controls the content of the popup.
These buttons do their job nicely when the page is first loaded. If the page is changed (using the nav buttons) and then changed back, the popup will open but the buttons don't work. If you click the buttons, close the popup, and then reopen the popup, the information you requested on the 1st click shows but the buttons still don't work.
This tells me that the ajax request is fine, there is a problem with the binding of the elements somewhere. Here is my Javascript:
$('#resTable').on('click',this,function() {
$('#ayAvgDPm').html("");
$('#aoAvgDPm').html("");
$('#ayTotProfit').html("");
$('#aoTotProfit').html("");
$('#ayAvgPcPm').html("");
$('#aoAvgPcPm').html("");
$('#ayTotPcProfit').html("");
$('#aoTotPcProfit').html("");
$('#ayrRes').html("");
$('#etfProductPopup').bPopup();
});
$('div[class^="sideNav"]').on('click',this,function() {
$('#yrSummary').fadeIn(200);
$('#yAvgDPm').html("");
$('#oAvgDPm').html("");
$('#yTotProfit').html("");
$('#oTotProfit').html("");
$('#yAvgPcPm').html("");
$('#oAvgPcPm').html("");
$('#yTotPcProfit').html("");
$('#oTotPcProfit').html("");
$('#yrRes').html("");
var yr = "20"+$(this).attr('class').substr(-2);
var req = $.ajax({
url : '../includes/prod_results.php',
type : 'POST',
dataType : "json",
data : {
y : yr,
t : 'ETF'
},
success : function(j) {
var table = "<table cellspacing='0'><tr><th>Year</th><th>Returns</th></tr>";
for(var i = 0; i < 12; i++) {
if (i === 5 && yr === '2014'){
break;
}
var obj = j[i];
var month = obj['month'];
var profit = obj['profit'];
var bal = obj['bal'];
table += "<tr><td style='width:75px'>"+month+"</td><td style='padding: 0 15px'>"+parseFloat(profit).toFixed(2)+"%</td><td style='width:75px'>$"+comma(parseFloat(bal).toFixed(2))+"</td></tr>";
if (i === (11)) {
table += "</table>";
}
}
var YAvgDPm = comma(parseFloat(j.YAvgDPm).toFixed(2));
var OAvgDPm = comma(parseFloat(j.OAvgDPm).toFixed(2));
var YTotProfit = comma(parseFloat(j.YTotProfit).toFixed(2));
var OTotProfit = comma(parseFloat(j.OTotProfit).toFixed(2));
var YAvgPcPm = comma(parseFloat(j.YAvgPcPm).toFixed(2));
var OAvgPcPm = comma(parseFloat(j.OAvgPcPm).toFixed(2));
var YTotPcProfit = comma(parseFloat(j.YTotPcProfit).toFixed(2));
var OTotPcProfit = comma(parseFloat(j.OTotPcProfit).toFixed(2));
$('#yAvgDPm').html("$"+YAvgDPm);
$('#oAvgDPm').html("$"+OAvgDPm);
$('#yTotProfit').html("$"+YTotProfit);
$('#oTotProfit').html("$"+OTotProfit);
$('#yAvgPcPm').html(YAvgPcPm+"%");
$('#oAvgPcPm').html(OAvgPcPm+"%");
$('#yTotPcProfit').html(YTotPcProfit+"%");
$('#oTotPcProfit').html(OTotPcProfit+"%");
$('#yrRes').html(table);
$('#yrGraph').html("<img src='../images/graphs/etf_"+yr+".jpg'>");
return false;
}
});
return false;
});
I know it's fairly lengthy...
I have tried the above script both inside and outside the $(document).ready() handler.
Can someone please help me as to what I am not doing?
EDIT As requested, HTML:
<table id="resTable" cellspacing="0">
<tr>
<th>Year</th>
<th> 1st Quarter</th>
<th>2nd Quarter</th>
<th>3rd Quarter</th>
<th>4th Quarter</th>
<th>Year Total</th>
<th>Month Avg</th>
</tr>
...
</table>
<div id="etfProductPopup">
<h1 style="text-align:center">ETF - Compounded Results</h1>
<div id="popupLeftBar">
<div class="sideNav14">
2014
</div>
<div class="sideNav13">
2013
</div>
<div class="sideNav12">
2012
</div>
<div class="sideNav11">
2011
</div>
<div class="sideNav10">
2010
</div>
<div class="sideNav09">
2009
</div>
<div class="sideNav08">
2008
</div>
<div class="sideNav07">
2007
</div>
<div class="sideNav06">
2006
</div>
<div class="sideNav05">
2005
</div>
<div class="sideNav04">
2004
</div>
<div class="sideNav03">
2003
</div>
</div>
<div id="popupMain">
<div id="yrSummary">
<table cellspacing="0">
<tr>
<th></th>
<th>Avg<br>$/Mth</th>
<th>Total<br>$ Profit</th>
<th>Avg<br>%/Mth</th>
<th>Total<br>% Profit</th>
</tr>
<tr>
<th>Year</th>
<td id="yAvgDPm"></td>
<td id="yTotProfit"></td>
<td id="yAvgPcPm"></td>
<td id="yTotPcProfit"></td>
</tr>
<tr>
<th>Overall</th>
<td id="oAvgDPm"></td>
<td id="oTotProfit"></td>
<td id="oAvgPcPm"></td>
<td id="oTotPcProfit"></td>
</tr>
</table>
</div>
<div id="yrGraph"></div>
<div id="yrRes"></div>
</div>
Really? No body got any other ideas on this? I really need you guys to come through for me on this!
Code for nav buttons:
function nav(d) {
n = page + d;
$('#slide').load('p/'+n+'.php');
}
HTML:
<div class="prev" onClick="nav(-1)" title="Previous Page"><< Previous</div>
<div class="next" onClick="nav(1)" title="Next Page">Next >></div>
EDIT
So I have tried all 3 of the (current) answers and am getting nowhere! This is very frustrating!
I am starting to think there may be some underlying issues and that the bindings are not the complete problem.
The page obviously nees to be loaded as if it was refreshed by the browser. The fact that the page works fine the 1st time it is loaded, regardless of how it is loaded, says to me that the bindings are all fine.
The page also works fine without the popup.
Are there any ideas, other than the bindings, what the underlying issue could be?
Also, I know it is against the rules of SO for me to publish a link to the webpage in question, but if anyone would like a link, I am desperate enough to provide it privately. Please ask.
EDIT
So, I'm thinking, the hidded div (for the popup) is staying populated even after I use the following script:
$('#etfProductPopup').bPopup({
onClose : function() {
postLoadBindings();
$('#ayAvgDPm').html("");
$('#aoAvgDPm').html("");
$('#ayTotProfit').html("");
$('#aoTotProfit').html("");
$('#ayAvgPcPm').html("");
$('#aoAvgPcPm').html("");
$('#ayTotPcProfit').html("");
$('#aoTotPcProfit').html("");
$('#ayrRes').html("");
}
});
I'm thinking the issue may be with the popup script...
https://raw.githubusercontent.com/dinbror/bpopup/master/jquery.bpopup.min.js
EDIT
Also just noticed that the popup div is being duplicated on page load. From the console:
<div id="etfProductPopup" style="display: none; left: 440px; position: absolute; top: 156px; z-index: 2147483650; opacity: 0;">...</div>
<div id="etfProductPopup" style="display: none; left: 440px; position: absolute; top: 156px; z-index: 2147483650; opacity: 0;">...</div>
EDIT
(Yes, I realize if there was a badge for 'Most Edits to Own Question' then I would have won, but I think the more data I provide, the better chance of a response)
I created a #resTable element on another page (loaded the same way as the previous). I noticed that, even when using $('#resTable').unbind() in the document ready handler, clicking the element brings up the popup from the previous page!
HOW IS THIS POSSIBLE WHEN THE SCRIPT FOR THE POPUP DOESN'T EVEN EXIST ON THAT PAGE, LET ALONE THE CONTENT??
Someone, PLEASE! There MUST be a rational explanation for this! I am not trying to program humans, this is a computer code, this runs of bits of data and cannot simply make it up as it goes along!
Can someone please help me with this?
Got this far: Popup is creating duplicate div inside the outer page (the one with the nav buttons). I guess it is doing this so that it layers properly over the whole page, rather than just the page that contains the original code for the div.
EDIT
A more in depth look as to what is happening. The div for the popup is obviously inside the page, not the container. bPopup is moving the div to within the <body> tags of the containing page. This means that the div is available on all pages navigated to after the bPopup call. Closing the popup is not moving the div back, so when the page is reloaded using the nav buttons, the div is being duplicated.
Latest Progress
After speaking to the client I am not able to plost a live link, unfortunately.And to create a jsFiddle would take ages.
As explained in the edits above, the issue is bPopup re-creating the popup div inside the parent page and not removing it on popup close.
I am not sure if there is a way to delete an element on the page? The problem is, if an element can be deleted, the copy that bpopup creates is exactly the same as the original, so any script that targets the duplicate will also target the original
change:
$('#resTable').on('click',this,function() {
...
to
$(document).on('click','#resTable',function() {
...
and
$('div[class^="sideNav"]').on('click',this,function() {
...
to
$(document).on('click','div[class^="sideNav"]',function() {
...
Event delegation that #Sudhir mentioned should have worked, but yet, if you are facing the problem you might wanna try forcefully binding new events every time the page loads. Something like -
In the Main Page, that has the Prev and Next button, define all your functions -
var bindEvents = function(){
//we are unbinding to make
//sure we are not attaching more than once since
//instead of on, I am using direct CLICK binding.
$('#resTable').unbind("click").click(function() {
....
});
$('div[class^="sideNav"]').unbind("click").click(function() {
....
});
};
var nav = function(d) {
n = page + d;
$('#slide').empty();
$('#slide').load('p/'+n+'.php', function(){
//bind events
bindEvents();
});
}
$(function(){
//the first page call, when page loads
nav(0);
});
Remember that, this is not the best approach, but this will ensure that other things are alright. If this binding works then we can isolate the issue and confirm that there is problem in how you are using your bindings. Let me know if it still does not work.
I didn't try any fiddle on this, but have you tried putting the events binding of popup buttons on the "complete" hanlder of the ajax request? It seems a safer way to assure bindings to a single element:
var req = $.ajax({
url : '../includes/prod_results.php',
type : 'POST',
dataType : "json",
data : {
y : yr,
t : 'ETF'
},
success : function(j) {
var table = "<table cellspacing='0'><tr><th>Year</th><th>Returns</th></tr>";
for(var i = 0; i < 12; i++) {
if (i === 5 && yr === '2014'){
break;
}
var obj = j[i];
var month = obj['month'];
var profit = obj['profit'];
var bal = obj['bal'];
table += "<tr><td style='width:75px'>"+month+"</td><td style='padding: 0 15px'>"+parseFloat(profit).toFixed(2)+"%</td><td style='width:75px'>$"+comma(parseFloat(bal).toFixed(2))+"</td></tr>";
if (i === (11)) {
table += "</table>";
}
}
var YAvgDPm = comma(parseFloat(j.YAvgDPm).toFixed(2));
var OAvgDPm = comma(parseFloat(j.OAvgDPm).toFixed(2));
var YTotProfit = comma(parseFloat(j.YTotProfit).toFixed(2));
var OTotProfit = comma(parseFloat(j.OTotProfit).toFixed(2));
var YAvgPcPm = comma(parseFloat(j.YAvgPcPm).toFixed(2));
var OAvgPcPm = comma(parseFloat(j.OAvgPcPm).toFixed(2));
var YTotPcProfit = comma(parseFloat(j.YTotPcProfit).toFixed(2));
var OTotPcProfit = comma(parseFloat(j.OTotPcProfit).toFixed(2));
$('#yAvgDPm').html("$"+YAvgDPm);
$('#oAvgDPm').html("$"+OAvgDPm);
$('#yTotProfit').html("$"+YTotProfit);
$('#oTotProfit').html("$"+OTotProfit);
$('#yAvgPcPm').html(YAvgPcPm+"%");
$('#oAvgPcPm').html(OAvgPcPm+"%");
$('#yTotPcProfit').html(YTotPcProfit+"%");
$('#oTotPcProfit').html(OTotPcProfit+"%");
$('#yrRes').html(table);
$('#yrGraph').html("<img src='../images/graphs/etf_"+yr+".jpg'>");
return false;
},
complete:function(){
//put the bindings to popup here
}
});
try this
$("body").delegate('#resTable','click',function() {
//some codes
}
$("body").delegate('div[class^="sideNav"]','click',function() {
//some codes
}
I want to access the div tag in the following HTML code:
<table>
<div class="rowBound">
<tr onclick="expandLastResultDetails(this);">
<td class="c1">56835-14513</td>
...
</tr>
<tr class="rowDetails">
<td colspan="0">
<div style="background-color: #0F9;"> expandable
</div></td>
</tr>
</div>
</table>
But jQuery commands just give me a TBODY instead of my DIV ..
This is what I was doing in another case:
function expandNavContent(navEntryTitle) {
var content = $(navEntryTitle).parent().children('.navContent');
$(content).slideToggle('slow', function () {
// Animation complete.
});
}
What I want:
rowDetails should be animated with slideToggle if someone clicks on the tr
If I use this code:
function expandLastResultDetails(tableEntry) {
var content =$(tableEntry).parent().children('.rowDetails');
$(content).slideToggle('slow', function () {
// Animation complete.
});
}
It toggles ALL rows but it should just toggle ONE row so I nested them into a division, maybe that was wrong
Try this:
$('tr.rowDetails').find('div');
But, your Markup is not valid. tr is element of table, not for div.
To get the outer parent div:
$('tr.rowDetails').closest('div');
After edit
function expandLastResultDetails(tableEntry) {
var content =$(tableEntry).next('.rowDetails'); // will point to next tr
$(content).slideToggle('slow', function () {
// Animation complete.
});
}
Try $('.rowDetails').closest('div.rowBound');
It will bubble from the current element (outwards) until it find a div element.
Hope it helps
What command did you try? You could have used this:
$(".rowDetails tr td div");
And moreover, there cannot be a <tr> inside a <div>!
Since your markup is invalid the browser will propably insert the tbody and table for you (look at the markup in FireBug/Dev tools). Something like $(".rowDetails").parent().parent().parent() could work (in some browsers) but I'd recommend fixing the markup instead
I've got a table with hidden rows on it, like such
-visible-
-invisible-
-visible-
-invisible-
When I click on a table row, I want it to show the invisible row. Currently I have that using this function:
var grid = $('#BillabilityResults');
$(".tbl tr:has(td)").click(
function () {
$(grid.rows[$(this).index()+1]).toggle();
}
However, this table also hides the visible rows if I click on one of the (now visible) hidden rows.
I'd like the click function to only work on the specific visible rows. Currently all my invisible rows have the class "even" so I figured I could limit the click based on that. However, I can't seem to find the syntax to explain that to my function. How would I go about doing that? And, more importantly, is there a better way to approach this?
Use next:
$(".tbl tr:has(td)").click(
function () {
$(this).next().toggle();
}
);
And also if you have specific selector for odd or even:
$(".tbl tr.odd").click(
function () {
$(this).next().toggle();
}
);
But I think that the major help with my answer is to use next() that get you the next row, instead of the index process that you were doing.
var grid = $('#BillabilityResults');
$(".tbl tr:visible").click(
function () {
$(this).next('tr').toggle();
});
Use the NOT function to disregard the EVEN tr elements:
http://jsfiddle.net/7AHmh/
<table class="tbl">
<tr><td>one</td></tr>
<tr class="even" style="display:none"><td>two</td></tr>
<tr><td>three</td></tr>
<tr class="even" style="display:none"><td>four</td></tr>
</table>
$(".tbl tr:has(td)").not("tr.even").click(function() {
alert("Click triggered.");
$(this).next("tr").show();
});
I guess you could check for even/odd rows with the modulus operator before calling your toggling code:
function() { // your anonymous function
if (rowNumber % 2 == 0) { // only even rows get through here
// toggle code here
}
}
I hope it helps.