Center a dynamically generated table cell in the window - javascript

I'm working on an employee directory that allows a user to search for an employee and show information about them in a tree/org-chart type layout. I'm using Google's Org Chart code to draw the chart. It displays each employee's contact card in a <td> with managers and subordinates above or below it in a different <tr>. The output looks something like this:
If an employee has more than a small handful of subordinates, the user has to scroll horizontally in order to see them all. Not a problem.
My problem is that if there are more than 10 or so, you lose sight of the employee you searched for completely and have to scroll right until you find them:
This seems like it would be annoying. I tried just dropping a <a name="anchor"> into the card and jumping to it on page load but it only scrolls far enough to barely put it on screen.
Ideally, it would center the card, putting it right in the user's focus.
Is there a way to jump directly to the employee in question when the page loads?
If it helps, here's a code snippet for what an individual card looks like:
<td>
<h1>Mike</h1>
<div class="cardBody">
<img src="Images/stock1.jpg" style="float:left; margin-right:5px;" />
<table class="data" cellpadding="0">
<tr>
<td><i class="fa fa-briefcase"></i></td>
<td><span style="color:red;">President</span></td>
</tr>
<tr>
<td><i class="fa fa-building"></i></td>
<td>Administration</td>
</tr>
<tr>
<td><i class="fa fa-globe"></i></td>
<td>Home Office</td>
</tr>
<tr>
<td><i class="fa fa-phone"></i></td>
<td>Ext. 2402</td>
</tr>
<tr>
<td><i class="fa fa-envelope"></i></td>
<td>Send Email</td>
</tr>
</table>
</div>
</td>

A little confused on what you have tried to far. Does jQuery work for you? If so, this solution seems simple enough.
$(container).scrollTo(target);
Now if you can pass your "target" through a url query. You should be able to parse and use it like so:
Note: This assumes you have a url like www.website/searchpage.html?i=targetID
Also: This is setup to work with IDs so change the code if you need to work with classes.
var params;
function parseURLParams(url) {
var queryStart = url.indexOf("?") + 1,
queryEnd = url.indexOf("#") + 1 || url.length + 1,
query = url.slice(queryStart, queryEnd - 1),
pairs = query.replace(/\+/g, " ").split("&"),
parms = {}, i, n, v, nv;
if (query === url || query === "") {
return;
}
for (i = 0; i < pairs.length; i++) {
nv = pairs[i].split("=");
n = decodeURIComponent(nv[0]);
v = decodeURIComponent(nv[1]);
if (!parms.hasOwnProperty(n)) {
parms[n] = [];
}
parms[n].push(nv.length === 2 ? v : null);
}
return parms;
}
$(document).ready(function(){
params = parseURLParams(window.location.href);
$("#Container").scrollTo("#"+params.i);
});
Hope this helps someone.
Edit:
I realize you want it to be centered which is going to be a little tricky. You're going to need your container to be much larger(or infinite?) than required for it to fit all the data, and then scroll to the position of the desired element, plus an offset for half the container's view able width, and half the element's width. Might just want to create an invisible element with an absolute position when you calculate this number. Then move the element to this position, and finally the screen to this element.

You could append the URL to so it jumps to the div with a specific ID. For example in the card code you posted you'd change the div to this:
<div class="cardBody" id="mikeCard">
Then change the link to the page to
Link to page with Mike's card centered
or if you want to link to that part from the same page just do
Jump to Mike's card

Related

Display array items in one td with each item on a new line

