Edit a specified cell in a table - jsp - javascript

I need some help with javascript/jquery or ajax.
A am writing a java web app and have question regarding table.
I need to have the possibility to edit one (and only one specified cell). In this case I have the "status" field. When clicking on the value I'd like to have a dropdown list with 2 possibilities to choice: "active" and "passive".
I tried to figure it out, but without success.
Here is my code:
<body>
<table border = "1">
<tr>
<td>name</td>
<td>surname</td>
<td>status</td>
</tr>
<tr>
<td> Adam</td>
<td>Smith</td>
<td id = "status" onclick = "update(this.id)">active</td>
</tr>
</table>
<script type = "text/javascript">
function update(id){
var content = document.getElementById(id).firstChild.nodeValue;
document.getElementById(id).innerHTML = "<input type = 'text' name = 'txtNewInput' id = 'txtNewInput' value = '" + content + "'/>";
}
</script>
</body>
In this case when I click on the cell the value changes to "null" and it is not editable anymore.

You want to do something like this:
<td>
<input
type='text'
name='txtNewInput'
id='txtNewInput'
value='<c:out value="${person.status}" />'
onChange='AjaxCallToUpdateDB(this.id, this.value)'
/>
</td>
Actually sending the update to the database when the user makes a change requires more than making this an input: you need an Ajax call to a Servlet to save the value in the database.

Related

Which event to trigger, programmatically simulating user blur

