Justify Inline elements with Input Boxes - javascript

I have a series of inline elements (with input text boxes) that should fit within one row. See picture below.
The number of input boxes can vary (dynamically loaded via AJAX), as can the labels of the input boxes. In the example below, it is length x width x height.
The div that the inline elements are in is a dynamic width, which depends on the content above and below this row.
In the event of the screenshot below, how can I get the input boxes to equally increase in width so that the content is justified on both sides? Is there a pure CSS solution?
.dynamicWidth {
background-color: green;
height: 400px;
position: absolute;
}
<div class="dynamicWidth">
<div>
<select>
<option>This could be longer or shorter dependending on what is dynamically loaded</option>
</select>
</div>
<hr>
<div>
<span>Length</span>
<input type="text" placeholder="length"><span> x Width</span>
<input type="text" placeholder="width"><span> x Height</span>
<input type="text" placeholder="height">
</div>
</div>

You can accomplish this using flexbox's justify-content and assigning the value of space-around to the div containing the input elements.
.dynamicWidth {
background-color: green;
width: 100%;
height: 400px;
position: absolute;
}
.dynamicWidth div:nth-of-type(2) {
display: flex;
justify-content: space-around;
}
<div class="dynamicWidth">
<div>
<select>
<option>This could be longer or shorter dependending on what is dynamically loaded</option>
</select>
</div>
<hr>
<div>
<span>Length</span>
<input type="text" placeholder="length"><span> x Width</span>
<input type="text" placeholder="width"><span> x Height</span>
<input type="text" placeholder="height">
</div>
</div>
If you're trying to support legacy browsers that don't support flexbox your alternative option would be to wrap each label and input in their own respective divs, give the enclosing parent of those divs a display of table and give the input divs a display of table-cell with width percentages of 33.3% (1/3s).
.dynamicWidth {
background-color: green;
width: 100%;
height: 400px;
position: absolute;
}
.dynamicWidth div:nth-of-type(2) {
display: table;
width: 100%;
}
.input-container {
width: 33.3%;
display: table-cell;
}
<div class="dynamicWidth">
<div>
<select>
<option>This could be longer or shorter dependending on what is dynamically loaded</option>
</select>
</div>
<hr>
<div>
<div class="input-container">
<span>Length</span>
<input type="text" placeholder="length">
</div>
<div class="input-container">
<span> x Width</span>
<input type="text" placeholder="width">
</div>
<div class="input-container">
<span> x Height</span>
<input type="text" placeholder="height">
</div>
</div>
</div>

Related

dynamically adding onfocus and onfocusout in a for loop not working [duplicate]

This question already has answers here:
Javascript: Creating Functions in a For Loop
(3 answers)
Closed 1 year ago.
I have a website with a bunch of inputs that looks like this (I cannot edit the HTML since this part is automatically generated):
<div style="display: inline; position: relative;">
<div>
<label for="inputID">label here</label>
<label >*</label>
</div>
<div>
<div>
<input type="text" fieldformat="None" id="inputID" placeholder="something">
</div>
</div>
</div>
I want to make it so that when the user is entering something on input field, the label will disappear appear
___________________________ _first name (label)_______
| first name (placeholder) | click | |
|___________________________| --------> |__________________________|
here is my attempt at doing it with javascript:
function displayOnFocusAndOnFocusOut() {
var inputs = [
'inputID1',
'inputID2',
'inputID3',
...
]
for(var i = 0; i < inputs.length; i++) {
var input = document.getElementById(inputs[i])
input.onfocus = function() {
input.parentElement.parentElement.parentElement.firstChild.style.display = 'none'
console.log(input.parentElement.parentElement.parentElement.firstChild)
}
input.onfocusout = function() {
input.parentElement.parentElement.parentElement.firstChild.style.display = 'block'
}
}
}
However this doesnt work as the label still displays when I click on the input, and with a console log it shows that only the last input is affected. I've also tried adding !important but it still does not work.
How can I fix this?
Thanks
You don't need any javascript:
body {
height: 200vh;
}
.field>div {
display: inline-flex;
flex-direction: column-reverse;
}
.label {
height: 1em;
margin-bottom: 0.2em;
}
.label>label {
transition: height 0.5s;
height: 0;
overflow: hidden;
display: inline-block;
}
.field input:not(:placeholder-shown) ~.label>label {
height: 1em;
}
<div class="field">
<div>
<input type="text" fieldformat="None" id="inputID1" placeholder="something">
<div class="label"><label>label here *</label></div>
</div>
</div>
<br>
<div class="field">
<div>
<input type="text" fieldformat="None" id="inputID2" placeholder="something">
<div class="label"><label>label here *</label></div>
</div>
</div>
This example will show labels when placeholder is hidden, you can change it so it would show labels when input field is in focus by replacing :not(:placeholder-shown) with :focus

