GridView Column Width - How To Stop "Shrink-To-Fit" Behavior - javascript

I am currently trying to implement a GridView with a frozen header. I've gotten the header frozen using javascript found online. Here is the code:
var GridId = "<%=dgContacts.ClientID %>";
var ScrollHeight = 180;
var ScrollWidth = 700;
window.onload = function () {
enablePostLog();
var grid = document.getElementById(GridId);
var gridWidth = grid.offsetWidth;
var headerCellWidths = new Array();
for (var i = 0; i < grid.getElementsByTagName("TH").length; i++) {
headerCellWidths[i] = grid.getElementsByTagName("TH")[i].offsetWidth;
}
grid.parentNode.appendChild(document.createElement("div"));
var parentDiv = grid.parentNode;
var table = document.createElement("table");
for (i = 0; i < grid.attributes.length; i++) {
if (grid.attributes[i].specified && grid.attributes[i].name != "id") {
table.setAttribute(grid.attributes[i].name, grid.attributes[i].value);
}
}
table.style.cssText = grid.style.cssText;
table.style.width = gridWidth + "px";
table.style.tableLayout = "fixed";
table.appendChild(document.createElement("tbody"));
table.getElementsByTagName("tbody")[0].appendChild(grid.getElementsByTagName("TR")[0]);
var headerRow = table.getElementsByTagName("TH");
var gridRow = grid.getElementsByTagName("TR")[0];
for (var i = 0; i < headerRow.length; i++) {
var width;
if (headerCellWidths[i] > gridRow.getElementsByTagName("TD")[i].offsetWidth) {
width = headerCellWidths[i];
}
else {
width = gridRow.getElementsByTagName("TD")[i].offsetWidth;
}
headerRow[i].style.width = parseInt(width - 3) + "px";
gridRow.getElementsByTagName("TD")[i].style.width = parseInt(width - 3) + "px";
}
parentDiv.removeChild(grid);
var dummyHeader = document.createElement("div");
dummyHeader.setAttribute('id', 'divHeader');
dummyHeader.style.cssText = "margin-left: auto; margin-right: auto; overflow: hidden; width: " + ScrollWidth + "px";
dummyHeader.appendChild(table);
parentDiv.appendChild(dummyHeader);
var scrollableDiv = document.createElement("div");
gridWidth = parseInt(gridWidth) + 17;
scrollableDiv.setAttribute('id', 'divBody');
scrollableDiv.style.cssText = "margin-left: auto; margin-right: auto; overflow: auto; height: " + ScrollHeight + "px; width: " + ScrollWidth + "px";
scrollableDiv.appendChild(grid);
scrollableDiv.onscroll = scrollHeader;
parentDiv.appendChild(scrollableDiv);
}
function scrollHeader() {
var header = document.getElementById('divHeader');
var body = document.getElementById('divBody');
header.scrollLeft = body.scrollLeft;
}
The problem I'm having is that the GridView being in a fixed-width div. The width styles added to the columns is being ignored.
The final HTML looks like this:
http://i.stack.imgur.com/xDzez.png
The actual table rendered looks like this (the problem is most noticable in the "View" and "Notify" columns):
http://i.stack.imgur.com/rA35z.png
If I remove the fixed width on the outer div, the column widths correct themselves, but obviously, I lose my scrollability. It appears to be trying to shrink the whitespace in the table cells to try and fit into the div. This isn't necessary because of the overflow: auto on the outer div. Is there a style or something I can add to stop the browser from doing this?

