JSP/Struts2: how to access object bean in selected table row - javascript

In my Struts2 application, I have a table that is dynamically populated with data, coming from the database (via Eclipselink JPA). Below that table there's a button that became enabled as soon as a row is selected in the table (jQuery). Now, when that button is clicked, I need to know which row is currently selected, so I can access the corresponding object bean, since I need to pass the bean ID (target_id) into the next page (createexperiment2 action). So, in short, the question is: How can I access the Struts2 object bean that is contained in the selected (clicked) table row?
1. Screenshots:
Before row selection -> After row selection
2. JSP code:
<table id="targets" class="ink-table grey tableSection">
<thead>
<tr>
<th colspan="5" class="align-left">Select your target:</th>
</tr>
</thead>
<tbody>
<s:if test="targets.size > 0">
<s:iterator value="targets">
<tr id="row_<s:property value="i"/>">
<td class="all-100"><s:param name="id"><s:property value="target_id"/></s:param></s:url>"><s:property value="name"/></td>
<td class="all-15"><s:param name="id"><s:property value="target_id"/></s:param></s:url>">edit</td>
<td class="all-5">|</td>
<td class="all-15"><s:param name="id"><s:property value="target_id"/></s:param></s:url>">delete</td>
<td class="all-5">?</td>
</tr>
</s:iterator>
</s:if>
</tbody>
</table>
[...]
<a href="createexperiment2" class="ink-button double-vertical-space all-25 buttonSection" id="next" disabled>Next ></a>
3. jQuery code:
$(document).ready(function(){
$('.tableSection tbody tr').click(function()
{
var selected = $(this).hasClass("highlight");
$('.tableSection tbody tr').removeClass("highlight");
$('.buttonSection').attr("disabled", false);
if(!selected)
$(this).addClass("highlight");
});
});
EDIT 1:
With the help of Andrea, I've finally been able to access Struts2 functions with jQuery, the poblem is that I can only access the properties of the last bean on the table (the last one that was accessed when the JSP was rendered, which makes sense). See the updated code below, while I'll try a workaround for this:
JSP:
<s:if test="targets.size > 0">
<s:iterator value="targets">
<tr onclick="<s:set var="tid" value="target_id"/>">
[...]
</tr>
</s:iterator>
</s:if>
[...]
<script type="text/javascript">
$(function () {
$('.tableSection tbody tr').click(function(event) {
alert ('<s:property value="%{#tid}" />');
});
});
</script>
EDIT 2:
Now I know which table row index has been clicked, but after hours of trying to assign it to a variable (using Struts tags) and send it to the action, I'm still not getting what I want. I'm not even being able to send this row index to the Action. This is frustrating. Nevertheless, that's how I got to know which row has been selected:
<tr onclick="getRow(this)">
[...]
<script>
function getRow(x)
{
alert("Selected row: "+x.rowIndex);
//return x.rowIndex;
}
</script>
EDIT 3:
This time, I was finally able to send the row ID (a String), to the action. The only remaining issue is that the action gets call twice, the first one on the click event, and the other one because of the href attribute of the a HTML element, which redirects to the desired Struts2 action. Apart of being obviously inneficient, this naturally makes the variable become null on the second call to the action. Do you know how can I somehwow "merge" this 2 calls to the createxperiment2 action into only one? I've tried with the async option in the AJAX call set to false, with no success.
[first, removed the onclick event from the table tr, since I only need to know which row is highlighted when the "Next" button is pressed]. The code currently goes like this:
<script type="text/javascript">
$('#next').click(function(event)
{
var row = $('.highlight').index();
alert (row);
$.ajax({
method: "POST",
url: "createexperiment2.action",
data: { row : row }
});
});
</script>