How to make width of <select> element proportional to <div> element

Now, I would like to make width of my select element, let's say 80% of its parent div ( div#queries). Is there anyway to do it?
<div id="flowchart-left-panel">
<div id ="queries">
<h3>Queries</h3>
<select class="query-list" size="20">
</select>
</div>
<div id="filters">
<h3>Filters</h3>
<select class="filter-list" size="10">
</select>
</div>
</div>
Of course, with CSS.
Demo here: http://codepen.io/anon/pen/JYYGvG
#queries, #filters{
width: 300px;
}
select{
width: 80%;
}

Bootstrap datetimepicker strange positioning on a different div altogether

I am using bootstrap datetimepicker with formatting to enable only editing time in my code, I do it like this:
function setTimepicker(object){
object.datetimepicker({
format: 'HH:mm'
});
}
I call this function in document.ready like so:
$(document).ready(function(){
setTimepicker(starttimefield);
setTimepicker(endtimefield);
});
The html I am using is like this:
<div class="panel-body">
<form id="myform">
<p> <b>Create a New Event:</b></p>
<br>
<p>Description for main page: <br>
<textarea id="summary" name="summary" maxlength="100"></textarea>
</p>
<p> Full description: <br>
<textarea id="description" name="description" maxlength="500"></textarea>
</p>
<div class="wrapper">
<div class="titles">
<p> Event date:
</p>
<p> Start time:
</p>
<p> End time:
</p>
</div>
<div class="values">
<input type="text" id="eventdate" readonly/><br>
<div id="starttimepicker">
<input type="text" id="starttime" onkeydown="return false"/><br>
</div>
<div id="endttimepicker">
<input type="text" id="endtime" onkeydown="return false"/>
</div>
</div>
</div>
<p> Location: <input type="text" id="location"/> </p>
<p><input type="hidden" id="userid" value="<?php echo Auth::id();?>"/></p>
<p><input id="saveevent" type="button" value="Save Event" />
</p>
</form>
</div>
Except for the standard css files (jquery-ui.css, bootstrap-datetimepicker.css) I added 1 extra css file that contains:
.wrapper {
display: inline-block;
width: auto;
overflow: hidden;
}
.titles {
width: 100px;
float:left;
}
.values {
overflow: hidden;
margin-left: 100px;
}
Now for the issue at hand, the fields endtime and starttime should have a timepicker when clicked (this works) but look at where it renders the timepicker in this image:
Can anyone help me to get that timepicker element next to (or above or close by, anything) the field that it belongs to
You are missing an .input-group wrapper which has a position value of "relative". Since the datepicker is absolutely positioned it's container needs to be relatively positioned for the datepicker to be positioned correctly.
So I believe something like this would work:
.values {
position: relative;
overflow: hidden;
margin-left: 100px;
}
Better yet, let's set position relative on the divs that actually hold our inputs like so:
#starttimepicker {
position: relative;
}
#endtimepicker {
position: relative;
}
If you want my opinion though that is not very DRY. If you have control over the html you might try to add a class of "values__datepicker" (or whatever class) to #starttimepicker and #endtimepicker and set just one CSS rule like so:
.values__datepicker {
position: relative;
}

How to style radio buttons differently if they fit in a single row?

