Find Duplicate Records in HTML Table - javascript

I am using DataTable pulgin and had question about adding duplicate row.
When user add a record to (HTML) table I want to check if that record already exists in Table (on client side).
For example:
Column A
Row 1 ABC
Now if user try to add "ABC", I want to throw error.
Can anyone provide pointer how to achieve this using jQuery or Datatables?

function findInTable(str, tableID){
$('#' + tableID + ' tr').each(function(){
$(this).children('td').each(function(){
if ( $(this).html() == str ){
alert('found');
return false;
}
});
});
}
findInTable('ABC', 'mytable'); // <table id="mytable">...</table>

This should solve your problem. Tweak this
<script type="text/javascript">
<!--
function cellContent() {
var content=document.getElementsByTagName('td');
for(c=0;c<content.length;c++) {
alert ('td cell number '+(c+1)+' contains...\n ' +content[c].innerHTML);
}
}
onload=cellContent;
//-->
</script>

There is a hacky way to do this for smaller tables. Convert the rows into strings, and put them in an associative array, works best for single column tables, and there are ways to work with multiple columns
Hence lets say you insert ABC
if (tableData["ABC"] != undefined) tableData["ABC"] = 1;
else alert("Duplicate");
Also if loop should take care of adding the row to the UI

Related

How to get complete data from (html) bootstrap table when pagination is turned on

I am using bootstrap table in my web page and want to get complete textual data from all table cells, when pagination is on. I have tried the following method and it returns all the data:
var data = $('#' + tableID).bootstrapTable('getData')
Now when i traverse data object to get value for every cell it works fine but, for those cells which have some nested html , for example:
<td class="danger">cell 4</td>
<td>
google
</td>
Now, in this case, i want to get value for second cell as google but it returns me whole html as
google
Any idea, how i can get only textual value.
I can't do any server side operation, I have to achieve this using javascript/jquery. I have also tried using jquery:
function getColData(tableID,colIndex) {
var colArray = $('#' + tableID + ' td:nth-child'+'('+colIndex+')').map(function(){
return $(this).text();
}).get();
return colArray
}
it returns data correctly but only which is visible on active page and i want all the data.
Based on your file on JSFiddle I have modified the JS part as follows, this will get you the text on every td(i.e. text or text content) and not the values of their attributes. Basically this traverses through the DOM searching for tags embedded in ones - except for those on the table header - then obtains the text value.
var table = $('#table'), button = $('#button');
button.click(function() {
var data = [];
table.find('tr:not(:first)').each(function(i, row) {
var cols = [];
$(this).find('td').each(function(i, col) {
cols.push($(this).text());
});
data.push(cols);
});
alert(data);
});
You can see it in action here
UPDATE:
This will get you all data regardless of pagination, also it will strip tags and nested tags.
var table = $('#table'), button = $('#button');
button.click(function() {
var messedData = table.bootstrapTable('getData');
var data = [];
$.each(messedData, function(i, row) {
var rowData = {
'name': row['0'],
'star': row['1'],
'forks': row['2'],
'desc': row['3'],
}
for (prop in rowData) {
var tmp = document.createElement("div");
tmp.innerHTML = rowData[prop];
rowData[prop] = tmp.textContent || tmp.innerText || "";
}
data.push(rowData);
});
console.log(data);
});
You can see it here
Since the actual data is coming in as a string, I don't think bootstrap-table can't differentiate it from the other data. The simple solution I can think of is to use substring() to extract the data from the cells that contain custom html.
http://jsfiddle.net/vwg5Lefz/
The alternative is to go through the generated table <td> and use text() to get the text data from the cells.
http://jsfiddle.net/n0djy60v/

RMarkdown: Color single cells in an HTML table based on conditions

