html table: row 2 alters the length of row 1 - html

I am trying to create a tree with a three elements. Main Element, -> children, -> children.
I got pretty far, I can even collaps entire portions of the table. The problem however is, when I collabs row two.
At first, the table looks like this:
Which is fine. I have three <td> in one row.
However, if I show the second row (clicking on my blue arrow),
this is the result:
So, what happens is that the second <tr> then pushes the elements of the second <td> so much forward, that "SubKategorie_1 DELETE" has enough room to fit before "Hauptkategorie_1" begins, which is in a different table row.
I am pretty sure that all I need is a css attribute.
Ill give you the code shortend:
<table class="mainTable">
#{
var position = 0;
for (int i = 0; i < Model.MainNodes.Count(); i++)
{
string catId = "CatId" + i.ToString();
string classToHideCatId = "classToHideCatId" + i.ToString();
<tr class="mainCatRow">
<td>
<div>
<img src="#Url.Content("~/Content/images/icons/icon-open.png")" id="#catId" class="buttonLayoutMain" />
</div>
</td>
<td>
<div class="mainCat">
#Model.MainNodes[i].name
</div>
<td>
Delete
</td>
</tr>
<!--subcategory-->
<tr class="tr2">
<td>
<div class="#classToHideCatId">
<table class="subTable">
...
</table>
</div>
</td>
</tr>
}
}
</table>
With some basic CSS:
.MainDiv{
padding: 20px;
}
.mainTable{
background-color: green;
}
.mainCat {
font-size: 20px;
}
.mainCatRow{
background-color:orange;
}
.subCat {
margin-left: 40px;
font-size: 18px;
}
.tr2{
background-color:gray;
}
.subsubTable {
margin-left: 80px;
}
Question:
How can I make my table have differnt lenght rows?

Related

HTML table; How to format content within 2nd column to align all - except first element - to right and stretch 1st element to fill remaining width

want to display the following:
where the "..." button in the first row (Web Project) is completely right-aligned to the red line (with a little padding to it)
where the Input field in the 2nd row (Root Namespace) is filling up the space to the right until the red line (with a little padding to it)
where the 2 buttons in the 3rd row (Connection String) are completely right-aligned to the red line (with a liddle padding to it).
I have tried the following but it does not do it correctly - and it only works with a certain width - If I increase or decrease the width, things are getting ugly:
decreasing the width:
My current HTML looks like this:
<div id = "ProjectSelector" width = 100%>
<table width = "100%" style = "padding-bottom: 10px;">
<tr>
<td style="white-space: nowrap; width: 140px;">Web Project (.csproj)</td>
<td style="width: 99%;" ><input id = "webproj" style="width: 97%"/><button id="webproj_browse">...</button></td>
</tr>
<tr>
<td>Root Namespace</td>
<td style="width: 99%;"><input id = "rootnamespace" style="width: 99%"/></td>
</tr>
<tr>
<td>Connection String</td>
<td style="width: 99%;"><select id = "connectionstring" style = "width: 87%"></select><button id="newConnection">New Connection</button><button id="connstringDelete">Delete</button></td>
</tr>
</table>
</div>
Question: How to format the table and the content of 2nd column to accomplish this properly?
the title of your question describes a typical flex behavior. You may use inside your table a flex container :
.flex {
display: flex;
}
.flex-1 {
flex-grow: 1;
}
<div id="ProjectSelector" width=1 00%>
<table width="100%" style="padding-bottom: 10px;">
<tr>
<td style="white-space: nowrap; width:0;">Web Project (.csproj)</td>
<td>
<div class="flex"><input id="webproj" class="flex-1" /><button id="webproj_browse">...</button></div>
</td>
</tr>
<tr>
<td>Root Namespace</td>
<td>
<div class="flex"><input id="rootnamespace" class="flex-1" /></div>
</td>
</tr>
<tr>
<td>Connection String</td>
<td>
<div class="flex">
<select id="connectionstring" class="flex-1"></select><button id="newConnection">New Connection</button><button id="connstringDelete">Delete</button></div>
</td>
</tr>
</table>
</div>
It can also be build with grid or flex without a table.
For infos & demo , an example mixing grid and flex, i would probably not use this HTML structure H + P at first :
* {
margin: 0;
}
.flex {
display: flex;
}
.flex-1 {
flex-grow: 1;
}
#ProjectSelector {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 0.25em;
;
}
p {
grid-column: 2;
}
<div id="ProjectSelector">
<h4>Web Project (.csproj)</h4>
<!-- title that matches your structure or else can be plain text -->
<p class="flex"><input id="webproj" class="flex-1" /><button id="webproj_browse">...</button></p>
<h4>Root Namespace</h4>
<p class="flex"><input id="rootnamespace" class="flex-1" /></p>
<h4>Connection String</h4>
<p class="flex">
<select id="connectionstring" class="flex-1"></select><button id="newConnection">New Connection</button><button id="connstringDelete">Delete</button></p>
</div>

how do I resize HTML onclick? how would I make two onclick functions next to each other?

