Restrict SELECT width to width of parent TH - javascript

I generate filter SELECTs and INPUTs to the footer TH of my data table. I want these items widths to match width of parent TH (minus some margin).
My TH elements have classes .datainput or .dataselect to know, whether SELECT or INPUT should be generated.
I've created this script, which is called after AJAX data are loaded and inputs are generated:
function fnFixElementsTH() {
// Fix data inputs
$('.datainput').each(function(i) {
var thWidth = $(this).width();
$(this).children().width(thWidth);
});
// Fix data selects
$('.dataselect').each(function(i) {
var thWidth = $(this).width() - 10;
$(this).children().width(thWidth);
});
}
I use following CSS for TH:
padding: 3px 0px 3px 10px;
font-weight: bold;
font-weight: normal;
And for select:
word-wrap: normal;
margin-right: 10px;
In chromium it is working perfectly:
But in firefox, SELECTs have invalid sizes:
I printed widths of THs and SELECTs in chromium and firefox and here are the results for second column in chromium:
And in firefox:
Could you tell me what I am doing wrong, or suggest a better solution?

Problem is in .width() Jquery API. It has some issue with FF. You can use .css to set the width.
$(".dataselect").each(function(i) {
var thWidth = $(this).width() - 10;
$(this).children().css('width',thWidth);
});
Solution Fiddle: jsfiddle.net/vfNRS/1

I've found a solution, outer width of select has to be set:
// Fix data selects
$('.dataselect').each(function(i) {
var thWidth = $(this).width() - 10;
//$(this).children().width(thWidth); THIS WAS WRONG
$(this).children().outerWidth(thWidth);
});
Solution is here: http://jsfiddle.net/gZEc9/12/

Related

Scrolling select element jumps to top when removing options from DOM in IE

This issue appears to be isolated to Internet Explorer:
I'm moving option tags from one select to another when they're double clicked using Javascript. The select elements can have many items, so I've set the height with overflow: auto; so that they scroll. If you scroll down the list and double click an item to move, the select list will scroll up to the top when the option is removed, instead of staying at the current scrolled-to position as it does in Chrome or Firefox.
I made a basic example to demonstrate this here: https://jsfiddle.net/yk8LeLbw/1/
The Javascript is pretty simple:
$(".listBoxSelectorAvail").dblclick(function() {
$(this).find("option:selected").remove().appendTo(".listBoxSelectorAssigned");
});
$(".listBoxSelectorAssigned").dblclick(function() {
$(this).find("option:selected").remove().appendTo(".listBoxSelectorAvail");
});
I haven't been able to find any specific reason why this happens - I'm not sure if it's a bug or if this is expected behavior, but is there anything that can be done?
EDIT: made the title more clear
EDIT 2: I was hoping to stop the scrolling, but the best solution I've come up so far is to rescroll once the item has been moved, as seen here:
https://jsfiddle.net/yk8LeLbw/2/
The issue is that IE behaves differently. So, we have to work around that unwanted behavior. The solution is to wrap the select in a div and use some CSS.
Here's a working jsFiddle.
Note how I wrapped a div around each select and replaced the size="50" attribute with the multiple="true" attribute. This removes the scrollbar on the select elements.
$(document).ready(function() {
var arr1 = [];
var arr2 = [];
arr1.push("<div class='scroll'><select class='listBoxSelectorAvail' multiple='true'>");
arr2.push("<div class='scroll'><select class='listBoxSelectorAssigned' multiple='true'>");
for (var i = 0; i < 20; i++) {
arr1.push("<option value=\"" + i + "\">Option " + i + "</option>");
}
arr1.push("</select></div>");
arr2.push("</select></div>");
$("body").append(arr1.join(""));
$("body").append(arr2.join(""));
$(".listBoxSelectorAvail").dblclick(function(e) {
$(this).find("option:selected").remove().appendTo(".listBoxSelectorAssigned");
});
$(".listBoxSelectorAssigned").dblclick(function(e) {
$(this).find("option:selected").remove().appendTo(".listBoxSelectorAvail");
});
});
Here's the modified CSS.
select {
width: 200px;
height: 200px;
}
.scroll {
overflow: auto;
display: inline-block;
margin-left: 10px;
}

Refresh a page with new div grid

