Cannot get table height to contstrain with in div - javascript

I've played around with a number of options, but I can't keep the table height from growing as I add lines dynamically.
This is a small section, part of a more complex page. Basically I have several div tags within the larger container div.
As more lines are added the table pushes the button below outside the boundaries of the div. Run the code snippet to observe the problem.
function onBodyLoader(obj) {
g.c.assignEventListners();
}
var g = {};
g.formClass = function() {
/*
----------------------------------
Properties for formClass
----------------------------------
*/
this.tr;
this.td;
this.elist = [];
/*
----------------------------------
Methods for formClass
----------------------------------
*/
this.assignEventListners = function() {
this.tbody = document.getElementById('emailDist');
g.sbAddELine = document.getElementById('sbAddELine');
g.sbAddELine.addEventListener("click", function(evt) {
g.c.addBlank();
}, false);
/*event listener for all links on the email list body*/
g.dataUpdate = document.querySelector("#emailDist");
g.dataUpdate.addEventListener("click", g.c.tableBodyRouter, false);
};
this.tableBodyRouter = function(e) {
/*
called from clicks on keyTable or task links
*/
if (e.target !== e.currentTarget)
if (e.target.id.indexOf('eRemove') > -1)
g.c.removeEmail(e);
e.stopPropagation();
};
this.redrawElist = function() {
/*delete current table*/
while (this.tbody.rows.length > 1)
this.tbody.deleteRow(1);
/*redraw table*/
for (var i = 0; i < this.elist.length; i++) {
this.rowLayout();
}
};
this.addBlank = function() {
/*add blank to this.elist array*/
this.elist.push({
eEmail: '',
eFirst: '',
eLast: '',
});
this.rowLayout();
}
this.removeEmail = function(e) {
var x = e.target.id.substr(7);
this.elist.splice(x, 1);
this.redrawElist();
};
this.rowLayout = function() {
var rowCnt = this.tbody.rows.length - 1;
this.tr = this.tbody.insertRow(this.tbody.rows.length);
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eFirst' + rowCnt + '" maxlength="20" size="20" value=""/>';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eLast' + rowCnt + '" maxlength="20" size="20" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eEmail' + rowCnt + '" maxlength="50" size="50" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="button" id="eRemove' + rowCnt + '" value="Remove" ">';
document.getElementById("eFirst" + rowCnt).focus();
document.getElementById("eFirst" + rowCnt).select();
}
}
g.c = new g.formClass;
table {
height: 60%;
max-height: 60%;
width: 100%;
display: inline-table;
border-style: none;
}
tbody {
font-size: 10pt;
display: block;
height: 90%;
overflow-y: scroll;
}
#container {
position: absolute;
width: 98%;
top: 40px;
height: 90%;
}
#dataEntryDiv {
border: medium groove;
position: absolute;
top: 0.5em;
height: 95%;
padding-left: 1em;
padding-right: 1em;
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Email List</title>
</head>
<body id="intactRolesBody" onLoad="onBodyLoader(this);">
<form id='intactRolesForm' method="post" action="" onSubmit="return false;">
<div id="container">
<div id="dataEntryDiv">
<input type="button" id='sbAddELine' value="Add non-company contact"><br>
<p>Email Distribution List</p>
<table>
<tbody id='emailDist'>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>email</th>
<th>remove from list</th>
</tr>
</tbody>
</table>
<input type="button" id='SaveEmailList' value="Save email List">
</div>
</div>
</form>
</body>
</html>

This is the basic behavior of a table. it shrinks and expand acording to its content.
What you can do to manage height is to reset the display.
it can be anything but table/inline-table/table-cell/table-row/.. . nor inline.
You used inline-table, inline-block might be fine:
function onBodyLoader(obj) {
g.c.assignEventListners();
}
var g = {};
g.formClass = function() {
/*
----------------------------------
Properties for formClass
----------------------------------
*/
this.tr;
this.td;
this.elist = [];
/*
----------------------------------
Methods for formClass
----------------------------------
*/
this.assignEventListners = function() {
this.tbody = document.getElementById('emailDist');
g.sbAddELine = document.getElementById('sbAddELine');
g.sbAddELine.addEventListener("click", function(evt) {
g.c.addBlank();
}, false);
/*event listener for all links on the email list body*/
g.dataUpdate = document.querySelector("#emailDist");
g.dataUpdate.addEventListener("click", g.c.tableBodyRouter, false);
};
this.tableBodyRouter = function(e) {
/*
called from clicks on keyTable or task links
*/
if (e.target !== e.currentTarget)
if (e.target.id.indexOf('eRemove') > -1)
g.c.removeEmail(e);
e.stopPropagation();
};
this.redrawElist = function() {
/*delete current table*/
while (this.tbody.rows.length > 1)
this.tbody.deleteRow(1);
/*redraw table*/
for (var i = 0; i < this.elist.length; i++) {
this.rowLayout();
}
};
this.addBlank = function() {
/*add blank to this.elist array*/
this.elist.push({
eEmail: '',
eFirst: '',
eLast: '',
});
this.rowLayout();
}
this.removeEmail = function(e) {
var x = e.target.id.substr(7);
this.elist.splice(x, 1);
this.redrawElist();
};
this.rowLayout = function() {
var rowCnt = this.tbody.rows.length - 1;
this.tr = this.tbody.insertRow(this.tbody.rows.length);
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eFirst' + rowCnt + '" maxlength="20" size="20" value=""/>';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eLast' + rowCnt + '" maxlength="20" size="20" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eEmail' + rowCnt + '" maxlength="50" size="50" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="button" id="eRemove' + rowCnt + '" value="Remove" ">';
document.getElementById("eFirst" + rowCnt).focus();
document.getElementById("eFirst" + rowCnt).select();
}
}
g.c = new g.formClass;
table {
height: 60%;
max-height: 60%;
width: 100%;
display: inline-block;/*... or block : do not use table display if you need to constrain height */
border-style: none;
}
tbody {/* this CSS could have been set to table directly :) */
font-size: 10pt;
display: block;
height: 90%;
overflow-y: scroll;
}
#container {
position: absolute;
width: 98%;
top: 40px;
height: 90%;
}
#dataEntryDiv {
border: medium groove;
position: absolute;
top: 0.5em;
/*left: 37em; removed for demo */
height: 95%;
padding-left: 1em;
padding-right: 1em;
}
<body id="intactRolesBody" onLoad="onBodyLoader(this);">
<form id='intactRolesForm' method="post" action="" onSubmit="return false;">
<div id="container">
<div id="dataEntryDiv">
<input type="button" id='sbAddELine' value="Add non-company contact"><br>
<p>Email Distribution List</p>
<table>
<tbody id='emailDist'>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>email</th>
<th>remove from list</th>
</tr>
</tbody>
</table>
<input type="button" id='SaveEmailList' value="Save email List">
</div>
</div>
</form>
</body>
Note: You did use display:block on tbody, you could have apply this directly to the table element and reset tbody to display:table :) (defaut is table-row-group )