I sucessfully generated a table in R markdown using xtable (HTML) .
Now I want to color format the 3rd column based on the values in the cell .
say highest value in red , lowest in green , and remaining in different shades.
The values in cell are generated dynamically . Some thing like this happens in excel quite easily using conditional formatting option . Can we do this in R using css ! Any help and suggestion welcome .. Thanks :)
You could use jQuery inside your RMarkdown script like this:
---
title: "Title"
author: "Yourname"
date: "June 16, 2016"
output: html_document
---
<script>
$(document).ready(function() {
$td = $('#myTable tr:not(:has(th)) :nth-child(5)');
var entries = new Array();
$td.each(function() {
entries.push(parseFloat($(this).html()));
})
var minimum = Math.min.apply(Math, entries);
var maximum = Math.max.apply(Math, entries);
$("#myTable tr :nth-child(5):contains('" + minimum + "')").css('background-color', 'green');
$("#myTable tr :nth-child(5):contains('" + maximum + "')").css('background-color', 'red');
});
</script>
```{r, echo=F, results='asis'}
library(xtable, quietly = T)
myTable <- xtable(head(mtcars))
print(myTable, type="html", html.table.attributes='border=1 id=myTable')
```
The JavaScript reads out all values of column 5 (:nth-child(5), including the row names) and checks for the minimum and maximum. Afterwards it matches the cells of that column with these values and applies CSS attributes.
Notice that I specified an ID for that table (#myTable). So if you have multiple table, the JavaScript can select the correct one.

Dyamically inserting array back into HTML from Javascript

In short, I'm trying to figure out how to change an HTML drop down based upon a selection made in another HTML dropdown. Something like this is the end product.. where you select something in the first box, and the second box populates based upon that first option.
However, I've become stuck at how to populate that second box with the code I have. It's not as simple as adding as the code creates arrays for all the options you have.
Some of the snippets I have are laid out like this.. (Javascript first)
function setModelLevels(mdlselc){
var selection = mdlselc;
if (selection == "nam_ncep" || selection == "nam_4km_ncep" || selection == "gfs_ncep" || selection == "rap_ncep" || selection == "wrf_nmm_ncep" || selection == "wrf_arw_ncep"){
levelDyMenuItems = new Array();
numDyLevelMenuItems = 0;
makeDyLevelMenuItem("sfc","***Surface***","","level")
makeDyLevelMenuItem("sfc","Surface","SELECTED ","level")
makeDyLevelMenuItem("pcp","Precip","","level")
makeDyLevelMenuItem("windvector","Wind Vector","","level")
makeDyLevelMenuItem("windgust","Wind Gusts","","level")
makeDyLevelMenuItem("ref","Simulated Reflectivity","","level")
} //Ends Model check
} //Ends setModelLevels
(HTML next)
<TR><TD>
<SELECT NAME="model" CLASS="controls1" onchange=setModelLevels(document.controls.model[document.controls.model.selectedIndex].value);>
<SCRIPT>
createMenuItems();
for (i = 1; i <= numModelMenuItems; i++) { document.writeln('<OPTION ' + modelMenuItems[i].modelDefault + 'VALUE="' + modelMenuItems[i].modelValue + '">' + modelMenuItems[i].modelLabel) }
</SCRIPT>
</SELECT>
</TD></TR><TR><TD>
<SELECT NAME="level" id="levelsel" CLASS="controls1">
<SCRIPT>
for (i = 1; i <= numDyLevelMenuItems; i++) { document.writeln('<OPTION ' + levelDyMenuItems[i].levelLabel + 'VALUE="' + levelDyMenuItems[i].levelValue + '">' + levelDyMenuItems[i].levelLabel) }
</SCRIPT>
</SELECT>
</TD></TR>
(The code isn't mine, it's a somewhat publicly available weather model animator that I'm messing around with on my side.)
So basically, when you change the dropdown with the NAME="model", it drops the name of the model into the setModelLevels code. That sees what model you've selected, and makes an array with the necessary parameters to drive the rest of the page.
The problem comes with the fact that the created array never displays back into the main webpage. I would assume I need to push my newly created array into the HTML document.. but I've only done that with jquery before. And I cannot use jquery for this due to the restrictions we have on our pcs.
I'm looking for any help here.. I'm a bit of a novice of a coder and I'm trying my hardest not to edit/rewrite the code here.
Thanks.
Addendum
The makeDyLevelMenuItem basically makes the array of menu items to list. It looks like this..
function makeDyLevelMenuItem(levelDyValue,levelDyLabel,levelDyDefault,levelDyClass) {
numDyLevelMenuItems++;
levelDyMenuItems[numDyLevelMenuItems] = new levelDyMenuItem(levelDyValue,levelDyLabel,levelDyDefault,levelDyClass);
}

Populating table with json data

I am trying to populate an HTML table using the JSON string retrieved from a $.getJSON() call. The $.getJSON() call is working fine. But I am not able to populate an html table with the retrieved json data. Please help me with my code..I'm new to this..
function loadTable(result){
if(result.groups="no"){
var num_rows = result.noofteams;
var rows = "";
for(var i=0;i<num_rows;i++){
rows +='<tr>'+result.noofteams+'</tr>';
}
$("#container").append(rows);
Here result is the json object that i am receiving. result.noofteams is giving proper value (i have checked it). But the problem is, i am unable to populate #container with result.noofteams Please help..
u used = while u need == or === for conditions
function loadTable(result){
if(result.groups==="no"){
var num_rows = result.noofteams;
var rows = "";
for(var i=0;i<num_rows;i++){
rows +='<tr><td>'+result.noofteams+'</td></tr>';
}
$("#container").append(rows);
}
}
EDIT: Add <td> they are important as well
It's much cleaner to work with JSON like so...
for (i in result) {
rows += '<tr>' + result[i]['noofteams'] + '</tr>';
}

How to display delete message in correct table row?

Below is a function where it controls whatever happens after a file has finished uploading in its own table row. Each table row consists of a file input where the user can upload a file and then the name of the file is appended within it's own table row.
If the upload was successful then it displays a successful message, if upload was not successful then it displays a message stating there is an error. But I also have another function within the function where the user can delete a file by clicking on the "Delete" button. The only problem I have is with this line of code:
$(".imagemsg" + counter).html(data);
Let's say that I have 2 table rows, and I delete a file in the first row, the message within .imagemsg should only be displayed in the first row as that was the row the deletion occured, it shouldn't display the message in the first and second row.
Another example is that if I have 4 table rows and I delete the file in the third row, then the message should be displayed in the 3rd row as that is where the deletion has occured.
So my question is what do I need to add to $(".imagemsg" + counter).html(data); so that the message is only displayed within the row the deletion of the file occured and not in all .imagemsg which is in every row?
Below is full code:
function stopImageUpload(success, imagefilename){
var result = '';
var counter = 0;
counter++;
if (success == 1){
result = '<span class="imagemsg'+counter+'">The file was uploaded successfully!</span><br/><br/>';
$('.listImage').eq(window.lastUploadImageIndex).append('<div>' + htmlEncode(imagefilename) + '<button type="button" class="deletefileimage" image_file_name="' + imagefilename + '">Remove</button><br/><hr/></div>');
}
else {
result = '<span class="imageemsg">There was an error during file upload!</span><br/><br/>';
}
$(".deletefileimage").on("click", function(event) {
var image_file_name = $(this).attr('image_file_name');
jQuery.ajax("deleteimage.php?imagefilename=" + image_file_name)
.done(function(data) {
$(".imagemsg" + counter).html(data);
});
$(this).parent().remove();
});
return true;
}
BELOW IS HTML CODE:
var $fileImage = $("<form action='imageupload.php' method='post' enctype='multipart/form-data' target='upload_target' onsubmit='return imageClickHandler(this);' class='imageuploadform' >" +
"Image File: <input name='fileImage' type='file' class='fileImage' /></label><br/><br/><label class='imagelbl'>" +
"<input type='submit' name='submitImageBtn' class='sbtnimage' value='Upload' /></label>" +
"</p><p class='listImage' align='left'></p>" +
"<iframe class='upload_target' name='upload_target' src='#' style='width:0;height:0;border:0px;solid;#fff;'></iframe></form>");
I believe that your counter variable will always be 1. So, all your span.imagemsg1 are the same. This is why you get the message in every row. Set the counter outside the function to increment the counter.
I believe that will stop the behavior that you are seeing, but I would like to give a shout out to the other answers as they are giving good advice to cleaning this code up.
Frankly, you should never use unique identifier in the class. Why not use an id or a data-image-count attribute?
In your html code you'll need to add a unique identifier, I would suggest using id. This way when you try to reference the element to add the error message in, it will only find one element. Currently it's looking for the first occurrence of the element with class = "imagemsg". You'll need a way to loop through each "row" and make the id's "imagemgs1", "imagemsg2", etc...Hope it helps.
It would be helpful to be able to see the HTML. Also, I cannot see in your script what you do with the "result" value. At this stage, I personally don't think there is enough info to help satisfactorily you yet.
However, an issue you will undoubtedly see is with your "counter" variable. Maybe that is your problem - hard to tell without the detail I asked for above. Your jQuery.ajax call will complete at some point but the value of "counter" may not be the same as when you called the jQuery.ajax() method. This is because the "counter" variable is being declared in a different scope.
E.g. Look at the code below. It sort of demonstrates your problem with the counter variable. It may look like at the end of 5 seconds it will spit out the numbers from 1 to 10 but it won't. It will spit out the value "10" ten times.
var x = 0;
for (var i = 0; i < 10; i++)
{
x++;
setTimeout(function() { console.log(x); }, 5000);
}
This problem applies to your code as well. You can fix the above by copying the variable value in to a variable of your local scope. E.g.:
var x = 0;
for (var i = 0; i < 10; i++)
{
var newScope = function() {
x++;
var y = x;
setTimeout(function() { console.log(y); }, 5000);
}();
}

Categories