jQuery Datatables - Can't get input value from hidden pages - javascript

I have this table in my HTML:
<table>
<thead>
<tr>
<th>Id</th>
<th>Actual weight</th>
<th>New weight</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>10</td>
<td><input data-id="{{ object.id }}" type="number" name="input_new_weight" /></td>
</tr>
<tr>
<td>1</td>
<td>20</td>
<td><input data-id="{{ object.id }}" type="number" name="input_new_weight" /></td>
</tr>
<!-- multiply by 10 the number of trs -->
</tbody>
</table>
And I have this code in my javascript to get the input values:
var new_weights = []
$("input[name='input_new_weight']").each(function(index, element){
if( $(this).val() != "" ){
var object_new_weight ={
id: $(this).data('id'),
new_weight: $(this).val()
}
new_weights.push(object_new_weight);
}
});
console.log(new_weights);
I'm using jQuery DataTables plugin to generate the tables and have the possibili ty to filter, paginate, ordenate and etc.
In some tables I have more than 10 entries, so the paginations works here. In the example above, it will be 2 pages: 1 and 2.
When my javascript code is executed, it does only gets the inputs values from the visible table page. The inputs from the hidden pages are not get!
Let's suppose that in page 1 I put the new weight values as 35, 75 and 80 and in the page 2 I put 40, 54, 97. When my javascript code runs, it does just get the values from the visible page.
Please, can someone tell me why this is happening?

It's really straightforward you know datatable generates table on the fly so when you are on page 1, inputs corresponding to page 2 (40, 54, 97) aren't there at all on the page.
So I am guessing you have put your this code out in the global
$("input[name='input_new_weight']").each(function(index, element){
//stuff
});
This runs only one time; on initial loading of your page when inputs from only page 1 are there, what you rather need is to be able to run your code every-time datatable re-renders.There's a hook that you may use page.dt
Put this after the code where you initialize datatable
$('#yourtable').on('page.dt', function(){
$("input[name='input_new_weight']").each(function(index, element){
//stuff
});
});

Related

How to get checkbox value from inside an HTML table using JS

I'm currently working on a simple website where I have a list of PC parts in a table. In this table I also have checkboxes which are meant to be checked if the parts are owned. At the bottom of a table is a button which will be pressed that is meant to check the status of the checkboxes and output the list of parts still needed and the approximate cost.
I'm having issues with accessing the checked state of the checkboxes through Javascript and keep getting undefined when I try to output the value in the console.
Site Table Image:
HTML Code:
<div class="beginnersguide">
<h1>What parts go into a gaming PC?</h1>
<table id="partsTable">
<tr>
<th onclick="sortTable(0)" id="partName">Part Name</th>
<th>Image</th>
<th>Description</th>
<th onclick="sortTable(3, 1)" id="averagePrice">Average Price ($CAD)</th>
<th>Already Owned?</th>
</tr>
<tr>
<td>Case</td>
<td><img src="../img/case.jpg"></td>
<td>The nicely designed box/container for all your PC parts. This is what you will first see when looking at your PC!</td>
<td>150</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>Motherboard</td>
<td><img src="../img/motherboard.jpg"></td>
<td>The Motherboard is a large circuit board which acts as the central hub for all your internal PC components. It will connect all the parts inside together to run!</td>
<td>210</td>
<td><input type="checkbox"></td>
</tr>
<tr>
// Code continues on like this for the rest of the table and ends like this:
<tr>
<td>Input and Output Devices</td>
<td><img src="../img/iodevice.jpg"></td>
<td>This would cover items such as a mouse, keyboard and monitors. These are needed to interact with your PC.</td>
<td>250</td>
<td><input type="checkbox"></td>
</tr>
</table>
<input type="submit" name="check" value="Check List" onclick="checkList()">
JavaScript Code:
/* Function for Parts checklist */
function checkList(){
var table, rows = 0;
table = document.getElementById("partsTable");
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
x = rows[i].getElementsByTagName("TD")[4];
//console.log(x);
if (x.checked == true){
/* code to output what parts are necessary */
}
}
}

Load HTML content in a newly created table row

