React not ordering JSX elements correctly - html

I'm new to React.
Here is my code inside a React component:
for (var i = 0; i < fields.length; i++) {
rows.push(
<tr>
<td>...</td>
<td>...></td>
</tr>
)
}
return (
<tr>
<form className="updateForm" onSubmit={this.handleSubmit}>
<td>
<table>
{rows}
</table>
</td>
<td>
<button id={this.props.id} name="Update" type="button">Update</button>
<button id={this.props.id} name="Delete" type="button">Delete</button>
<button id={this.props.id} name="Add" type="button">Add</button>
</td>
</form>
</tr>
Here is the output HTML:
<tr data-reactid=".au4np63w8w.1.0.1.0.$0">
<form class="updateForm" data-reactid=".au4np63w8w.1.0.1.0.$0.0"></form>
<td data-reactid=".au4np63w8w.1.0.1.0.$0.0.0">
<table data-reactid=".au4np63w8w.1.0.1.0.$0.0.0.0">
<tbody>
...
</tbody>
</table>
</td>
<td data-reactid=".au4np63w8w.1.0.1.0.$0.0.1">
<button id="0" name="Update" type="button" data-reactid=".au4np63w8w.1.0.1.0.$0.0.1.0">Update</button>
<button id="0" name="Delete" type="button" data-reactid=".au4np63w8w.1.0.1.0.$0.0.1.1">Delete</button>
<button id="0" name="Add" type="button" data-reactid=".au4np63w8w.1.0.1.0.$0.0.1.2">Add</button>
</td>
</tr>
Notice that the form element that is supposed to include the table cells renders so that the table cells are outside of the form. I would expect that it should all be WYSIWYG. Am I doing something wrong or is it an actual bug? BTW, I'm using Babel with Webpack to parse JSX.

This is not a bug in React but rather the browser cleaning your erroneous semantics up.
A form element is not allowed as a direct child of a tr element. That's why your browser/React is outputting the HTML you see.
Paste below HTML in JSBin/Fiddle or the W3 validator and see the results
<table>
<tr>
<form>
<td>Hello!</td>
</form>
</tr>
</table>
A td can contain a form or a form can contain a table.

Related

esp32, button onclick Can't find variable: of function

I cant get any of the buttons using onclick to recognise the functions. I get an error "cant find variable". Im very new to all this and at a loss. It doesn't matter which button I click I have the same issues with all of them.
in the below code,
I click on <button onclick="show_admin()">Admin</button> which should call function show_admin().. What am I doing wrong please.
Inspector output
const char main_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset='UTF-8'">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="refresh" content="500; url=/">
<title>System Settings</title>
<body onload="show_admin()">
<div class="banner">
<h1>X Controller</h1>
</div>
<div class="split left">
<div class="centered">
These are my button
<button onclick="show_admin()">Admin</button>
<br/>
<button onclick="show_wifi()">WIFI</button>
<br/>
<button onclick="show_tags()">Tags</button>
<br/>
</div>
</div>
<div class="split right">
<div class="centered" id="showdata">
</div>
</div>
</body>
<script>
These are my functions
function show_admin() {var table_data = <h1>Admin Settings</h1><br/>%s<br/>
<form action="/ADMINSetting" method="POST">
<table><tr>
<td> User Name </td> <td> <input type="String" name="UserName" placeholder="%s"></td>
</tr><tr>
<td> Password </td> <td> <input type="String" name="UserPass" placeholder="%s">
</td></tr></table>
<input type="submit" value="Update Admin Details">
</form>
document.getElementById("showdata").innerHTML = table_data
}
function show_wifi() { var table_data = <h1>WIFI Settings</h1><br/>%s<br/>
<form action="/WIFISetting" method="POST">
<table>
<tr>
<td> SSID Network </td> <td> <input type="String" name="WifiSsid" placeholder="%s"></td>
</tr><tr>
<td> SSID Password </td> <td> <input type="String" name="SsidPass" placeholder="%s"></td>
</tr>
</table>
<input type="submit" value="Update Wifi Details">
</form>
document.getElementById("showdata").innerHTML = table_data
}
function show_tags() { let table_data = <h1>Tag Settings</h1><br/>%s<br/>
<form action="/DEVICESetting" method="POST">
<table>
<tr>
<td> Access Tag 1 </td> <td> <input type="String" name="TAG1" placeholder="%s"></td>
</tr>
<tr>
<td> Access Tag 2 </td> <td> <input type="String" name="TAG2" placeholder="%s"></td>
</tr>
<tr>
<td> Cleaner Tag 1 </td> <td> <input type="String" name="CTAG1" placeholder="%s"></td>
</tr>
</table>
<input type="submit" value="Update BLE Tag Details">
</form>
document.getElementById("showdata").innerHTML = table_data
}
</script>
</body>
</html>
)=====";
I have tried rearranging the function and moving its position. with no luck
Unless you have JSX installed, You can't just stick HTML elements into JavaScript like that. You will need to use quotes around all the HTML.
It looks like you're reusing the same tags anyway, why not stick all those tags into the HTML portion and update the values in Javascript? You can also update the CSS through JavaScript and set display:none if you want to hide an unused element.
I added the below to the html section
<div class="split right">
<div class="centered" id="showdata">
<form id="adminForm">
<table>
<tr>
<td> User Name </td>
<td>
<input type="String" name="UserName" placeholder="%s">
</td>
</tr>
<tr>
<td> Password </td>
<td>
<input type="String" name="UserPass" placeholder="%s">
</td>
</tr>
</table>
<input type="submit" value="Update Admin Details">
</form>
and the following to the script section
function admin(){
document.getElementById("wifiForm").style.display="none";
document.getElementById("tagForm").style.display="none";
document.getElementById("adminForm").style.display="block";
}