I'm trying to make a grid of divs that, when mouseentered change color. Then, when the a button is clicked and new number is entered to then generate a new grid with a side length of that many divs. I'm new to javascript and jQuery and can't figure out why my code won't generate the divs.
here's my script
$('.block').mouseenter(function () {
$(this).css('background-color', 'black');
});
function newGrid(x) {
for (i = 0; i > x * x; i++) {
$('.container').append('<div class="block"></div>');
}
$('.block').height(960 / );
$('.block').width(960 / );
}
function clearContainer() {
$('.block').remove();
}
function askGrid() {
var num = prompt("enter box length");
clearContainer();
newGrid(num);
}
function firstGrid() {
newGrid(16);
$('#reset').click(function () {
askGrid();
});
}
$(document).ready(firstGrid);
here's my css
.container {
margin: 30px auto 0px auto;
height: 960px;
width: 960px;
border: 1px solid black;
}
.block {
border:0px;
margin:0px;
padding:0px;
float:left;
background-color: yellow;
}
#reset {
display:block;
padding:5px 20px;
margin:0 auto;
}
html has a css reset and in the body i have a button with id="reset" and a div with class="container"
thanks!
Several problems:
The slash when setting height and width is wrong (either is 960 divided by something or just 960)
The for loop is wrong: it should be
for (i = 0; i < x * x; i++)
And the css thing is not going to apply since there are no .block elements when executed. You should probably move it into newGrid
You have a bug here for (i = 0; i > x * x; i++) it should be i < x.
And im not sure what this is
$('.block').height(960 / );
$('.block').width(960 / );
you can set the height and width respectively in the css
Also you need to this for the mouseenter event to work
$('.container').on('mouseenter','.block',function () {
$(this).css('background-color', 'black');
});
Since the items added are dynamic.
Welcome to jquery, a world of excitement and pain!
This code
$('.block').mouseenter(function () {
$(this).css('background-color', 'black');
});
binds the hover function to all existing .block elements on the page when it is run. It's at the top of your script so it'll execute once, binding this property to all .block elements when the page loads, but not to .block elements created after. To fix this add it inside your "newGrid" function so it rebinds each new element as they are created.
In your loop, you want for (i = 1; i < x * x; i++), starting index from 1 rather than 0, or else you'll have an off by 1 error and create an extra box.
To set the proper heights of .block, you want to divide your .container's dimentions by x, the size of block:
$('.block').height(960 / x);
$('.block').width(960 / x);
The following are general programming tips:
As a good practice, functions should have a specific job and only do that job. I moved the clearContainer call to inside newGrid, because it should be the function that builds the new grid that clears the old one, not the one called askGrid. askGrid should do as it is named, and only ask for your new grid dimension.
You should do a validation on the number received through askGrid. If the user types something that isn't a number, or a negative number, or 0, you shouldn't start making boxes or newGrid will break. I added a loop to keep asking for a size until a proper dimension is provided, but you can chose your behaviour.
I changed the variable "x" to "block_length" since variables should be given names indicative of that they mean, so that there aren't a bunch of mysterious variables all over the place called x, y, z that you can't tell what they mean from a glance.
Demo in this fiddle!

Control table width with Jquery issue

I have a question regarding the IE7
I want to make every column of my table has the same width no matter what contents they have
$("table").each(function(){
var column =0;
var totalWidth = $(this).width();
$('tr:nth-child(1) td',this).each(function(){
column ++;
})
var cellWidth = totalWidth / column;
$('td', this).css('width', cellWidth);
})
My codes work perfect on chrome and FF but not IE 7. I am not sure why. Can anyone help me about it? Thanks a lot!
nth-child is CSS3 selector and does not supported by IE 7. Try something else.
Why don't you just put a class on all of your columns and then set it in CSS? That is just a waste of jQuery code.
<td class="col">...</td>
Then...
.col {
width: 50px;
}
Or if you need it to be a certain percent of the page/table...
.col {
width: 20%; /* if 5 columns in the table, make each 20% of table width */
}
Set the table's table-layout to
table-layout:fixed;
and provide a width shouldn't need jquery then

scrollHeight not resetting after programmatically changing content

