Populate table with an array of objects - javascript

I have a table that I need to populate with data from an array of objects.
The table looks and works like this.
The problem is, if I click on any row it shows me data from the last object of the endpointsData array({epid: 4... etc). What I want is to have the right data in the right place.
For example for the 1st row containing this object data:
{
"nodeid": 1,
"vendor": "0x0345",
"product_id": "0x0201",
"product_type": "0x0008",
"home_id": "0xD087E344",
"secure": "1",
},
After I click it, the div that opens below it, must contain this data:
{
"epid": 1,
"clslist": "5f",
"type": "0x02,0x01",
"zplus": "0x00,0x00,0x00,0x0000,0x0000"
},
But as you can see in the demo, any row I click it displays this data:
{
"epid": 4,
"clslist": "134,547,843,122",
"type": "2x07,0x01",
"zplus": "3x44,0x0d01,0x1ed01"
},
Any ideas on what I'm doing wrong?
Code (as requested):
function insertObject() {
var data = [{
"nodeid": 1,
"vendor": "0x0345",
"product_id": "0x0201",
"product_type": "0x0008",
"home_id": "0xD087E344",
"secure": "1",
},
{
"nodeid": 2,
"vendor": "0x0285",
"product_id": "0x0777",
"product_type": "0x0001",
"home_id": "0xD087D213",
"secure": "0",
},
{
"nodeid": 3,
"vendor": "0x1145",
"product_id": "0x7899",
"product_type": "0x0851",
"home_id": "0xD034T13",
"secure": "0",
},
{
"nodeid": 4,
"vendor": "0x8992",
"product_id": "0x1236",
"product_type": "0x8101",
"home_id": "0xD0682F13",
"secure": "1",
}
];
var endpointsData = [{
"epid": 1,
"clslist": "5f",
"type": "0x02,0x01",
"zplus": "0x00,0x00,0x00,0x0000,0x0000"
},
{
"epid": 2,
"clslist": "20,5e,72,86,59,73,5a,8f,98,7a,80,71,85,5c,70,30,31,84",
"type": "0x07,0x01",
"zplus": "0x01,0x00,0x06,0x0c07,0x0c07"
},
{
"epid": 3,
"clslist": "20,5e,72,86,59,73,5a,8f,98,7a,80,71,85,5c,70,30,31,84",
"type": "0x07,0x01",
"zplus": "0x01,0x00,0x06,0x0d01,0x0d01"
},
{
"epid": 4,
"clslist": "134,547,843,122",
"type": "2x07,0x01",
"zplus": "3x44,0x0d01,0x1ed01"
},
];
//populate the table with data from "data" object
var tbl = document.getElementById('tableData');
var tblBody = document.getElementById('tableBody');
for (var i = 0; i < data.length; i++) {
var row = document.createElement('tr');
row.classList.add("header");
for (var value in data[i]) {
var cell = document.createElement("td");
var cellText = document.createTextNode(data[i][value]);
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
//populate #divTemplate with data from "endpointsData" object
var key = ["epid", "clslist", "type", "zplus"];
for (var d = 0; d < endpointsData.length; d++) {
var endValue = {};
endValue = endpointsData[d];
for (var k = 0; k < key.length; k++) {
if (endpointsData[d]) {
$('#' + key[k]).text(endValue[key[k]]);
}
}
}
//create a row for displaying the #divTemplate data
var $contentCell = $("#divTemplate");
var $newRow = $("<tr style='display: none;'><td colspan='6'></td></tr>");
$newRow.find('td').append($contentCell);
$("tr.header:not(#hDeselect)").after($newRow);
$('tr.header').click(function() {
$contentCell.show();
$(this).next('tr').css('display', function() {
return this.style.display == 'none' ? 'table-row' : 'none'
});
});
}
insertObject();
th {
white-space: nowrap;
color: #D5DDE5;
background: #1b1e24;
border-bottom: 4px solid #9ea7af;
border-right: 1px solid #343a45;
font-size: 23px;
font-weight: 100;
padding: 24px;
text-align: left;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
vertical-align: middle;
}
tr {
border-top: 1px solid #C1C3D1;
border-bottom-: 1px solid #C1C3D1;
color: #666B85;
font-size: 16px;
font-weight: normal;
text-shadow: 0 1px 1px rgba(256, 256, 256, 0.1);
cursor: pointer;
}
/*grey row*/
tr:hover td {
background: #4E5066;
color: #FFFFFF;
border-top: 1px solid #22262e;
}
tr:nth-child(odd) td {
background: #EBEBEB;
}
tr:nth-child(odd):hover td {
background: #4E5066;
}
td {
text-align: center;
background: #FFFFFF;
vertical-align: middle;
font-weight: 300;
font-size: 18px;
text-shadow: -1px -1px 1px rgba(0, 0, 0, 0.1);
border-right: 1px hidden #C1C3D1;
}
tr:hover a {
text-decoration: none;
color: white;
}
tr a {
text-decoration: none;
color: black;
}
tr.header {
display: table-row;
}
.rounded-list label {
position: relative;
display: block;
padding: .4em .4em .4em 2em;
*padding: .4em;
margin: .5em 0;
background: #ddd;
color: #444;
text-decoration: none;
border-radius: .3em;
}
button {
position: relative;
display: block;
margin: .5em 0;
background: #87ceeb;
color: #444;
text-decoration: none;
border-radius: .5em;
}
.rounded-list label:hover,
button {
background: #eee;
}
.rounded-list label:before {
content: counter(li);
counter-increment: li;
position: absolute;
left: -1.3em;
top: 50%;
margin-top: -1.3em;
background: #87ceeb;
height: 2em;
width: 2em;
line-height: 2em;
border: .3em solid #fff;
text-align: center;
font-weight: bold;
border-radius: 2em;
transition: all .3s ease-out;
}
#name,
#loc:focus {
outline: 0px solid transparent;
}
#tableheader {
cursor: default;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableData">
<thead>
<tr id="tableheader">
<th>NODE ID</th>
<th>VENDOR</th>
<th>PRODUCT ID</th>
<th>PRODUCT TYPE</th>
<th>HOME ID</th>
<th>SECURE</th>
</tr>
</thead>
<tbody id="tableBody">
</tbody>
<div id="divTemplate">
<ol class="rounded-list">
<li><label>ID: <input id="roomName"/></label></li>
<li><label>LOC. NAME: <input id="loc"/></label></li>
<li><label>EPID: <span id="epid"></span></label></li>
<li><label>CLSLIST: <span id="clslist"></span></label></li>
<li><label>TYPE: <span id="type"></span></label></li>
<li><label>ZPLUS: <span id="zplus"></span></label></li>
<button onclick="submitData();">Submit changes</button>
</ol>
</div>

It's better to separate your code into functions that each handle a task.
You're using jQuery, so use jQuery.
Store the index of the data object into each tr, that way you can update the template div using the object from endpointsData of that same index. A data-index will be perfect.
Put the template div inside a tr in HTML instead of doing it in JS.
Here it is:
function createRow(object, index) { // this function takes an object and its index from the data array and then creates a tr for it
return $("<tr>").append( // create a tr
$.map(object, function(value) { // and fill it
return $("<td>").text(value); // with each value from the object mapped into a td
})
).addClass("header") // then add the class header to it
.data("index", index); // and store the index of the object as data-index so it can be used to fill the template when the tr is clicked
}
function populateTable(data) { // this function takes an array of data object and fill the table with trs
$("#tableBody").append( // fill the table
$.map(data, createRow) // with each object from the array mapped into a tr using createRow
);
}
function updateTemplate(object) { // this function takes an object and fill the template with its values
$.each(["epid", "clslist", "type", "zplus"], function(index, key) { // for each key in the array ...
$('#' + key).text(object[key]); // fill the template with values from the object
});
}
var $templateRow = $("#templateRow"); // template row that contain the template div
$("#tableBody").on("click", "tr.header", function() { // when a .header row is clicked (using event delegation as the rows are still not generated yet)
updateTemplate(endpointsData[$(this).data("index")]); // get the object from endpointsData using the index of the current tr (stored eariler as data-index) and then pass it to updateTemplate so the template is updated with newer values
$templateRow.toggle(); // toggle the visibility of the template row (hide it if visible, show it otherwise)
$templateRow.insertAfter(this); // put the template row right after the currently clicked row
});
populateTable(data); // populate the table
Working code snippett:
var data = [{"nodeid":1,"vendor":"0x0345","product_id":"0x0201","product_type":"0x0008","home_id":"0xD087E344","secure":"1"},{"nodeid":2,"vendor":"0x0285","product_id":"0x0777","product_type":"0x0001","home_id":"0xD087D213","secure":"0"},{"nodeid":3,"vendor":"0x1145","product_id":"0x7899","product_type":"0x0851","home_id":"0xD034T13","secure":"0"},{"nodeid":4,"vendor":"0x8992","product_id":"0x1236","product_type":"0x8101","home_id":"0xD0682F13","secure":"1"}];
var endpointsData = [{"epid":1,"clslist":"5f","type":"0x02,0x01","zplus":"0x00,0x00,0x00,0x0000,0x0000"},{"epid":2,"clslist":"20,5e,72,86,59,73,5a,8f,98,7a,80,71,85,5c,70,30,31,84","type":"0x07,0x01","zplus":"0x01,0x00,0x06,0x0c07,0x0c07"},{"epid":3,"clslist":"20,5e,72,86,59,73,5a,8f,98,7a,80,71,85,5c,70,30,31,84","type":"0x07,0x01","zplus":"0x01,0x00,0x06,0x0d01,0x0d01"},{"epid":4,"clslist":"134,547,843,122","type":"2x07,0x01","zplus":"3x44,0x0d01,0x1ed01"}];
function createRow(object, index) {
return $("<tr>").append(
$.map(object, function(value) {
return $("<td>").text(value);
})
).addClass("header")
.data("index", index);
}
function populateTable(data) {
$("#tableBody").append(
$.map(data, createRow)
);
}
function updateTemplate(object) {
$.each(["epid", "clslist", "type", "zplus"], function(index, key) {
$('#' + key).text(object[key]);
});
}
var $templateRow = $("#templateRow");
$("#tableBody").on("click", "tr.header", function() {
updateTemplate(endpointsData[$(this).data("index")]);
$templateRow.toggle();
$templateRow.insertAfter(this);
});
populateTable(data);
th { white-space: nowrap; color: #D5DDE5; background: #1b1e24; border-bottom: 4px solid #9ea7af; border-right: 1px solid #343a45; font-size: 23px; font-weight: 100; padding: 24px; text-align: left; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); vertical-align: middle; } tr { border-top: 1px solid #C1C3D1; border-bottom-: 1px solid #C1C3D1; color: #666B85; font-size: 16px; font-weight: normal; text-shadow: 0 1px 1px rgba(256, 256, 256, 0.1); cursor: pointer; } /*grey row*/ tr:hover td { background: #4E5066; color: #FFFFFF; border-top: 1px solid #22262e; } tr:nth-child(odd) td { background: #EBEBEB; } tr:nth-child(odd):hover td { background: #4E5066; } td { text-align: center; background: #FFFFFF; vertical-align: middle; font-weight: 300; font-size: 18px; text-shadow: -1px -1px 1px rgba(0, 0, 0, 0.1); border-right: 1px hidden #C1C3D1; } tr:hover a { text-decoration: none; color: white; } tr a { text-decoration: none; color: black; } tr.header { display: table-row; } .rounded-list label { position: relative; display: block; padding: .4em .4em .4em 2em; *padding: .4em; margin: .5em 0; background: #ddd; color: #444; text-decoration: none; border-radius: .3em; } button { position: relative; display: block; margin: .5em 0; background: #87ceeb; color: #444; text-decoration: none; border-radius: .5em; } .rounded-list label:hover, button { background: #eee; } .rounded-list label:before { content: counter(li); counter-increment: li; position: absolute; left: -1.3em; top: 50%; margin-top: -1.3em; background: #87ceeb; height: 2em; width: 2em; line-height: 2em; border: .3em solid #fff; text-align: center; font-weight: bold; border-radius: 2em; transition: all .3s ease-out; } #name, #loc:focus { outline: 0px solid transparent; } #tableheader { cursor: default; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableData">
<thead> <tr id="tableheader"> <th>NODE ID</th> <th>VENDOR</th> <th>PRODUCT ID</th> <th>PRODUCT TYPE</th> <th>HOME ID</th> <th>SECURE</th> </tr> </thead>
<tbody id="tableBody">
<tr id="templateRow" style='display: none;'>
<td colspan='6'>
<div id="divTemplate">
<ol class="rounded-list">
<li><label>ID: <input id="roomName"/></label></li>
<li><label>LOC. NAME: <input id="loc"/></label></li>
<li><label>EPID: <span id="epid"></span></label></li>
<li><label>CLSLIST: <span id="clslist"></span></label></li>
<li><label>TYPE: <span id="type"></span></label></li>
<li><label>ZPLUS: <span id="zplus"></span></label></li>
<button onclick="submitData();">Submit changes</button>
</ol>
</div>
</td>
</tr>
</tbody>
<table>

Related

How to use Get-EventLog, Convert-ToHTML and add a javascript search box to filter entries?

Edit: added a screenshot for Santiago of the HTML event viewer
To describe what I am trying to do. Note: in the meantime, I use ctrl f which is still way quicker than the Windows event viewer on a slow server.
I want to use PowerShell's Get-EventLog (done)
Convert the system event log into a nicely formatted HTML File (done)
Enable the ability to search the HTML generated EventLog data with a JavaScript
search box that will essentially filter the data as you might with
the filter functions in an Excel Spreadsheet (not yet working in
Get-EventLog.ps1)
I have a test script where this works because I set the document.getElementByID, - table = document.getElementById("myTable"); - creating the html table myself and setting the ID. I'm not able to use the same function to grab the ID of the EventLog info to apply the same principle
Artefacts:
The working search function from Convert-toHTML-and-Search-Test.htm
#------------------------------------------------#
# Convert to HTML and Search #
#------------------------------------------------#
# Version 1 #
$TESTCSSbody = #"
<h1>Type in a value from the table below to search</h1>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search..." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:auto;">Hostname</th>
<th style="width:auto;">DomainName</th>
<th style="width:auto;">ServerRole</th>
<th style="width:auto;">ServerDescription</th>
<th style="width:auto;">MaintenanceWindow</th>
<th style="width:auto;">PatchingStatus</th>
</tr>
<tr>
<td>Server1</td>
<td>Domain1</td>
<td>Role</td>
<td>Domain Controller</td>
<td>MaintenanceW1</td>
<td>Patched</td>
</tr>
<tr>
<td>Server2</td>
<td>Domain2</td>
<td>Role</td>
<td>Domain Controller</td>
<td>MaintenanceW2</td>
<td>Pending</td>
</tr>
<tr>
<td>Server3</td>
<td>Domain3</td>
<td>Role</td>
<td>Domain Controller</td>
<td>MaintenanceW3</td>
<td>Failed</td>
</tr>
</table>
<script>
function myFunction() {
var input, filter, table, tr, td, i, ii;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.querySelectorAll("tbody tr:not(.header)");
for (i = 0; i < tr.length; i++) {
var tds = tr[i].getElementsByTagName("td");
var found = false;
for (ii = 0; ii < tds.length && !found; ii++) {
if (tds[ii].textContent.toUpperCase().indexOf(filter) > -1) {
found = true;
break;
}
}
tr[i].style.display = found?"":"none";
}
}
</script>
<style>
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 20%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable { width: auto; border: 1px solid #ddd; font-size: 18px;}
#myTable th, #myTable td { text-align: left; padding: 12px; }
#myTable tr { border-bottom: 1px solid #ddd; }
#myTable tr.header, #myTable tr:hover { background-color: #c4c4c4;
}
h1 { text-align: left; font-size: 20pt; font-family: Calibri; }
h5, th { text-align: left; font-size: 14pt; font-family: Calibri; }
table { width: auto; font-family: Calibri; box-shadow: 5px 5px 5px #888; border: thin ridge grey; }
th { background: black; color: white; max-width: 400px; padding: 5px 10px; }
td { font-size: 11pt; padding: 5px 20px; color: black; }
tr { background: #b8d1f3; }
tr:nth-child(even) { background: white; }
tr:nth-child(odd) { background: #f1f1f1; }
tr:hover {background-color: #ddd;}
</style>
"#
#HTML Report info
$SEARCHTESTREPORT = "C:\htmlreports\ConvertToHTML-and-Search-Test.htm"
$SEARCHTESTREPORTtitle = "TESTING SEARCH FUNCTIONALITY"
ConvertTo-Html -Body $TESTCSSbody -Title $SEARCHTESTREPORTtitle |
#Output the HTML File to $HTMLREPORT
Out-File $SEARCHTESTREPORT
start $SEARCHTESTREPORT
Get-EventLog.ps1
#----------------------------------------------------------------------------#
# This script produces the Windows Event Viewer in HTML #
#----------------------------------------------------------------------------#
#HTML Report info
$HTMLREPORT = "C:\Get-EventLog\eventlogreport.htm"
$HTMLREPORTtitle = "Event Log Report"
#Apply CSS Formatting
$CSSbody = #"
<h1>Event Viewer</h1>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search..." title="Type in a name">
<script>
function myFunction() {
var input, filter, table, tr, td, i, ii;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.querySelectorAll("tbody tr:not(.header)");
for (i = 0; i < tr.length; i++) {
var tds = tr[i].getElementsByTagName("td");
var found = false;
for (ii = 0; ii < tds.length && !found; ii++) {
if (tds[ii].textContent.toUpperCase().indexOf(filter) > -1) {
found = true;
break;
}
}
tr[i].style.display = found?"":"none";
}
}
</script>
<style>
#myInput {
background-position: 10px 10px;
background-repeat: no-repeat;
width: 20%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable { width: auto; border: 1px solid #ddd; font-size: 18px;}
#myTable th, #myTable td { text-align: left; padding: 12px; }
#myTable tr { border-bottom: 1px solid #ddd; }
#myTable tr.header, #myTable tr:hover { background-color: #c4c4c4;
}
h1 { text-align: left; font-size: 20pt; font-family: Calibri; }
h5, th { text-align: left; font-size: 11; font-family: Calibri; }
table { width: auto; font-family: Calibri; box-shadow: 5px 5px 5px #888; border: thin ridge grey; }
th { background: #00078A; color: white; max-width: 400px; padding: 5px 10px; }
td { font-size: 11pt; padding: 5px 20px; color: black; }
tr { background: #b8d1f3; }
tr:nth-child(even) { background: white; }
tr:nth-child(odd) { background: #f1f1f1; }
tr:hover {background-color: #ddd;}
</style>
"#
#EntryTypes:
#-EntryType Error, FailureAudit, Information, SuccessAudit, Warning
#Lognames
#-Logname Application, Security, Setup, System
#$Begin = Get-Date -Date 01/01/2021 08:00:00
#$End = Get-Date -Date 04/02/2021 16:00:00
Get-EventLog -LogName System -Newest 100 |
Select -Property EventID,Source,MachineName,EntryType,Message,TimeGenerated,UserName |
ConvertTo-Html -Body $CSSbody -Title $HTMLREPORTtitle |
#Output the HTML File to $HTMLREPORT
Out-File $HTMLREPORT
start $HTMLREPORT

Why img inside a button with onclick not trigger the script?

I have a button with onclick. There is an image inside of the button but its not trigger the script.
function myFunction1() {
document.getElementById("rightdrop02").classList.toggle("show");
}
window.addEventListener('click', function(event) {
if (!event.target.matches('.rightmenubtn02')) {
var dropdowns = document.getElementsByClassName("right_content02");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
});
body {
background-color: limegreen;
}
.rightmenubtn01,
.rightmenubtn02,
.rightmenubtn03,
.rightmenubtn04,
.rightmenubtn05 {
border: none;
cursor: pointer;
color: white;
font-family: "focim";
font-size: 17px;
width: 100%;
line-height: 38px;
text-align: left;
padding-left: 20px !important;
border-bottom: solid 1px white;
background-color: transparent;
}
.right_content02,
.right_content03 {
display: none;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
z-index: 1;
}
.right_content02 a,
.right_content03 a {
border-bottom: solid 1px #00765a;
}
.right_content02 a,
.right_content03 a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.rightmenu01 a:hover,
.rightmenu02 a:hover,
.rightmenu03 a:hover,
.rightmenu04 a:hover,
.rightmenu05 a:hover {
background-color: #ddd;
}
.show {
display: block;
}
.right_img button:focus {
outline: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.right_img button:hover {
background-color: rgba(255, 255, 255, 0.3);
}
.right_img img {
float: right;
padding: 6px 16px 6px 0;
}
.right_img button {
padding: 0;
padding-left: 10px;
border-radius: 0;
}
<div class="right_img">
<div class="rightmenu02">
<button onclick="myFunction1()" class="rightmenubtn02">Button<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAA81BMVEX////eAADwe4mNGCX9ASD/AADdAAUYGBj5w8zhFxoIAAArKyvaAADEABapFxn/ASU9S0qNGCH/HCEzMzMkJCSpFx75AAD+DxI7OzudGCj/AAmpGCn/ABm/GCt8FyTOARn0mqT6zNf+8Pbta3Ltd4TmMDoiFxfob3Lwnq7tiJDkSU7cBw/iMT/qeHfnVVqDg4NKSkpyb299fHyioqKPj4+0tLQaGhoODg5PT09hYWEcJCIVAAAUIRuzAAjCAAlednRKXFoJGBczQkHpQ1XsTWaLFxf0pKpxLDRyGiT72Nv3uL3kGyr83eL4r7rqWGHubHjoMETZSe+SAAABc0lEQVQokZWR6XKCMBSFE4EABQsoIi6tu5aGKqjFtVbRauvS9v2fpjEBdWz/9M5kTnK+ycmdXADAJsdxnGFwrI76bmwArZzGa0XLymo8zxO1snzy1mCI42WMlqsGlmWE3NVShljOxUhVWwA4ECNcJueKC4sFhoyiWyeSgAitqVFtWBF6S1FJQPhNbEciAVYmQlr5UKXoCwBJ/QRgm83EbyFZitFWbQNwOCMVS3FgBdYuAk+3EEqA6nYPpF22cIUwdKmxVovXCO4+yC2yar8CaYe49meHTtThPnX7D0QC90vyjdJlYIWiBjNA3bpGGNaqR0OS86fmMW4/tVwsY/XReSi3sMoX4ilrmiAI+eOwBYHutDuG7kvJc81ms2TypRRNuTm5ocVkQmQ6aTI0DvVQn+vjha6Hob6Y6vNXfcyQ2e/1e6PnfuD3On7Xszu+3/cYCjzPtoOhZ4/sdNc3lbSiDE2GlEEgimIgmqYYpBWyCYKBQvwf4QQtRo/eO0oAAAAASUVORK5CYII="></button>
<div id="rightdrop02" class="right_content02">
Dropdown01
Dropdown02
Dropdown03
Dropdown04
Dropdown05
Dropdown06
</div>
</div>
</div>
The img is not the original one because its from a private site. Stripped the html so its less complicated but the css is the same. I also know my code is awful, no need to remind me...
When you click the image, the event target is the image, not the button. You have to fix the condition in order to get that to work:
if (!event.target.matches('.rightmenubtn02') &&
!event.target.matches('.rightmenubtn02 img')) {
https://jsfiddle.net/swynmuat/
The condition now checks not only for the button but for the image inside the button as well.

Hide table header without seach input using HTML/CSS/JavaScript

I'm trying to create a table with a header, which is completely hidden without any input. I have the following code, but the header is still visible. I have tried many, many different options, but I can't seem to be able to hide the header when the search input is empty.
Detail: I can't use jQuery.
To add: I have searched and tried for 3 days now (I have zero education on this matter). I have read a lot of posts and websites.
The thing is that I have to add it to a HTML macro. The weird thing is that for instance var tr = getElementsByTagName("tr"); is not replaceable by var tr = table.rows. When I enter this in the function, it doesn't render what it normally renders. So it could be I did already find the answer, but it's purely the macro causing the issue.
The following code is working, but displays the header:
a) Javascript
document.addEventListener('DOMContentLoaded', function () {
if (document.getElementById("myInput").value.length > 1) {
document.getElementById("header").className= "hideHeader";
} else {
ContactsearchFX();
document.getElementById('myInput').addEventListener('input', ContactsearchFX);
}
});
function ContactsearchFX() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 1; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td"),
match = false;
for (j = 0; j < td.length; j++) {
if (filter && td[j].textContent.toUpperCase().indexOf(filter) > -1) {
match = true;
break;
}
}
if (!match) {
tr[i].style.display = "none";
} else {
tr[i].style.display = "";
}
}
}
b) HTML
<br>
<img src="www.example.com/somebanner.png" class="centered">
<br>
<input class="form-control" style="width:40%" type="search" id="myInput" placeholder="Enter keywords here...">
<table id="myTable">
<tr class="header">
<th style="width:20%;">One</th>
<th style="width:20%;">Two</th>
<th style="width:20%;">Three</th>
<th style="width:60%;">Four</th>
</tr>
<tr>
<td>aaaa</td>
<td>bbbb</td>
<td>cccc</td>
<td>dddd</td>
</tr>
<tr>
<td>eeee</td>
<td>ffff</td>
<td>gggg</td>
<td>hhhh</td>
</tr>
<tr>
<td>iiii</td>
<td>jjjj</td>
<td>kkkk</td>
<td>llll</td>
</tr>
</table>
c) CSS
.hideHeader {
position: fixed;
display: none;
}
.centered {
display: block;
margin-left: auto;
margin-right: auto;
width: 18%;
}
.form-control {
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 200px;
width: 18%;
-webkit-box-shadow: 0 8px 6px -6px black;
-moz-box-shadow: 0 8px 6px -6px black;
box-shadow: 0 8px 6px -6px black;
}
#myInput{
width: 100%;
font-size: 14px;
padding: 14px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 75px;
align: center;
}
#myTable{
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 14px;
margin-top: 75px;
}
#myTable th,
#myTable td {
text-align: left;
padding: 12px;
font-size: 12px;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
margin-top: 12px;
background-color: #f1f1f1;
font-size: 14px;
}
define the class in css :
.hideHeader {
display: none;
}
add it to the header in html :
<tr class="header hideHeader">
and then use Js to remove and return the class to the header :
var table = document.getElementById("myTable");
var tableHeader = table.getElementsByClassName("header")[0];
if (input.value.length > 0) {
if (tableHeader.classList.contains("hideHeader")) {
tableHeader.classList.remove("hideHeader");
}
} else {
if (!tableHeader.classList.contains("hideHeader")) {
tableHeader.classList.add("hideHeader");
}
}
here is the whole code :
document.addEventListener('DOMContentLoaded', function() {
if (document.getElementById("myInput").value.length > 1) {
document.getElementById("header").className = "hideHeader";
} else {
ContactsearchFX();
document.getElementById('myInput').addEventListener('input', ContactsearchFX);
}
});
function ContactsearchFX() {
var input, filter, table, tr, td, i;
var input = document.getElementById("myInput");
var table = document.getElementById("myTable");
var filter = input.value.toUpperCase();
var tr = table.getElementsByTagName("tr");
var tableHeader = table.getElementsByClassName("header")[0];
if (input.value.length > 0) {
if (tableHeader.classList.contains("hideHeader")) {
tableHeader.classList.remove("hideHeader");
}
} else {
if (!tableHeader.classList.contains("hideHeader")) {
tableHeader.classList.add("hideHeader");
}
}
for (i = 1; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td"),
match = false;
for (j = 0; j < td.length; j++) {
if (filter && td[j].textContent.toUpperCase().indexOf(filter) > -1) {
match = true;
break;
}
}
if (!match) {
tr[i].style.display = "none";
} else {
tr[i].style.display = "";
}
}
}
.hideHeader {
display: none;
}
.centered {
display: block;
margin-left: auto;
margin-right: auto;
width: 18%;
}
.form-control {
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 200px;
width: 18%;
-webkit-box-shadow: 0 8px 6px -6px black;
-moz-box-shadow: 0 8px 6px -6px black;
box-shadow: 0 8px 6px -6px black;
}
#myInput {
width: 100%;
font-size: 14px;
padding: 14px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 75px;
align: center;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 14px;
margin-top: 75px;
}
#myTable th,
#myTable td {
text-align: left;
padding: 12px;
font-size: 12px;
}
#myTable tr.header,
#myTable tr:hover {
margin-top: 12px;
background-color: #f1f1f1;
font-size: 14px;
}
<br>
<img src="http://www.atelierdecoz.fr/img/cms/thunderbird-logo-200x200.png" class="centered">
<br>
<input class="form-control" style="width:40%" type="search" id="myInput" placeholder="Enter keywords here...">
<table id="myTable">
<tr class="header hideHeader">
<th style="width:20%;">One</th>
<th style="width:20%;">Two</th>
<th style="width:20%;">Three</th>
<th style="width:60%;">Four</th>
</tr>
<tr>
<td>aaaa</td>
<td>bbbb</td>
<td>cccc</td>
<td>dddd</td>
</tr>
<tr>
<td>eeee</td>
<td>ffff</td>
<td>gggg</td>
<td>hhhh</td>
</tr>
<tr>
<td>iiii</td>
<td>jjjj</td>
<td>kkkk</td>
<td>llll</td>
</tr>
</table>

Stying in React-tag-input

I am using "React-tag-input" react-tag-input.
But can't find how to do styling of react-tag-input
my code looks like this
import { WithContext as ReactTags } from 'react-tag-input';
const App = React.createClass({
getInitialState() {
return {
tags: [],
suggestions: []
}
},
handleDelete(i) {
let tags = this.state.tags;
tags.splice(i, 1);
this.setState({tags: tags});
},
handleAddition(tag) {
let tags = this.state.tags;
tags.push({
id: tags.length + 1,
text: tag
});
this.setState({tags: tags});
},
handleDrag(tag, currPos, newPos) {
let tags = this.state.tags;
tags.splice(currPos, 1);
tags.splice(newPos, 0, tag);
this.setState({ tags: tags });
},
render() {
let tags = this.state.tags;
let suggestions = this.state.suggestions;
return (
<div>
I am looking for styling in ReactTags
<ReactTags tags={tags}
suggestions={suggestions}
handleDelete={this.handleDelete}
handleAddition={this.handleAddition}
handleDrag={this.handleDrag} />
</div>
)
}
});
ReactDOM.render(<App />, document.getElementById('app'));
Can you guide me, how to do styling in this??
You can use CSS. From the documentation:
<ReactTags> does not come up with any styles. However, it is very easy to customize the look of the component the way you want it. By default, the component provides the following classes with which you can style -
ReactTags__tags
ReactTags__tagInput
ReactTags__tagInputField
ReactTags__selected
ReactTags__selected ReactTags__tag
ReactTags__selected ReactTags__remove
ReactTags__suggestions
So, if you want to change the background of a tag, you could do something like this in your CSS:
.ReactTags__tag {
background-color: red;
}
/* Example Styles for React Tags*/
#app {
padding: 40px;
}
div.ReactTags__tags {
position: relative;
}
/* Styles for the input */
div.ReactTags__tagInput {
width: 200px;
border-radius: 2px;
display: inline-block;
}
div.ReactTags__tagInput input.ReactTags__tagInputField,
div.ReactTags__tagInput input.ReactTags__tagInputField:focus {
height: 31px;
margin: 0;
font-size: 12px;
width: 100%;
border: 1px solid #eee;
padding: 0 4px;
}
/* Styles for selected tags */
div.ReactTags__selected span.ReactTags__tag {
border: 1px solid #ddd;
background: #eee;
font-size: 13px;
display: inline-block;
padding: 6px;
margin: 0 5px 5px 5px;
cursor: default !important;
border-radius: 2px;
}
div.ReactTags__selected a.ReactTags__remove {
color: #9c9c9c;
margin-left: 5px;
cursor: pointer;
}
/* Styles for suggestions */
div.ReactTags__suggestions {
position: absolute;
color: #000 !important;
font-weight: normal !important;
font-size: 14px !important;
}
div.ReactTags__suggestions ul {
list-style-type: none;
box-shadow: .05em .01em .5em rgba(0,0,0,.2);
background: white;
width: 200px;
}
div.ReactTags__suggestions li {
border-bottom: 1px solid #ddd;
padding: 15px 10px;
margin: 0;
}
div.ReactTags__suggestions li mark {
text-decoration: underline;
background: none;
font-weight: 600;
}
div.ReactTags__suggestions ul li.ReactTags__activeSuggestion {
background: #b7cfe0;
cursor: pointer;
}

Drop down with a custom template + search + Add new (always on top)

Edit
I am open to any way to achieve this requirement as far as it works on IE-8+
Original
I am implementing custom template of typeahead, but I would like to add a always on top suggestion,
http://twitter.github.io/typeahead.js/examples/#custom-templates
Like this,
This is what I have tried so far,
http://jsfiddle.net/tvp9Q/172/
Markup
<div class="outer">
<input type="text" class="form-control typeahead" placeholder="Typeahead . . ." />
<p id="selected"></p>
</div>
JS
var selected = [];
var select = function(e, datum, dataset) {
selected.push(datum.FirstName);
$("#selected").text(JSON.stringify(selected));
$("input.typeahead").val("");
}
var filter = function(suggestions) {
return $.grep(suggestions, function(suggestion) {
return $.inArray(suggestion.FN, selected) === -1;
});
}
var data = new Bloodhound({
name: 'animals',
local: [{ "FirstName": "Tom", "LastName" : "Fire", "FN" : "T Fire - myEmail#google.com" }],
datumTokenizer: function(d) {
return Bloodhound.tokenizers.whitespace(d.FN);
},
queryTokenizer: Bloodhound.tokenizers.whitespace
});
data.initialize();
$('input.typeahead').typeahead(null,
{
name: 'animals',
displayKey: 'FN',
/* don't use
source: data.ttAdapter(), */
source: function(query, cb) {
data.get(query, function(suggestions) {
cb(filter(suggestions));
});
},
templates: {
empty: '<div class="empty-message">No matches.</div>'
}
}
).bind('typeahead:selected', select);
CSS
div.outer {
padding: 5%;
}
#selected {
margin-top: 5%;
}
.tt-hint {
color: #999
}
.tt-dropdown-menu {
font-weight: lighter;
width: 100%;
margin-top: -6px;
padding: 8px 0;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
max-height: 150px;
overflow-y: auto;
}
.tt-suggestion {
padding: 3px 20px;
font-size: 18px;
line-height: 24px;
}
.tt-suggestion.tt-cursor, .tt-suggestion.tt-cursor small {
color: #fff;
background-color: #0097cf;
}
.tt-suggestion p {
margin: 0;
}
.twitter-typeahead {
top: 8px;
width: 100%;
}
.empty-message {
padding-left: 12px;
}
Update typehead from 0.10.2 to latest and now its not working at all now...
http://jsfiddle.net/tvp9Q/188/

Categories

Resources