PLAYGROUND HERE
I'd like to style radio buttons differently if they fit in a single row. For example:
The first container doesn't have enough space to fit all the radio buttons in a single row. Therefore, they appear vertically as normal radio buttons.
The second container has enough space. Therefore, the radio buttons appear as buttons.
Is that possible to achieve this behaviour using CSS only?
If not, Javascript "hack" is welcome.
PLAYGROUND HERE
HTML
<div class="container radio">
<div>
<input id="a1" type="radio" name="radio">
<label for="a1">Yes,</label>
</div>
<div>
<input id="a2" type="radio" name="radio">
<label for="a2">it</label>
</div>
<div>
<input id="a3" type="radio" name="radio">
<label for="a3">is</label>
</div>
<div>
<input id="a4" type="radio" name="radio">
<label for="a4">possible</label>
</div>
<div>
<input id="a5" type="radio" name="radio">
<label for="a5">to</label>
</div>
<div>
<input id="a6" type="radio" name="radio">
<label for="a6">achieve</label>
</div>
<div>
<input id="a7" type="radio" name="radio">
<label for="a7">this</label>
</div>
</div>
<div class="container buttons">
<div>
<input id="b1" type="radio" name="buttons">
<label for="b1">Yes,</label>
</div>
<div>
<input id="b2" type="radio" name="buttons">
<label for="b2">it</label>
</div>
<div>
<input id="b3" type="radio" name="buttons">
<label for="b3">is</label>
</div>
<div>
<input id="b4" type="radio" name="buttons">
<label for="b4">possible</label>
</div>
</div>
CSS (LESS)
.container {
display: flex;
width: 220px;
padding: 20px;
margin-top: 20px;
border: 1px solid black;
&.radio {
flex-direction: column;
}
&.buttons {
flex-direction: row;
> div {
input {
display: none;
&:checked + label {
background-color: #ADFFFE;
}
}
label {
padding: 5px 10px;
margin: 0 1px;
background-color: #ccc;
}
}
}
}
Not possible in CSS, but it doesn't take much JavaScript.
In CSS, add flex-shrink: 0 to > div. This will prevent .container's children from shrinking smaller than their extent.
In JavaScript:
Apply the buttons class.
Use Element.getBoundingClientRect to determine if the last child of .container is outside the extent of .container. If so, switch to the radio class. (You also need to take the right padding into account. Thanks to #Moob for pointing that out.)
Javascript
var container = document.querySelector('.container'),
lastChild= document.querySelector('.container > :last-child'),
paddingRight= parseInt(window.getComputedStyle(container, null).getPropertyValue('padding-right')),
timer;
window.onresize = function() {
clearTimeout(timer);
timer= setTimeout(function() {
container.classList.remove('radio');
container.classList.add('buttons');
if (container.getBoundingClientRect().right-paddingRight <
lastChild.getBoundingClientRect().right) {
container.classList.add('radio');
container.classList.remove('buttons');
}
});
}
Updated JSBin
I can't think of a CSS only solution but you could use JS to test if the items would fit in a row and apply the 'radio' or 'buttons' classname accordingly:
Forgive my rough JS - its inelegant and for modern browsers only but you get the idea:
var containers = document.querySelectorAll(".container"),
test = function(){
for (i = 0; i < containers.length; ++i) {
var container = containers[i],
divs = container.querySelectorAll("div"),
iw = 0;
container.classList.remove("radio");
container.classList.add("buttons");
//get the sum width of the div
for (d = 0; d < divs.length; ++d) {
iw+=divs[d].offsetWidth;
}
var style = window.getComputedStyle(container, null);
var ow = parseInt(style.getPropertyValue("width"));
if(ow<=iw){
container.classList.add("radio");
container.classList.remove("buttons");
}
}
};
window.onresize = function(event) {
test();
};
test();
http://jsbin.com/zofixakama/3/edit?html,css,js,output
(resize the window / panel to see the effect)
Update: If you add .container div {flex-shrink:0;} to the style the JS can be much simpler as we don't have to measure the combined width of the divs (thanks #rick-hitchcock). However, although the code is more elegant, it does not take the container's padding into account.
See: http://jsbin.com/zofixakama/5/edit?html,css,js,output
If I understand what you're asking correctly, you can change your flex-direction portion to row instead of column. This will cause them to align inside the box.
You'll have to do some more styling to properly get the labels to appear the way you want, but this should put them in the row for you. I've updated the playground with my changes.
Try the following example..............
------------HTML-----------
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="table-row">
<div class="col">
<input type="Radio">This
</div>
<div class="col" style="padding-top: 2px;">
<input type="Radio">Is
</div>
<div class="col">
<input type="Radio">Simply
</div>
<div class="col" style="padding-top: 2px;">
<input type="Radio">Possible
</div>
</div>
</body>
</html>
-------CSS-------------
.table-row{
display:table-row;
/* text-align: center; */
}
.col{
display:table-cell;
/* border: 1px solid #CCC; */
}
Wouldn't it work to test for width then if necessary remove the radio button icon and replace with a graphic or shape?
.checkbox {
display:none;
}
.label {
display: inline-block;
height: 20px;
background: url('picture.png');
}
It's probably not that simple but I use that for check boxes and it seems to work in that situation.
You can achieve this only by using css and no need of scripting.
HTML: You have to place the input within tag which will contain the text.
<div>
<label for="a1">
<input id="a1" type="radio" name="radio">Yes,
</label> </div>
CSS: Here in CSS we will have to hide the radio button, so that only the text will be visible. When the user clicks on the text, it actually clicks the radio button.
div lable input#a1{
display:none;
}
there is pretty solution CSS only, but you have to know maximum amount of elements in row. It is based on counter, but not on real size.
For example, if you are sure, that you can put 4 elements into a row, in any case, you may use following selector:
if amount is more less or equal 4:
div:nth-last-child(-n+5):first-child,
div:nth-last-child(-n+5):first-child ~ div {
}
if amount is more then 4:
div:nth-last-child(n+5),
div:nth-last-child(n+5) ~ div {
}
try this: http://jsbin.com/fozeromezi/2/edit (just remove/add divs)