I have an array from a datatable populating a table in my Bootstrap modal.
When displayed in the modal it displays as the below:
This is my current jQuery to populate my table in my modal:
$('#selectedReportDataTable').on('click', 'button[name="deleteContentButton"]', function () {
var deleteRunData = selectedReportDataTable.row($(this).closest('tr')).data();
$('#deleteModal').modal('show');
$('span[name=selectedReport').text(reportSelectedLowerCased);
$('td[name=modalPeriod]').text(deleteRunData.period);
$('td[name=modalSpecParams]').text(deleteRunData.specialParams);
$('td[name=modalFreq]').text(deleteRunData.frequency);
$('td[name=modalTimeFrame]').text(deleteRunData.timeFrame);
$('td[name=modalTime]').text(deleteRunData.time);
$('td[name=modalRecipients]').text(deleteRunData.recipient);
$('#deleteModal').on('shown.bs.modal', function () {
$('#deleteModalNoButton').focus();
});
})
It's the last line:
$('td[name=modalRecipients]').text(deleteRunData.recipient);
that populating the email column
This is the code I have tried:
var abc = deleteRunData.recipient
var def = deleteRunData.recipient.toString().split(", ").join("<br/>");
var ghi = $('td[name=modalRecipients]').text();
var jkl = def.replace(/,/g, "\n")
console.log(abc)
console.log(def)
console.log(ghi)
console.log(jkl)
console.log(abc.join('\r\n'));
and this gives me the following:
If I replace:
$('td[name=modalRecipients]').text(deleteRunData.recipient);
with the following (as an example):
$('td[name=modalRecipients]').text(def.replace(/,/g, "\n"));
It looks like the below:
It's replaced the comma with a space, not what I was after. I want each entry on a new line - what am I doing wrong?
HTML just in case:
<table class="table" style="table-layout: fixed; width: 100%">
<tr>
<th class="modalTable" style="width: 50px">Period</th>
<th class="modalTable" style="width: 85px">Additional details</th>
<th class="modalTable" style="width: 55px">Frequency</th>
<th class="modalTable" style="width: 45px">Time frame</th>
<th class="modalTable" style="width: 25px">Time</th>
<th class="modalTable">Recipient(s)</th>
</tr>
<tr>
<td name="modalPeriod" class="modalTable"></td>
<td name="modalSpecParams" class="modalTable"></td>
<td name="modalFreq" class="modalTable"></td>
<td name="modalTimeFrame" class="modalTable"></td>
<td name="modalTime" class="modalTable"></td>
<td name="modalRecipients" class="modalTable" style="word-wrap: break-word"></td>
</tr>
</table>
God dam it. Soon as i hit submit the answer came instantly using the below code
for (var i = 0; i < deleteRunData.recipient.length; i++) {
$('td[name=modalRecipients]').append('<div>' + deleteRunData.recipient[i] + '</div>');
}
you should replace $('td[name=modalRecipients]').text(def.replace(/,/g, "\n")); with $('td[name=modalRecipients]').html(def.replace(/,/g, "<br \/>")
try this
edit:- rightt well i started this reply before the accepted answer came but i thought i would put it here in-case it other people run into this and need helps.
Original Answer
Totally understand the code blindness, especially with divs and css because this is the most fustrating and angry part of coding the backends! As I understand it, you are looking for multiple emails to display in the email column. So as an example, if there were two recipients, tony#tony.com and crisps#cristony.com, then we would expect
tony#tony.com
crisps#cristony.com
NOTE: NO COMMAS INBETNWNEN THE EMAILS.
When I come across this problem, normally I would write the following code in javascripts
for (var i = 0; i < deleteRunData.recipient.length; i++) {
$('td[name=modalRecipients]').append('<div>' + deleteRunData.recipient[i] +
'</div>');
}
Thsi works some of the time when the deleteRunData exists, if it does not then we have a problem!! Sometimes it does not exist because the people who coded the front ends who we are relying on (server guys), don't make this!! In the case of when deleteRunData does not exist, what I do is create an image of all possible combinations of emails with new lines!!
so for example, for your example i would make a jpeg image of the two emails on photoshops or paintshopro, then i would do
$('td[name=modalRecipients]').append('<img src="http://en.wikipedia.org/wiki/Potato_chip#/media/File:Potato-Chips.jpg" width="500" height="600">')
works for me.
just two extra things that i have come across after regianing my sight
why is tony#test.com receiving five emails about their evening call costs? I would have thought one would suffice?
2.jquery is known to be dangerous when mixed with css and php-sass. please make sure its the rite back end technology for your use case!
hope this helps

Tooltip showing hidden values in table format on hover

My site is set up in the following way:
4 user groups. Each user group can see different information. An example would be stock quantity for a store. So the user from London can't see the stock availability for Manchester. This information is taken from the database for EACH item in stock. So if you have a list of 20 items, their individual values will be displayed.
I would like to do the following:
If I, or anyone I give permission to, hovers over the "In Stock" column for their own store, a tooltip table must appear showing the current stock levels for the 3 other stores, for each individual product. So if I hover over item SKU-001, I will only see the stock availability for that item. I had an issue where it was displaying the whole list for each item.
I was thinking of this:
<table>
<tr>
<th>Store1></th>
<th>Store2></th>
<th>Store3></th>
<th>Store4></th>
</tr>
<?php foreach($this->products as $product) { ?>
<tr>
<td id="stock1" title="myFunction">Stock of Item 1st store</td> *If I hover/mouseover here, another table must appear showing only store name and values of "#stock2, #stock3 and #stock4* for the stock item I am hovering on.
<td id="stock2">Stock of Item 2nd store</td>
<td id="stock3">Stock of Item 3rd store</td>
<td id="stock4">Stock of Item 4th store</td>
</tr>
<?php } ?>
</table>
Here is some code I wrote:
function myFunction() {
var x = document.createElement("TABLE");
x.setAttribute("id", "table10");
document.body.appendChild(x);
var y = document.createElement("TR");
y.setAttribute("id", "myTr");
document.getElementById("myTable").appendChild(y);
var z = document.createElement("TD");
var t = document.getElementByID("riyadhbalance").value();
z.appendChild(t);
document.getElementById("myTr").appendChild(z);
However, for some reason this is not working. I have not found a way to include a tooltip. All the stock values are there for each individual item, so I just need to find a way to add the 3 values for the other stores and display them in a table format via a tooltip. That would be ideal.
So basically the tooltip should show the 3 values of the stores which are currently not on display, as the other 3 values are hidden. The user can only see their store's stock levels. But I would like to include this for myself as it would make it easier to view stock levels across the board.
Check this solution with jQuery and Bootstrap Working fiddle
You have four options:
1 - You can dynamically add it to your code on domReady (like the fiddle)
2 - You can directly print the needed html to make the plugin work. Check docs POPOVER or TOOLTIP
<button type="button" class="btn btn-lg btn-danger my_elements" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Click to toggle popover</button>
// and then, just call from javscript
<script>
$('.my_elements').popover(); // or $('.my_elements').tooltip();
</script>
3 - You can create it when you hover any element. Like the following example (this is particulary helpful if you have a lot of elements needing popover/tooltip, which would consume a lot of time and memory to init and handle)
<table>
<thead>
<tr>
<th>SKU</th>
<th>Description></th>
<th>Stock Tooltip</th>
<th>Stock Popover</th>
</tr>
</thead>
<tbody>
<tr><td>SKU-0001</td><td>This is a description for SKU-0001</td><td class="stock_t">5</td><td class="stock_p">5</td></tr>
</tbody>
</table>
<script>
$('.stock_p').on('mouseover', function(){
// get data from AJAX
// create table element
$(this).attr('title', table_element);
$(this).tooltip({
placement: 'top',
trigger: 'hover',
html: true,
container: 'body',
}).tooltip('show');
});
</script>
4 - with AJAX
<?php
// server side PHP
$other_stores_stock = [ "store_1" => 5, "store_2" => 20, "store_3" => 50 ];
header( 'Content-Type: application/json' );
echo json_encode( $other_stores_stock );
?>
//client side JS - like 1st example
<script>
$('.stock_p').on('mouseover', function(){
$.ajax({
url: your_url,
type: 'POST',
data: { your_data: 'get_stock_qty"},
dataType: "json",
async: false,
success: function (res) {
let table_html = '<table><tr><td>'+res['store_1']+'</td><td>'+res['store_2']+'</td><td>'+res['store_3']+'</td></tr></table>';
$(this).attr('title', 'Stock value for other Stores');
$(this).attr('data-placement', 'left');
$(this).attr('data-toggle', 'popover');
$(this).attr('data-trigger', 'hover');
$(this).attr('data-html', true);
$(this).attr('data-content', table_html);
$(this).popover('show');
}
});
});
</script>

How pick up checkbox result in post method angularjs

I have a table that sets out a list of rules. When the checkboxes are clicked, I need them to take this "true" value and post to an API endpoint. This has been set up, but what I am getting back is that "associated_rule" is undefined.
I have tried setting $scope.associated_rule.selected = true; in my controller, but this still doesn't define the variable and throws up the same error in the console.
Here is my HTML form:
<form name="rules_form" method="post" ng-submit="attach()">
<table class="table table-striped table-hover" ng-model="associated_rules">
<thead>
<th>Rule Types:</th>
<th>Description:</th>
<th>Start Time:</th>
<th>End Time:</th>
<th>Apply Rule to Vehicle:</th>
</thead>
<tr ng-repeat="associated_rule in associated_rules">
<td>#{{ associated_rule.resource_ids.accounts }}</td>
<td>#{{ associated_rule.description }}</td>
<td>#{{ associated_rule.start_time }}</td>
<td>#{{ associated_rule.end_time }}</td>
<td><input type="checkbox" ng-model="associated_rule.selected" aria-label="rule"></td>
</tr>
</table>
<button class="btn btn-primary" ng-click="attach()">Attach</button>
</form>
My Controller event:
$scope.attach = function () {
$scope.associated_rule.selected = true;
var i;
for (i = 0; i < $scope.associated_rule.selected.length; i++) {
//need to create a loop where the true value is picked up and then I can send the data using a POST method. But I'm stuck on this.
}
console.log(the result of the event);
};
For now, I just want the results to console.log, so I can see that the event is creating the loop and displaying the results. After that, I should be OK.
Any help would be much appreciated.
I have fixed this by defining the $scope.rule as an empty array and setting the $scope.rule.selected to "false" by default.
Great! step one! But the checkboxes are ALL selecting when you click A checkbox - think this may be the ng-repeat causing me a pain in the backside.
$scope.rule = [];
$scope.rule.selected = false;
So, how do I ensure that only the checkboxes set that I select and not all at once?
Fixed this too; as the above was just making the entire array selected; as i wasn't drilling down into the array. This did it:
ng-model="rules.selected[associated_rule.id]"
by modelling the a rule within that defined array, it shows up when testing. Brill. :)
By mistake you are changing the value of your check box on clicking the button:
$scope.associated_rule.selected = true;
This will give the current value, selected or not selected
$log.log($scope.associated_rule.selected);

Alternative method to get data in jQuery than to use parent() and next() repeatedly?

I have an HTML Table of Task List Data that I am trying to get all the data values and store them to an object when a row is clicked on.
I have a demo of some HTML and the JavaScript below that is all functioning just as I need it.
The problem is that I know the jQuery part is really bad quality as it calls things like this...
$taskEl.parent().parent('td').next().next().next().text()
I feel these can be improved but I am not sure how so. Most of this was already done on an existing project that I am trying to clean up and this 1 section is really bugging me.
I would appreciate any help in alternative ways to get the data please?
Or if this is the most efficient way?
Also if I need to I have access to modify some of the HTML if need to add new ID's or data attributes.
JSFiddle demo...when you click a link in the Task Title, it will print the values that it selected to the DOM for demo puirposes...: DEMO
Demo JavaScript to get Task Data from the DOM Task List and create a JS Object with it:
//Open Task Modal when a Task record is clicked in Task List
$('body').on('click', '.taskName', function() {
// Set and Cache Task ID from clicked on Task Item
var taskId = $(this).parent().parent().parent().dataAttr('task-id');
var $taskEl = $(this);
// Populate Task Data Object from DOM values
taskDataObject = {
//projectId: projectTaskModal.cache.projectId,
taskId: taskId,
taskName: $taskEl.text(),
taskDescription: $taskEl.next('.description').text(),
taskStatus: $taskEl.parent().parent('td').next().text(),
taskPriority: $taskEl.parent().parent('td').next().next().text(),
taskTags: $taskEl.parent().parent('td').next().next().next().text(),
taskCreatedDate: $taskEl.parent().parent('td').next().next().next().next().text(),
taskModifiedDate: $taskEl.parent().parent('td').next().next().next().next().next().text(),
taskDueDate: $taskEl.parent().parent('td').next().next().next().next().next().next().text(),
};
});
Demo Task List HTML
<span id="projectIdPlaceholder" data-project-id="1234"></span>
<table>
<!-- test task list record 1 -->
<tr id="task-row-1414135033730" data-task-id="1414135033730">
<td width="1%" class="task-checkbox">
<div class="status_update status-checkbox-Not-Started" data-id="1414135033730" data-status="Not Started" id="1414135033730"></div>
</td>
<td width="59%" class="task-name">
<div><span id="1414135033730-taskName" class="taskName strikethrough">Add a Plugin System similar to WordPress Action and Filter Hooks
<span class="open-description-icon open-description-icon-close" title"toggle="" description="" view"="">+</span>
</span>
<div id="1414135033730-taskDescription" class="description" style="display: block;">Project module will Fire Events before and After key events and Plugins in a custom/modulename/plugins/ folder will load and be able to Listen for these Event Hooks and then run it;s own code before and after these actions are executed!</div>
</div>
</td>
<td width="10%">
<div id="1414135033730-status" class="Not Started status"> Not Started</div>
</td>
<td width="10%">
<div id="1414135033730-taskPriority" class="priority">Low</div>
</td>
<td width="10%">
<div class="type">Other</div>
</td>
<td width="10%">
<div id="1414135033730-createdDate" class="createdDate">2014-10-24 07:18:41</div>
</td>
<td width="10%">
<div id="1414135033730-modifiedDate" class="modifiedDate">2014-10-24 07:18:41</div>
</td>
<td width="10%">
<div id="1414135033730-dueDate" class="dueDate">None</div>
</td>
</tr>
<!-- test task list record 2 -->
<tr id="task-row-1414135033731" data-task-id="1414135033731">
<td width="1%" class="task-checkbox">
<div class="status_update status-checkbox-Completed" data-id="1414135033731" data-status="Completed" id="1414135033731"></div>
</td>
<td width="59%" class="task-name">
<div>
<span id="1414135033731-taskName" class="taskName">Testing Task Record Number 2
<span class="open-description-icon open-description-icon-close" title"toggle="" description="" view"="">+</span>
</span>
<div id="1414135033731-taskDescription" class="description" style="display: block;">My project task description for demo testing task record number 2!</div>
</div>
</td>
<td width="10%">
<div id="1414135033731-status" class="Completed status">Completed</div>
</td>
<td width="10%">
<div id="1414135033731-taskPriority" class="priority">High</div>
</td>
<td width="10%">
<div class="type">Magento</div>
</td>
<td width="10%">
<div id="1414135033731-createdDate" class="createdDate">2014-10-27 03:10:14</div>
</td>
<td width="10%">
<div id="1414135033731-modifiedDate" class="modifiedDate">2014-10-27 03:22:24</div>
</td>
<td width="10%">
<div id="1414135033731-dueDate" class="dueDate">06/21/2015</div>
</td>
</tr>
</table>
Since you have Task ID available and the divs all have ID's, I would target the element ID's directly. In jQuery, the more specific you can be, the better.
$('body').on('click', '.taskName', function() {
// Get the task (row) that will be used for running all the selections
var taskid = $(this).closest("tr").dataAttr('task-id');
var taskSel = "#" + taskid + "-";
// Populate Task Data Object from DOM values
taskDataObject = {
taskId: taskid;,
taskName: $(taskSel + "taskName").text(),
taskDescription: $(taskSel + "taskDescription").text(),
taskStatus: $(taskSel + "taskStatus").text(),
taskPriority: $(taskSel + "taskPriority").text(),
taskTags: $(taskSel + "taskTags").text(),
taskCreatedDate: $(taskSel + "taskCreatedDate").text(),
taskModifiedDate: $(taskSel + "taskModifiedDate").text(),
taskDueDate: $(taskSel + "taskDueDate").text(),
};
});
Your different values are in div and span with a descriptive class name, you could just select them using find() and their className within the row that was clicked.
Something like this:
//Open Task Modal when a Task record is clicked in Task List
$('body').on('click', '.taskName', function() {
// Get the task (row) that will be used for running all the selections
$task = $(this).closest("tr");
// Populate Task Data Object from DOM values
taskDataObject = {
//projectId: projectTaskModal.cache.projectId,
taskId: $task.data('task-id'),
taskName: $task.find(".taskName").text(),
taskDescription: $task.find(".description").text(),
taskStatus: $task.find(".status").text(),
taskPriority: $task.find(".priority").text(),
taskTags: $task.find(".type").text(),
taskCreatedDate: $task.find(".createdDate").text(),
taskModifiedDate: $task.find(".modifiedDate").text(),
taskDueDate: $task.find(".dueDate").text()
};
});
Edit: To be consistent, I replaced $(this).text() with $task.find(".taskName").text(), and $(this).next(".description").text() with $task.find(".description").text(). And removed taskId and taskEl as they were redundant.
Edit2: Replaced $(this).parent().parent().parent() with $(this).closest("tr"). That way if the HTML structure changes in the future (and the number of parents change), still the task row will be selected and the code should work without issues.
Instead of manually selecting each element, I suggest you to use data-* attributes to store values and use JavaScript to dynamically build the object, for example:
HTML:
<table id="table">
<tr>
<td data-name="taskName" data-value="Test">
<div class="foo">Test</div>
</td>
<td data-name="taskDate" data-value="1439275213">
<div class="foo">2014-10-24 07:18:41</div>
</td>
</tr>
</table>
JavaScript:
var $nodes = $('#table').find('td[data-name]'); // find TDs with 'data-attr'
var attributes = {};
$nodes.each(function() { // generate object with all data-name/data-value pairs
var $node = $(this);
attributes[$node.attr('data-name')] = $node.attr('data-value');
});
console.log(attributes); // prints { taskName: "Test", taskDate: "1439275213" }
Demo: http://jsfiddle.net/andunai/uu65ntks/
P. S. This method will also allow you to display values different from their value, for example, to display human-readable date, but to serialize it as unix timestamp.
There are various options here, depends on what you need,
This example is not the fastest but is closed to best performance,
great usage of this is reloading DOM element from $ selectors, meaning that parallel events processing the DOM will render same thing,
instead of $this = $(this), reelect your dom element, again not the best practice in term of performance (search in dom), still provides the best results over dynamic modified html.
Your call:
$('body').on('click', '.taskName', function() {
var taskId = $(this).attr('id').replace('-taskName', '');
taskDataObject = {
//projectId: projectTaskModal.cache.projectId,
taskId: taskId,
taskName: $(this).text(),
taskDescription:$('[id="' + taskId + '-taskDescription"').text(),
taskStatus:$('[id="' + taskId + '-status"').text(),
taskPriority: $('[id="' + taskId + '-taskPriority"').text(),
taskTags: "undefined please defeine corect atribute on div",
taskCreatedDate: $('[id="' + taskId + '-createdDate"').text(),
taskModifiedDate: $('[id="' + taskId + '-modifiedDate"').text(),
taskDueDate: $('[id="' + taskId + '-dueDate"').text(),
};
deepTrim(taskDataObject);
printObjectToDom(taskDataObject);
});
you can write custom selector over your main parent html, similar with my example
var T_REX = $(this).parent().parent()... whatever;
var T_REX_CUBS = TREX.children();
var taskname = T_REX_CUBS[0].find("div.taskName").text();
or the simplest ones
var T_REX = $(this).closest('tr');
var taskid = T_REX.attr('data-task-id');
var taskname = T_REX.find("div.taskName").text();
Now the fastest option is to save the main parent object, over that apply jquery custom selectors, but this is not the recommend if your data from table is changing real time.

How to get html table values from multiple columns with single checkbox and submit to servlet?

I have html data table. I want to get values from multiple columns with single checkbox and when click on submit button values should go to servlet. Please help how to do this?
function refile(){
$('#resend').click(function() {
$("input:checked").each(function () {
var id = $(this).attr("id");
var messagePayload = $('#'+id).val();
var messageType = $('#msgType'+id).val();
alert("Payload Alert:"+ messagePayload);
alert("MessageType Alert:"+ messageType);
$.ajax({
type: "POST",
url: "http://localhost:8080/InterfaceMonitoring/ResendServlet",
data: {
messagePayload:messagePayload,
messageType:messageType
}
});
});
});
}
<c:otherwise>
<c:forEach items="${msgs}" var="msg" varStatus="count">
<tr id="check">
<td>
<input type="checkbox" id ="payloadMsg${count.index}" name="payload" value="${msg.messagePayload}">
</td>
<td></td>
<td>${msg.dob}</td>
<td></td>
<td>${msg.name}</td>
<td></td>
<td>
<div class="accordion">
<h3>Payload</h3>
<div id="payloadMsg${count.index}">${msg.messagePayload}</div>
</div>
</td>
<td></td>
<td>
<div id="msgType${count.index}">${msg.messageType}</div>
</td>
</tr>
</c:forEach>
</c:otherwise>
The problem is the way you try to get messageType.
Since you're using the ID of the input element, and prefixing it with #msgType it results in #msgTypepayloadMsgX so that element will never be found.
And since it's a DIV you're looking for you should use .html() to get the content.
Try adding data-index="${count.index}" to each input[checkbox] and get it in the script using $(selector).data('index') so that you can query for $('#msgType' + index)
And you should not make an ajax request for each row. Instead store the payloadMessage and messageType in an object and send it all to the backend at once, after iterating all rows.
An example could be:
Javascript
function refile(){
$('#resend').click(function() {
var payloads = [];
$('input:checked').each(function () {
var $this = $(this),
index = $this.data('index'),
$type = $('#msgType' + index);
payloads.push({
messageType: $type.html(),
messagePayload: $this.val()
});
});
if (payloads.length === 0) {
return;
}
$.ajax({
type: 'POST',
url: 'http://localhost:8080/InterfaceMonitoring/ResendServlet',
data: {
'payload': payloads
}
});
});
}
HTML
<tr id="check">
<td><input type="checkbox" id="payloadMsg${count.index}" data-index="${count.index}" name="payload" value="${msg.messagePayload}"></td>
<td></td>
<td>${msg.dob}</td>
<td></td>
<td>${msg.name}</td>
<td></td>
<td>
<div class="accordion">
<h3>Payload</h3>
<!-- Note that this ID is conflicting with the input#payloadMsg${count.index} -->
<div id="payloadMsg${count.index}">${msg.messagePayload}</div>
</div>
</td>
<td></td>
<td>
<div id="msgType${count.index}">${msg.messageType}</div>
</td>
</tr>
So, from what I've seen, on the front-end, at least, your code SHOULD work, but you've made it REALLY complex. . . . more complicated than you need it to be, I think. Again, while it should work, simplifying it will mean that there are much fewer places in the code where something could go wrong.
I think the best way to do this is make it easy on yourself:
flag the <div> elements that you want to retrieve with a class value that you can use to get their values (rather than relying on the unique IDs)
make the "unique" identifier of the message at the highest level in the table as you can (in this case, the <tr>
simplify your HTML attributes . . . you've got a lot of duplicate data and excess identifiers in your table structure. Try something like this:
HTML
<c:otherwise>
<c:forEach items="${msgs}" var="msg" varStatus="count">
<tr id="payloadMsg${count.index}">
<td>
<input type="checkbox" name="payload">
</td>
<td></td>
<td class="msg-dob">${msg.dob}</td>
<td></td>
<td class="msg-name">${msg.name}</td>
<td></td>
<td>
<div class="accordion">
<h3>Payload</h3>
<div class="msg-payload">${msg.messagePayload}</div>
</div>
</td>
<td></td>
<td>
<div class="msg-type">${msg.messageType}</div>
</td>
</tr>
</c:forEach>
</c:otherwise>
Once you've set that up, you have a much more simple structure, with all of the values that you could ever need, clearly identified. Now, you can pretty easily you can pretty easily get to the values that you need, using jQuery . . . just update your existing code to be something like this:
$(document).ready(function() {
$('#resend').click(function() {
$("input:checked").each(function () {
var currRow = $(this).closest("tr");
var currPayload = currRow.find(".msg-payload").text();
var currType = currRow.find(".msg-type").text();
alert("Payload Alert:"+ currPayload );
alert("MessageType Alert:"+ currType );
$.ajax({
type: "POST",
url: "http://localhost:8080/InterfaceMonitoring/ResendServlet",
data: {
messagePayload: currPayload,
messageType: currType
}
});
});
});
});
NOTE: You were using .val() instead of .text() to retrieve the text in the "type" <div> . . . .val() is only used with input elements.
Not knowing what you are doing on the back-end with this data, I can't really help you make sure that it is storing it correctly, but removing the reliance on the indexes to find the data that you want, should help simplify your logic a lot.
Also, if you ever want any other data from the row, you can capture it pretty easily now . . . for example:
var currMsg = currRow.attr("id");
var currDOB = currRow.find(".msg-dob").text();
var currName = currRow.find(".msg-name").text();
. . . after you have set the currRow value in your code, of course. :)
So, give that a try and see how things go. On the front-end, you should be good with this, at that point, you would need to just focus on the back-end and make sure that everything is working there.

Categories

Resources