Submit not submitting form but moving cursor to input field

I'm out of options and a bit frustrated. I'm not that familiar with HTML but I have got two forms one where a button of the type="submit" sends my view model to the server side controller and this here where it does not do it. In this form, if I click the submit button the cursor gets moved to the Surcharges[i].Price input field in my table instead. The only difference between the two forms is that this form here has input fields in the table whereas the other has select fields.
<form autocomplete="off" asp-controller="PriceList" asp-action="UpdateSurchargeFixPrices" enctype="multipart/form-data">
<div class="container">
<div class="card">
<div class="card-header bg-primary text-white">
<h4 class="text-center">#localizer["PriceListEdit"]</h4>
</div>
<div class="card-body">
<input hidden value="#Model.BackTo" asp-for="BackTo" />
<table class="table">
<thead>
<tr class="table-secondary">
<th>#localizer["Bezeichnung"]</th>
<th>#localizer["Gruppe"]</th>
<th>#localizer["Code"]</th>
<th>#localizer["Maximaler Wert in"] #Model.Currency</th>
<th>#localizer["Preis in"] #Model.Currency</th>
</tr>
</thead>
<tbody>
#if (Model.Surcharges != null)
{
for (int i = 0; i < Model.Surcharges.Count; i++)
{
<tr>
<td><input hidden value="#Model.Surcharges[i].Id" asp-for="Surcharges[i].Id" /><input value="#Model.Surcharges[i].Description" asp-for="Surcharges[i].Description" /></td>
<td>
<input value="#Model.Surcharges[i].Group" asp-for="Surcharges[i].Group" />
</td>
<td>
<input value="#Model.Surcharges[i].Code" asp-for="Surcharges[i].Code" />
</td>
<td>
<input value="#Model.Surcharges[i].MaxValue" asp-for="Surcharges[i].MaxValue" />
</td>
<td>
<input value="#Model.Surcharges[i].Price" asp-for="Surcharges[i].Price" />
</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
<a class="btn btn-primary" asp-controller="PriceList" asp-action="BackTo" asp-route-backTo="#Model.BackTo">#localizer["zurück"]</a>
<a class="btn btn-primary" asp-controller="PriceList" asp-action="NewSurchargeFixPrice">#localizer["neuer Aufschlag"]</a>
<button class="btn btn-primary" type="submit">#localizer["speichern"]</button>
</div>
</form>
I change the input field to
< input formnovalidate="formnovalidate".../>
and now I can reach the breakpoint in my controller.

Change input format in dynamic table: dropdown, number, date

I'm working on dynamic 3 column table that has 3 input text type : Product, quantity and date
This works good but i want to change type format:
Product column => Dropdown type
Quantity column => number type
Date column => Date type (dd-mm-yyyy)
How i do change it?
Thank you
Original source: link
Code online: https://jsfiddle.net/bvotcode/r61ptxe9/7/
HTML
<body>
<div id="wrapper">
<table align='center' cellspacing=2 cellpadding=5 id="data_table" border=1>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Date</th>
</tr>
<tr id="row1">
<td id="product_row1">Car</td>
<td id="quantity_row1">10</td>
<td id="date_row1">20/12/2021</td>
<td>
<input type="button" id="edit_button1" value="Edit" class="edit" onclick="edit_row('1')">
<input type="button" id="save_button1" value="Save" class="save" onclick="save_row('1')">
<input type="button" value="Delete" class="delete" onclick="delete_row('1')">
</td>
</tr>
<tr id="row2">
<td id="product_row2">Book</td>
<td id="quantity_row2">22</td>
<td id="date_row2">26</td>
<td>
<input type="button" id="edit_button2" value="Edit" class="edit" onclick="edit_row('2')">
<input type="button" id="save_button2" value="Save" class="save" onclick="save_row('2')">
<input type="button" value="Delete" class="delete" onclick="delete_row('2')">
</td>
</tr>
<tr id="row3">
<td id="product_row3">Laptop</td>
<td id="quantity_row3">44</td>
<td id="date_row3">19/01/2022</td>
<td>
<input type="button" id="edit_button3" value="Edit" class="edit" onclick="edit_row('3')">
<input type="button" id="save_button3" value="Save" class="save" onclick="save_row('3')">
<input type="button" value="Delete" class="delete" onclick="delete_row('3')">
</td>
</tr>
<tr>
<td><input type="text" id="new_product"></td>
<td><input type="text" id="new_quantity"></td>
<td><input type="text" id="new_date"></td>
<td><input type="button" class="add" onclick="add_row();" value="Add Row"></td>
</tr>
</table>
</div>
</body>
</html>
</body>
CSS
.pt-3-half { padding-top: 1.4rem; }
Javascript
function edit_row(no)
{
document.getElementById("edit_button"+no).style.display="none";
document.getElementById("save_button"+no).style.display="block";
var product=document.getElementById("product_row"+no);
var quantity=document.getElementById("quantity_row"+no);
var date=document.getElementById("date_row"+no);
var product_data=product.innerHTML;
var quantity_data=quantity.innerHTML;
var date_data=date.innerHTML;
product.innerHTML="<input type='text' id='product_text"+no+"' value='"+product_data+"'>";
quantity.innerHTML="<input type='text' id='quantity_text"+no+"' value='"+quantity_data+"'>";
date.innerHTML="<input type='text' id='date_text"+no+"' value='"+date_data+"'>";
}
function save_row(no)
{
var product_val=document.getElementById("product_text"+no).value;
var quantity_val=document.getElementById("quantity_text"+no).value;
var date_val=document.getElementById("date_text"+no).value;
document.getElementById("product_row"+no).innerHTML=product_val;
document.getElementById("quantity_row"+no).innerHTML=quantity_val;
document.getElementById("date_row"+no).innerHTML=date_val;
document.getElementById("edit_button"+no).style.display="block";
document.getElementById("save_button"+no).style.display="none";
}
function delete_row(no)
{
document.getElementById("row"+no+"").outerHTML="";
}
function add_row()
{
var new_product=document.getElementById("new_product").value;
var new_quantity=document.getElementById("new_quantity").value;
var new_date=document.getElementById("new_date").value;
var table=document.getElementById("data_table");
var table_len=(table.rows.length)-1;
var row = table.insertRow(table_len).outerHTML="<tr id='row"+table_len+"'><td id='product_row"+table_len+"'>"+new_product+"</td><td id='quantity_row"+table_len+"'>"+new_quantity+"</td><td id='date_row"+table_len+"'>"+new_date+"</td><td><input type='button' id='edit_button"+table_len+"' value='Edit' class='edit' onclick='edit_row("+table_len+")'> <input type='button' id='save_button"+table_len+"' value='Save' class='save' onclick='save_row("+table_len+")'> <input type='button' value='Delete' class='delete' onclick='delete_row("+table_len+")'></td></tr>";
document.getElementById("new_product").value="";
document.getElementById("new_quantity").value="";
document.getElementById("new_date").value="";
}
You're using the type="text" for all of the <input> tags. You should consider changing the type of the inputs in your edit_row function.
For numbers, the type of input should be number;
For dates, date;
And finally, to render a dropdown box, the best solution is to use a <select> tag instead of an <input>. Don't forget to write all the options of your dropdown inside of <option> tags (which should be all inside of one <select> tag); Here you can find a simple explanation on how to use the <select> tag.

Table with identical submit button in every row: first submit button doesn't work (multiple same ids?)

I have a table which show product's files. A file can have a note added. If a note was added, it is displayed in a row. If not, text area field with submit button is displayed instead.
Short story, it all works, except for the first row without a note. After typing a note and clicking submit button nothing happens.
HTML:
<div id="files-list" style="display: none">
<table class="table">
<thead>
<tr>
<th>File</th>
<th>Date</th>
<th>Notes</th>
<th></th>
</tr>
</thead>
<tbody>
<c:if test="${fn:length(bean.product.files)>0}">
<c:forEach items="${bean.product.files}" var="na">
<tr>
<td>${na.name}</td>
<td><fmt:formatDate value="${na.created}" pattern="yyyy-MM-dd HH:mm" /></td>
<td>
<c:if test="${empty na.note}">
<form:form id="${na.id}" method="POST" modelAttribute="bean" action="${pageContext.request.contextPath}/app/updateFile.ajax?id=${bean.product.id}&fileId=${na.id}" style="display: inline">
<form:textarea path="prodFiles" rows="1" cols="50" />
<input type="hidden" name="version" value="${bean.product.version}">
<input type="submit" id="submitButton" value="Save it!" />
</form:form>
</c:if>
<c:if test="${not empty na.note}">
<div style="max-width: 400px">${na.note}</div>
</c:if>
</td>
<td><button type="button" class="btn btn-xs btn-danger" onclick="$().mkdelformTable('${pageContext.request.contextPath}/app/deleteFile.ajax?id=${bean.product.id}&fileId=${na.id}', this)">Delete it!</button></td>
</tr>
</c:forEach>
</c:if>
</tbody>
</table>
</div>
Possible hints:
When I open the table (it's a pop-up) console shows multiple [DOM] Found X elements with non-unique id errors
Checking elements in dev's tools I noticed that the first row doesn't include the form part. Possibly connected with the multiple-same-ids problem. Example:
<td>
<textarea id="prodFiles" name="prodFiles" rows="1" cols="50"></textarea>
<input type="hidden" name="version" value="181">
<input type="submit" id="submitButton" value="Save it!">
</td>
VS
<td>
<form id="65" style="display: inline" action="/oferty/app/updateFile.ajax?id=12701&fileId=65" method="POST">
<textarea id="prodFiles" name="prodFiles" rows="1" cols="50"></textarea>
<input type="hidden" name="version" value="181">
<input type="submit" id="submitButton" value="Save it!">
</form>
</td>
Edit: Also, new files can be added so hard-coding different names/ids can't be done, if suggested.
As I found out, there was some legacy code. I managed to get rid of 'multiple same ids' etc. errors by adding a note in an additional pop-up - on a previos page, instead of an input, I included a button to the new pop-up.

Ajax loading HTML form is closing directly

I am loading an Ajax form with Smarty and jQuery.
It should load this:
{foreach $topFEED as $article}
<tr>
<td><form action='postbox.php' method='POST'></td>
<td><img class="favicon_prev" src="http://www.google.com/s2/favicons?domain={$article.img_link}"> <input type="text" name="link" style="width: 300px;" value="{$article.link}" READONLY/></td>
{if $loggedin}<td><input type='submit' id="abo" name="submit" value='Abonnieren' /></td>
<input type='hidden' name="action" value='add_feed' READONLY />{/if}
<td></form></td>
</tr>
{/foreach}
Ajax Code:
$.ajax({
type: 'GET',
url: "article.php?method=top_feeds",
dataType: 'html',
})
.done(function(html) {
$("#ajax_top_feeds").replaceWith(html);
});
Result:
<tr>
<td><form action="postbox.php" method="POST"></form></td>
<td><img class="favicon_prev" src="http://www.google.com/s2/favicons?domain=http://www.n-tv.de"> <input type="text" name="link" style="width: 300px;" value="http://www.n-tv.de/rss" readonly=""></td>
<td><input type="submit" id="abo" name="submit" value="Abonnieren"></td>
<input type="hidden" name="action" value="add_feed" readonly=""> <td></td>
</tr>
Your HTML is invalid, the browser is simply correcting it for you. form elements can't cross multiple table cells like that.
You can wrap a form around your entire table:
<form>
<table>
<!--- etc. --->
</table>
</form>
Or you can place a form inside of a table cell:
<table>
<tr>
<td>
<form>
<!--- etc. --->
</form>
</td>
</tr>
</table>
But you can't begin a form in one cell and end it in another. The hierarchy of HTML markup isn't structured that way. Tags must be closed before parent tags are closed.