Turns out I needed table-layout: fixed AND width: 100% to both tables. I had tried the table-layout solution, but didn't realize about the width needing to be 100% as well.
Final javascript:
var GridId = "<%=dgContacts.ClientID %>";
var ScrollHeight = 180;
var ScrollWidth = 700;
window.onload = function () {
enablePostLog();
var grid = document.getElementById(GridId);
var gridWidth = grid.offsetWidth;
var headerCellWidths = new Array();
for (var i = 0; i < grid.getElementsByTagName("TH").length; i++) {
headerCellWidths[i] = grid.getElementsByTagName("TH")[i].offsetWidth;
}
grid.parentNode.appendChild(document.createElement("div"));
var parentDiv = grid.parentNode;
var table = document.createElement("table");
for (i = 0; i < grid.attributes.length; i++) {
if (grid.attributes[i].specified && grid.attributes[i].name != "id") {
table.setAttribute(grid.attributes[i].name, grid.attributes[i].value);
}
}
table.style.cssText = grid.style.cssText;
table.appendChild(document.createElement("tbody"));
table.getElementsByTagName("tbody")[0].appendChild(grid.getElementsByTagName("TR")[0]);
var headerRow = table.getElementsByTagName("TH");
var gridRow = grid.getElementsByTagName("TR")[0];
for (var i = 0; i < headerRow.length; i++) {
var width;
if (headerCellWidths[i] > gridRow.getElementsByTagName("TD")[i].offsetWidth) {
width = headerCellWidths[i];
}
else {
width = gridRow.getElementsByTagName("TD")[i].offsetWidth;
}
gridRow.getElementsByTagName("TD")[i].style.width = parseInt(width - 3) + "px";
if (i == headerRow.length - 1) {
width = width + getScrollBarWidth();
}
headerRow[i].style.width = parseInt(width - 3) + "px";
}
parentDiv.removeChild(grid);
grid.style.tableLayout = "fixed";
table.style.tableLayout = "fixed";
grid.style.width = "100%";
table.style.width = "100%";
var dummyHeader = document.createElement("div");
dummyHeader.setAttribute('id', 'divHeader');
dummyHeader.style.cssText = "margin-left: auto; margin-right: auto; overflow: hidden; width: " + ScrollWidth + "px";
dummyHeader.appendChild(table);
parentDiv.appendChild(dummyHeader);
var scrollableDiv = document.createElement("div");
scrollableDiv.setAttribute('id', 'divBody');
scrollableDiv.style.cssText = "margin-left: auto; margin-right: auto; overflow: auto; height: " + ScrollHeight + "px; width: " + ScrollWidth + "px";
scrollableDiv.appendChild(grid);
scrollableDiv.onscroll = scrollHeader;
parentDiv.appendChild(scrollableDiv);
}
function scrollHeader() {
var header = document.getElementById('divHeader');
var body = document.getElementById('divBody');
header.scrollLeft = body.scrollLeft;
}
function getScrollBarWidth() {
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement('div');
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild(inner);
document.body.appendChild(outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;
document.body.removeChild(outer);
return (w1 - w2);
}

Related

make divs with an resizeable width on both sides

I have some trouble making my divs resizeable.
Im trying to make a time scheduler, but the divs should be resizeable and change width based on the resized one.
This is what I currently have now.
var stepsize = 5;
var min = 0;
var max = 1440;
var stepwidth = 100 / max;
let original_width = 0;
let original_height = 0;
let original_x = 0;
let original_y = 0;
let original_mouse_x = 0;
let original_mouse_y = 0;
console.log(stepwidth);
var timeblocks = {0: [50, 100, "red"], 1: [100, 200, "blue"], 2: [200, 400, "red"]};
calcwidth(timeblocks);
function calcwidth(timeblocks){
const values = Object.values(timeblocks)
var container = document.getElementById("container");
var int = 0;
var startmargin = 0;
for (const arrayv of values) {
console.log(arrayv);
var start = 0;
var end = 0;
if(int == 0){
start = stepwidth * arrayv[0];
console.log(start);
end = stepwidth * arrayv[1] - start;
startmargin = startmargin + (start + end);
}
else{
start = startmargin;
end = stepwidth * arrayv[1] - start;
startmargin = startmargin + (end);
}
console.log(startmargin);
var timeblock = document.createElement('div');
timeblock.className = "timeblock";
timeblock.style.background = arrayv[2];
timeblock.style.marginLeft = start + "%";
timeblock.style.width = end + "%";
var moverleft = document.createElement('div');
moverleft.style.width = "5px";
moverleft.style.height = "50px";
moverleft.style.background = "black";
moverleft.style.marginLeft = "0px";
moverleft.style.position = "absolute";
moverleft.style.opacity = "0.4";
moverleft.addEventListener('mousedown', function(e) {
e.preventDefault()
original_width = timeblock.style.marginLeft;
original_x = timeblock.getBoundingClientRect().left;
original_mouse_x = e.pageX;
console.log(original_width);
moverleft.addEventListener('mousemove', resize);
moverleft.addEventListener('mouseup', stopResize);
});
var moverright = document.createElement('div');
moverright.style.width = "5px";
moverright.style.height = "50px";
moverright.style.background = "black";
moverright.style.right = "0px";
moverright.style.position = "absolute";
moverright.style.opacity = "0.4";
timeblock.appendChild(moverleft);
timeblock.appendChild(moverright);
container.appendChild(timeblock);
int++;
}
}
function resize(e) {
const width = original_width - (e.pageX - original_mouse_x)
console.log(e.target.parentElement);
e.target.parentElement.style.marginLeft = width + 'px'
}
function stopResize() {
window.removeEventListener('mousemove', resize)
}
.timeblock{
position: absolute;
height: 50px;
}
.timeblock:hover{
background: green !important;
}
#container{
width: 100%;
height: 50px;
border: 1px solid black;
}
<div class="col-xs-12">
<div class="col-xs-12" id="container">
</div>
</div>
It seems the divs don't get resized, what am I doing wrong?
I want to make all divs resizeable by their handlers and move others based on the resize.
Does someone have an example what I can use, cuz I have no clue on how to do this.
Please help me!