I am trying to learn a few things without jQuery. Here is one of the challenges I'm facing.
I have a fixed contenteditable div that when adding text to the div, if the scrollHeight exceeds the clientHeight I shrink the font until content fits the div.
Occasionally I "rebuild" the text which replaces the innerHTML programmatically. Or the user can delete text which should reduce the scrollHeight, but in both cases, the scrollHeight remains the maximum value. I need some way to increase the font size to "fit" the div again. (that ideally isn't super expensive)
Example:
My clientHeight = 142, and the scrollHeight = 158. A loop reduces the font size, until scrollHeight is 142.
Then, the user deletes a line of text, but the scrollHeight is still 142, no change.
code to reduce/increase height:
var textBox = document.getElementById('text');
var current, min = 6, max = 14;
current = textBox.style.fontSize.substr(0, textBox.style.fontSize.length - 2);
current = parseInt(current);
if (textBox.clientHeight < textBox.scrollHeight) {
while (textBox.clientHeight < textBox.scrollHeight) {
current--;
if (current < min) break;
textBox.style.fontSize = '' + current + 'pt';
}
} else if (textBox.clientHeight > textBox.scrollHeight) {
while (textBox.clientHeight > textBox.scrollHeight) {
current++;
if (current > max) break;
textBox.style.fontSize = '' + current + 'pt';
}
}
html (incase it matters):
<div id="text" contenteditable="true"></div>
css (incase it matters):
#text {
position: relative;
border: 1px solid blue;
top: 180px;
left: 31px;
width: 300px;
height: 132px;
padding: 5px;
font-family: 'mplantin';
font-size: 14pt;
font-weight: 200;
}
I was on the same boat, but with an iframe; I'm not sure if my solution suits your chat window because its for page transitioning, but after some testing this is my hack. "content" is the id of an iframe and this is executed inside a javascript function that is called when the page change is needed:
var c=document.getElementById("content");
c.width=0;
c.height=0;
c.src="page.html";
the `src' assignment method expands the values set to 0 right after, achieving the desired result; there may be a way for you to constantly re-size a text area like that; however, I had visual issues with you; I ended up using timers so that the change would take place while the transition between pages was transparent.
This seemed to fix my issue:
element.style.height = "auto";
both answers from #nixahn and #jeff are working for me (chrome,ff)
iframe.style.height ="0"; // or "auto"
iframe.contentWindow.document.open();
iframe.contentWindow.document.write('<style>'+css+'</style>');
iframe.contentWindow.document.write(html);
iframe.contentWindow.document.close();
I have used a div with a fixed height, and the problem with auto is that it resizes the element, I fixed that with the following code after my inner HTML was set:
element.style.height = "auto";
element.style.height = "400px";
now scrollHeight is resetted correctly and gives the real height of the inner HTML
I had this same issue -- A content editable div whose scrollHeight wouldn't shrink when lines were removed.
The accepted answer didn't fix the problem for me, however, removing the div's parent's display: flex; did.

Resizing a select multiple list with the size of the dialog box

I have a select list inside a dialog box:
<div id='Dialog' title='Title'>
<div id='list_container'>
<select id='file_list' multiple='multiple'>
</select>
</div>
</div>
I'm populating file_list in javascript. The css for list_container and 'file_list` look like this:
#list_container {
width: auto;
height: auto;
overflow: auto;
border: 1px black solid;
margin: auto;
}
#file_list {
border: none;
}
The file_list opens inside a dialog box and typically has many options(>20). When the dialog box pops up, the list shows about 10 entries and I can scroll down to other entries. However, I want the list to expand vertically when I resize the dialog box vertically (i.e. the list should show more than 10 entries depending on the vertical space available in the dialog box). How can I do this? I tried doing a few things like setting the height css attribute for file_list to auto , but it doesn't seem to work.
You could use something similar to the following either called during an event call or otherwise at a point when the elements have been added to the body
var width = document.getElementById("list_container").offsetWidth;
document.getElementById("file_list").style.width = width;
This is similar to the answer provided by SOliver. I solved it by firing a function at the dialog resize event, and modifying the size attribute of the select-list depending on the height of the dialog box:
$('#Dialog').dialog({
height: 460,
width: 500,
//Add a function on the dialog resize event
resize: function(event, ui) {
var default_height = 460; //default height
var new_height = ui.size.height; //Gives height after resize
if (new_height > default_height) {
var list = $('#file_list');
var row_height = ((flist.height())/(flist.attr('size')));
//Get height of one row
var extra_space = new_height-default_height;
var list_newSize = Math.floor(extra_space/row_height) + 11;
//11 is the default or minimum 'size' of file_list
flist.attr('size',list_newSize);
}
}
);
Make sure you set the height and width of the div that contains select list to auto. Now the size of the list should scale with the size of the dialog box.
Though this works, it seems like an ad-hoc solution. Any there any more elegant ways to do this?

Categories

Resources