Add
#dataEntryDiv {
overflow: auto;
}

To get a simplified version of the situation, I would suggest writing something like this - instead of putting in the code from your actual project. This way, you can get away from trying to 'fix' something - and possibly see a better way to build the layout - or at least make the use-case more specific.
https://stackoverflow.com/help/how-to-ask
markup
<section class="table-wrapper">
<header>
I'm a table wrapper thing
</header>
<main>
<table>
<!-- populate this -->
</table>
</main>
<footer>
<button>button (add row)</button>
</footer>
</section>
styles
.table-wrapper {
height: 300px; /* arbitrary */
border: 2px solid red;
}
.table-wrapper main {
height: 260px; /* likely you'd use flexbox or percentages or JS */
border: 2px solid blue;
overflow: auto;
}
js
var $table = $('.table-wrapper').find('table');
var $moreButton = $('.table-wrapper').find('button');
var counter = 0;
function addRow() {
counter = counter + 1;
$table.prepend('<tr><td>row and data ' + counter + '</td></tr>');
}
addRow();
// populate some things to start
$moreButton.on('click', function() {
addRow();
});
https://jsfiddle.net/sheriffderek/b6z4ep46/

Related

Use JS to determine if all form fields are filled and correctly

*Edit: Fixed so that all inputs are now validated on one form. However, I can only add one variable to check if blank, as soon as I add more, none of the submit functions work. I have been trying multiple things.
function validateForm() {
var inputVelocity = document.getElementById("dzCalculator").inputVelocity.value;
var inputYellowPhase = document.getElementById("dzCalculator").inputYellowPhase.value;
var inputRedPhase = document.getElementById("dzCalculator").inputInterPhase.value;
var inputReactionTime = document.getElementById("dzCalculator").inputReactionTime.value;
if(inputVelocity === "" && inputYellowPhase === "" && inputRedPhase === "" && inputReactionTime === ""){
alert("Input all fields to calculate.");
return false;
}
}
I have checked the HTML matches - it does. But I found I could not use onsubmit="return validateForm" as this wouldn't work at all.
This is only 4 of the form values, there are seven all up. But when I can get the four working, I can get them all working.
How can I use JS to make sure that no input is left blank or empty? I already have made it so that it will only accept numbers and decimal points. So no one can add an incorrect field. But currently, they can leave a field blank which means my calculator generates a NaN response.
Also, how can I make sure one of my fields can not accept a number greater than 1 or less than 0. I tried min="0" max="1" in the input tag, but because I have removed spinners, this doesn't work.
So, in summary, I am looking to make sure when a button is clicked that all the form sections are filled in and that one of the fields doesn't accept a number greater that 1 or less than zero.
there are 2 options for this.
You can select all the inputs (inside the form tag) using querySelector and check the value of each input by looping through them.
use this trick selector to get all the invalid inputs
document.querySelectorAll('input:not([value]):not([value=""])');
replace input with more precise selector.
Can you please give more detail about how your form is in multiple places?
For input I think you need to use step attribute
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number#step
Reference: javascript_form_validation
Depends when would you like to validate form fields
For example: Form validation on submit
function validateForm() {
var x = document.forms["myForm"]["fname"].value;
if (x == "") {
alert("Name must be filled out");
return false;
}
}
<html>
<body>
<form name="myForm" action="/action_page.php" onsubmit="return validateForm()" method="post">
Name: <input type="text" name="fname">
<input type="submit" value="Submit">
</form>
</body>
</html>
Give name to your form using name attribute such as <form name="myForm" ..>
Then using document.forms["myForm"] you can have access to your form
There you can validate your input fields value. return true if validates
This works for me. You can use it, style it however you want or not. You do need JQuery. It has powerful selectors.
<!DOCTYPE html>
<html lang="en">
<head>
<style type="text/css">
body{
font-size: 12px;
}
.main-container{
display: flex; /* DO NOT CHANGE */
height: 100vh; /* DO NOT CHANGE */
width: 100%; /* DO NOT CHANGE */
}
.c-message{
display: flex; /* DO NOT CHANGE */
position: fixed; /* DO NOT CHANGE */
top: 0px; /* DO NOT CHANGE */
left: 0px; /* DO NOT CHANGE */
width: 100%; /* DO NOT CHANGE */
height: 100%; /* DO NOT CHANGE */
}
.c-msgbox{
padding: 30px;
text-align: center;
margin: auto; /* DO NOT CHANGE */
background-color: #e4e4e4;
border-radius: 4px;
border: 1px solid #adadad;
-webkit-box-shadow: 0px 0px 50px rgba(0, 0, 0, 0.60);
-moz-box-shadow: 0px 0px 50px rgba(0, 0, 0, 0.60);
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.40);
}
.standerd-button2{
border: none;
font-family: arial,helvetica,clean,sans-serif;
font-size: 10px;
font-weight: 600;
color: white;
background: #1A709F;
padding: 3px;
text-align: center;
vertical-align: middle;
-webkit-border-radius: 3px;
width: max-content;
min-width: 50px;
margin: 2px;
}
.standerd-button2:hover{
background: crimson;
cursor: default;
}
.f-table {
display: table;
width: max-content;
padding: 5px;
border-spacing: 2px;
}
.f-tablerow {
display: table-row;
}
.f-tablecell{
display: table-cell;
}
.label-cell-r{
text-align: right;
}
.dd-required{
margin: auto;
color: red;
}
input, select{
border: 1px solid lightgrey;
}
</style>
<script type="text/javascript" src="JQuery.js"></script>
</head>
<body>
<div class="main-container">
<div>
<form id="f1" name="f1">
<div class="f-table">
<div class="f-tablerow">
<div class="f-tablecell label-cell-r">
<label for="firstname">First Name</label>
</div>
<div class="f-tablecell input-cell">
<input id="firstname" name="firstname" type="text" data-er="First Name"/>
<span class='dd-required'>*</span>
</div>
</div>
<div class="f-tablerow">
<div class="f-tablecell label-cell-r">
<label for="lastname">Last Name</label>
</div>
<div class="f-tablecell input-cell">
<input id="lastname" name="lastname" type="text" data-er="Last Name"/>
<span class='dd-required'>*</span>
</div>
</div>
<div class="f-tablerow">
<div class="f-tablecell label-cell-r">
<label for="company">Company</label>
</div>
<div class="f-tablecell input-cell">
<select id="company" name="company" data-er="Company Name">
<option value="0"> - Select Comapny - </option>
<option value="1">Company 1</option>
<option value="2">Company 2</option>
<option value="3">Company 3</option>
<option value="4">Company 4</option>
</select>
<span class='dd-required'>*</span>
</div>
</div>
</div>
<input id="b1" type="submit" value="Submit" />
</form>
</div>
<div>
<script type="text/javascript">
$.fn.CustomAlert = function (options, callback) {
var settings = $.extend({
message: null,
detail: null,
yesno: false,
okaytext: null,
yestext: null,
notext: null
}, options);
var frm = "";
detail = "<b>" + settings.detail + "</b>";
message = "<b>" + settings.message + "</b>";
if (settings.detail === null) {
detail = "";
};
frm = frm + message + "<div style='text-align: left; margin-top: 15px; margin-bottom: 15px;'>" + detail + "</div>";
if (settings.yesno === false) {
frm = frm + "<input id='ok' type='button' value='" + settings.okaytext + "' class='standerd-button2' />";
} else {
frm = frm + "<div><input id='yes' type='button' value='" + settings.yestext + "' name='yes' class='standerd-button2' />" +
"<input id='no' type='button' value='" + settings.notext + "' name='no' class='standerd-button2' /></div>";
};
var frmesg = "<div id='cmessage' name='cmessage' class='c-message'>" +
"<div class='c-msgbox'>" +
"<form>" + frm + "</form>" +
"</div>" +
"</div>";
$(".main-container").append(frmesg);
if (!settings.yesno) {
$("#cmessage #ok").click(function () {
$("#cmessage").remove();
callback(false);
});
} else {
$("#cmessage #yes").click(function () {
$("#cmessage").remove();
callback(true);
});
$("#cmessage #no").click(function () {
$("#cmessage").remove();
callback(false);
});
};
};
$.fn.JsFormCheck = function () {
var MessData = "";
this.find('select, input').each(function () {
if ($(this).attr("data-er")) {
m = $(this).attr("data-er");
switch ($(this).get(0).tagName) {
case "INPUT":
if ($(this).val().length === 0) {
MessData = MessData + "- " + m + "<br>";
$(this).css('border-bottom', '2px solid green');
};
break;
case "SELECT":
if ($(this).val() === "0") {
MessData = MessData + "- " + m + "<br>";
$(this).css('border-bottom', '2px solid green');
};
break;
};
};
});
if (MessData.length > 0) {
MessData = "<b>" + MessData + "</b>";
x = $().CustomAlert({message: "<b>Please fill in the following required fields to continue.</b>",
detail: MessData,
okaytext: "Close",
yesno: false});
return true;
} else {
return false;
};
};
$('#f1 #b1').click(function(event){
event.preventDefault();
Error = $("#f1").JsFormCheck();
if(Error === false){
null;
//Do Something
};
});
</script>
</body>