style.pointerEvents not functioning

I'm trying to make an element that shrinks as you click it more and more. Once it reaches a threshold of 1%, it should reappear in full length and not be clickable. the style.pointerEvents is not working. (This is code added in, in order to solve an issue.) This is all of the code, there must be conflicting variables or something. But the main premise is to shake the element and shrink and then regrow and disable itself and after a waiting period enable itself.
`var rotated = false;
var height = 24.6;
var width = 15
function clickedhub() {
clicked();
timeout();
}
function clicked() {
document.getElementById('box').onclick = function() {
var div = document.getElementById('box'),
deg = rotated ? 0 : 10;
div.style.webkitTransform = 'rotate('+deg+'deg)';
div.style.msTransform = 'rotate('+deg+'deg)';
div.style.oTransform = 'rotate('+deg+'deg)';
div.style.transform = 'rotate('+deg+'deg)';
}
setInterval(res, 140);
function res() {
document.getElementById('box').style = function() {
var div = document.getElementById('box'),
deg = rotated ? 0 : 0;
div.style.webkitTransform = 'rotate('+deg+'deg)';
div.style.mozTransform = 'rotate('+deg+'deg)';
div.style.msTransform = 'rotate('+deg+'deg)';
div.style.oTransform = 'rotate('+deg+'deg)';
div.style.transform = 'rotate('+deg+'deg)';
}
}
}
function timeout() {
document.getElementById('box').onclick = function() {
var div = document.getElementById('box');
width = width / 1.5;
height = height / 1.5;
}
}
setInterval(gamerule, 10);
function gamerule() {
var div = document.getElementById('box');
if (width <= 1) {
div.removeEventListener("click", gamerule);
width = 100;
height = 100;
} else {
width--;
height--;
}
div.style.width = width + '%';
div.style.height = height + '%';
div.addEventListener("click", gamerule);
}
`
This should work for you
//setInterval(gamerule, 10);
let width = 100;
let height = 100;
var div = document.getElementById('box');
function gamerule() {
if (width <= 1) {
div.removeEventListener("click", gamerule);
width = 100;
height = 100;
} else {
width--;
height--;
}
div.style.width = width + '%';
div.style.height = height + '%';
}
div.addEventListener("click", gamerule);
#box{
background-color:red;
width:100%;
height:100%;
}
#container{
width:500px;
height:500px;
}
Click on the red box
<div id="container" >
<div id="box">
</div>
</div>

javascript append elements into a div