<!DOCTYPE html>
<html>
<style>
#media only screen and (max-width: 600px) {
p {
background-color:powderblue;
}
}
.row {
display: flex;
flex-wrap: wrap;
padding: 0 4px;
}
.column {
padding: 0 4px;
flex: 20%;
}
I'm not sure if this is actually doing anything
.onclick{
width: 20px;
height: 20px;
}
</style>
<body>
I want these two onclicks to be next to each other
<table style="width:100%">
<tr>
<p id="demo" onclick="myFunction1()">Click me.</p>
</tr>
</tr>
<p id="funct" onclick="myFunction2()">Click me.</p>
</tr>
</table>
This part details what the functions do
<script>
function myFunction1() {
if (document.getElementById("demo").innerHTML == "Click me."){
document.getElementById("demo").innerHTML = "YOU CLICKED ME!";
}
else{
document.getElementById("demo").innerHTML = "Click me.";
}
}
function myFunction2() {
if (document.getElementById("funct").innerHTML == "Click me."){
document.getElementById("funct").innerHTML = "YOU CLICKED ME!";
}
else{
document.getElementById("funct").innerHTML = "Click me.";
}
}
</script>
</body>
</html>
You see your paragraphs in the different rows because you placed them in different rows of your table.
Just change into
<table style="width:100%">
<tr>
<td>
<p id="demo" onclick="myFunction1()">Click me.</p>
</td>
<td>
<p id="funct" onclick="myFunction2()">Click me.</p>
</td>
</tr>
</table>
and they will be placed in the same row.
In HTML tables:
<tr> tag starts a new row
</tr> tag ends current row
<td> tag starts a new box in current row
</td> tag ends current box in current row
Anyway, though it's not the object of the current question, I suggest you finding a different way than tables for organizing your web page. Take a look to <div>s + CSS.

CSS position absolute do not extend beyond the left most of container