.html() not showing the whole text that contains the ' character

When i try to edit the value on fields that contain the ' character in them, it cuts the string to that character. For example if I put O'Hara as name a try to edit it, it will give me only the O from O'Hara. Also on a side note is this "valid", correct way to edit the values of the properties on the the contact objects? Thanks in advance.
class Contact{
constructor(id, first, last, email, password, phone) {
this.id = id || "WTF";
this.first = first || this.get_Random_F_name();
this.last = last || this.get_Random_F_name();
this.email = email || (this.get_Random_F_name() + "#hotmail.com");
this.password = password || Math.floor(Math.random() * Math.floor(90000));
this.phone = phone || Math.floor(Math.random() * Math.floor(500));
}
get_Random_F_name(){
let cityIndex = Math.floor(Math.random() * Math.floor(9));
if(cityIndex == 0){
return "O'mara"
}
else if(cityIndex == 1){
return "F'airfax"
}
else if(cityIndex == 2){
return "C'harlie"
}
else if(cityIndex == 3){
return "Evereteze"
}
else if(cityIndex == 4){
return "H'errera"
}
else if(cityIndex == 5){
return "Guerriero"
}
else if(cityIndex == 6){
return "I'mperio"
}
else if(cityIndex == 7){
return "Levitan"
}
else {
return "A'mato"
}
}
}
function dontCoptThatFloppy(id, first, last, email, password, phone) {
let proactiveBitch = ("<tr><td class='td-id'>"+ id +
"</td><td class='f_Name'>"+first+
"</td><td class='l_Name'>"+last+
"</td><td class='e_mail'>"+email+
"</td><td class='pass_in'>"+password+
"</td><td class='phone_in'>"+phone+
"</td><td class='td-three-Btn'><button class='save-Btn'>save</button>"+
"<button class='edit-Btn'>edit</button><button class='del-Btn'>Broken</button></td>"+
"<td class='td-del'><button class='del-row'>Del</button></td>"+"</tr>")
return proactiveBitch;
}
$(document).ready(function(){
let idCounter = 1;
let a_contacts = [];
let a_contacts2 = [];
let a_contacts3 = [];
let contacts_arr_obj = [];
let new_contacts_arr_obj = contacts_arr_obj;
$('#new-row-btn').click(function(){
let newContact = new Contact(idCounter, $("#name-input").val(), $("#lastname-input").val(), $("#email-input").val(), $("#pass-input").val(), $("#phone-input").val());
$("#my-table").append(dontCoptThatFloppy(idCounter, newContact.first, newContact.last, newContact.email, newContact.password, newContact.phone))
a_contacts.push(newContact);
$("#name-input").val("")
$("#lastname-input").val("")
$("#email-input").val("")
$("#pass-input").val("")
$("#phone-input").val("")
idCounter++;
});
$(document).on('click', '.del-row', function (event) {
$(event.target).parent().parent().remove()
});
$(document).on('click', '.edit-Btn', function (event) {
var $row = $(this).closest('tr');
var id = $row.find('.td-id').text();
var fName = a_contacts[id-1].first;
var lName = a_contacts[id-1].last;
var email = a_contacts[id-1].email;
var pass = a_contacts[id-1].password;
var phone = a_contacts[id-1].phone;
let my_input_f_Name = "<input class='in_f_name' type='text' value='"+fName+"'>"
let my_input_l_Name = "<input class='in_l_name' type='text' value='"+lName+"'>"
let my_input_e_mail = "<input class='in_e_mail' type='text' value='"+email+"'>"
let my_input_pass = "<input class='in_pass_in' type='text' value='"+pass+"'>"
let my_input_phone = "<input class='in_phone_in' type='text' value='"+phone+"'>"
$row.find('.f_Name').html(my_input_f_Name)
$row.find('.l_Name').html(my_input_l_Name)
$row.find('.e_mail').html(my_input_e_mail)
$row.find('.pass_in').html(my_input_pass)
$row.find('.phone_in').html(my_input_phone)
let edit = $row.find('.edit-Btn')
let del_btn = $row.find('.del-Btn')
let save_btn = $row.find('.save-Btn')
edit.css('display','none');
del_btn.css('display','none');
save_btn.css('display','block');
});
$(document).on('click', '.save-Btn', function (event) {
var $row = $(this).closest('tr');
var id = $row.find('.td-id').text();
a_contacts[id-1].first = $row.find('.in_f_name').val();
a_contacts[id-1].last = $row.find('.in_l_name').val();
a_contacts[id-1].email = $row.find('.in_e_mail').val();
a_contacts[id-1].password = $row.find('.in_pass_in').val();
a_contacts[id-1].phone = $row.find('.in_phone_in').val();
$row.find('.f_Name').html( a_contacts[id-1].first);
$row.find('.l_Name').html(a_contacts[id-1].last);
$row.find('.e_mail').html(a_contacts[id-1].email);
$row.find('.pass_in').html(a_contacts[id-1].password);
$row.find('.phone_in').html(a_contacts[id-1].phone);
let edit = $row.find('.edit-Btn')
let del_btn = $row.find('.del-Btn')
let save_btn = $row.find('.save-Btn')
edit.css('display','inline');
del_btn.css('display','inline');
save_btn.css('display','none');
});
$(document).on('click', '#sup', function (event) {
console.log(a_contacts);
});
$("#sort").on("change", function(event){
let pickedValue = event.target.value;
let table = $('#my-table')
let rows = table.find('.td-id').toArray()
if (pickedValue === "1"){
a_contacts.sort(function(a, b){
return a.id - b.id;
});
}
else if (pickedValue === "2"){
a_contacts.sort(function(a,b) {
return a.first.localeCompare(b.first);
});
}
else if (pickedValue === "3"){
a_contacts.sort(function(a,b) {
return a.last.localeCompare(b.last);
});
}
else if (pickedValue === "4"){
a_contacts.sort(function(a,b) {
return a.email.localeCompare(b.email);
});
}
else if (pickedValue === "5"){
a_contacts.sort(function(a, b){
return a.password - b.password;
});
}
else if (pickedValue === "6"){
a_contacts.sort(function(a, b){
return a.phone - b.phone;
});
}
else{}
$(tbody).html("");
for (var i = 0; i < rows.length; i++){
$("#my-table").append(dontCoptThatFloppy(a_contacts[i].id, a_contacts[i].first, a_contacts[i].last, a_contacts[i].email, a_contacts[i].password, a_contacts[i].phone))
}
});
});
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<link rel="stylesheet" type="text/css" media="screen" href="CSS/style.css" />
</head>
<body>
<div id="inputs-div">
<input type="text" placeholder="Your Name Sir" id="name-input">
<input type="text" placeholder="Your Last Name Sir" id="lastname-input">
<input type="text" placeholder="Your Email Sir" id="email-input">
<input type="password" placeholder="Your Password Sir" id="pass-input" >
<input type="text" placeholder="Your Phone Number" id="phone-input" >
<button id="new-row-btn">Add Contact</button>
<button id="sup">Console.Log</button>
</div>
<select class="custom-select" id="sort">
<option selected>Choose...</option>
<option value="1">ID</option>
<option value="2">First Name</option>
<option value="3">Last Name</option>
<option value="4">Email</option>
<option value="5">Password</option>
<option value="6">Phone</option>
</select>
<div>
<table id="my-table">
<thead>
<tr id="first-row">
<th>ID</th>
<th>First name</th>
<th>Last name</th>
<th>Email</th>
<th>Password</th>
<th>Phone</th>
<th>Action</th>
<th>Delete</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</div>
<script src="JS/jquery-3.2.1.js"></script>
<script src="JS/script.js"></script>
</body>
</html>
*{
margin: 0px;
padding: 0px;
}
body{
background-color: black;
color: wheat;
}
input{
display: block;
margin: 2px;
border: 2px solid #ac7b11;
background-color: rgba(44, 42, 42, 0.863);
color: #bebe35;
}
::placeholder {
color: #bebe35;
}
button{
background-color: #1a64a0;
border: 2px solid #1a64a0;
color: white;
border-radius: 3px;
outline:none;
/* text-align: center;
display:table-cell;
vertical-align:middle; */
}
#new-row-btn, #sup{
width: 100px;
height: 30px;
margin: 3px;
}
.del-row{
/* display: flex; */
width: 100%;
height: 100%;
/* margin: 0px auto; */
/* text-align: 0px auto; */
}
.small-Btn, .medium-Btn{
display: none;
}
.del-Btn, .edit-Btn{
background-color: #10b133;
border: 2px solid #10b133;
width: 50%;
height: 100%;
}
.save-Btn{
background-color: #a1b110;
border: 2px solid #a1b110;
display: none;
width: 100%;
height: 100%;
}
th{
height: 30px;
width: 100px;
}
td{
height: 30px;
width: 100px;
}
.td-id{
width: 30px;
text-align: center;
}
#my-table tbody tr td {
background-color: #a35635;
}
#my-table tbody tr td:nth-child(odd) {
background-color: #828e20;
}
.td-del, .td-three-Btn{
background-color: transparent !important;
}
td input{
box-sizing: border-box;
width: 100%;
height: 100%;
margin:0px;
}
When you write something like this:
let my_input_f_Name = "<input class='in_f_name' type='text' value='"+fName+"'>"
if the value of fName is O'hara, the resulting HTML is:
<input class='in_f_name' type='text' value='O'hara'>
The ' in the name matches the ' that starts the value attribute, so it ends the attribute; it's equivalen to writing
<input class='in_f_name' type='text' value='O' hara'>
Since you're using jQuery, you can use its methods to create your elements instead of concatenating strings:
let my_input_f_Name = $("<input>", {
"class": "in_f_name",
type: "text",
value: fName
});

