The problem I am encountering, is that I have to many duplicates. I am basically trying to show 1/11 tables by which bottom is clicked (list_row[1-11]), so when I show for instance table 2, it must hide all the other tables.
I believe this can be shortened by a loop or something else, because if I have 100 tables then I must copy and paste, not smart. Keep in mind that the code below is just showing table 1 to table 3. How can I prevent these duplicates?
// hide the tables by default when page loads
$('#table1').hide();
$('#table2').hide();
$('#table3').hide();
$('#table4').hide();
$('#table5').hide();
$('#table6').hide();
$('#table7').hide();
$('#table8').hide();
$('#table9').hide();
$('#table10').hide();
$('#table11').hide();
// Show Exhaust Temperature diagram
$('#list_row1').on('click',function(){
$('#table1').show();
$('#table2').hide();
$('#table3').hide();
$('#table4').hide();
$('#table5').hide();
$('#table6').hide();
$('#table7').hide();
$('#table8').hide();
$('#table9').hide();
$('#table10').hide();
$('#table11').hide();
});
// Show Cylinder Pressure diagram
$('#list_row2').on('click',function(){
$('#table1').hide();
$('#table2').show();
$('#table3').hide();
$('#table4').hide();
$('#table5').hide();
$('#table6').hide();
$('#table7').hide();
$('#table8').hide();
$('#table9').hide();
$('#table10').hide();
$('#table11').hide();
});
$('#list_row3').on('click',function(){
$('#table1').hide();
$('#table2').hide();
$('#table3').show();
$('#table4').hide();
$('#table5').hide();
$('#table6').hide();
$('#table7').hide();
$('#table8').hide();
$('#table9').hide();
$('#table10').hide();
$('#table11').hide();
});
// Code continues to table11.
Set all your tables to display: none then introduce an .active class set to display: block (or display: table, in this case). Then simply toggle the class on and off:
.active {
display: table;
}
$('#list_row1').on('click', function() {
$('.active').removeClass('active');
$('#table1').addClass('active');
});
To avoid repetition, however, you'd be better off extending this this to add data-* attributes to your #list_row/n/ elements, and handle click events on these:
<elem id="list_row1" data-row="1"></elem>
$('[data-row]').on('click', function() {
var row = $(this).attr('data-row');
$('.active').removeClass('active');
$('#table' + row).addClass('active');
});
Do also note that you can chain selectors with commas. Rather than using $(elem1).hide(); $(elem2).hide() you can instead $(elem1, elem2).hide().
Try
$('[id^=list_row]').on('click',function(){
$('table').hide();
$('#table'+$(this).attr('id').slice(8)).show();
});
You can also use the starts-with jQuery selector:
$('id^="table"').hide();
$('id^="list_row"').on('click',function(){
var num = this.id.split('w')[1]; //alert(num)
$('id^="table"').hide();
$('#table'+num).show();
});
Reference:
All jQuery Selectors
Add a class to all your table and listrow elements, and a custom attribute on those lasts to identify where are you clicking.
<table id="table2" class="tableClass">
<whatever id="list_row2" class="listRowClass" data-yourProjectname-numRow="2">
This way you can just show the table that's been clicked and hide all the rest:
$(".listRowClass").on("click", function() {
$(".tableClass").hide() // Hides all tables
$("#table" + $(this).attr("data-yourProjectname-numRow")).show() //Shows clicked table
});
Related
I have a snippet I've developed to increase the size of an image and take the td to the right of the image and drop it beneath.
However - it's taking a good few seconds, from the time it takes to remove the TD to add it in, and it makes the page rendering/paint/flow look terrible.
Please see the video below for a better understanding of what is happening.
http://screencast.com/t/RQdBiNyGkEm
Please also see my code snippet below;
<script>
$(document).ready(function() {
$('html').addClass('js');
$('.description').show();
// add a td for initial page load of cart.
$("table#shopping-cart-items tr td.image").after($('<td id="clearSpacePageLoad"></td>'));
// take content from right - and drop it beneath the image
$('#shopping-cart-items > tbody > tr').each(function() {
var desc = $('td.description', this).html()
$('td.description', this).remove();
$('td.image', this).append(desc);
});
});
</script>
<script>
//When selecting a delivery method - everything resets due to AJAX.
$(document).ready(function() {
// Use .live() in stead of .on() since jQuery is < 1.9
// On select of delivery method do the following
$('.shippingOpt').live('click', function() {
// Wait for ALL ajax requests on page (Past and future) to execute BEFORE executing the following
$(document).ajaxStop(function() {
// Repeat the same code as initial page load.
$('img.item-img').each(function() {
var str = $(this).attr('src'),
arr = str.split("?");
query = "?hei=200&wid=200&op_sharpen=1"
$(this).attr('src', arr[0] + query);
});
$('#shopping-cart-items > tbody > tr').each(function() {
var desc = $('td.description', this).html()
$('td.image', this).append(desc);
$('td.description', this).remove();
});
// If ID of 'clearSpaceOnClick' exists don't add another td, if it doesn't - add it!
if ($('#clearSpaceOnClick').length) {} else {
$("table#shopping-cart-items tr td.image").after($('<td id="clearSpaceOnClick"></td>'));
}
});
});
});
</script>
<style>
.checkoutBasket table.cart-container td.image img {
width: 200px;
height: auto;
}
#clearSpace {
padding: 0 0 0 15px;
}
</style>
From looking at the video, you are almost certainly injecting an additional td element and now there are more tds on the row than there are columns in your table. You should be able to see an issue if you inspect element.
Off hand, I would look very closely at the logic related to the line below but you dont give us your html so we cant know for sure:
$("table#shopping-cart-items tr td.image").after($('<td id="clearSpaceOnClick"></td>'));
If there are multiple td.image in table#shopping-cart-items then you should not append an element with an ID (as ID's must be unique), which you're doing in 2 places in your code.
It looks like you might be selecting an (already active) shipping option. In that case ajaxstop may be delaying things if there are any outstanding ajax requests.
Also, jQuery .on has been available since v1.7, not 1.9
I have my menu like this:
https://jsfiddle.net/23r4q610/
And my code to change the selected menu button like below:
$('#bluebutton').click(function () {
$('.testul li').removeClass('selectedred selectedpurple selectedgreen selectedorange');
$('#bluebutton').addClass('selectedblue');
});
$('#redbutton').click(function () {
$('.testul li').removeClass('selectedblue selectedpurple selectedgreen selectedorange');
$('#redbutton').addClass('selectedred');
});
$('#purplebutton').click(function () {
$('.testul li').removeClass('selectedblue selectedred selectedgreen selectedorange');
$('#purplebutton').addClass('selectedpurple');
});
$('#greenbutton').click(function () {
$('.testul li').removeClass('selectedblue selectedred selectedpurple selectedorange');
$('#greenbutton').addClass('selectedgreen');
});
$('#orangebutton').click(function () {
$('.testul li').removeClass('selectedblue selectedred selectedpurple selectedgreen ');
$('#orangebutton').addClass('selectedorange');
});
Ofcourse this is bad code since it could be written much shorter. Should I go about this using just numbers so I can do some foreach, or is there a better way to do this?
This can be condensed by adding a generic click event on all buttons by using [id*="button"]. Then grab the relevant color from the nested anchor.
$('[id*="button"]').click(function(){
$('.testul li').removeClass();
$(this).addClass('selected'+$('a',this).attr('class'));
});
or
$('li').click.../*this would be the same as above*/
fiddle
In this particular case, there doesn't appear to be a good reason to add and remove classes. Just change the background color instead of adding and removing a class to do so.
$(this).css("background-color", "red");
I would avoid hard-coding the color names into the HTML IDs. Rather use a CSS class name like "selected" and describe in your CSS what that should look like. Example:
<li id="home-button" class="color-button">Home
CSS:
#home-button.selected,
#home-button:hover {
background: -webkit-linear-gradient(#78b1ff, #4881dc);
}
JS:
$('.color-button').click(function () {
$(this).toggleClass("selected").siblings(".color-button").removeClass("selected");
}
This way color information (presentation) is separated from semantic information (like "home") and JS code is daramtically shorter.
Note: this is just an advice, I have not tested it but should give you a good point to start.
You can reduce the code to only 1 click binding. Where when an element is clicked, class from all the li's is removed and then on the current clicked li, selected class is added.
$(".testul > li").click(function(){
$('.testul li').removeClass('selectedred selectedpurple selectedgreen selectedorange selectedblue');
var color = $(this).attr("id").replace("button","");
$('#'+color+'button').addClass('selected'+color);
});
Here is the updated fiddle - https://jsfiddle.net/23r4q610/2/
I've got a "tablesorter table" containing a category names in the first column. I filter the rows using shortcut buttons which trigger the specific "search" actions depending on which one is active:
function do_filtering() {
var category = $('#categories .active a').attr('data-filter-text');
var columns = [];
columns[0] = category;
$('table').trigger('search', [columns]);
}
Contents of the table may change. Until now I triggered on the table two events: "updateCell" and "search" and it got properly updated.
I need to separate these calls:
"updateCell" would be triggered by the cell editor (attached by a "sorter" for that specific columns' content)
"search" would be triggered after the cell is updated.
Unfortunately filtering in the "updateComplete" handler doesn't work, please see: http://jsfiddle.net/8cg4f/352/
How can I retain the search criteria after updating the table?
Well, the problem seems to be that since the filter inputs are empty, the filter widget is showing all rows after the update. I have two solutions, the second one probably being the better one because the first method causes flickering:
1) Add a setTimeout in the callback, with a time of 1 millisecond (demo):
$('td').click(function () {
resort = false;
$("table").trigger('updateCell', [$(this).closest('td'), resort, function(table){
setTimeout(function(){ do_filtering(); }, 1);
}]);
});
2) Update the filters, and hide the filter row (demo):
CSS
.tablesorter-filter {
display: none;
}
Code
function do_filtering() {
var category = $('#categories .active a').attr('data-filter-text');
$('.tablesorter-filter:first').val(category).trigger('search');
}
$('td').click(function () {
resort = false;
$("table").trigger('updateCell', [$(this).closest('td'), resort, function(table){
do_filtering();
}]);
});
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.
I have the following example http://jsfiddle.net/zidski/MxqRu/1/
When you click on 2010 I need valuation to disappear with the list items.
Here is the code which I am using to do this:
$("#yearfilter a").live("click", function(e) {
e.preventDefault();
//var v = $(this).val();
var v = $(this).attr("data-value");
if(v.length > 0) {
$('tr.reports').show();
$('tr.reports ul').hide();
$('tr.reports ul.year-'+v).show();
$('tr.reports').each(function() {
if($('ul:visible', this).size() == 0) {
$(this).hide();
}
});
} else {
$('tr.reports').show();
$('tr.reports ul').show();
}
});
I have done it in my project something like this:
function toggleRow(row_id) {
row_selector = "#row_" + row_id;
$(row_selector).toggleClass("shown hidden")
}
Then in the CSS:
.hidden {display:none;}
.shown {}
Then in the HTML I have alternating table rows, where the odd rows act as headings for the content in the even rows. Clicking an odd row toggles the visibility of the corresponding even row.
...
<tr onclick="toggleRow(17)">...</tr>
<tr class="hidden" id="row_17">...</tr>
...
Give each tr an ID something like id="row_2010" then look for that and hide the whole entire row at once.
UPDATE
I would strongly suggest not using so many tables and use more classes to classify your data structure. It would help your javascript be much more clean, concise and function easier.
UPDATE
I adjusted all your javacsript and some of your html. Here is a fully working example jsFiddle Demo