I build this looping animation with dynamic words but I need to append all the span into the div <div id"wordcloud"></div>. I can't get it done as I want so I need a bit of help here.
var interval = 100;
var width = 800;
var height = 500;
var words = [
'Liberty',
'Morality',
'Modesty',
'Curiosity',
'Imagination',
'Excitement',
'Structure',
'Intellect',
'Friendliness',
'Conversation'
];
var wordPlacementInterval = setInterval(function() {
var currentWord = words.shift();
if (currentWord) {
var word = document.createElement('span');
word.innerHTML = currentWord;
word.style.top = Math.floor((Math.random() * height) + 1) + 'px';
word.style.left = Math.floor((Math.random() * width) + 1) + 'px';
document.body.appendChild(word);
} else {
clearInterval(wordPlacementInterval);
}
}, interval);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wordcloud"></div>
You had a missing = in the id property <div id[HERE]"wordcloud"></div>
and then add the elements you create to
document.querySelector('#wordcloud').appendChild(word);
like so:
var interval = 100;
var width = 800;
var height = 500;
var words = [
'Liberty',
'Morality',
'Modesty',
'Curiosity',
'Imagination',
'Excitement',
'Structure',
'Intellect',
'Friendliness',
'Conversation'
];
var wordPlacementInterval = setInterval(function() {
var currentWord = words.shift();
if (currentWord) {
var word = document.createElement('span');
word.innerHTML = currentWord;
word.style.top = Math.floor((Math.random() * height) + 1) + 'px';
word.style.left = Math.floor((Math.random() * width) + 1) + 'px';
document.querySelector('#wordcloud').appendChild(word);
} else {
clearInterval(wordPlacementInterval);
}
}, interval);
<div id="wordcloud"></div>
If you are trying to use the positions you are setting via javascript you need to add little CSS like:
var interval = 100;
var width = 800;
var height = 500;
var words = [
'Liberty',
'Morality',
'Modesty',
'Curiosity',
'Imagination',
'Excitement',
'Structure',
'Intellect',
'Friendliness',
'Conversation'
];
var wordPlacementInterval = setInterval(function() {
var currentWord = words.shift();
if (currentWord) {
var word = document.createElement('span');
word.innerHTML = currentWord;
word.style.top = Math.floor((Math.random() * height) + 1) + 'px';
word.style.left = Math.floor((Math.random() * width) + 1) + 'px';
document.querySelector('#wordcloud').appendChild(word);
} else {
clearInterval(wordPlacementInterval);
}
}, interval);
#wordcloud {
position: relative;
}
#wordcloud span {
position: absolute;
}
<div id="wordcloud"></div>
You have to add CSS position relative to the span elements.
Code example:
var interval = 100;
var width = 200;
var height = 150;
var words = ['Liberty', 'Morality', 'Modesty', 'Curiosity', 'Imagination', 'Excitement', 'Structure', 'Intellect', 'Friendliness', 'Conversation'];
var wordPlacementInterval = setInterval(function() {
var currentWord = words.shift();
var word = document.createElement('span');
var wordcloud = document.getElementById('wordcloud');
if (!currentWord) {
clearInterval(wordPlacementInterval);
return;
}
word.innerText = currentWord;
word.style.top = Math.floor((Math.random() * height) + 1) + 'px';
word.style.left = Math.floor((Math.random() * width) + 1) + 'px';
wordcloud.appendChild(word);
}, interval);
#wordcloud {
height: 100%;
width: 100%;
}
span {
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wordcloud"></div>
I think this will help
$("#wordcloud").html(word)
Do this instead of the document.body.appendChild()

Bullet Point not moving, only the image is

I need to animate the points in a bullet list, the bullet list is a div that contains bullet points that are divs.
A bullet point div contains an image and another div which has the bullet point text, the problem is when I try and move a given bullet point div only the image is moved.
I have tried various changes to the .style.position to no avail.
I could not create an account on jsfiddle.net so the following is a working example that moves only the first bullet point:
<html>
<head>
<title>Build Bullets</title>
<body>
<script>
window.setTimeout('initBuildBullets()',100);
function initBuildBullets(){
var bulletPointsDiv = document.createElement('div');
var bName = 'BulletList';
bulletPointsDiv.style.visibility='visible';
bulletPointsDiv.style.position = 'fixed';
bulletPointsDiv.style.display = 'block';
bulletPointsDiv.style.textAlign = 'left';
bulletPointsDiv.id = bName;
document.body.appendChild(bulletPointsDiv);
var bullet_src = 'bullet_level_1.gif';
var bulletText=[];
bulletText[0]='Bullet Point 1';
bulletText[1]='Bullet Point 2';
bulletText[2]='Bullet Point 3';
var x=100;
var y=100;
var h=100;
var w=200;
var lastBot = 0;
var indent = 0;
var imgW = 25;
var hOffset = 5;
for(var i=0;i<bulletText.length;i++){
var bp_id = bName + '_Bullet_Point_' + i;
var bulletPointDiv = document.createElement('div');
bulletPointDiv.id = bp_id;
bulletPointDiv.style.overflow = 'hidden';
bulletPointDiv.style.visibility='visible';
bulletPointDiv.style.position = 'inherit';
bulletPointDiv.style.display = 'inherit';
bulletPointDiv.style.textAlign = 'left';
bulletPointDiv.style.top = (y + lastBot) + 'px';
bulletPointDiv.style.left = (x + indent) + 'px';
var bulletImage = document.createElement('img');
bulletImage.src = bullet_src;
bulletImage.id = bName + '_Bullet_Image_' + i;
var bulletFieldDiv = document.createElement('div');
bulletFieldDiv.id = bName + '_Bullet_Field_' + i;
bulletFieldDiv.style.overflow = 'hidden';
bulletFieldDiv.style.position = 'inherit';
bulletFieldDiv.style.display = 'inherit';
bulletFieldDiv.style.textAlign = 'left';
bulletFieldDiv.style.top = (y + lastBot) + 'px';
bulletFieldDiv.style.left = (x + imgW + indent) + 'px';
bulletFieldDiv.style.width = (w - (imgW + indent)) + 'px';
bulletFieldDiv.innerHTML = bulletText[i];
bulletFieldDiv.style.visibility='visible';
bulletPointDiv.appendChild(bulletImage);
bulletPointDiv.appendChild(bulletFieldDiv);
bulletPointsDiv.appendChild(bulletPointDiv);
lastBot += bulletFieldDiv.offsetHeight + hOffset;
}
window.setTimeout('moveBullets()',100);
}
function moveBullets(){
var bp_id = 'BulletList_Bullet_Point_0';
bulletPointDiv = document.getElementById(bp_id);
bulletPointDiv.style.top = '0px';
bulletPointDiv.style.left = '0px';
}
</script>
</body>
</html>
If I could ask that you copy/paste to test.
The following image is the bullet_level_1.gif
I need to set the style.position to 'relative' and then the top and left needs to account for the image (ONLY), once I do that then all objects within the div will move with the div, e.g.:
...
var bulletImage = document.createElement('img');
bulletImage.src = bullet_src;
var imgW = bulletImage.width + 8;
var bulletFieldDiv = document.createElement('div');
bulletFieldDiv.style.position = 'relative';
bulletFieldDiv.style.top = '-' + (bulletImage.height + 8) + 'px';
bulletFieldDiv.style.left = imgW + 'px';
...
That said, I'm not sure why I need the additional 8px for both the height and width??

Expand the width of an element with a setTimeOut loop

I am trying to create a simple javascript animation that will expand the width of an element from 0px to a specified width. Although this is probably a pretty elementary problem for some, I just can't seem to figure out what I am doing wrong. Instead of the loop running and expanding the div as desired I am only able to expand the div by repeatedly firing the function manually.
Fiddle
Current js code:
var el = document.getElementById('h');
var btn = document.getElementById('button1');
var oswidth = el.offsetWidth;
var target_width = 100;
btn.onclick = function grow() {
var loop = setTimeout('grow(\'' + el + '\')', 20);
if (oswidth < target_width) {
oswidth += 5;
} else {
clearTimeout(loop);
}
el.style.width = oswidth + 'px';
}
And as always, thank you in advance!
Try this code.fiddle-https://jsfiddle.net/L8kLx7d2/
var el = document.getElementById('h');
var btn = document.getElementById('button1');
var oswidth = el.offsetWidth;
var target_width = 100;
var loop;
function grow() {
if (oswidth < target_width) {
oswidth += 5;
} else {
clearInterval(loop);
}
el.style.width = oswidth + 'px';
}
btn.onclick=function(){
loop=setInterval(grow, 1000)};
Try this:
var el = document.getElementById('h');
var btn = document.getElementById('button1');
var oswidth = el.offsetWidth;
var target_width = 100;
btn.onclick = function grow() {
if (oswidth < target_width) {
oswidth += 5;
el.style.width = oswidth + 'px';
setTimeout(grow, 20);
}
}
I'll leave it to you to puzzle over the differences.
You can call the grow function in setInterval
JS:
var el = document.getElementById('h');
var btn = document.getElementById('button1');
var oswidth = el.offsetWidth;
var target_width = 100;
function grow() {
var loop = setTimeout('grow(\'' + el + '\')', 20);
if (oswidth < target_width) {
oswidth += 5;
} else {
clearTimeout(loop);
}
el.style.width = oswidth + 'px';
}
setInterval(grow, 1000);
Demo: http://jsfiddle.net/lotusgodkk/jeq834de/1/
There are three solutions. The first is using recursive setTimeout:
function grow(time) {
if (oswidth < target_width) {
oswidth += 5;
el.style.width = oswidth + 'px';
setTimeout(function() {grow(time);}, time);
}
}
The second is to use setInterval as described in the answer of K K.
The third is my personal favorite, using the transition css attribute.

Categories