Unable to populate a list of data into table dynamically - javascript

Functionality:
I have a String of data =>("A, 4.0. 00:04#B,5.0,00:05#C,9.0,00:09#......"). The String will be split into individual element, and the individual element will be appended to the tag in the table. Whereby, it will look like:
A 00:04
B 00:05
C 00:09
....
G 00:29
Issue:
Currently, the entire table just looks like this:
G 00:29
2.
3.
.....
10.
Hence, the last value of the data is just appended to the first row of the table.
I am not sure if this is the correct method of populating the within the . Please help.
Code:
console.log("Leaderboard: " + data);
var playerList = data.split("#");
var innerList;
for (i = 0; i < playerList.length; i++) {
innerList = playerList[i].split(",");
console.log(innerList[0] + "|" + innerList[1] + "|" + innerList[2]);
//innerList[0] ==> A to be appended to Player_Name
//innerList[1] ==> 4.0 not needed to be appended
//innerList[2] ==> 00:04 to be appended to Player_Score
$("#Player_Name").html(innerList[0]);
$("#Player_Score").html(innerList[2]);
}
#Rugby_Scoreboard {
position: absolute;
left: 335px;
top: 182px;
width: 825px;
height: 818px;
border-spacing: 5px;
border-collapse: collapse;
}
<!-- ScoreBoard -Table form-->
<div id="Game_LeaderBoard" style="position:absolute; z-index:6; top:0px; left:0px; width: 1920px; heigth: 1000px; margin:auto;">
<table id="Rugby_Scoreboard">
<tr>
<td>
<div id="Player_Name" style="z-index:50; position:absolute; top:5px; left:150px; font-size:40px; font-family:'OpenSans-Light'; width:1080; color:#fff;">
<font face="OpenSans-Light"></font>
</div>
</td>
<td>
<div id="Player_Score" style="z-index:50; position:absolute; top:5px; left:700px; font-size:40px; font-family:'OpenSans-Light'; width:1080; color:#fff;">
<font face="OpenSans-Light"></font>
</div>
</td>
</tr>
</table>
</div>

