How to bind multiple elements to scroll together? - javascript

I have 3 different tables that scroll horizontally (one scrolls vertically). How do I bind them all together so if I scroll horizontally on one, they all scroll?
I've read through here (Mozilla docs) but I can't get it to work.
It seems like it should be fairly simple.
<div class="page-wrapper relative">
<div class="table-wrapper-outter">
<div class="table-wrapper">
<div class="header header-wrapper">
<div class="header-inner">
<table id="headerTable" class="table-contents">
<tr>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> etc... </td>
</tr>
</table>
</div>
</div>
<div id="bodyHolder" class="table-content-outter">
<div class="table-content-inner">
<table id="mainTable" class="table-contents">
<tr>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> etc... </td>
</tr>
<!-- many rows -->
</table>
</div>
</div>
<div class="header footer-wrapper">
<div class="header-inner">
<table id="footerTable" class="table-contents">
<tr>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> 1234567890 </td>
<td> etc... </td>
</tr>
</table>
</div>
</div>
</div>
</div>
And here is the javascript I tried:
function megaTableInit(tableBodyHolder, mainTable, headerTable, footerTable, tablePullDivs, tableRowHeads) {
var bodyHolder = document.getElementById(tableBodyHolder);
var mTable = document.getElementById(mainTable);
var hTable = document.getElementById(headerTable);
var fTable = document.getElementById(footerTable);
var pullDivs = document.getElementsByClassName(tablePullDivs);
var rowHeads = document.getElementsByClassName(tableRowHeads);
bodyHolder.onmousemove = bodyHolder.onscroll = function() {
pullDivs[0].scrollLeft = this.scrollLeft;
var sl = this.scrollLeft;
if(this.oldSL != sl) {
this.oldSL = sl;
for (i=0; i<pullDivs.length; i++) {
pullDivs[i].scrollLeft = this.scrollLeft;
}
}
}
I don't get any errors. It just doesn't do anything with the over divs. When I run console.log for sl and this.scrollLeft I get the pixels as I scroll. But it doesn't set the scroll for the other divs.
Any help would be appreciated.

I'm not sure if this is exactly what you want but it does what you described, it scrolls all the others when you scroll 1.
$('.scroller').scroll(function(e){
$('.scroller').scrollLeft(e.target.scrollLeft);
});
http://codepen.io/anon/pen/QbaKNz
EDIT: here is the same example with vanilla JavaScript:
var scrollers = document.getElementsByClassName('scroller');
var scrollerDivs = Array.prototype.filter.call(scrollers, function(testElement) {
return testElement.nodeName === 'DIV';
});
function scrollAll(scrollLeft) {
scrollerDivs.forEach(function(element, index, array) {
element.scrollLeft = scrollLeft;
});
}
scrollerDivs.forEach(function(element, index, array) {
element.addEventListener('scroll', function(e) {
scrollAll(e.target.scrollLeft);
});
});
http://codepen.io/anon/pen/zGpNrm

Here's a fairly simple implementation:
<style>
.container { width: 300px; height: 400px; overflow-y: scroll; float: left; margin: 20px; }
</style>
<div class="container">
<table>
<!-- table rows here -->
</table>
</div>
<div class="container">
<table>
<!-- table rows here -->
</table>
</div>
<div class="container">
<table>
<!-- table rows here -->
</table>
</div>
<script>
(function(){
var boxes = document.querySelectorAll('.container');
for(var boxIndex = 0, bl = boxes.length; boxIndex < bl; boxIndex++) {
boxes[boxIndex].onscroll = function(){
for(var boxIndex2 = 0, bl2 = boxes.length; boxIndex2 < bl2; boxIndex2++) {
if(boxes[boxIndex2] !== boxes[boxIndex]) {
boxes[boxIndex2].scrollTop = this.scrollTop;
}
}
};
}
})();
</script>
When the container element is scrolled, it updates the scrollTop value for the remaining elements.

Okay, you already picked the answer, but there are some elements to your problem that weren't addressed. I liked the idea of binding a scroll to all boxes, including one that is horizontal. I've created this jQuery plugin that will allow you to bind scroll boxes together, and will even bind cross-plane scrolling. You can check it out here
Now, it's a pretty big plugin but I'll explain what it does.
say you have three divs
<div class="scroll">
Vertical
Vertical
vertical
Vertical
Vertical
vertical
</div>
<div class="scroll">
Vertical
Vertical
vertical
Vertical
Vertical
vertical
Vertical
Vertical
vertical
</div>
<div class="scroll" data-horizontal="true"> horizontal horizontal horizontal horizontal </div>
Two of these are vertical (and different heights) and the last one is vertical.
To bind these together, you simply implement the jQuery extension like so:
$(".scroll").bindScroll();
Not only will the plugin bind the scroll, but it will also adjust to accommodate different heights. So if you scroll to the bottom (or far right) of one div, despite the difference in size, it will go to the bottom or far right of the other divs.
If you have any questions regarding the plugin, let me know.

Related

JavaScript calc function - no longer works after switching to Bootstrap4

I am shifting a website over to Bootstrap4. One of the pages contained a simple calculator to generate percentages based on user input. This worked fine on the old site using basic HTML with no additional framework but no longer responds to the user input.
I tried double checking against a similar real-time calculator (http://javascript-coder.com/javascript-form/javascript-calculator-script.phtml), but I can't seem to get that one to work either.
function getSupport() {
var theForm = document.forms["calculator"];
var supportV = theForm.elements["support"];
var indvSupport = 0;
if (support.value != "") {
indvSupport = parseInt(supportV.value);
}
return indvSupport;
}
function getTotal() {
var indvSupport = getSupport();
//set values
var parentV = (indvSupport * 0.535).toFixed(2);
var partnersV = (indvSupport * 0.0760).toFixed(2);
var programsV = (indvSupport * 0.06).toFixed(2);
var staffV = (indvSupport * 0.255).toFixed(2);
var adminV = (indvSupport * 0.074).toFixed(2);
//display result
document.getElementById('parent').innerHTML = "$" + parentV;
document.getElementById('partners').innerHTML = "$" + partnersV;
document.getElementById('programs').innerHTML = "$" + programsV;
document.getElementById('staff').innerHTML = "$" + staffV;
document.getElementById('admin').innerHTML = "$" + adminV;
}
<form action="" id="calculator" onsubmit="return false;">
<table align="center" style="border:none;">
<tbody>
<tr>
<td style="font-weight: bold;">Total anticipated support:</td>
<td>$ <input id="support" name="support" oninput="getTotal()" type="text" /></td>
</tr>
<tr>
<td>Parent Organization (53.5%)</td>
<td>
<div id="parent" style="float: right;"> </div>
</td>
</tr>
<tr>
<td>Supporting Partners (7.6%)</td>
<td>
<div id="partners" style="float: right;"> </div>
</td>
</tr>
<tr>
<td>Programs & Support (6.0%)</td>
<td>
<div id="programs" style="float: right;"> </div>
</td>
</tr>
<tr>
<td>Staffing (25.5%)</td>
<td>
<div id="staff" style="float: right;"> </div>
</td>
</tr>
<tr>
<td>Administration (7.4%)</td>
<td>
<div id="admin" style="float:right;"> </div>
</td>
</tr>
</tbody>
</table>
</form>
Or at https://jsfiddle.net/zimerhonzl/ub7z09oL/9/
This is a fairly basic form where the user inputs their donation and can see how it will be distributed. Upon entry in the main box the lower fields should auto populate.
The "no wrap" solution in jsfiddle fixed the issue. On the actual site it turns out there was a code error above the snippet in the common.js file preventing the functions from loading properly. Unfortunately the CMS strips out any in-line javascript so I could not post the directly code above it on the actual page. Now the common.js file is properly loading the function prior to the form.

Count Table Rows Hidden In Overflow with Javascript

I have a bootstrap 3 dashboard where I am hiding the overflow in a particular div. I need to be able to identify the number of table rows hidden in the overflow that are not visible in the div. jQuery method preferred but vanilla JS also fine.
have been trying to sort this out and have not been able to find any ways so far to count the number of rows that are hidden in overflow.
NB: There is no markup difference between the rows that are visible and those that are not visible as CSS is used to hide the excess rows using overflow: hidden; on the parent DIV.
Thanks.
Additional #1
Here is the HTML I am working with. The height is set by javscript at runtime.
<div id="jobs-list" class="box-body no-padding job-list" style="overflow: hidden;">
<table class="table">
<tbody>
<tr>
<th>Account</th>
<th class="text-center">Due</th>
</tr>
<tr>
<td>
Customer 1 (MCB#123456789)<br />
<small>Job name</small>
</td>
<td class="text-center text-green">-- TODAY --</td>
</tr>
<tr>
<td>
Customer 2 (MCB#123456789)<br />
<small>Job name</small>
</td>
<td class="text-center text-green">-- TODAY --</td>
</tr>
<tr>
<td>
Customer 3 (MCB#123456789)<br />
<small>Job name</small>
</td>
<td class="text-center text-green">-- TODAY --</td>
</tr>
<tr>
<td>
Customer 4 (MCB#123456789)<br />
<small>Job name</small>
</td>
<td class="text-center">-- TOMORROW --</td>
</tr>
</tbody>
</table>
</div>
<div class="box-footer text-center">
152 More Jobs
</div>
As you can see in the example above I am using a bootstrap 3 box to contain the data. The height of .box-body is set using javascript (which works fine already and is based on the window height). By using the overflow: hidden; CSS rule instead of showing scroll bars on .box-body the overflow is hidden and not visible. I need to be able to adjust the text in .box-footer using javascript to identify the number of rows that are not visible.
Now there is a mathematical approach to this problem, suppose that all the children have the same height (or width, depends on your aligning) :
console.log($('#main div').length - $('#main').height()/$('#main div').height());
#main {
height:200px; /*Suppose 200px*/
overflow:hidden;
}
#main div {
height:100px;
border:1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<div>
Hello 1
</div>
<div>
Hello 2
</div>
<div>
Hello 3
</div>
<div>
Hello 4
</div>
<div>
Hello 5
</div>
</div>
Thanks for all the answers...
I was able to find a way to do this using jQuery and a jQuery extension by Kevin Marx.
Firstly you need to add the jquery.overflowing.js plugin to the page...
/* Overflowing.js
*
* A plugin based on Elving Rodriguez's Overflowed
* http://elvingrodriguez.com/overflowed
*
*/
(function($){
$.fn.overflowing = function(options, callback){
var self = this
var overflowed = []
var hasCallback = callback && typeof callback === 'function' ? true : false;
var status = false
this.options = options || window
this.each(function(){
var $this = $(this)
elPosition = $this.position()
elWidth = $this.width()
elHeight = $this.height()
var parents = $this.parentsUntil(self.options)
var $parentsTo = $(self.options)
parents.push($parentsTo)
for(var i=0; i<parents.length; i++){
var parentPosition = $(parents[i]).position()
var parentWidth = $(parents[i]).width()
var parentHeight = $(parents[i]).height()
if ( elPosition.top<0
|| elPosition.left<0
|| elPosition.top>(parentHeight+parentPosition.top)
|| elPosition.left>(parentWidth+parentPosition.left)
|| (elPosition.top + elHeight) > (parentHeight+parentPosition.top)
|| (elPosition.left+elWidth) > (parentWidth+parentPosition.left)){
status = true
$(parents[i]).addClass('overflowed')
overflowed.push(parents[i])
if (hasCallback) callback(parents[i])
}
}
if($this.parents(self.options).hasClass('overflowed')) $this.addClass('overflowing')
})
if (!hasCallback) return overflowed.length > 1 ? overflowed : status
}
})(jQuery)
Then you run...
$("tr").overflowing("#jobs-list");
Which through the overflowing plugin adds the class overflowing to each overflowing row (first selector) within the target parent (second selector).
At this point it is a simple case of using jQuery's .length property and a selector to target only the .overflowing classes within the target object you are wanting to calculate for, ie...
var hiddenRows = $("#jobs-list .overflowing").length;
I'm unsure by what you mean by 'hidden by overflow'. Does that mean include stuff that's partially hidden, or things that are fully hidden only? My solution includes partially hidden as 'not hidden'.
Regardless, offset is your best solution.
let jobs = $("#jobs-list");
let offset = jobs.offset().top;
let height = jobs.height();
let tr = $("tr", $("#jobs-list")).toArray();
let stopped = 0;
for (let i in tr)
{
let total_offset = $(tr[i]).offset().top - offset;
if (total_offset >= height)
{
stopped = i;
break;
}
}
console.log("hidden:", tr.length - stopped);
#jobs-list {
height: 80px;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="jobs-list" class="box-body no-padding job-list" style="overflow: hidden;">
<table class="table">
<tbody>
<tr>
<th>Account</th>
<th class="text-center">Due</th>
</tr>
<tr>
<td>
Customer 1 (MCB#123456789)<br />
<small>Job name</small>
</td>
<td class="text-center text-green">-- TODAY --</td>
</tr>
<tr>
<td>
Customer 2 (MCB#123456789)<br />
<small>Job name</small>
</td>
<td class="text-center text-green">-- TODAY --</td>
</tr>
<tr>
<td>
Customer 3 (MCB#123456789)<br />
<small>Job name</small>
</td>
<td class="text-center text-green">-- TODAY --</td>
</tr>
<tr>
<td>
Customer 4 (MCB#123456789)<br />
<small>Job name</small>
</td>
<td class="text-center">-- TOMORROW --</td>
</tr>
</tbody>
</table>
</div>
<div class="box-footer text-center">
152 More Jobs
</div>
Found this: Count List Items shown on screen and not overflow
Working jQuery example: https://jsfiddle.net/Twisty/jzmqfeyj/
JavaScript
$(function() {
//Add random count of jobs
var i = 0;
for (i = 0; i < Math.floor(Math.random() * 100); i++) {
$("#jobs-list tbody").append($("#jobs-list table tbody tr:last").clone());
}
console.log("Created", i, "Jobs");
console.log("Total", $("#jobs-list table tbody tr:not('.header')").length, "Jobs");
var mh = $("#jobs-list").height();
var overflowed = $("#jobs-list table tbody tr:not('.header')").filter(function() {
return $(this).position().top + $(this).height() > mh;
});
console.log("Invisible", overflowed.length, "Jobs");
$(".job-number").html(overflowed.length);
});
Since :visible counts only items that are hidden, you can't really use it. We can .filter() on items that are in our "viewport" or not in overflow. We know the height of each element and the div. Anything greater than the height of the div, we count.

Fitting content horizontally [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am rewriting a web application that visually represents data and would like to make the result fill the available width automatically (the previous version had a few user selectable scaling factors). I have simplified the layout to this:
.bar {
height: 25px;
background: green;
color: white;
}
<table>
<thead>
<tr>
<th></th>
<th>column #1</th>
<th>column #2</th>
</tr>
</thead>
<tbody>
<tr>
<td>row #1</td>
<td>
<div class="bar" style="width:50px">
cell #1
</div>
</td>
<td>
<div class="bar" style="width:150px">
cell #2
</div>
</td>
</tr>
<tr>
<td>row #2</td>
<td>
<div class="bar" style="width:100px">
cell #3
</div>
</td>
<td>
<div class="bar" style="width:75px">
cell #4
</div>
</td>
</tr>
</tbody>
</table>
The width of the bars should be adjusted so that the table as a whole fills the horizontally available space (the left column should keep its width and ideally the height of the table should not be altered). The amount of columns as well as the amount of rows will vary.
I have full control over the generated html, so the solution may use a different markup (just note that the calculated bar widths are not limited to a few values).
It is important that the relative lengths of the bars are not changed. In this example, the bar in cell #4 should always be 50% longer than the one in cell #1. It should be possible to have text inside the bars and it should not be stretched (therefore, I could not solve my problem with CSS transformations).
The solution may use JavaScript. I think that I could make it work using only JavaScript by measuring the left over space and then scaling each bar manually, but this seems fragile and difficult to maintain to me (the given example is simplified).
Is there an elegant solution? I found it quite hard to search for this problem, so I might have overlooked something (usually I never need to ask questions as others have had similar problems before).
Edit: It seems that I wrote too much text and the actual question became unclear. I am looking for a solution that scales the bars inside the table from the given code snippet so that the table takes up all the available vertical horizontal (too hasty edit) space. The caveat is, that the contained bars should keep their relative lengths.
You can accomplish what you want with just a little bit of JavaScript and a slightly modified CSS file. This will calculate the number of columns (minus the initial column) and will distribute their width evenly.
<style>
.bar {
height: 25px;
background: green;
color: white;
}
table{
width: 100%;
}
table tbody tr td:first-child{
width: 20%;
}
table tbody tr td{
width: 40%;
}
</style>
Then your HTML
<table>
<thead>
<tr>
<th></th>
<th>column #1</th>
<th>column #2</th>
</tr>
</thead>
<tbody>
<tr>
<td>row #1</td>
<td>
<div class="bar" data-value="50">
cell #1
</div>
</td>
<td>
<div class="bar" data-value="100">
cell #2
</div>
</td>
</tr>
<tr>
<td>row #2</td>
<td>
<div class="bar" data-value="80">
cell #3
</div>
</td>
<td>
<div class="bar" data-value="75">
cell #4
</div>
</td>
</tr>
</tbody>
</table>
Then some simple JavaScript:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
var v, b, n, max = 0;
var t = $('table');
var w = t.width();
// Set equal width for all columns
var c = (80/(t.find('thead tr th').length-1));
// Set widths of internal bars relative to the max value
$('.bar')
.parent()
.css({width: c + "%"})
.end()
.each(function(){
// Determines max value
v = parseFloat($(this).attr('data-value'));
if(v>max){
max = v;
}
})
.each(function(){
// Sets each bar to be a percent width based on max value
b = $(this);
n = (((parseFloat(b.attr('data-value')) / max) * 100));
b.css({width: n + "%"})
});
});
</script>
Create a class on the first column you require to be "fixed",also 2nd and 3rd columns.Add id'sto the 4 div bars so we can manipulate them with respect to their widths:
HTML
<table>
<thead>
<tr>
<th class="fixed"></th>
<th class="col">column #1</th>
<th class="col">column #2</th>
</tr>
</thead>
<tbody>
<tr>
<td class="fixed">row #1</td>
<td class="col">
<div class="bar" id="cell1" style="width:50px">
cell #1
</div>
</td>
<td class="col">
<div class="bar" id="cell2" style="width:150px">
cell #2
</div>
</td>
</tr>
<tr>
<td class="fixed">row #2</td>
<td class="col">
<div class="bar" id="cell3" style="width:100px">
cell #3
</div>
</td>
<td class="col">
<div class="bar" id="cell4" style="width:75px">
cell #4
</div>
</td>
</tr>
</tbody>
</table>
Next apply 100% width on the table, then apply the desired widths to your three columns respectively so that they sum up to 100%.
CSS
table{
width: 100%;
}
.bar {
height: 25px;
background: green;
color: white;
}
.fixed{
width: 200px;
text-align: center;
}
.col{
text-align: left;
width: auto;
}
Finally,get each div by its id and set its width as follows,taking in account that 150px is your base here:
JS
document.getElementById("cell1").style.width = ((50/150)*100)+"%";
document.getElementById("cell2").style.width = ((150/150)*100)+"%";
document.getElementById("cell3").style.width = ((100/150)*100)+"%";
document.getElementById("cell4").style.width = ((75/150)*100)+"%";
I hope that was helpful!

Make tr width match thead width on sticky table header

I have a sticky table header that I am working on. Right now, the user scrolls passed the header, and the header sticks correctly. The problem I am having is that tableHeaderRow is not the same width as tableHeader.
Current steps for sticky header:
Ajax call to fill table with data
Save column widths
Make tableHeader position:absolute
Set column widths back into tableHeader (this is where it gets close but about 100 pixels short)
Tried
Set tableHeaderRow to the expected width.
Set tableHeaderRow to 100% width.
Remove padding and margin
HTML
<table id="table" class="table tablesorter table-responsive table-striped table-hover" style="overflow:auto;border-collapse:collapse;">
<thead id='tableHeader' style="background-color:LightBlue;">
<tr id='tableHeaderRow' >
<th id="col1" class='header'>Column1</th>
<th id="col2" class='header'>Column2</th>
<th id="col3" class='header'>Column3</th>
<th id="col4" class='header'>Column4</th>
<th id="col5" class='header'>Column5</th>
<th id="col6" class='header'>Column6</th>
<th id="col7" class='header'>Column7</th>
</tr>
</thead>
<tbody id='tableBody'>
</tbody>
</table>
Save off widths
col1Width = $('#col1').width();
col2Width = $('#col2').width();
col3Width = $('#col3').width();
col4Width = $('#col4').width();
col5Width = $('#col5').width();
col6Width = $('#col6').width();
col7Width = $('#col7').width();
Stick Scroll Event Listener
var tableHeaderTop = $("#tableHeader").offset().top;
var above = true;
//Window scroll event listener to fix table headers
$( window ).scroll(function() {
if(tableHeaderTop - $(window).scrollTop() <= 0){
if(above){
$('#tableHeader').css({
position:'absolute',
top: $(window).scrollTop() - $("#top").height() -15,
width:$('table#table').width(),
});
$('.column1Value').width(col1Width);
$('#col1').width(col1Width);
$('.column2Value').width(col2Width);
$('#col2').width(col2Width);
$('.column3Value').width(col3Width);
$('#col3').width(col3Width);
$('.column4Value').width(col4Width);
$('#col4').width(col4Width);
$('.column5Value').width(col5Width);
$('#col5').width(col5Width);
$('.column6Value').width(col6Width);
$('#col6').width(col6Width);
$('.column7Value').width(col7Width);
$('#col7').width(col7Width);
above = false;
}else{
$('#tableHeader').css({
top: $(window).scrollTop() - $("#top").height() -15,
});
}
}else{
$('#tableHeader').css({
position:'static',
});
above = true;
}
});
Please ask for any clarification. Working on a bootply to show issue.
Note: I made a bootply for the issue, but it works as I would want it to on bootply. This leads me to believe it would be some sort of 3rd party plugin that changes CSS. I will update with an answer when I have one, in the mean time if anyone wants to use my custom sticky table header code (thanks to others who helped) you're welcome to do so.
Well, this may not completely answer your question.
But, for what you're trying to do - this jQuery plugin is pretty much the best I've seen out there: http://www.fixedheadertable.com/
Doing a google search I also found a pure css solution (that I have no personal experience with, but if it works as intended that's just cool!): http://jsfiddle.net/dPixie/byB9d/3/
I did a script like that myself once too.
A simplified version of it was looking something like this.
jsFiddle: http://jsfiddle.net/L0oy2L01/
HTML (sorry for inline css styling... feel free to add your own classes!)
<div>
<table>
<tr style="background-color: #ccc;">
<td data-col="1" class="header">
Column1
</td>
<td data-col="2" class="header">
Column2
</td>
<td data-col="3" class="header">
Column3
</td>
</tr>
</table>
</div>
<div id="contentDiv" style="max-height: 50px; overflow-y: auto;">
<table class="contentTable">
<tr>
<td data-col="1" class="content">
My Content1
</td>
<td data-col="2" class="content">
My Content2
</td>
<td data-col="3" class="content">
My Content3
</td>
</tr>
<tr>
<td data-col="1" class="content">
My Content4
</td>
<td data-col="2" class="content">
My Content5
</td>
<td data-col="3" class="content">
My Content6
</td>
</tr>
<tr>
<td data-col="1" class="content">
My Content7
</td>
<td data-col="2" class="content">
My Content8
</td>
<td data-col="3" class="content">
My content9
</td>
</tr>
</table>
</div>
jQuery
<script type="text/javascript">
$(document).ready(function(){
var totalWidth = 0;
$('.header').each(function(){
var colwidth = $(this).outerWidth();
var colnumber = $(this).data('col');
$('.content[data-col="'+ colnumber +'"]').each(function(){
if($(this).outerWidth() >= colwidth){
colwidth = $(this).outerWidth();
}
});
$('td[data-col="'+ colnumber +'"]').css('width',colwidth);
totalWidth += colwidth;
});
//if table height is bigger than contentDiv height there will be a scroll.. therefor we adjust contentDiv to it's content + scrolling
if($('.contentTable').outerHeight() > 50){
$('#contentDiv').outerWidth(totalWidth + 30);
}
});
</script>

Trying to make an html checkbox which adds a number to an output field

I am trying to create a table in which when I check a box, if the image displayed is yes.jpg, a number gets added in the output box at the bottom of the column. If not, no number gets added. There are three columns, and each checkbox affects three images and so three output boxes. Here is my code.
<html>
<head>
<script>
function onSelect(rowId)
{
var row = document.getElementById(rowId);
var checkBox = row.getElementsByTagName("checkRow")[0];
var outputRow = document.getElementById("outputRow");
var totalRow1 = outputRow.getElementById("total1");
var totalRow2 = outputRow.getElementById("total2");
var totalRow3 = outputRow.getElementById("total3");
//If box is checked, check images. If they are yes, edit boxes.
if (checkBox.checked)
if (row.getElementById.("image1").src.indexOf(yes.png) > -1)
{
totalRow1.innerHTML = "dfd";
}
else {
//checkBox =
}
}
/*function onCheck()
{
var total1 = document.getElementById("total1");
window.alert("sometext");
total1.innerHTML = "dfd";
} */
</script>
</head>
<body>
<table border="1">
<tr> <!-- Table Header -->
<td>
Checkbox
</td>
<td>
Items
</td>
<td>
Area 1
</td>
<td>
Area 2
</td>
<td>
Area 3
</td>
</tr>
<tr id="checkRow"> <!-- Row 1 -->
<td>
<form>
<input type="checkbox" name="Row1" value="Row1" onclick="onCheck();">
</form>
</td>
<td>
Item
</td>
<td id="image1">
<img src="yes.png" alt="Needed">
</td>
<td id="image2">
<img src="yes.png" alt="Needed">
</td>
<td id="image3">
<img src="no.png" alt="Needed">
</td>
</tr>
<tr id="outputRow"> <!-- Table Bottom -->
<td>
<!--Empty-->
</td>
<td>
Summation
</td>
<td id="total1">
Area 1
</td >
<td id="total2">
Area 2
</td>
<td id= "total3">
Area 3
</td>
</tr>
</table>
</body>
Currently, I am just trying to edit the output text on one of the output boxes (as seen in my onCheck() method). However, even this does not seem to work. I added an alert, which does not happen either. What am I doing wrong?
there are so many things, you are doing wrong,
firstly, you have called onCheck() function upon click on your checkbox, but there is not such javascript function. you have onSelect(id) instead.
second, you are trying to .getElementById your TDs as those ids, 'image1' and all are ids of tds and not imgs
and then you are accessing .src for them, so anyway that is wrong.
Improvements:
change your input checkbox to this:
<input type="checkbox" name="Row1" value="Row1" onchange="onCheck(this);">
what you are doing is that, you are passing reference of your input in the function onCheck(this);
2. now change your markup like this:
<td>
<form>
<input type="checkbox" name="Row1" value="Row1" onchange="onCheck(this);">
</form>
</td>
<td>
Item
</td>
<td >
<img id="image1" src="yes.png" alt="Needed">
</td>
<td >
<img id="image2" src="yes.png" alt="Needed">
</td>
<td >
<img id="image3" src="no.png" alt="Needed">
</td>
</tr>
all i've done is to provide IDs to the right elements i.e. to the IMGs, instead of TDs;
thirdly, make your onCheck() like this:
function onCheck(cb)
{
if(cb.checked===true)
{
if(document.getElementById('image1').src.toString().indexOf('yes')>0){
document.getElementById('total1').innerHTML='555';
}
else
{
document.getElementById('total1').innerHTML='No';
}
if(document.getElementById('image2').src.toString().indexOf('yes')>0){
document.getElementById('total2').innerHTML='555';
}
else
{
document.getElementById('total2').innerHTML='No';
}
if(document.getElementById('image3').src.toString().indexOf('yes')>0){
document.getElementById('total3').innerHTML='555';
}
else
{
document.getElementById('total3').innerHTML='No';
}
}
}
so basically onCheck is pretty much same as your one.
now , see this working fiddle, i've made for you, it works. ofcourse I hate the way you are doing it all. This all can be done in a much easier way.
also, learn about jQuery, it makes life easy.

Categories