I'm using Power Automate Desktop with an Execute Javascript flow to try to automate some user entry in a Quickbooks Online Payroll form.
When natively using the form, it seems there is an event triggered on blur to validate the numerical input, among other things.
Using the JS flow, updating the input values is not being recognized by the form as once I save it, it shows those inputs as empty.
So I thought I need to trigger the blur event to get the data to save. Here is my JS script:
function ExecuteScript() {
var $payrollTableRows = $("table").first().find("tbody > tr.enabled");
var $regHoursInput;
var decRegHours;
var $bonusInput;
var employeeName;
console.log('Power Automate: Rows Found: ' + $payrollTableRows.length);
$payrollTableRows.each(function(){
employeeName = $(this).find("td:eq(1)").find("a").text();
$regHoursInput = $(this).find("input[wageitemid='HOURLY_PAY']");
if($regHoursInput){
decRegHours = Number($regHoursInput .val());
$bonusInput = $(this).find("input[wageitemid='BONUS']");
$bonusInput.focus();
if($bonusInput){
$bonusInput.val(decRegHours);
$bonusInput.trigger('blur');
}
}
});
}
Here is the script that gets executed on focus and blur on the QB Payroll page.
Why does the script initiated triggers not fire this code?
UPDATE 1:
Adding image of page:
UPDATE 2:
Posting the PAD flow I used. Also got a good overview of this from this video. And how to use Loop and Loop Index from this article.
My Flow:
To do something similar without relying on the JavaScript you could use a variable and loops.
Html used for this flow:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Column A</th>
<th>Column B</th>
<th>Column C</th>
<th>Column D</th>
</tr>
</thead>
<tbody>
<tr>
<td>A <input type="text" id="text-1-input" value="One"></td>
<td>B <input type="text" id="text-2-input" value="Two"></td>
<td>C <input type="text" id="text-3-input" value="Three"></td>
<td>D <input type="text" id="text-4-input" value="Four"onblur="txtOnblur();"></td>
</tr>
<tr>
<td><input type="text" id="text-5-input" ></td>
<td><input type="text" id="text-6-input" ></td>
<td><input type="text" id="text-7-input" ></td>
<td><input type="text" id="text-8-input" hidden></td>
</tr>
</tbody>
</table>
</div>
<script src="https://code.jquery.com/jquery-3.6.1.slim.min.js"></script>
<script>
function txtOnblur(){
$("#text-8-input").show(true);
$("#text-8-input").val('blur triggered!');
}
</script>
</body>
</html>
I used a bit of JavaScript to extract the number of columns and rows in the table, this could have been done with the flow function 'Extract data from web page', but I find the JavaScript a bit faster/easier.
function ExecuteScript() {
var table = document.querySelector('body > div > table');
var colCount = table.children[0].children[0].children.length;
var rowCount = table.children[1].children.length;
return `${colCount} ${rowCount}`
}
Declare one UI element of the first input box. You can reuse this element by replacing/changing the selector properties to use a variable.
In the flow assign the value that will match the HTML selector for the particular control.
and then use the same element wherever you want to change/extract a value (remember the variable now sets the UI element)
The full flow code (copy this and paste it to PAD to see the details)
There will be errors on your side, but you will see the flow.
WebAutomation.LaunchEdge.AttachToEdgeByUrl TabUrl: $'''http://localhost/stackoverAnswer/''' AttachTimeout: 5 BrowserInstance=> Browser
WebAutomation.ExecuteJavascript BrowserInstance: Browser Javascript: $'''function ExecuteScript() {
var table = document.querySelector(\'body > div > table\');
var colCount = table.children[0].children[0].children.length;
var rowCount = table.children[1].children.length;
return `${colCount} ${rowCount}`
}''' Result=> cols_rows
Text.SplitText.Split Text: cols_rows StandardDelimiter: Text.StandardDelimiter.Space DelimiterTimes: 1 Result=> ColsAndRows
Text.ToNumber Text: ColsAndRows[0] Number=> numCols
Text.ToNumber Text: ColsAndRows[1] Number=> numRows
LOOP colIdx FROM 1 TO numCols STEP 1
SET inputBoxVariable TO $'''text-%colIdx%-input'''
WebAutomation.GetDetailsOfElement BrowserInstance: Browser Control: appmask['Web Page \'http://localhost/stackoverAnswer/\'']['Input text \'text-1-input\''] AttributeName: $'''Own Text''' AttributeValue=> inputBoxValue
IF colIdx = 4 THEN
WebAutomation.Focus.Focus BrowserInstance: Browser Control: appmask['Web Page \'http://localhost/stackoverAnswer/\'']['Input text \'text-1-input\''] WaitForPageToLoadTimeout: 60
MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False
END
SET inputBoxVariable TO $'''text-%colIdx + 4%-input'''
IF inputBoxValue <> $'''Three''' THEN
WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserInstance: Browser Control: appmask['Web Page \'http://localhost/stackoverAnswer/\'']['Input text \'text-1-input\''] Text: inputBoxValue Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: False WaitForPageToLoadTimeout: 60
ELSE
WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserInstance: Browser Control: appmask['Web Page \'http://localhost/stackoverAnswer/\'']['Input text \'text-1-input\''] Text: $'''Skip this one''' Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: False WaitForPageToLoadTimeout: 60
END
END
How it runs:
I don't have QB but I put together a quick html page with a script.
This is the html
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Column 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>Value <input type="text" id="text-1-input" onblur="txtOnblur();">1</td>
</tr>
<tr>
<td>Value <input type="text" id="text-2-input" hidden></td>
</tr>
</tbody>
</table>
</div>
<script src="https://code.jquery.com/jquery-3.6.1.slim.min.js"></script>
<script>
function txtOnblur(){
$("#text-2-input").show(true);
$("#text-2-input").val('blur triggered!');
}
</script>
</body>
</html>
When I run the following script on the page with Power automate it triggers the onblur event on the textbox
function ExecuteScript() {
var $txt = $("input[id='text-1-input']");
$txt[0].onblur();
}
In action:
When I try and call the code in a similar way as you do I only get the list of controls linked to the blur event.
I'm assuming it's jQuery being used in QB. I tend to stick to native JavaScript when it comes to PAD, more typing, but less abstraction.

can't print a variable in a table from json recordset