You can use destructuring assignment and trailing comma to exclude 4.0 from result of .split(), use multiple selectors at jQuery(), call .html(function) to set html of both elements
var data = "A,4.0,00:04#B,5.0,00:05#C,9.0,00:09";
console.log("Leaderboard: " + data);
var playerList = data.split("#");
console.log(playerList)
var innerList;
for (i = 0; i < playerList.length; i++) {
var [name,,score] = playerList[i].split(",");
//innerList[0] ==> A to be appended to Player_Name
//innerList[1] ==> 4.0 not needed to be appended
//innerList[2] ==> 00:04 to be appended to Player_Score
$("#Player_Name, #Player_Score")
.html(function(index, html) {
var prop = index === 0 ? name : score;
return html + prop + "<br>"
})
}
/*
#Rugby_Scoreboard {
position: absolute;
left: 335px;
top: 182px;
width: 825px;
height: 818px;
border-spacing: 5px;
border-collapse: collapse;
}
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- ScoreBoard -Table form-->
<div id="Game_LeaderBoard" style="">
<table id="Rugby_Scoreboard">
<tr>
<td>
<div id="Player_Name" style="">
<font face="OpenSans-Light"></font>
</div>
</td>
<td>
<div id="Player_Score" style="">
<font face="OpenSans-Light"></font>
</div>
</td>
</tr>
</table>
</div>

All this code is doing is replacing the contents of a set of elements.
With this part inside the loop:
$("#Player_Name").html(innerList[0]);
$("#Player_Score").html(innerList[2]);
You're replacing the same contents over and over.
If you want each of the values to show in the table, you need to create new <tr> elements and append them to the end of the <table> element.
$('#Rugby_Scoreboard').append('<tr><td><div id="Player_Name_' + innerList[0] + '">' +
innerList[2] +
'</div></td></tr>`);

Related

Save content editable HTML table in multiple fields

I need to develop a HTML table where one of the table column is editable on its row and the table row is dynamic in term of the row number.
I come across a problem where when I automate the saveEdits() function, the code is not working.
Here is my code, where the 'cnt' is a dynamic numeric number. Example cnt=50
<!DOCTYPE html>
<html>
<head>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
table ,tr td{
border:1px solid #dddddd;
padding: 8px;
}
tbody {
display:block;
height:600px;
overflow:auto;
}
thead, tbody tr {
display:table;
width:100%;
table-layout:fixed;
}
thead {
width: calc( 100% - 1em )
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
<script type="text/javascript">
function saveEdits(cnt) {
//get the editable elements.
var str_out = ''
while (cnt>0){
str1 = '\'edit' + cnt + '\': document.getElementById(\'edit' + cnt + '\').innerHTML,\n'
str_out = str_out.concat(' ', str1);
cnt--;
};
var editElems= { str_out };
alert(editElems)
//save the content to local storage. Stringify object as localstorage can only support string values
localStorage.setItem('userEdits', JSON.stringify(editElems));
}
function checkEdits(){
//find out if the user has previously saved edits
var userEdits = localStorage.getItem('userEdits');
alert(userEdits) // suppose to print {"edit1":" rpeyy7<br>","edit2":" tpruiiy<br>","edit3":" opty<br>"}
if(userEdits){
userEdits = JSON.parse(userEdits);
for(var elementId in userEdits){
document.getElementById(elementId).innerHTML = userEdits[elementId];
}
}
}
</script>
</head>
<body onload="checkEdits()">
<table id="myTable">
<thead>
<tr>
<td style="background-color:#A9A9A9" > Field#1 </td>
<td style="background-color:#A9A9A9" > Field#2 </td>
<td style="background-color:#A9A9A9" > Field#3- Each Row Under field#3 is content EditableByUser </td>
</tr>
</thead>
<tbody>
// Here is the python code that loop through a diectionary content
cnt = 0
for c in sorted(data_dict.keys()) :
cnt += 1
<tr>
<td> {0} </td> //Field#1
<td> {0} </td> //Field#2
...
...
<td id="edit{0}" contenteditable="true" onKeyUp="saveEdits({0});"> {1} </td>\n'.format(cnt,comment)]
</tr>
</table>
</body>
I'm not sure where goes wrong as when I automate the saveEdits() function with 'cnt' in while loop, the above code doesn't works for me. But when I defined each row clearly like below, the data the keyed-in are properly saved to each column.
function saveEdits(cnt) {
//get the editable elements.
var editElems = {
'edit1': document.getElementById('edit1').innerHTML,
'edit2': document.getElementById('edit2').innerHTML,
'edit3': document.getElementById('edit3').innerHTML,
};
alert(editElems) //print [object Object]
//save the content to local storage. Stringify object as localstorage can only support string values
localStorage.setItem('userEdits', JSON.stringify(editElems));
}
I would be much appreciate if someone can point out my mistake. The error is very much likely on saveEdits(cnt) function but I'm not sure how to fix that cause it I define each count 1 by 1, each update that being keyed-in is actually saved properly and able to retrieve when rerun. Thanks you!

Hide/show div based on search input

I have worked out some javascript to use my search bar in order to filter/hide things that don't match the search input. I've got it working about 95% I would say but I have one problem to fix.
So my page displays furniture groups and their containing pieces of furniture. The group name/number and description exists as a heading div and below that there is a table created with the actual pieces of furniture. My current javascript works as long as I'm typing 'sofa' or 'chair' which would be in the table row. However, If I type the name of a furniture group, it just shows the name/number/description and images, but hides the table. The group names/descriptions are in this block:
#foreach ($orderFormData->pgroups as $pgroup)
<div class="group-container">
<h3 style="font-size: 26px; padding: 10px 0;">{{ $pgroup->group_name
}} - {{ $pgroup->group_code }}</h3>
<p class="uk-text-muted" style="font-size: 20px;" >{!!
html_entity_decode($pgroup->group_desc) !!}</p>
So, I need to try and slightly refactor this to add the functionality so that if my input matches the group name or description, it still shows the whole table for that div.
An idea I had was to add something like this
<script type="text/javascript">
if($('.group-container').children('tr:visible').length == 0) {
$('.group-container').hide();
} else {
$('.group-container').show();
}
</script>
Under my first line of html below, right under the foreach loop. But I don't know if that would be the right idea or how to use that exactly the way it should.
HTML:
#foreach ($orderFormData->pgroups as $pgroup)
<div class="group-container">
<h3 style="font-size: 26px; padding: 10px 0;">{{ $pgroup->group_name }} - {{ $pgroup->group_code }}</h3>
<p class="uk-text-muted" style="font-size: 20px;" >{!! html_entity_decode($pgroup->group_desc) !!}</p> <!--Group Description-->
<div class="uk-grid">
<div class="uk-width-2-10">
<ul style="margin: 0; padding: 0; list-style-type: none; float: left; width: 100%;">
#foreach ($pgroup->image_names as $image_name)
<li><a href="/imagelib/Bigthumbs/{{ substr($image_name, 0, strpos($image_name, ',')) }}" target=_blank><img src="/imagelib/Bigthumbs/{{ substr($image_name, 0, strpos($image_name, ',')) }}" style="width: 100%; height: auto;" /></a><span class="uk-text-center" style="padding: 0 0 5px;">{{ substr($image_name, strpos( $image_name, ',') + 1) }}</span></li>
#endforeach
</ul>
</div>
<div class="uk-width-8-10">
<table id="userTbl" class="uk-table" style="width: 100%; min-width: 768px;">
<thead>
<tr>
<th style="width: 10%; font-size: 20px;">Frame</th>
<th style="width: 20%; font-size: 20px;">Description</th>
<th style="width: 15%; font-size: 20px;">Cover/Color</th>
<th style="width: 15%; font-size: 20px;">Cover/Color</th>
<th style="width: 20%; font-size: 20px;">Quantity</th>
<th style="width: 15%; font-size: 20px; text-align: center;"><b>Price</b></th>
</tr>
</thead>
<tbody>
#foreach ($pgroup->pskus as $psku)
<?php $tempdata['sku-' . $i] = $psku ?>
<tr class="#if (isset($psku->quantity) && $psku->quantity > 0) {{ highlight }} #endif">
<td style="font-weight: 500; line-height: 30px; font-size: 14px;">{{ $psku->frame_fmt }}</td>
<td style="font-weight: 500; line-height: 30px; font-size: 14px;">{!! html_entity_decode($psku->frame_desc) !!}</td>
<td style="font-weight: 500; line-height: 30px; font-size: 14px;">{{ $psku->cover1_code }}/{{ $psku->color1_code }} {{ $psku->color1_desc }}</td>
<td style="font-weight: 500; line-height: 30px; font-size: 14px;">{{ $psku->cover2_code }}/{{ $psku->color2_code }} {{ $psku->color2_desc }}</td>
<td style="font-weight: 700; line-height: 30px; font-size: 14px;">
<span style="text-align: center; display: block; width: 100%;">${{ $psku->price }}</span>
</td>
</tr>
<?php $i++; ?>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
#endforeach
JS:
<script>
$(document).ready(function(){
$("#srch-term").keyup(function(){
// Retrieve the input field text and reset the count to zero
var filter = $(this).val(), count = 0;
// Loop through the main container as well as the table body and row that contains the match
$(".group-container, tbody tr").each(function(){
// If the list item does not contain the text phrase fade it out
if ($(this).text().search(new RegExp(filter, "i")) < 0) {
$(this).fadeOut();
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show();
count++;
}
});
});
});
</script>
You could search the groups first and if the name/description matches, show the whole group and all it's rows. Otherwise do the usual procedure.
<script>
$(document).ready(function(){
$("#srch-term").keyup(function(){
// Retrieve the input field text and reset the count to zero
var filter = $(this).val(), count = 0;
var search_regex = new RegExp(filter, "i")
// Loop through the main container as well as the table body and row that contains the match
$(".group-container").each(function(){
//check if filter matches the group name or description
var group_name = $(this).children('h3').text()
var group_description = $(this).children('.uk-text-muted').text()
if(group_name.search(search_regex)>=0 || group_description.search(search_regex)>=0){ // filter matches
$(this).show() // show group
$(this).find("tbody tr").show() // and all children
return // skip tr filtering
}
var no_matches = true
$(this).find("tbody tr").each(function(){
// If the list item does not contain the text phrase fade it out
if ($(this).text().search(search_regex) < 0) {
$(this).fadeOut();
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show();
count++;
no_matches = false
}
});
if(no_matches){ // if no tr matched the search either, hide whole group
$(this).fadeOut();
}
});
});
});
</script>

HTML column layout - automatically wrap div element to next column

I want an HTML layout with max 5 rows
If I have 6 items (i.e. divs) I want to wrap the 6th element in the 2nd column of 1st row
I tried the following, But can't get the 6th element in the next column.
p {
display: inline-block;
background-color:gray;
}
.wrap {
display: inline;
background-color:red;
}
<div>
<div><p>I am bla</p></div>
<div><p>Your mom</p></div>
<div><p>Test</p></div>
<div><p>Teddy</p></div>
<div><p>James</p></div>
<div><p class="wrap">John Appleseed</p></div>
</div>
Update: the Problem is that the items needs to have a flexible width, see here: https://dl.dropboxusercontent.com/u/1771956/float_html2.png
Going back some years, the Html layout was often completely built with the table element, today most layouts are not.
However, you seem to want your layout built table-like (rows, columns...) so I would not hesitate to use a table.
<table>
<tr>
<td>row 1 column 1</td>
<td>row 1 column 2</td>
</tr>
<tr>
<td>row 2 column 1</td>
</tr>
<tr>
<td>row 3 column 1</td>
</tr>
<tr>
<td>row 4 column 1</td>
</tr>
<tr>
<td>row 5 column 1</td>
</tr>
</table>
If ancient browser support is not an issue, you can make use of css3 flexible box.
#container{
display:-webkit-flex;
display:flex;
-webkit-flex-direction:column;
flex-direction:column;
-webkit-align-content:flex-start;
align-content:flex-start;
-webkit-flex-wrap:wrap;
flex-wrap:wrap;
height:500px;
background:hotpink;
}
#container div{
display:inline-block;
width:90px;
height:90px;
margin:5px;
background-color:gray;
}
.wrap {
display: inline;
background-color:red;
}
<div id='container'>
<div><p>I am blah</p></div>
<div><p>Your mom</p></div>
<div><p>Test</p></div>
<div><p>Teddy</p></div>
<div><p>James</p></div>
<div><p class="wrap">John Appleseed</p></div>
</div>
this is not a complete solution, hopefully you can tweak it according to your needs
More about css flex # css tricks
Fixed it
I used some javascript and position absolute to calculate the layout
$(function () {
// Handler for .ready() called.
var rows = 5
var items = $("#container").children()
var firstDiv = $("#container").children().eq(0)
var height = firstDiv.height()
var margin_bottom = firstDiv.outerHeight(true) - firstDiv.innerHeight()
var margin_right = firstDiv.outerWidth(true) - firstDiv.innerWidth()
var row = 0
var index = 0
items.each(function () {
var leftPos = 0
if (index >= rows) {
var siblingDiv = $("#container").children().eq(index-rows)
if (index == 10) {
}
leftPos = siblingDiv.width() + siblingDiv.position().left + margin_right
}
var topPos = ((height + margin_bottom) * row)
$(this).css('top', topPos + 'px')
$(this).css('left', leftPos + 'px')
row += 1
index += 1
if (row >= rows) {
row = 0
}
})
});
#container {
background-color:gray;
position:relative;
top: 10px;
left:0px;
height:500px;
}
.item {
background-color:green;
position:absolute;
height:50px;
top: 0px;
left:0px;
margin-right:10px;
margin-bottom:10px;
}
JSFiddle Demo
Here is my solution:
p {
display: inline-block;
background-color:gray;
}
.wrap {
display: inline-block;
background-color:red;
}
div {
float:left;
}
.clr {
clear:both;
}
<div>
<div><p>I am bla</p></div>
<div class="clr"></div>
<div><p>Your mom</p></div>
<div class="clr"></div>
<div><p>Test</p></div>
<div class="clr"></div>
<div><p>Teddy</p></div>
<div class="clr"></div>
<div><p>James</p></div>
</div>
<div><p class="wrap">John Appleseed</p></div>

JavaScript how to get this html to read this CSS and organise my script into the table

How it looks:
How I want it to look:
I have a CSS file that has a table all organised and ready my question is how do I get my script to use the table in the CSS file this is my CSS file:
/*
styles.css
*/
body{
background-color:#cecece;
color:#fff;
font-family: Arial, Tahoma, Sans-Serif;
font-size:1em;
}
h1{
color:#FF8000;
text-align:center;
}
table{
width:95%;
}
caption{
font-size:1.2em;
margin:10px;
color:#FF8000;
}
th{
width:33.333%;
font-size:1.1em;
text-align:left;
color:steelblue;
}
#output{
position:absolute;
width:50%;
height:70%;
top:15%;
left:25%;
margin:0px;
padding:10px;
font-size:.9em;
background-color:#2E2E2E;
color:ivory;
}
this is my Html document that calls the css and my script
<html lang="en">
<head>
<title>Student Grades - [Your Name]</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>
<h1>Student Grades System</h1>
<div id="output"></div>
<script src="./assignment.js"></script>
</body>
</html>
This is my JavaScript that prints everything out if u need more of the script let me know
var mytable = "<table><caption>Grading Results</caption>";
document.write(mytable);
document.write('<td><tr><th>' + "Student"+'</th><th>' + "Mark!" + '</th><th>'+"Grade" + '</th> </tr></td>');
for(var i = 0; i < markArr.length; i++){
document.write(' <tr><td>'+studentArr[i] + space1+markArr[i] + space1+gradeAwarded[i] + '</td> </th> ');
}
document.write(' </tr>');
document.write('<td>'+ "The Highest mark was : "+max+ ''+'</td> </th>');
document.write('<td>' + "The Lowest mark was : "+min+''+'</td> </th>');
document.write('<td>'+ "The Average mark was : "+average+''+'</td> </th>');
document.write('<td>' + "number A grades : "+A+''+'</td> </th>');
document.write('<td>'+ "number B grades : "+B+''+'</td> </th>');
document.write('<td>'+ "number C grades : "+C+''+'</td> </th>');
document.write('<td>'+ "number F grades : "+F+''+'</td> </th>');
document.write('</table>');
Try this
Add the code below before the for loop:
document.write('<table><caption>My Caption</caption>');
and this after the loop:
document.write('</table>');
The problem you told me happened because the <div> was closed before the <table> was created. Try this:
<div id="output">
<script src="./assignment.js"></script>
</div>
together with my code above.
Hope it works!
A HTML table generally has the format
<table>
<tr>
<th>Header1</th>
<th>Header2</th>
</tr>
<tr>
<td>Item1Row1</td>
<td>Item1Row2</td>
</tr>
<tr>
<td>Item2Row1</td>
<td>Item2Row2</td>
</tr>
</table>
Try creating a variable and build the html object as a string, then adding it to a element.
something like this:
var myTable= "<table><tr><td style='width: 100px; color: red;'>Col Head 1</td>";
myTable+= "<td style='width: 100px; color: red; text-align: right;'>Col Head 2</td>";
myTable+="<td style='width: 100px; color: red; text-align: right;'>Col Head 3</td></tr></table>";
document.getElementById('body').innerHTML = myTable
Try this
Add the code below before the for loop:
var mytable = "<table><caption>My Caption</caption>";
and this after the loop:
document.write(mytable +'</table>');
#HelloWorld, here you go. Click on CSS and JavaScript tabs to see how I set it up
http://jsbin.com/cogux/1/edit?html,output
Without knowing what assignment.js does, the main steps would be:
Create/compile a data set you can loop through
Dynamically create the table rows and data
Create the statistics area for top student, marks and number of grades (just refer to how I set up #2)
Insert table into a target element. In the case for #2 the target was the <tbody> element
I hope this helps.

jquery floating div on hover

What I have?
A html-table which has a lot of rows.
A hidden (display=none) div which contains some input controls (lets call it "div-to-display"). Only one div-to-display in whole page.
What I'm trying to do?
When the mouse hovers on the first cell in each row - show the "div-to-display" below it (like tool tip).
But, I can't create a separated div-to-display div for each table row. All cells must use the same "div-to-display" element.
While showing the div-to-display div, it should be float. What it means is that it won't change the location of the other cells in the table. It will be above them.
Do you have idea how to do this with jquery`javascript`?
DEMO: http://jsfiddle.net/sBtxq/
JQuery
// Add our div to every td
$('td').append('<div class="div-to-display">yay</div>');
CSS
.div-to-display {
display: none;
position: absolute;
top: 50%;
left: 50%;
border: 1px solid red;
background-color: #eee;
z-index: 10;
}
td {
position: relative;
}
td:hover > .div-to-display {
display: block
}
Updated (non-JS) version
CSS
td {
position: relative;
}
td:after {
display: none;
position: absolute;
top: 50%;
left: 50%;
border: 1px solid red;
background-color: #eee;
z-index: 10;
content: "yay";
}
td:hover:after {
display: block
}
DEMO: http://jsfiddle.net/sBtxq/20/
use jquery offset() method to get position of hover of those elements and apply that as a left and top for the div. (Make sure to position the div as ABSOLUTE).
If you want a simple solution try using tooltip plugins. There will be loads available out there. One such is jquery UI tooltip plugin.
Style it on your own
#div-to-display{
position:absolute;
top:50px;
left:50px;
width:300px;
height:200px;
z-index:99999;
display:none;
}
add this class="toHover" to each or table rows whom on hover you want to show div
add this function
window.onload = function(){
$('.toHover').each(function() {
$(this).mouseenter(function(){ $('#div-to-display').show(); });
$(this).mouseleave(function() { $('#div-to-display').hide();});
});
}
Html For i.e.
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
<tr>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
</table>
<div id="divInput" style="display:none;position:absolute;">
<input type="type" name="name" value=" " />
</div>
jQuery:
<script type="text/javascript">
var s = 'ss';
$('table tr').each(function () {
var this_tr = $(this);
this_tr.find('td:first').mouseenter(function () {
var this_td = $(this);
$('#divInput').css({ top: this_td.offset().top + this_td.height(), left: this_td.offset().left });
$('#divInput').show();
}).mouseout(function () {
var this_td = $(this);
$('#divInput').css({ top: this_td.offset().top + this_td.height(), left: this_td.offset().left });
$('#divInput').hide();
})
})
</script>

Categories