I'm trying to create a table where each cell has additional description that is displayed underneath it on hover.
I want to display the description directly under the cell only when hovered.
The description should be left aligned with the cell unless it extends beyond the bounds of the table at which point it should become right aligned with the end of the table.
I have been able to make things left aligned however I have failed to find a way to ensure the description doesn't extend beyond the end.
The Code (https://jsfiddle.net/9en4v2as/3/):
.description {
display: none;
}
table {
position: relative;
}
td:hover .description {
display: block;
position: absolute;
white-space: nowrap;
background-color: red;
}
td:last-child:hover .description {
right: 0;
}
<table border=1>
<tr>
<td>
<div class="value">Value1</div>
<div class="description">Description of Value1</div>
</td>
<td>
<div class="value">Value2</div>
<div class="description">Description of Value2</div>
</td>
<td>
<div class="value">Value3</div>
<div class="description">Description of Value3</div>
</td>
<td>
<div class="value">Value4</div>
<div class="description">Unknown description length</div>
</td>
<td>
<div class="value">Value5</div>
<div class="description">Description of Value5</div>
</td>
<td>
<div class="value">Value6</div>
<div class="description">Description of Value6</div>
</td>
</tr>
</table>
With jquery
$(document).ready(function(){
//get width table
var w_table = $("table").width();
var w_description;
$("table td").hover(function(){
//sum width td
var w_td = 0;
//get hover position
var pos = $(this).index();
$("table td").each(function(i){
//sum width td until hover position
w_td = w_td + $(this).width();
if(i==pos)
return false;
});
//get description width
w_description = $(this).find(".description").width();
//if width description+width td > width table
if(w_description+w_td > w_table)
$(this).find(".description").css("right",w_table-w_td-30);
});
});
Test here

HTML-find in page and display ONLY relevant portion

Ok, the title may sound a bit easy or common but my problem is not that easier. I'm working on making a HTML page that displays a database in table rows. A sample code is:
<table>
<tr><td>ABC Hospitals</td></tr>
<tr><td>India</td><td>Contact:9999999999</td></tr>
</table>
<table>
<tr><td>XYZ Blood Bank</td></tr>
<tr><td>NewJersey</td><td>Contact:8888888888</td></tr>
</table>
<table>
<tr><td>ABC Inn</td></tr>
<tr><td>California</td><td>Contact:7777777777</td></tr>
</table>
I have used tables to group data, with each one containing rows to display data. The code gives the following output sample, with the CSS effects added:
Image1 - Sorry, I'm a new user and StackOverflow doesn't allow me to post images.
I'm now in requirement of a 'Find in page' box to search the HTML document for a specific piece of information(say "ABC"). The search must display ONLY the table(s) that contains the query term("ABC"), in our case, hiding ALL other tables which do not contain the search term. I have achieved the sample output by manually editing the HTML, just to more clearly show my requirement. I'm in need of the JScript(or any appropriate) code to achieve the result:
Image2 - Sorry again.
I'm sure somebody here will be able to help me, either provide me some code piece or guiding me to some useful link. Thanks in advance.
-Sriram
var search = document.querySelector('#search');
var database = document.querySelector('#database');
search.addEventListener('input', function (e) {
// Every time the input changes, execute filterMatching.
filterMatching(search.value, database);
});
function filterMatching(value, parent) {
// Get the parent's children into an array
var children = [].slice.call(parent.children);
// Everything is shown by default.
children.forEach(function removeHiddenFromAll(child) {
child.classList.remove('hidden');
});
// Find those who are not matching
children.filter(function findNonMatching(child) {
// the toLowerCase() on both ensures the search is not case sensitive.
return child.textContent.toLowerCase().indexOf(value.toLowerCase()) < 0;
})
// After we found all the non matching, hide them
.forEach(function hideNonMatching(nonMatching) {
nonMatching.classList.add('hidden');
});
}
.hidden {
display: none;
}
<input type="text" id="search" />
<div id="database">
<table>
<tr>
<td>ABC Hospitals</td>
</tr>
<tr>
<td>India</td>
<td>Contact:9999999999</td>
</tr>
</table>
<table>
<tr>
<td>XYZ Blood Bank</td>
</tr>
<tr>
<td>NewJersey</td>
<td>Contact:8888888888</td>
</tr>
</table>
<table>
<tr>
<td>ABC Inn</td>
</tr>
<tr>
<td>California</td>
<td>Contact:7777777777</td>
</tr>
</table>
</div>
Never mind, for some reason, the thing doesn't work when the element are stored as 'var' types. So I modified the code slightly as follows: I created a new function:
function fn_search(){
var phrase = document.querySelector('#search').value;
filterMatching(phrase, document.querySelector('#database'));
}
and called
<input type="text" id="search" oninput="fn_search()" />
The program now works fine.
The complete code is below:
<html>
<head>
<style>
table{
padding: 20px;
margin: 10px;
background: #990030;
color: #fff;
font-size: 17px;
font-weight: bold;
line-height: 1.3em;
border: 2px dashed #9ff;
border-radius: 10px;
box-shadow: 0 0 0 4px #990030, 2px 1px 6px 4px rgba(10, 10, 0, 0.5);
text-shadow: -1px -1px #aa3030;
font-weight: normal;
table-layout: fixed;
width: 325px;
height:75px;
}
th, td {
overflow: hidden;
width: 100px;
}
table.hidden {
display: none;
}
</style>
</head>
<body>
<script>
function fn_search(){
var phrase = document.querySelector('#search').value;
filterMatching(phrase, document.querySelector('#database'));
}
function filterMatching(value, parent) {
// Get the parent's children into an array
var children = [].slice.call(parent.children);
// Everything is shown by default.
children.forEach(function removeHiddenFromAll(child) {
child.classList.remove('hidden');
});
// Find those who are not matching
children.filter(function findNonMatching(child) {
// the toLowerCase() on both ensures the search is not case sensitive.
return child.textContent.toLowerCase().indexOf(value.toLowerCase()) < 0;
})
// After we found all the non matching, hide them
.forEach(function hideNonMatching(nonMatching) {
nonMatching.classList.add('hidden');
});
}
</script>
<input type="text" id="search" oninput="fn_search()" />
<div id="database">
<table>
<tr>
<td>ABC Hospitals</td>
</tr>
<tr>
<td>India</td>
<td>Contact:9999999999</td>
</tr>
</table>
<table>
<tr>
<td>XYZ Blood Bank</td>
</tr>
<tr>
<td>NewJersey</td>
<td>Contact:8888888888</td>
</tr>
</table>
<table>
<tr>
<td>ABC Inn</td>
</tr>
<tr>
<td>California</td>
<td>Contact:7777777777</td>
</tr>
</table>
</div>
</body>
</html>

Issue setting up grid style results

I want to show a table in a grid result table and I am failing...
I want it to look like so:
I'm trying to do it this way, but it only shows one line:
<div class="resultsTable">
<table style="display: inline-table">
<tr ng-repeat="result in results" class="resultsBox">
<td>
<img src="{{result.imageUrl}}" width="200px">
<h4>{{result.name}}</h4>
</td>
</tr>
</table>
</div>
CSS:
.resultsBox{
background-color: #ffffff;
height: 200px;
width: 200px;
padding-left: 10px;
padding-top: 20px;
}
.resultsBox>img{
max-width: 200px;
margin-left: auto;
margin-right: auto;
}
.resultsTable{
max-height: 500px;
overflow: scroll;
display: inline-table;
height: 500px;
}
From the template you have shared it's normal that you see only one column of n row. It is not link to the css but to the markup that will be generated.
Your results property is an array of one dimension something like [{obj1}, {obj2}, {obj3}] but you want to display a matrix an array of two dimensions i.e [[{obj1}, {obj2}], [{obj3}, {obj4}]]. Unfortunately it is not that easy in AngularJS to generate a matrix based on a one dimension array. That's why I will recommend that you change the structure of your result to match its matrix display. Then change your template to something like :
<div class="resultsTable">
<table style="display: inline-table">
<tr ng-repeat="row in results"> //loop over all row of 2 elements
<td ng-repeat="cell in row" class="resultsBox"> //loop over elements
<img src="{{cell.imageUrl}}" width="200px">
<h4>{{cell.name}}</h4>
</td>
</tr>
</table>
</div>
See a working plunker here