Q: I have assigned an ID to each table row. How can I know which one is the selected one?
Obtain the object's id with the this keyword:
$('.tableSection tbody tr').click(function(event) {
alert (this.id);
...
Q: how can I use the selected table row ID to access the corresponding bean object (represented in the row itself)?
This is not clear: just submit your id and retrieve the object serverside, no matter if through AJAX or a standard form submit.

Finally, the solution:
First get the ID of the object (I made it with Struts). Then, with the help of an AJAX call, send the ID to the desired action (url: attribute). Upon success of this action, define with the success: callback option where you want to redirect it.
Struts / JSP:
<s:if test="targets.size > 0">
<s:iterator value="targets">
<tr id="<s:property value="target_id"/>" class="highlight">
[...]
</tr>
</s:iterator>
</s:if>
jQuery:
<script type="text/javascript">
$('#next').click(function(event)
{
var tid = $('.highlight').attr("id");
$.ajax({
method: "POST",
url: "createexperiment2.action",
data: { tid : tid },
success:
function()
{
//alert("TID -> "+tid);
window.location = "loadworkloads.action";
}
});
});
</script>

Related

reload only TR if clicked

I am listing items from SQL in a HTML table <tr>'s and <td>'s. The table is inside a div that is refreshed with jQuery AJAX in every 30 seconds (that is why the div has a unique id). This part works fine. Here is the HTML:
function auto_load()
{
$.ajax({
url: "/folder/content.php",
cache: false,
success: function(data){
$("#live").html(data);
}
});
}
$(document).ready(function(){
auto_load(); //Call auto_load() function when DOM is Ready
});
setInterval(auto_load,30000);
<div id="live">
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tr>
<td></td>
<td></td>
</tr>
<!-- and so on -->
</table>
</div>
Now what I want to do is make each of the clickable, but so that if it is clicked,
1) a GET request is sent to a PHP file indicating which particular was clicked;
2) and only that particular (or content inside that ) is refreshed right after that, not the whole page.
I cannot do it with a regular http link, as that way if a is clicked, the whole page would be reloaded.
As this is where my knowledge is short, maybe someone kind can share me some ideas on how to solve this. Thanks!
NOt sure what you want exactly, but if I understand you want to load the row? So you want to listen for a click on the row, read the cells, make an ajax call, and replace the content.
$("#live").on("click", "tbody tr", function() { //listen for click on a table row
var tr = $(this), //the row
tds = tr.find("td"), //the cells of the row
id = tds[0].text(), //the first column text
output = tds[1]; //where to output
$.ajax({
method: "POST",
url: "some.php", //where to post the data
data: { id: id } //value to pass to the server
})
.done(function( result ) {
output.html(result); //output the returned value
})
.fail(function() {
alert( "error" );
});
});
If that is not right, and you want to load the entire table, than you just need to look up the tree to get the div.
$(document).on("click", "tr", function() {
var div = $(this).closest("div");
console.log(div.attr("id"));
div.load("foo.php?id=" + div.attr("id"));
});
$('#myTable').on('click', '.someClass',function () {
var trID=$(this).attr('id');
$(this).find('td').append(new Date());//replace this with your AJAX call
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tr id="x" class="someClass"><td>Click Me 1</td></tr>
<tr id="y" class="someClass"><td>Click Me 2</td></tr>
<table>

Delete multiple rows of Table in AngularJS

I have angularjs table added with check boxes to each row and a common remove button outside the table, so that multiple rows can be selected and deleted at a time. When rows are selected and remove is clicked, that particular rows will be deleted. This is fine and till here its working in the below plunker too. Now what I need is when a particular row is selected, its rowid has to be sent as a parameter to another URL. when this URL(URL formed by selected rowIds) with ids is called, automatically the rows will be deleted from first URL data, and now the table has to be updated from first URL. null will be returned from second url with ids as parameters and at the same time that rows will be deleted from JSON data of first URL.
Here is a demo:http://plnkr.co/edit/UzKdIGSubEfHoF7FHoCd?p=preview
Below is the code for the table:
<div ng-controller="SampleController">
<form class="form-horizontal">
<a class="btn btn-info" ng-click="subt_click()">Submit</a>
</form>
<div class="table-responsive" ng-show="tableData.length > 0">
<table class="table table-striped table-bordered table-hover dataTables-example">
<thead>
<tr>
<th><input name="all" type="checkbox" ng-click="selectAllFriends()" /></th>
<th>ID</th>
<th>Body</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in tableData">
<td><input name="all" type="checkbox" ng-model="x.checked" /></td>
<td>{{x.id}}</td>
<td>{{x.body}}</td>
</tr>
</tbody>
</table>
</div>
<input ng-hide="!tableData.length" type="button" class="btn btn-danger pull-left" ng-click="remove()" value="Remove">
app.js:
$scope.remove = function () {
var newDataList = [];
$scope.selectedAll = false;
angular.forEach($scope.tableData, function (checked) {
if (!checked.checked) {
newDataList.push(checked);
}
});
$scope.tableData = newDataList;
};
$scope.isAll = false;
$scope.selectAllFriends = function () {
if ($scope.isAll === false) {
angular.forEach($scope.tableData, function (x) {
x.checked = true;
});
$scope.isAll = true;
} else {
angular.forEach($scope.tableData, function (x) {
x.checked = false;
});
$scope.isAll = false;
}
};
In brief what i need is:
I get table data from first url. (pls check the plunk and the url i used is jsonplaceholder.typicode.com/posts)
When a checkbox is selected from a row in table and remove button is clicked, that rowid has to be sent to second URL(need to call another url, need not post) and this url when called along with selected rowids deletes that particular row details from first url and returns a null.
Finally, the first url data(which will be modified by just calling second url with rowids) has to be updated in the table present already.
How can I change this code to send rowid to second url and call that url to update the table. Thanks in advance!!
$scope.xListNo is never affected in your statements.
May be you wanted to use xListNo which is your function parameter (without $scope) ?
So does index in your second statement, which should be idx.
Double check your variables spelling and it should work !
#Deborah : Went through your Plunker and could not find any code for Posting ids to an URL. Assuming that you are doing that somewhere, Still there can be two cases, whether to remove data as soon as call is made or removing it after response from API call. The better way would be removing after the success of API.
So, what you should do probably is to keep your entire table data in a variable (as you have already done, after your GET call).
//Table Data
$http.get("http://jsonplaceholder.typicode.com/posts")
.success( function(response) {
$scope.tableData = response;
});
Now In remove function you can create an array of rows which are checked and send them to URL..Like:
$scope.remove = function(){
$scope.deletedIds = [];
$scope.tableData.forEach(function(x){
if(x.checked){
$scope.deletedIds.push(x)
}
}
makePostCallFOrDeletion()
}
//use this if POST call
function makePostCallFOrDeletion(){
$http.post("deleteurl", angular.toJson($scope.deleteIds)).then(function(response){
$scope.tableData = response //assuming you get the updated JSON back.
//if you don't get JSON back, delete yourself from JSON, like
$scope.tableData.forEach(function(x,i){
if ($scope.deleteIds.indexOf(x.id) !== -1)
$scope.tableData.splice(i, 1);
}
}
As per my understanding of your question, this should get you going..
EDIT: OP wanted GET call for deleting (which as per my opinion is not a good idea, since number of IDs can be too large)
//use this if GET call
function makePostCallFOrDeletion(){
$http.get("deleteurl" + append IDs here,).then(function(response){
//$scope.tableData = response //assuming you get the updated JSON back.
//if you don't get JSON back, delete yourself from JSON, like
$scope.tableData.forEach(function(x,i){
if ($scope.deleteIds.indexOf(x.id) !== -1)
$scope.tableData.splice(i, 1);
}
}

jQuery AJAX Button Click - Remove Table Row after AJAX Call is Successful

I'm displaying an HTML table and would like to include a button in the last column that, when clicked, performs an AJAX call which will result in the removal of the table row from the table. I'm new to jQuery and AJAX and working things out as I go - I've managed to setup some AJAX calls that run when a field is edited, but now I'm struggling to attach one to a button in a table row.
Here's how the table looks:
<tr class="" id="tableRow1"><td>Store 1</td><td>lorem ipsum</td><td>John Smith</td><td>20/11/2014 12:53:52 AM</td><td><button type="button" id="closeNote" class="btn btn-primary">Acknowledge</button></td></tr>
<tr class="" id="tableRow2"><td>Store 2</td><td>lorem ipsum</td><td>Sally Jones</td><td>20/11/2014 12:53:52 AM</td><td><button type="button" id="closeNote" class="btn btn-primary">Acknowledge</button></td></tr>
<tr class="" id="tableRow3"><td>Store 3</td><td>lorem ipsum </td><td>Bill Howden</td><td>12/11/2014 01:43:03 PM</td><td><button type="button" id="closeNote" class="btn btn-primary">Acknowledge</button></td></tr>
I know that the ID for the button is not unique - at the moment the script only fires when the button in the first row is clicked. I'm not sure how to assign a unique ID for each button which the script can see.
Here's my script:
<script type="text/javascript">
$(document).ready(function() {
$("#closeNote").click(function(){
$.post('editNote.php', { type: 'hideNote', id: '1E1DDA14-D2C6-4FC8-BA5F-DBCCC7ABAF7F' }, function(data) {
data = JSON.parse(data);
if (data.error) {
$("#ajaxAlert").addClass("alert alert-danger").html(data.text);
$("#ajaxAlert").show();
return; // stop executing this function any further
} else {
$("#ajaxAlert").hide();
$(this).closest('tr').remove();
}
}).fail(function (xhr) {
// no data available in this context
$("#ajaxAlert").addClass("alert alert-danger");
//display AJAX error details
$("#ajaxAlert").html(xhr.responseText);
$("#ajaxAlert").show();
});
});
});
</script>
I just need some help in bring this altogether so that when the button is clicked on any row it calls the script which in turn, if the PHP script it then calls is successful, it then removes the row where the button was clicked.
Rather than applying the button to an ID give each link a class:
<button class="btn btn-primary close-note"
Then amend your JS as follows:
$("button.close-note").click(function(){
Inside your callback functions the keyword this no longer refers to the element, but instead refers to the XHR object.
To solve this assign $(this) to a variable outside of the $.post
var $self = $(this);
$.post( ... ... function(response){
// code and stuff
$self.closest('tr').hide();
});
You also need to ensure that the browser doesn't then follow the link; amend the click line again:
.click(function(e){
e.preventDefault();

jquery, remove table row when unchecked

I have a table with rows of data, when a user clicks on the row (tr) or the checkbox, it appends that row of data into another location. How do I make it that when a user unchecks from the original table AND the new appended row, that the row disappears?
I want it so that when the user unchecks from the original table, the appended row disappears. When the user unchecks from the appended row, only the appended row disappears.
// original table
<div id="searchsub">
<table class="showsub">
<tr class="datarow">
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
</table>
</div>
Row appends to this new table:
<table id="datarow">
</table>
Here's the jquery I have:
$(document).ready(function() {
$("#searchsub table tr").click(function(event) {
if(event.target.type !== 'checkbox') {
$(":checkbox", this).trigger("click");
}
});
$i = 1;
$("input[type='checkbox']").change(function(e) {
if($(this).is(":checked")) {
$(this).closest("tr").addClass("highlightrow");
var datarow = $(this).closest("tr.datarow");
var row = datarow.clone();
row.addClass("append" + $i);
$("#submitshipment #datarow").append(row);
$i++;
} else {
$(this).closest("tr").removeClass("highlightrow");
$(".append").closest("tr").remove();
}
})
})
Of course this way whenever the row is unchecked ALL of the rows are deleted, which isn't what I want. Please help?
EDIT: mark up of the appended row:
<tr class="datarow highlightrow append1">
<td>120093</td>
<td>G13</td>
<td><input type="checkbox" class="searchsub" name="searchsub[]" value="1"></td>
</tr>
jsFiddle:
http://jsfiddle.net/7cXqR/1/
Yes, unfortunately the non-functional jsFiddle doesn't really help ;-)
I think I've sorted out what you're trying to do though; the issue is you don't have anything (be it using jQ .data() or in markup) that relates your appended rows to your source rows. If you look at the jsFiddle I made (forked from yours) you'll see how I use the "value" attribute you have on the checkbox in the source table to find the cloned rows in the append table:
$('#datarow').find('input:checkbox[value="' + $(this).val() + '"]').closest('tr').remove();
http://jsfiddle.net/A4w59/
This approach could be modified to use any markup (stock or custom data-* attributes) or even jQ's .data() method; the key is being able to associate the source & append rows so that you can remove the appended row when unselecting it in the source table.

Can't click button more than one time when append html data

I've a problem with jquery. I use ajax to send id to delete from DB and then return html file to update content without reload page (I use struts 2) , first time run or reload page my button work fine ( row was deleted and my content was updated) but when I try to click button again , it doesn't respond.
My script
$(document).ready(function() {
$(".btnEdit").click(function() {
alert("Edit");
});
$(".btnDelete").click(function() {
id = $(this).attr('id');
alert("Delete ID : " + id);
$.ajax({
url: "delete",
type: 'POST',
data: {'id': id},
cache: false,
success: function(data, textStatus, jqXHR) {
$('.catagoryContent').remove();
$('.container').append(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert("error");
}
});
});
});
Sorry, I forgot return data code.
<div class="catagoryContent">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Edit / Delete</th>
</tr>
</thead>
<tbody>
<s:iterator value="catagoryList" var="catagory">
<tr>
<td>${catagory.id}</td>
<td>${catagory.name}</td>
<td>
<button class="btn btn-primary btnEdit" id="${catagory.id}">Edit</button>
<button class="btn btn-warning btnDelete" id="${catagory.id}">Delete</button>
</td>
</tr>
</s:iterator>
</tbody>
</table>
At document ready you initialize all tags with class "btnDelete" to the click function.
When you do a successfully ajax call, you replace all your content with response from the server.
At that point you remove all your buttons and add new data with new buttons.
jQuery is not listening to these buttons because the $(".btnDelete").click(... was only set at page load.
if you change
$(".btnDelete").click(function() {
to
$(document).on("click", ".btnDelete", function() {
it will still work after you add new data to .container
The "on" function also triggers when you dynamically add new tags with class ".btnDelete" (See here)
You aren't listening to the click event on your updated html.
You should use
$list.on('click', '.btnEdit', function() { ... })
where $list is the element containing the items (probably a <ul>)
This is because click event handler is attached at the page startup.
But when you reload the part of your page, old button with onclick handler is being removed.
The decision is to use
$(document.body).delegate('.btnDelete', 'click', function(){...})
instead of
$(".btnDelete").click(function(){...})
This way you will attach event handler to body element (which will fire always), and jQuery will check whether the clicked element has class .btnDelete, or not.
So it will work even if you delete these buttons and then insert new ones.
Another approach is to attach onclick handlers to the buttons every time they created, but I think the first approach is easier

Categories

Resources