I have a Json recordset, that is working perfectly, however so far I can't sort out how to place a value of the json array into an specific cell of a table.
this is my function that looks for the form and start printing the values but only if there is an input component inside the table
function process_response(response) {
var frm = document.getElementById("form-ajax");
var i;
console.dir(response); // for debug
for (i in response) {
if (i in frm.elements) {
frm.elements[i].value = response[i];
}
}
}
and this is table
form id="form-ajax" action="form-ajax.php">
<table class="table">
<thead>
<tr>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" id="name" name="ID" maxlength="12" size="12"></td>
<th scope="row"><input type="submit" value="1" /></th>
<td></td>
this is the place where I want to the resultset without the need of place a input
if I place something like this.
<td><input type="text" name="1" /></td>
then the javascript works and it reads whatever is in the json name with 1.
but if I do something like this.
<td name="1"></td>
then nothing prints out.
Whatever I do different than place an input type="text" then the Function doesn't work.
I need to populate the table with an specific order from the json .
TDs are not part of a form and do not have value or name attributes
You could do
var tds = document.querySelectorAll("td[name]");
for (var i=0;i<tds.length;i++) {
tds[i].innerText=response[tds[i].getAttribute("name")];
}
assuming the name attribute matches the response key
You also likely do not want to have a submit button but a type="button"
I figure out a way to print an specific value inside the table ...
var s = document.getElementById("so");
s.innerHTML =response['sort'];
this way I force td component with ID="SO" to print the value I passed over the json file.
<td id="so"></td>

Rows-Element, where are these whitespaces coming from?

First: My problem is that by inserting strings into several fields of a form from a row via DOM, the values occure with a lot of whitespaces, both at the beginning and the end.
What I want to do:
look up the values of the cells in the row I doubleclicked, and put these values in the fields of a form.
The HTML is equivalent to :
<form>
<fieldset>
<legend> Very Important </legend>
<label for="input_representing_all_the_inputs">
<input id="input_representing_all_the_inputs"></input>
</fieldset>
</form>
<table id="issue_table" class="sortable", border="1" >
<tr ondblclick="values_into_form(issue_table)">
<td>
a value
</td>
<td>
another one
<td>
</tr>
<tr ondblclick="values_into_form(issue_table)">
<td>
here's also another value
</td>
<td>
aaand one more.
</td>
</tr>
</table>
<table id="not_the_issue_table" class="sortable", border="1">
[...] blabla looks similar [...]
</table>
Now I got a js function to look up values from the table and putting them into the form.
function values_into_form( id ) {
//find index of row with given id
for (i = 0; i<= document.getElementById("accl_content").rows.lenght; i++){
if ( document.getElementById("issue_table").rows[i].id == id) {
var idx = i;
break;
}
}
// now insert the values into the editor-form
document.getElementById("input_representing_all_the_inputs" =
document.getElementById("issue_table").rows[idx].cells[0];
// repeat the above for each input_field with the specific cell_idx.
}
}
So now, let's look at the first of the first of issue_table.
The value is "a value". However, the inputfield will contain something like " a value ".
Is there a specific misstake I made to produce this?
I don't want a solution to get rid of the whitespaces, I want a real solution, want to say, I don't want them to occure at all.
I'm fresh to JS, coming from lua. So if I made some conceptional misstakes, I would be happy if you could tell me in a sidenote.
Change your html to this:
<table id="issue_table" class="sortable", border="1" >
<tr ondblclick="values_into_form(issue_table)">
<td>a value</td>
<td>another one<td>
</tr>
<tr ondblclick="values_into_form(issue_table)">
<td>here's also another value</td>
<td>aaand one more.</td>
</tr>
</table>
The spaces are because in your html there are spaces. You could of course alternatively strip beginning and ending white spaces using javascript. But if you do not want to do that, the above solution should work.
It is good practice to separate HTML and JavaScript.
JavaScript:
var myTable = document.getElementById("myTable");
var myInput = document.getElementById("myInput");
var td = myTable.getElementsByTagName("td");
for(var i = 0; i < td.length; i += 1) {
td[i].addEventListener("dblclick", function() {
myInput.value = this.innerHTML;
});
}
Demo

Uncaught TypeError: Illegal invocation:error with modal form