Having trouble passing a value from one input to another with jquery

I'm doing a little noob project and making a simple "to-do list" and I'm stuck on something that seems so simple! I'm trying to pass the main up top from #myInput and pass it to the next down and so on. Right now, if you enter something then click add, it creates a blank new line at first for some reason then if you type something else and click add, what you typed before shows up on the next line. It will keep doing that for as long as you type something different in the input, but if you keep hitting add a couple times with the same thing in the input, nothing shows up. Then change the input again to something different and click add and all that will show up lol, but still no current line outputs from what you typed...going nuts. Any suggestions on the proper way to do this? I left a JSfiddle link to see exactly what is happening down below.
<div>
<form id="addThings" type="text">
<input type="text" id="myInput" placeholder="add to your to-do list" size="50" maxlength="40" autocomplete="off" autofocus>
<input type="button" id="addButton" value="add">
</form>
</div>
Also, when you click the button and it creates a new line down below it shifts everything around a bit..ideas on what needs to be changed in the css? Trying to get it a little smoother. Thanks!
$(function() {
var i = 2;
$('#addButton').click(function(e) {
var input = $('#myInput').val();
console.log(input);
var id = "newLine" + i;
var line = '<input type=\"text\" id=\"' + id + '\" size=\"50\" disabled><input type=\"checkbox\" >';
$('form').append(line);
var newId = "#" + id;
$('#myInput').change(function() {
$(newId).val(input);
});
i += 1;
});
});
JSFiddle
Try this. Providing a value to the input field before you append it works well.In your case there is an issue with javascript closure. To solve it just define the input variable outside of the click function
$(function() {
var i = 2;
$('#addButton').click(function(e) {
var input = $('#myInput').val();
console.log(input);
var id = "newLine" + i;
var line = '<input type=\"text\" id=\"' + id + '\" value=\"'+input+'\" size=\"50\" disabled><input type=\"checkbox\" >';
console.log(line);
$('form').append(line);
i += 1;
});
});
JSFIDDLE
Try assigning the input value to the value attribute of your new input when you create the new line:
$(function() {
var i = 2;
$('#addButton').click(function(e) {
var input = $('#myInput').val();
var id = "newLine" + i;
var line = '<input type=\"text\" id=\"' + id + '\" size=\"50\" value="' + input + '" disabled><input type=\"checkbox\">';
$('form').append(line);
var newId = "#" + id;
/*$('#myInput').change(function() {
$(newId).val(input);
});*/
i += 1;
});
});
body {
background-color: white;
}
div {
width: 750px;
margin: 0 auto;
margin-top: 200px;
margin-bottom: 0;
padding: 0;
}
form {
margin: 0 auto;
display: inline-block;
margin-bottom: 0px;
}
input {
padding: 10px 18px;
float: bottom;
}
input[type=text] {
border-left: white;
border-right: white;
border-top: white;
font-size: 20px;
i height: 21px;
text-align: center;
outline: none;
float: right;
background-color: white;
}
input[type=button] {
display: inline-block;
height: 25px border: 0;
margin: 0 auto;
font-size: 20px;
float: right;
}
input[type=checkbox] {
vertical-align: top;
width: 10%;
margin: 15px auto;
float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<body>
<div>
<form id="addThings" type="text">
<input type="text" id="myInput" placeholder="add to your to-do list" size="50" maxlength="40" autocomplete="off" autofocus>
<input type="button" id="addButton" value="add">
</form>
</div>
</body>
It's a closure/scope issue. Your variable input is inside the click function. Therefore it is not going to be in the scope of the change function.
Move the declaration of inputoutside of the click function.
Create a wrapper function.
That way all the variables needed are in the scope of addButtonScopeFunc and there only.
Those variables aren't needed in the global scope window. nor in the scope of the '#addButton' event function.
$(function() {
var addButtonScopeFunc = function (input, inputValChangeEl) {
var i = 2,
id = "newLine" + i,
newId = "#" + id,
line = '<input type=\"text\" id=\"' + id + '\" size=\"50\" disabled><input type=\"checkbox\" >';
console.log(input);
console.log(line);
$('form').append(line);
$(inputValChangeEl).change(function() {
$(newId).val(input);
});
i += 1;
};
$('#addButton').click(function(e) {
addButtonScopeFunc($('#myInput').val(), '#myInput');
});
});
To give an other example, just for showing up things.
You could "outscope" the $(inputValChangeEl).change(...) event function outside of addButtonScopeFunc in its own wrapper function handling over the input value as parameter.
$(function() {
var addButtonScopeFunc = function (input, inputValChangeEl) {
/* ... */
$('form').append(line);
changeInputVal(inputValChangeEl, newId, input);
i += 1;
},
changeInputVal = function (el, id, input) {
$(el).change(function() {
$(id).val(input);
});
};
$('#addButton').click(function(e) {
addButtonScopeFunc($('#myInput').val(), '#myInput');
});
});
Further reading: Javascript Scopes well explained

Name href Label According to User Text Input JavaScript

In my app, I am letting the user add categories. Each category is a simple href with label that the user entered as a name of category. The problem I am having is the category name is shown (undefined). So I am not sure where is the problem. Also, when I click again on add category, the previously created one disappear!
var boxName="type here";
var inputt = document.getElementById("boxName").value;
function addInput()
{
// var boxName="type here";
document.getElementById('responce').innerHTML='<br/><input type="text" id="'+boxName+'" value="'+boxName+'" /><input type="button" onclick="addlinking()" value="Add"/><span id="Adding"></span>';
var inputt = document.getElementById("boxName").value;
addlinking(inputt);
}
function addlinking(tt){
document.getElementById('Adding').innerHTML = '<br/><input type="submit" onclick="addinghref()" value="'+tt+'"><i class="fa fa-angle-right"></i></a><span id="Linking"></span>';
}
function addinghref()
{
document.getElementById('Linking').innerHTML='';
}
<input type="button" onclick="addInput()" value="Add Category">
<span id="responce"></span>
var catTemplate = document.getElementById("adding-template")
.content
.querySelector(".category");
var createCatDiv = document.getElementById('create-cat');
var createCatInput = createCatDiv.querySelector("input[type=text]");
function addInput()
{
// Clear previous entry.
createCatInput.value = "";
// Show the div.
createCatDiv.classList.remove("hidden");
}
function addlinking()
{
// Hide the create cat div.
createCatDiv.classList.add("hidden");
// Import the category div from the template.
var catDiv = document.importNode(catTemplate, true);
document.getElementById("response").appendChild(catDiv);
// Set the input.
var input = catDiv.querySelector("input");
input.value = createCatInput.value;
// Replace duckduckgo by the address of your link.
input.onclick = location.assign.bind(location, "https://duckduckgo.com");
}
#create-cat {
margin-top: 1em;
}
#create-cat.hidden {
display: none;
}
.category{
margin-top: 1em;
}
.category input[type=button] {
background-color: lightblue;
border-style: solid;
border-color: gray;
border-width: 1px;
border-radius: 5px;
}
.category input[type=button]:hover {
background-color: blue;
color: white;
border-color: black;
}
.category input[type=button]:active {
background-color: black;
color: white;
border-color: black;
}
<template id="adding-template">
<div class="category">
<input type="button" />
</div>
</template>
<input type="button" onclick="addInput()" value="Add Category">
<div id="response"></div>
<div id="create-cat" class="hidden">
<input type="text" placeholder="type here" />
<input type="button" onclick="addlinking()" value="Add"/>
</div>
var boxName = "type here";
var id = boxName.replace(/\s/g, '_');
function addInput() {
document.getElementById('responce').innerHTML = '<br/><input type="text" id="' + id + '" value="' + boxName + '" /><input type="button" onclick="addlinking()" value="Add"/><span id="Adding"></span>';
}
function addlinking(tt) {
var inputt = document.getElementById(id).value;
document.getElementById('Adding').innerHTML = '<br/><input type="submit" onclick="addinghref()" value="' + inputt + '"><i class="fa fa-angle-right"></i></a><span id="Linking"></span>';
}
function addinghref() {
document.getElementById('Linking').innerHTML = 'Link';
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.1.1/normalize.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
<input type="button" onclick="addInput()" value="Add Category">
<span id="responce"></span>

How to assign a class or ID to a table within a JavaScript function?

I have to use HTML, CSS and JavaScript (so no jQuery).
I have created a table that receives JSON data via API. I have a function to show/hide each of the table rows by clicking a check box. I already included the JavaScript function, but I cannot figure out where to place a class or id, so I can connect the function to each of the table rows. Generally, I would add a class to <td> for example, like this: <td class="example"> but in this case it won't work. The code breaks when I do this.
I did search online for hours, but wasn't able to find an answer. I'm not looking for finished code, but rather a hint/help how to achieve this.
This table is created using:
body {
background: white;
}
h1 {
color: black;
font-size: 35px;
text-align: center;
font-family: 'Quicksand', sans-serif;
}
h2 {
font-family: 'Quicksand', sans-serif;
margin-left: 3.3em;
}
table, th , td {
border: none;
border-collapse: collapse;
padding: 15px;
margin-left: 5em;
margin-top: -25em;
}
table tr:nth-child(odd) {
background-color: #f1f1f1;
}
table tr:nth-child(even) {
background-color: #ffffff;
}
#form {
font-family: 'Quicksand', sans-serif;
margin-left: 5em;
}
#googleMap {
margin-left: 45em;;
margin-right: auto;
}
#chkbox_display {
margin-left: 5em;
margin-top: 3em;
font-family: 'Quicksand', sans-serif;
}
.hidden {
display: none;
}
<html>
<head>
<link rel="stylesheet" type="text/css" href="main.css">
<link href='https://fonts.googleapis.com/css?family=Quicksand' rel='stylesheet' type='text/css'>
<title>Weather App</title>
</head>
<body>
<h1>Weather Forecast</h1>
<div id="id01"></div>
<h2>Please enter the following information:</h2>
<form id="form" onsubmit ="return fetchUrl()">
Enter your City:<br>
<input id="weather_city" placeholder="Entere here..."><br>
How to display values: <br>
<select id="weather_scale">
<option value="Metric">Metric Units (Celcius/mm)</option>
<option value="Imperial">Imperial Units (Fahrenheit/inch)</option>
</select><br>
Number of days to show weather:<br>
<select id="weather_numberOfDays">
<option value="1">Today only</option>
<option value="2">2 days</option>
<option value="3">3 days</option>
<option value="4">4 days</option>
<option value="5">5 days</option>
</select>
<br><br>
<button onclick="initialize">Submit</button>
</form>
<div id="chkbox_display">
<form action="#">
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Max. Temp.</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Min. Temp</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Rainfall</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Pressure</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Humidity</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Wind Speed</label>
</form>
</div>
<script>
function initAutocomplete() {
weather_city = new google.maps.places.Autocomplete(
(document.getElementById('weather_city')),
{types: ['geocode']});
weather_city.addListener('place_changed');
}
</script>
<script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDgIpTEmegx81sL3ukhIdYVQrPkufyjEj4&callback=initalize&libraries=places&callback=initAutocomplete"></script>
<script>
var longitude;
var latitude;
function initalize(arr) {
var lon = arr.city.coord.lon;
var lat = arr.city.coord.lat;
var mapProp = {
center:new google.maps.LatLng(lat,lon),
zoom:10,
mapTypeId:google.maps.MapTypeId.ROADMAP
}
var map=new google.maps.Map(document.getElementById("googleMap"), mapProp);
}
</script>
<div id="googleMap" style="width:600px;height:480px;"></div>
<section>
<div id="table">
<!--
<tr>
<td class="hidden">example</td>
<td class="hidden"></td>
<td class="hidden"></td>
</tr>
-->
</div>
</section>
<script>
function getJson(request) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", request, true);
xmlhttp.send();
xmlhttp.onreadystatechange=function() {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
myFunction(xmlhttp.responseText);
}
}
}
function fetchUrl() {
var form = document.getElementById("form");
var city = form.weather_city.value;
var value = form.weather_scale.value;
var days = form.weather_numberOfDays.value;
var url = "http://api.openweathermap.org/data/2.5/forecast/daily?q="+city+"&type=accurate,us&mode=json&appid=a0dd3d46dd5b22c0581030acf10af408&units="+value+"&cnt="+days;
getJson(url);
return false;
}
function myFunction(response) {
var arr = JSON.parse(response);
initalize(arr);
var i;
var out = "<table>";
for(i = 0; i < arr.list.length; i++) {
out += "<tr><td>" +
new Date(arr.list[i].dt * 1000) +
"</td></tr>" +
"<tr><td>" +
getIcon(arr.list[i].weather[0].icon) +
"</td><td>" +
arr.list[i].weather[0].description +
"</td><tr>" +
"</tr><td>" +
"Min. Temperature" +
"</td><td>" +
arr.list[i].temp.min +
"</td><tr>" +
"</tr><td>" +
"Max. Temperature" +
"</td><td>" +
arr.list[i].temp.max +
"</td><tr>" +
"</tr><td>" +
"Pressure" +
"</td><td>" +
arr.list[i].pressure +
"</td><tr>" +
"</tr><td>" +
"Windspeed" +
"</td><td>" +
arr.list[i].speed +
"</td><tr>" +
"</tr><td>" +
"Humidity" +
"</td><td>" +
arr.list[i].humidity +
"</td><tr>" +
"</tr><td>" +
"Predicted Rainfall" +
"</td><td>" +
arr.list[i].rain +
"</td><td>";
}
out += "</table>";
document.getElementById("table").innerHTML = out;
}
function getIcon(s) {
return("<img src=\"http://openweathermap.org/img/w/"+s+".png\"/>");
}
</script>
<script>
//function to show and hide pressure, humidity, etc.... doesnt work yet. not connected!
function showHide() {
var checkbox = document.getElementById("chkbox");
var hiddenInput = document.getElementsByClassName("hidden");
for(var i = 0; i !=hiddenInput.length; i++) {
if(checkbox.checked) {
hiddenInput[i].style.display = "inline";
} else {
hiddenInput[i].style.display = "none";
}
}
}
</script>
</body>
</html>
The simplest means of achieving this, given the current approach, is to convert the HTML of the <td> opening tags from:
"<tr><td>"
to:
"<tr><td class='example'>"
And then use CSS to style the relevant elements, for example:
.example {
color: #f90;
}
Or, once you've assigned the string of innerHTML, you could simply add this line:
// retrieves the collection of <td> elements from within the
// element with the id of 'table', and uses Array.from() to
// convert that collection into an Array.
// Then iterates over the array of elements using
// Array.prototype.forEach():
Array.from( document.querySelectorAll('#table td') ).forEach(function (td) {
// within the anonymous function the 'td' argument is a reference
// to the current array-element of the array over which we're
// iterating.
// here we use the Element.classList API to add the 'example'
// class-name to the existing (if any) class-names of the <td>
// elements:
td.classList.add('example');
});
body {
background: white;
}
h1 {
color: black;
font-size: 35px;
text-align: center;
font-family: 'Quicksand', sans-serif;
}
h2 {
font-family: 'Quicksand', sans-serif;
margin-left: 3.3em;
}
table, th , td {
border: none;
border-collapse: collapse;
padding: 15px;
margin-left: 5em;
margin-top: -25em;
}
table tr:nth-child(odd) {
background-color: #f1f1f1;
}
table tr:nth-child(even) {
background-color: #ffffff;
}
#form {
font-family: 'Quicksand', sans-serif;
margin-left: 5em;
}
#googleMap {
margin-left: 45em;;
margin-right: auto;
}
#chkbox_display {
margin-left: 5em;
margin-top: 3em;
font-family: 'Quicksand', sans-serif;
}
.hidden {
display: none;
}
.example {
color: #f90;
}
<html>
<head>
<link rel="stylesheet" type="text/css" href="main.css">
<link href='https://fonts.googleapis.com/css?family=Quicksand' rel='stylesheet' type='text/css'>
<title>Weather App</title>
</head>
<body>
<h1>Weather Forecast</h1>
<div id="id01"></div>
<h2>Please enter the following information:</h2>
<form id="form" onsubmit ="return fetchUrl()">
Enter your City:<br>
<input id="weather_city" placeholder="Entere here..."><br>
How to display values: <br>
<select id="weather_scale">
<option value="Metric">Metric Units (Celcius/mm)</option>
<option value="Imperial">Imperial Units (Fahrenheit/inch)</option>
</select><br>
Number of days to show weather:<br>
<select id="weather_numberOfDays">
<option value="1">Today only</option>
<option value="2">2 days</option>
<option value="3">3 days</option>
<option value="4">4 days</option>
<option value="5">5 days</option>
</select>
<br><br>
<button onclick="initialize">Submit</button>
</form>
<div id="chkbox_display">
<form action="#">
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Max. Temp.</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Min. Temp</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Rainfall</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Pressure</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Humidity</label>
<input type="checkbox" name="chkbox" id="chkbox"/>
<label for="chkbox">Wind Speed</label>
</form>
</div>
<script>
function initAutocomplete() {
weather_city = new google.maps.places.Autocomplete(
(document.getElementById('weather_city')),
{types: ['geocode']});
weather_city.addListener('place_changed');
}
</script>
<script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDgIpTEmegx81sL3ukhIdYVQrPkufyjEj4&callback=initalize&libraries=places&callback=initAutocomplete"></script>
<script>
var longitude;
var latitude;
function initalize(arr) {
var lon = arr.city.coord.lon;
var lat = arr.city.coord.lat;
var mapProp = {
center:new google.maps.LatLng(lat,lon),
zoom:10,
mapTypeId:google.maps.MapTypeId.ROADMAP
}
var map=new google.maps.Map(document.getElementById("googleMap"), mapProp);
}
</script>
<div id="googleMap" style="width:600px;height:480px;"></div>
<section>
<div id="table">
<!--
<tr>
<td class="hidden">example</td>
<td class="hidden"></td>
<td class="hidden"></td>
</tr>
-->
</div>
</section>
<script>
function getJson(request) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", request, true);
xmlhttp.send();
xmlhttp.onreadystatechange=function() {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
myFunction(xmlhttp.responseText);
}
}
}
function fetchUrl() {
var form = document.getElementById("form");
var city = form.weather_city.value;
var value = form.weather_scale.value;
var days = form.weather_numberOfDays.value;
var url = "http://api.openweathermap.org/data/2.5/forecast/daily?q="+city+"&type=accurate,us&mode=json&appid=a0dd3d46dd5b22c0581030acf10af408&units="+value+"&cnt="+days;
getJson(url);
return false;
}
function myFunction(response) {
var arr = JSON.parse(response);
initalize(arr);
var i;
var out = "<table>";
for(i = 0; i < arr.list.length; i++) {
out += "<tr><td>" +
new Date(arr.list[i].dt * 1000) +
"</td></tr>" +
"<tr><td>" +
getIcon(arr.list[i].weather[0].icon) +
"</td><td>" +
arr.list[i].weather[0].description +
"</td><tr>" +
"</tr><td>" +
"Min. Temperature" +
"</td><td>" +
arr.list[i].temp.min +
"</td><tr>" +
"</tr><td>" +
"Max. Temperature" +
"</td><td>" +
arr.list[i].temp.max +
"</td><tr>" +
"</tr><td>" +
"Pressure" +
"</td><td>" +
arr.list[i].pressure +
"</td><tr>" +
"</tr><td>" +
"Windspeed" +
"</td><td>" +
arr.list[i].speed +
"</td><tr>" +
"</tr><td>" +
"Humidity" +
"</td><td>" +
arr.list[i].humidity +
"</td><tr>" +
"</tr><td>" +
"Predicted Rainfall" +
"</td><td>" +
arr.list[i].rain +
"</td><td>";
}
out += "</table>";
document.getElementById("table").innerHTML = out;
Array.from( document.querySelectorAll('#table td') ).forEach(function (td) {
td.classList.add('example');
});
}
function getIcon(s) {
return("<img src=\"http://openweathermap.org/img/w/"+s+".png\"/>");
}
</script>
<script>
//function to show and hide pressure, humidity, etc.... doesnt work yet. not connected!
function showHide() {
var checkbox = document.getElementById("chkbox");
var hiddenInput = document.getElementsByClassName("hidden");
for(var i = 0; i !=hiddenInput.length; i++) {
if(checkbox.checked) {
hiddenInput[i].style.display = "inline";
} else {
hiddenInput[i].style.display = "none";
}
}
}
</script>
</body>
</html>
This does, of course, assume that you're correct that you need to append class-names to the elements; with no explanation of the problem you're trying to solve by adding the class-names it's hard to offer better advice.
I suggest you to use 'knockoutjs' for filling in the table by returned Json data. For your purpose it is really suitable. Its absolutely easy to learn. If you interested in this approach you may ask me questions in comments. And i will trying to help you to solve your particular problem.
Reference: Knockout tutorial

Categories