I've got a web page of very neatly structured data. There are about 20 "parents" and about 1000 "children". Right now I show a huge table of all the children. What I want to do is display the table of parents, and have a button/toggle for each row that when clicked would:
add a row beneath that parent in the table
execute a GET request to display an HTML table of children in that row
on the next click the button/toggle would remove that row from the table
My HTML looks like this:
<table id="tableofparents">
<tr>
<th>Buttons</th>
<th>Col B</th>
<th>Col C</th>
</tr>
<tr class="adder" id="101">
<td id="101" class="toggleChildren">Button</td> # unique id per row already exists
<td>Info Field 1</td>
<td>Info Field 2</td>
</tr>
<tr class="adder" id="202">
<td id="202" class="toggleChildren">Button</td>
<td>Info Field 1</td>
<td>Info Field 2</td>
</tr>
</table>
I figured out the code to toggle creation/deletion of a new table row here from here - Toggle between the creation and destruction of a table row jquery
<script type="text/javascript">
$(document).ready(function()
{
$('#tableofparents').on('click', ".toggleChildren", function () {
var thisRow = $(this).parents('tr.adder');
var hasNextRow = thisRow.next('tr.added').length;
if (hasNextRow) {
thisRow.next('tr.added').remove();
} else {
$(this).parents('tr.adder').after('<tr class="added"><td colspan="3" >This is where I want to load the HTML of the children via a GET request</td></tr>');
}
});
}
</script>
When I click on the button in the first row, it now toggles the addition of a new table row. But I also need that same click to execute a GET request to http://example.com/childdata?id=101 and load the HTML from that request into the new row, and I just can't figure out how to do that.
Is there a way to load HTML into the newly created row?
In your else statement you can do this:
var parent = $(this).parents('tr.adder'), id = parent.attr('id');
$.get('http://example.com/childdata?id='+id, function(html) {
parent.after('<tr class="added"><td colspan="3" >'+html+'</td></tr>');
});
I hope this will help you.

jQuery - .each() over dynamically removed rows - numbering is off

JSFiddle: https://jsfiddle.net/dxhen3ve/4/
Hey guys,
I've been trying to figure out the issue here for some time.
Essentially, I have a table with rows. You can add new rows (works fine). However, on the deletion of rows, I would like to re-number all of the rows below it (including all of their input names/ids within).
This works fine as I have it on the first time you click "remove" for any row.. say, if you have rows 0-4 and delete row 1, you will now have rows 0-3 and they will be numbered correctly--however, after that if you click remove again on another row, the numbers do not update
The indexes are getting mixed up some how and it almost seems like it's not recognizing that I've removed an element from the DOM.. when I console.log the indexes everything looks fine.
As an example:
- Add 5 rows (0-4)
- Remove row #1 (the rows below get updated as they should).
- Remove the new row #1, and you will see that row #2 takes its place instead of changing to row #1.
- In the function 'renumber_budget_rows', the if statement seems to get skipped for that row #2, even though I feel like it should meet the conditions (and is present if I console.log(item)
What am I missing? https://jsfiddle.net/dxhen3ve/4/
** Update: Just wanted to update that I have a true resolution that works, which is great! However, I am more interested in knowing WHY my solution is failing. At the moment, the best I have, from the correct answer, was that my indexes were misaligned. I'm going to take a new look at them.
HTML
<script type="text/template" id="budget_row-template">
<tr id="budget_row-{{index}}" class="budget-row" data-budget-index="{{index}}">
<td class="budget-line">{{index}}</td>
<td><input type="text" name="budget_description-{{index}}" id="budget_description-{{index}}" class="budget-description" /></td>
<td><input type="text" name="budget_amount-{{index}}" id="budget_amount-{{index}}" class="budget-amount" /></td>
<td>
<select name="budget_costcode-{{index}}" id="budget_costcode-{{index}}" class="budget-costcode">
<option>-- Select Cost Code</option>
</select>
</td>
<td><i class="fa fa-share"></i></td>
<td>remove</td>
</tr>
</script>
<div class="table-scroll-container">
<table class="table table-striped table-bordered table-hover tablesorter" id="budget-display">
<thead>
<tr>
<th>Line #</th>
<th>Description</th>
<th>Amount</th>
<th>Cost Code</th>
<th data-sorter="false"></th>
<th data-sorter="false"></th>
</tr>
</thead>
<tbody id="test">
<tr id="budget_row-0" class="budget-row" data-budget-index="0">
<td class="budget-line">0</td>
<td><input type="text" name="budget_description-0" id="budget_description-0" class="budget-description" /></td>
<td><input type="text" name="budget_amount-0" id="budget_amount-0" class="budget-amount" /></td>
<td>
<select name="budget_costcode-0" id="budget_costcode-0" class="budget-costcode">
<option>-- Select Cost Code</option>
</select>
</td>
<td><i class="fa fa-share"></i></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div class="text-align-center">
<i class="icon icon-plus icon-white"></i> Add Line Item<br />
</div>
JS
function renumber_budget_rows(removed) {
$('#budget-display tbody .budget-row').each(function(indite, item) {
var ti = $(item).data('budget-index');
if( ti > removed ) {
ti--;
//console.log(item);
$(item).attr('id', 'budget_row-'+ti);
$(item).attr('data-budget-index', ti);
$(item).find('.budget-line').html(ti);
$(item).find('.budget-description').attr({ 'name': 'budget-description-'+ti, 'id': 'budget-description-'+ti });
$(item).find('.budget-amount').attr({ 'name': 'budget-amount-'+ti, 'id': 'budget-amount-'+ti });
$(item).find('.budget-costcode').attr({ 'name': 'budget-costcode-'+ti, 'id': 'budget-costcode-'+ti });
$(item).find('.add-budget-child').attr({ 'id': 'budget_row-addparent-'+ti, 'data-budget-index': ti });
$(item).find('.trash-budget-row').attr({ 'id': 'budget_row-'+ti+'-trash' });
$(item).find('.trash-budget-row').attr('data-budget-index', ti);
}
});
}
var budget_index = 0;
$('.add-budget-row').click(function(e) {
budget_index++;
e.preventDefault();
var budget_html = $('#budget_row-template').html();
budget_html = budget_html.replace(/{{index}}/g, budget_index);
$('#budget-display tbody').append(budget_html);
});
$('#budget-display').on('click', '.trash-budget-row', function(e) {
var removed = $(this).data('budget-index');
$(this).closest('tr').remove();
console.log(removed);
renumber_budget_rows(removed);
budget_index--;
});
While you are deleting the row, after a row deletion, you can iterate through every tr using .each() function and change the attributes based on the index i value.
$('#budget-display').on('click', '.trash-budget-row', function(e) {
var removed = $(this).data('budget-index');
$(this).closest('tr').remove();
$('tbody tr').each(function(i){
$(this).find('td').eq(0).text(i);
$(this).attr("data-budget-index",i);
$(this).attr("id","budget-row-" + i);
});
budget_index--;
});
Working example : https://jsfiddle.net/DinoMyte/dxhen3ve/5/

Populate HTML table with search value Angular

I have a json file, that will eventually be called from a server with an API. Currently am just calling from an object.
I am creating an HTML file with a table navigation, where each header element also has a search box and submit button.
I would like the table to be blank on start, and when one of the header values is searched (id, nickname, email, etc), the json value that contains at least part of that search will populate the table.
I am new to the Angular syntax and am trying to get an idea of how this would even work.
(function() {
var app = angular.module('tool', []);
app.controller('searchController', function() {
this.info = data.people;
this.findId = function(idInput) {
angular.forEach(that.id, function(value, key) {
if (value.contains(idInput)) {
// not sure what to put here.
}
});
};
});
var data = {
"people": [{
"id": "2245231",
"nickname": "heyyman",
"email": "info#gmail.net",
"lastIp": "127.0.0.1",
"regIp": "127.0.0.1",
}, {
"id": "2245232",
"nickname": "heyyman2",
"email": "info2#gmail.net",
"lastIp": "127.0.0.2",
"regIp": "127.0.0.2",
}
};
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<main>
<table ng-controller="searchController as search">
<thead>
<tr id="tableNavigation">
<td></td>
<td>ID
<input type="text" ng-model="idInput">
<input type="submit" ng-click="findId(idInput)">
</td>
<td>Nickname</td>
<td>Login / Email</td>
<td>Last IP</td>
<td>Registration IP</td>
</tr>
</thead>
<tbody id="tableCanvas">
<tr ng-repeat="people in search.info" ng-class-even="'even'">
<td></td>
<td>{{people.id}}</td>
<td>{{people.nickname}}</td>
<td>{{people.email}}</td>
<td>{{people.lastIp}}</td>
<td>{{people.regIp}}</td>
</tr>
</tbody>
</table>
</main>
So far, this is what I've done. Also, I've linked a JSFiddle.
http://jsfiddle.net/ho00cLkk/
Please let me know if what I am asking is confusing or not clear.
It seems to me that your question consists of two separate parts:
How do I filter the displayed items?
How do I hide all results until the first search is made?
As the second question seems uninteresting to me (many possible solutions, no general problem), I'll focus on the first one. You might want to read the documentation: https://docs.angularjs.org/api/ng/filter/filter . Then it's pretty simple and you don't even need any submit buttons:
<table>
<thead>
<tr>
<th>
Name
<input type="text" ng-model="searchProps.name">
</th>
...
</tr>
</thead>
<tbody>
<tr ng-repeat="person in people | filter:searchProps">
...
</tr>
</tbody>
</table>
(where people is your search.info). Table rows will be automatically filtered to contain only the items with properties partially matching the values in searchProps.
CodePen example: http://codepen.io/anon/pen/jEEZaa

Can I call a jquery or javascript function in grails g:each element?

I want to call a jquery function in grails g:each element, i'm using a function call on page load to filter a table which has a loop as follows
<g:each in="${sampleTypes}" status="i" var="sampleType">
<div class="uniq">${sampleType}</div>
<table id="sampleTable">
<thead>
<tr>
<th class="no-sort"><g:message code="labWorkItem.testUnit.label"
default="CustomerId" /></th>
<th class="no-sort"><g:message code="labWorkItem.testUnit.label"
default="OrderNo" /></th>
<th class="no-sort"><g:message code="labWorkItem.testUnit.label"
default="DateCreated" /></th>
<th class="no-sort"><g:message code="labWorkItem.testUnit.label"
default="Test unit" /></th>
<th class="no-sort no-visible"><g:message
code="labWorkItem.sampleType.label" default="Sample Type" /></th>
</tr>
</thead>
<tbody>
<g:each in="${labWorkItemInstance}" status="a" var="labWorkItem">
<tr class="${(a % 2) == 0 ? 'even' : 'odd'}">
<td>
${labWorkItem?.order?.customer?.customerId}
</td>
<td>
${labWorkItem?.order?.orderNo}
</td>
<td>
${labWorkItem?.order?.dateCreated}
</td>
<td >
${labWorkItem?.testUnit}
</td>
<td id = "labSample">
${labWorkItem?.testUnit?.sampleType}
</td>
</tr>
</g:each>
</tbody>
</table>
<g:textField name="singleValue" value="Blood" id="someHiddenField"/>
</g:each>
i am using the class "uniq" to filter the table
function typeSampleCollected() {
jQuery.fn.dataTableExt.afnFiltering.push(function(oSettings, aData,
iDataIndex) {
if (oSettings.nTable.id != "sampleTable") {
return true;
}
var uniq = jQuery("div.uniq").html();
alert(uniq);
jQuery("#someHiddenField").val(uniq);
var someHiddenField = jQuery("#someHiddenField").val()
if(someHiddenField){
//var sampleValue = jQuery("#someHiddenField").val();
//alert(sampleValue.toString());
if (someHiddenField != aData[4]){
console.log("sampleType"+someHiddenField);
console.log("aData"+aData[4]);
return false;
}
}
else{
console.log("else condition");
}
return true;
});
}
The problem is, it executes at the first on page load, only the first data of the loop executed others remains the same, i want the remaining data also to execute.
jQuery + HTML answer.
Your generated HTML will be wrong because the id "someHiddenField" will be duplicated. An id has to be unique within the HTML document. View the source of the document to check. Copy into an IDE or use w3c validator to check.
Once you have unique ID's you need to iterate over them and run your filter.
I am not sure whether by filter you are sending information back to the server. i.e. text blood results in only content relating to blood being displayed. I don't see any events in your code. Is the code incomplete?
A similar thing - click on an icon to only display items relating to that class. View code:
<g:each in="${assetTypes}" status="i" var="assetType">
<li>
<span class="atext">${assetType.name?.encodeAsHTML()}</span>
</li>
</g:each>
I used delegate() to late-bind jQuery to the click - use go() after 1.7 jQuery. The javascript had to be in a grails view because I use the gsp tags. With delegate() it could be anywhere:
/* Change asset types */
jQuery('body').delegate('[name=assetTypeSelector]', 'click', function() {
var newAssetIconId = jQuery(this).attr("id").split("-").pop();
// set the asset type.
${remoteFunction(controller: 'assetType', action: 'selector', name: 'assetTypeSelector', update: 'assetTypeSelector', params:'\'currentAssetTypeIconId=\' + newAssetIconId')}
});
Alternatively we have had a lot of success with DataTables which is a more complete solution.

Categories

Resources