this is my first question in stackoverflow, in my html page i have a table, i want to send data to the servlet using modal form. But, i have this error :Uncaught TypeError: Illegal invocation.
table.html
<body>
<table border="1">
<tr>
<th>ID</th>
<th>NAME</th>
<th>ACTION</th>
</tr>
<tr>
<td>1</td>
<td>JHON</td>
<td><input type="button" value="display" class="d"></td>
</tr>
<tr>
<td>2</td>
<td>Max</td>
<td><input type="button" value="display" class="d"></td>
</tr>
</table>
<div id="dialog-form">
<input type="text" value="" id="id">
<input type="text" value="" id="name">
</div>
<div id="res"></div>
</body>
test.js
$(".d").click(function(){
var id =$("#id").attr("value",$(this).parent().prev().prev().text());
var name =$("#name").attr("value",$(this).parent().prev().text());
$("#dialog-form").dialog({
modal: true,
buttons: {
"Send":function () {
$.post("Controller",{id:id,name:name},function(data){
$("#res").html(data);
}) ;
}
Servlet.java
String name=request.getParameter("name");
String id=request.getParameter("id");
out.println(id +" "+ name);
I guess you are trying to modify the value and update it in the backend.
var id =$("#id").attr("value",$(this).parent().prev().prev().text());
var name =$("#name").attr("value",$(this).parent().prev().text());
This will assign the objects to the variables id and name. You cannot send them in ajax and you don't need to. Hence the error.
In your case, you need to update the modal text box with the id and name values and send them to the server. Also do note that since it is a text box, you need to send the updated value which the user might have changed.
Hence we do the following changes.
First we just set the id and name values in the text box present in the modal
$("#id").attr("value", $(this).parent().prev().prev().text());
$("#name").attr("value", $(this).parent().prev().text());
Then in the ajax post, we send the updated value taken from the text box
$.post("Controller", {
id: $("#id").val(),
name: $("#name").val()
}, function (data) {
$("#res").html(data);
});
Here is the working code http://jsfiddle.net/xec61c0m/

Trace the particular row from a result set and then getting column value of that row

<%
while(rs.next())
{
String flight_no=rs.getString("flight_no");
String flight_name=rs.getString("flight_name");
String from =rs.getString("from");
String to=rs.getString("to");
SimpleDateFormat reFormat = new SimpleDateFormat("YYYY-MM-DD") ;
Date activityDate =rs.getDate("departure");
java.sql.Date departure = new java.sql.Date(activityDate.getTime());
String departure_time=rs.getString("departure_time");
String arrival_time=rs.getString("arrival_time");
int avail_seatss=rs.getInt("avail_seats");
%>
<TR>
<TD align=left><%out.print(to);%></TD>
<TD align=left width=10%><value="<%out.print(flight_no); %>"/></TD>
<TD align=left width=20%><value="<%out.print(from);%>"/></TD>
<TD align=left width=20%><value="<%out.print(to);%>"/></TD>
<TD align=left width=10%><value="<%out.print(departure);%>"/></TD>
<TD align=left width=10%><value="<%out.print(departure_time);%>"/></TD>
<TD align=left width=10%><value="<%out.print(arrival_time);%>"/></TD>
<TD align=left width=5%><value="<% out.print(avail_seatss);%>"/></TD>
<TD align=left width=10%><input type="button" name="Book_Now" value="Book Now">
</TR>
}
I have a sql resultset in jsp. i have added a new column which has a button.
i want that when user clicks that button , it fetches the column value of that particular row .i find a method to only trace rows in javascript but i didnt find any method to do so in jsp. i was able to track the row but how to get the value of column of that row wasnt working. Help !
In the above example i want that when user clicks the particular row's book now button then it returns me the flight no. of that row. The result set contains multiple rows and result is purely dynamic.
Delegate an onclick method for the button like
onclick="book_now(this)"
Then in book_now function you can get the flight number with
function book_now(elem){
var flight_no = elem.parentNode.parentNode.children[1].innerHTML;
// do your stuff with flight_no
}
FIDDLE
EDIT
You can get that flight_no in 2 ways. 1st you can store it in a cookie/storage and read it from the other page. 2nd and the one i recommend you can simply redirect the page with query in the function like
function book_now(elem){
var flight_no = elem.parentNode.parentNode.children[1].innerHTML;
window.open("2ND_PAGE_URL?flight_no=" + flight_no, "_self");
}

Categories