JQuery UI buttonset misbehaving

I am building a UI app using JQuery UI elements. I need radio buttons as part of the functionality. While using JQuery buttonset by itself works, once I try to incorporate it with the rest of UI elements they don't align properly:
http://jsfiddle.net/sEunS/2/
Including code here:
$(document).ready(function()
{
$("button").button();
$("#tdiDir").buttonset();
$("#acqMode").buttonset();
});
<div id='primaryLatestControl'
class="ui-corner-top pacontainer"
style='padding: 4px; display: inline-block; '>
<button id="setGain" class="button">Set</button>
<span class="label">Gain Value</span>
<input type="text" id="gainValue" class="value" value="2"></input>
<button id="setLineRate" class="button">Set</button>
<span class="label">Line Rate, HZ</span>
<input type="text" class="value" id="lineRateValue" value="3750"></input>
<button id="setExposeTime" class="button">Set</button>
<span class="label">Exposure Time(ms)</span>
<input type="text" class="value" id="exposeTimeValue" value="100"></input>
<button id="setTDI" class="button">Set</button>
<span class="label">TDI Direction</span>
<form>
<div id="tdiDir">
<label class="checkLabel" for="forward">Forward</label>
<label class="checkLabel" for="reverse">Reverse</label>
<input type="radio" class="value" name="tdiDir" id="forward" checked="checked"/>
<input type="radio" class="value " name="tdiDir" id="reverse"/>
</div>
</form>
<button id="setAcqMode" class="button">Set</button>
<span class="label">Acquisition Mode</span>
<form>
<div id="acqMode">
<label class="checkLabel" for="tdi">TDI</label>
<label class="checkLabel " for="area">Area</label>
<input type="radio" class="value" name="acqMode" id="tdi" checked="checked"/>
<input type="radio" class="value" name="acqMode" id="area"/>
</div>
</form>
.pacontainer {
position: relative;
width: 80%;
}
.label {
float: left;
margin: 10px;
}
.checkLabel {
width: 100px;
float: right;
margin: 10px;
}
.endLine {
clear: right;
}
.button {
float: left;
margin-left: 10px;
clear: left;
}
.value {
float: right;
width: 45px;
height: 20px;
margin: 5px;
background-image: none;
}
I quickly made some changes to your code to give you an idea. http://jsfiddle.net/sEunS/3/
You want your buttons in your buttonset to be ordered because the buttonset gives the outer buttons round corners and the inner buttons get 'squished' margins to be close together. Without the right ordering, the buttonset will always not look right.
Floating the radio's labels will cause the radios to be unordered in the buttonset. I suggest floating the radio's containers instead of the labels.
#acqMode, #tdiDir {
float: right;
}
and remove the float on the .checkLabels as they are no longer needed
.checkLabel {
//float: right;
}
You should also keep your radio's labels together with the radio inputs. This is another ordering issue with buttonsets.
<div id="acqMode">
<label class="checkLabel " for="area">Area</label>
<input type="radio" class="value" name="acqMode" id="area"/>
<label class="checkLabel" for="tdi">TDI</label>
<input type="radio" class="value" name="acqMode" id="tdi" checked="checked"/>
</div>
The last issue is you will need has to do with a clearfix. The buttonset is larger than the text on the same line, so the next line will not look straight without a clearfix. JQuery UI has a helper class
ui-helper-clearfix
I added this class to the line above that was uneven. The class goes on the parent of the last floated element. (try removing this class to get an idea of what I mean).

Categories

Resources