I have a table and a list. I want the user to click on an item in the table and the text from the cell is added to the list.
function history_buff(obj){
var elList = Document.getElementById("user_history");
//alert("Trying to add item " + obj);
var element = Document.getElementById(str(obj))
var text = element.innerText || element.textContent;
var user_item = element.innerHTML = text;
alert("Trying to add: " + user_item)
var li = document.createElement("li");
li.innerHTML = user_item.value;
elList.appendChild(user_item);
}
function welcome(){
alert("Welcome home!");
}
And here's the HTML:
<div class="block" id="one">
<table id="name_table">
<tr>
<th>Name</th>
<th>Age</th>
<th>Job</th>
</tr>
<tr id="name_1">
<td><a onclick="history_buff();" href="static\text_files\alex.txt">Alex</a></td>
<td onclick="welcome();">12</td>
<td>Analyst</td>
</tr>
<tr id="name_2">
<td>Bill</td>
<td>54</td>
<td>Car Salesman</td>
</tr>
<tr id="name_3">
<td><a id="item_3" href="static\text_files\Rodrigo.txt">Rodrigo</a></td>
<td>7</td>
<td id="job_3" onclick="history_buff(this.id)">Merchant</td>
</tr>
</table>
</div>
<div class="block" id="two">
<h2>History</h2>
<ul id="user_history">
<li>Nothing</li>
<li>Something</li>
</ul>
</div>
I've tried many different ways similar to this, but can't seem to get it.
There are some errors in your function. Here is a fixed and working version:
function history_buff(obj) {
var elList = document.getElementById("user_history");
//alert("Trying to add item " + obj);
var element = document.getElementById(obj)
var text = element.textContent;
var user_item = text;
alert("Trying to add: " + user_item);
var li = document.createElement("li");
li.innerHTML = user_item;
elList.appendChild(li);
}
function welcome() {
alert("Welcome home!");
}
<div class="block" id="one">
<table id="name_table">
<tr>
<th>Name</th>
<th>Age</th>
<th>Job</th>
</tr>
<tr id="name_1">
<td>Alex</td>
<td onclick="welcome();">12</td>
<td id="job_1" onclick="history_buff(this.id)">Analyst</td>
</tr>
<tr id="name_2">
<td>Bill</td>
<td>54</td>
<td id="job_2" onclick="history_buff(this.id)">Car Salesman</td>
</tr>
<tr id="name_3">
<td><a id="item_3" href="static\text_files\Rodrigo.txt">Rodrigo</a></td>
<td>7</td>
<td id="job_3" onclick="history_buff(this.id)">Merchant</td>
</tr>
</table>
</div>
<div class="block" id="two">
<h2>History</h2>
<ul id="user_history">
<li>Nothing</li>
<li>Something</li>
</ul>
</div>
This is not the best way to do things, though.
Embrace the function addEventListener to bind events.
A string doesn't have a property called value, so, this user_item.value won't work.
Append to the list the new element li.
This approach is preventing the default behavior of a link using the function preventDefault from the event object, this way you will be able to see the added elements to the parent element user_history.
Array.prototype.forEach.call(document.querySelectorAll('td a'), function(a) {
a.addEventListener('click', history_buff)
});
function history_buff(event) {
event.preventDefault();
var elList = document.getElementById("user_history");
var text = this.innerText || element.textContent;
var user_item = this.innerHTML = text;
//console.log("Trying to add: " + user_item)
var li = document.createElement("li");
li.innerHTML = user_item;
elList.appendChild(li);
}
function welcome() {
alert("Welcome home!");
}
<div class="block" id="one">
<table id="name_table">
<tr>
<th>Name</th>
<th>Age</th>
<th>Job</th>
</tr>
<tr id="name_1">
<td>Alex</td>
<td onclick="welcome();">12</td>
<td>Analyst</td>
</tr>
<tr id="name_2">
<td>Bill</td>
<td>54</td>
<td>Car Salesman</td>
</tr>
<tr id="name_3">
<td><a id="item_3" href="static\text_files\Rodrigo.txt">Rodrigo</a></td>
<td>7</td>
<td id="job_3" onclick="history_buff(this.id)">Merchant</td>
</tr>
</table>
</div>
<div class="block" id="two">
<h2>History</h2>
<ul id="user_history">
<li>Nothing</li>
<li>Something</li>
</ul>
</div>
First, it is a bad habit to give your rows an ID, cause the records in the table could be dynamically generated,
Secondly, one likely reason your code didn't run is that when defining the
function history_buff(obj){
... do something
}
but when calling the function, you didn't pass the obj as a parameter
ie <td><a onclick="history_buff();" href="static\text_files\alex.txt">Alex</a></td>
finally,
` var element = Document.getElementById(str(obj)),
why dont you try
var element = Document.getElementById(${obj})`
I hope this helps
Try check this snippet :
function history_buff(value){
$("#user_history").append('<li><span class="tab">'+value+'</span></li>');
}
function welcome(){
alert("Welcome home!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block" id="one">
<table id="name_table">
<tr>
<th>Name</th>
<th>Age</th>
<th>Job</th>
</tr>
<tr id="name_1">
<td><span onclick="history_buff('Alex');">Alex</span></td>
<td onclick="welcome();">12</td>
<td>Analyst</td>
</tr>
<tr id="name_2">
<td><span onclick="history_buff('Bill');">Bill</span></td>
<td>54</td>
<td>Car Salesman</td>
</tr>
<tr id="name_3">
<td><a id="item_3" href="static\text_files\Rodrigo.txt">Rodrigo</a></td>
<td>7</td>
<td id="job_3" onclick="history_buff(this.id)">Merchant</td>
</tr>
</table>
</div>
<div class="block" id="two">
<h2>History</h2>
<ul id="user_history">
<li>Nothing</li>
<li>Something</li>
</ul>
</div>
You should go through understanding and basic tutorials on Javascript and jQuery. You should achieve your desired outcome easily.
https://www.w3schools.com/js/default.asp
https://www.w3schools.com/jquery/default.asp
function history_buff(obj){
var elList = document.getElementById("user_history");
var element = document.getElementById(obj)
var text = element.innerText || element.textContent;
var user_item = element.innerHTML = text;
alert("Trying to add: " + user_item)
var li = document.createElement("li");
li.innerHTML = user_item;
elList.appendChild(li);
}
Notice from your code:
str() is not a js function
li.innerHtml should equal to user_item instead of user_item.value - which is undefined. Then append li to the ul list
Related
I have the following html table:
<table border="1" cellpadding="5" class="test">
<tr>
<td class="talent-cell"><div class="btn7" data-value="0">aaa</div></td>
<td class="talent-cell"><div class="btn8" data-value="1">bbb</div></td>
<td class="talent-cell"><div class="btn9" data-value="2">ccc</div></td>
</tr>
<tr>
<td class="talent-cell"><div class="btn7" data-value="0">ddd</div></td>
<td class="talent-cell"><div class="btn8" data-value="1">eee</div></td>
<td class="talent-cell"><div class="btn9" data-value="2">fff</div></td>
</tr>
<tr>
<td class="talent-cell"><div class="btn7" data-value="0">ggg</div></td>
<td class="talent-cell"><div class="btn8" data-value="1">hhh</div></td>
<td class="talent-cell"><div class="btn9" data-value="2">iii</div></td>
</tr>
</table>
If you click on a "div attribute" inside a table cell I need to get the "data-value" of the clicked div attribute. After that I build a query string to use it with "URLSearchParams". This works so far.
Now I need a certain condition. It should be only allowed to select one div-attribute per table row and column. But I don't know how to implement this condition in my code.
This is the Fiddle and the code:
var btn7;
var btn8;
var btn9;
$('.btn7').click(function () {
if ($(this).attr('data-selected') === 'true') {
$(this).attr('data-selected', 'false');
$(this).removeClass('selected');
} else {
$(this).closest('tr').find('.btn7').not(this)
.removeClass('selected').attr('data-selected', 'false');
$(this).attr('data-selected', 'true');
$(this).addClass('selected');
params.set('var7', $(this).data("value"));
window.history.replaceState({}, '', `?${params}`);
}
});
$('.btn8').click(function () {
if ($(this).attr('data-selected') === 'true') {
$(this).attr('data-selected', 'false');
$(this).removeClass('selected');
} else {
$(this).closest('tr').find('.btn8').not(this)
.removeClass('selected').attr('data-selected', 'false');
$(this).attr('data-selected', 'true');
$(this).addClass('selected');
params.set('var8', $(this).data("value"));
window.history.replaceState({}, '', `?${params}`);
}
});
$('.btn9').click(function () {
if ($(this).attr('data-selected') === 'true') {
$(this).attr('data-selected', 'false');
$(this).removeClass('selected');
} else {
$(this).closest('tr').find('.btn9').not(this)
.removeClass('selected').attr('data-selected', 'false');
$(this).attr('data-selected', 'true');
$(this).addClass('selected');
params.set('var9', $(this).data("value"));
window.history.replaceState({}, '', `?${params}`);
}
});
const params = new URLSearchParams({
var7: btn7,
var8: btn8,
var9: btn9,
});
Idea
Mark each table cell with a data- attribute indicating its respective row and column, and maintain 2 arrays that hold the currently selected element (if any) for each of the columns and row.
Implementation
The following code implements the selection logic. Based on the arrays holding the currently active selections you can visit all relevant elements and assemble the parameters when you send a request to the server.
The specs of single cell/row selection implies that there will usually be rows and columns that do not carry a selection.
Note that the case of expressly deselecting a cell is not handled.
The code does not resort to jquery.
<!DOCTYPE html>
<html>
<head>
<title>SO _: 1-in-a-row, 1-in-a-col selection</title>
<style type="text/css">
.selected {
background: #333;
color: #fff;
}
</style>
<script type="text/javascript">
let a_colSelection = new Array(3)
, a_rowSelection = new Array(3)
;
document.addEventListener ( 'DOMContentLoaded', () => {
Array.from(document.querySelectorAll('div[data-row][data-col]')).forEach ( el => {
el.addEventListener ( 'click', eve => {
let c = parseInt(eve.target.getAttribute('data-col'))
, r = parseInt(eve.target.getAttribute('data-row'))
;
if (a_colSelection[c] !== undefined) {
document.querySelector(`div[data-col="${a_colSelection[c][1]}"][data-row="${a_colSelection[c][0]}"]`).classList.remove("selected");
}
if (a_rowSelection[r] !== undefined) {
document.querySelector(`div[data-col="${a_rowSelection[r][1]}"][data-row="${a_rowSelection[r][0]}"]`).classList.remove("selected");
}
a_colSelection[c] = [r, c];
a_rowSelection[r] = [r, c];
document.querySelector(`div[data-col="${a_colSelection[c][1]}"][data-row="${a_rowSelection[r][0]}"]`).classList.add("selected");
});
});
});
</script>
</head>
<body>
<table border="1" cellpadding="5" class="test">
<tr>
<td class="talent-cell"><div data-value="0" data-col="0" data-row="0">aaa</div></td>
<td class="talent-cell"><div data-value="1" data-col="1" data-row="0">bbb</div></td>
<td class="talent-cell"><div data-value="2" data-col="2" data-row="0">ccc</div></td>
</tr>
<tr>
<td class="talent-cell"><div data-value="0" data-col="0" data-row="1">ddd</div></td>
<td class="talent-cell"><div data-value="1" data-col="1" data-row="1">eee</div></td>
<td class="talent-cell"><div data-value="2" data-col="2" data-row="1">fff</div></td>
</tr>
<tr>
<td class="talent-cell"><div data-value="0" data-col="0" data-row="2">ggg</div></td>
<td class="talent-cell"><div data-value="1" data-col="1" data-row="2">hhh</div></td>
<td class="talent-cell"><div data-value="2" data-col="2" data-row="2">iii</div></td>
</tr>
</table>
</body>
</html>
Consider the following.
Fiddle: https://jsfiddle.net/Twisty/dzng31f5/39/
HTML
<table border="1" cellpadding="5" class="test">
<tr class="var7">
<td class="talent-cell">
<div class="btn" data-value="0">aaa</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="1">bbb</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="2">ccc</div>
</td>
</tr>
<tr class="var8">
<td class="talent-cell">
<div class="btn" data-value="0">ddd</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="1">eee</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="2">fff</div>
</td>
</tr>
<tr class="var9">
<td class="talent-cell">
<div class="btn" data-value="0">ggg</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="1">hhh</div>
</td>
<td class="talent-cell">
<div class="btn" data-value="2">iii</div>
</td>
</tr>
</table>
I adjusted the HTML Structure, such that each Row has a Class that represents the Index name that will be used in the Object.
jQuery
$(function() {
function checkCol(colIndex, table) {
var result = true;
console.log("Col Index:" + colIndex)
$("tbody tr", table).each(function(i, el) {
result = result && !$("td:eq(" + colIndex + ") div.btn", el).hasClass("selected");
});
return !result;
}
function checkRow(target, row) {
var isInCol = checkCol($(target).parent().index(), $(row).closest("table"));
if (!isInCol) {
if ($(".selected", row).length) {
$(".selected", row).removeClass("selected");
$(target).addClass("selected");
} else {
$(target).addClass("selected");
}
}
}
var selected = {};
$('.btn').click(function(event) {
var row = $(this).closest("tr");
checkRow(this, row);
$(".test tbody tr").each(function(i, el) {
selected[$(el).attr("class")] = $(".selected", el).length ? $(".selected", el).data("value") : "";
});
console.log(selected);
var params = new URLSearchParams(selected);
console.log(params.toString());
});
});
You can now use selected as your Data in a POST or GET call.
Updated
I had missed that each Row and Column needed to be unique. Code is updated to use Functions to check both conditions.
"Now I need a certain condition. It should be only allowed to select one div-attribute per table row and column."
The versatility of jQuery is leveraged by the use of this because it narrows down from many objects (all <td> in <table>) to a single object (<td> the user clicked). The behavior needed is common with radio button groups called "mutual exclusive selection", using .not(this) makes it simple.
In HTML,
assign a common class to each <div> (ex. '.col', see Figure I)
assign a class to each <div> that corresponds to the value of it's [data-value] (ex. '.c0', see Figure I)
Figure I
<div class='col c0' data-value='0'>
I did not include the params part in OP since it's beyond the scope of the question (see beginning of this answer). The values are stored in object C and is easily accessible (ex. C.c0).
BTW, I hope that the logic is different with your real code. For example, there is no difference between .c0 2nd row and .c0 1st row.
Details are commented in example below
// Declare object to store [data-value]
let C = {};
// Any click on a .col calls the event handler
$('.col').on('click', function() {
// Flip .selected on this .col
$(this).toggleClass('selected');
// If this .col is flipped to be .selected...
if ($(this).is('.selected')) {
//... get this .col [data-value] (0, 1, or 2)...
let idx = $(this).data('value');
/*
... find all .c0, .c1, or .c2 BUT NOT this .col and
remove .selected from them...
*/
$('.c' + idx).not(this).removeClass('selected');
/*
... then find the closest <tr>, then find all .col of
<tr> BUT NOT this .col and remove .selected from them
*/
$(this).closest('tr').find('.col')
.not(this).removeClass('selected');
// set key 'c0', 'c1', or 'c2' of C to this .col [data-value]
C['c'+idx] = $(this).data('value');
}
console.log(C);
});
<table border="1" cellpadding="5" class="test">
<tr>
<td><div class="col c0" data-value="0">aaa</div></td>
<td><div class="col c1" data-value="1">bbb</div></td>
<td><div class="col c2" data-value="2">ccc</div></td>
</tr>
<tr>
<td><div class="col c0" data-value="0">aaa</div></td>
<td><div class="col c1" data-value="1">bbb</div></td>
<td><div class="col c2" data-value="2">ccc</div></td>
</tr>
<tr>
<td><div class="col c0" data-value="0">aaa</div></td>
<td><div class="col c1" data-value="1">bbb</div></td>
<td><div class="col c2" data-value="2">ccc</div></td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I have this counter for word occurrence in the textarea. The problem is, I have a lot of items in the table, and so it can be distracting to include the zero results.
So what I'm hoping to achieve is, if the user checks the checkbox, it will not show the zero results anymore (preferably the whole row)..
Please see the code so far:
let textarea = $('#textarea3');
textarea.on('keyup', _ => counting());
function counting() {
var searchText = $('#textarea3').val();
let words = [];
words['1 sample'] = '#one';
words['2 sample'] = '#two';
words['3 sample'] = '#three';
words['4 sample'] = '#four';
words['5 sample'] = '#five';
words['6 sample'] = '#six';
for (const word in words) {
var outputDiv = $(words[word]);
outputDiv.empty();
let count = searchText.split(word).length - 1;
searchText = searchText.replaceAll(word,'');
outputDiv.append('<a>' + count + '</a>');
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox">
<label> Don't show zero results</label><br>
<button onclick="counting();">Count</button>
<table>
<thead>
<tr>
<th scope="col">Items</th>
<th scope="col">Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>1 sample</td>
<td><a id="one"></a></td>
</tr>
<tr>
<td>2 sample</td>
<td><a id="two"></a></td>
</tr>
<tr>
<td>3 sample</td>
<td><a id="three"></a></td>
</tr>
<tr>
<td>4 sample</td>
<td><a id="four"></a></td>
</tr>
<tr>
<td>5 sample</td>
<td><a id="five"></a></td>
</tr>
<tr>
<td>6 sample</td>
<td><a id="six"></a></td>
</tr>
</tbody>
</table>
<textarea id="textarea3" rows="5">
1 sample
2 sample
3 sample
5 sample
</textarea>
If the checkbox isn't checked, it should function as is and still show all results.
I've seen this post but I'm not really sure how to implement it to my own project. Show or hide table row if checkbox is checked
Thank you in advance for any help.
Consider the following.
$(function() {
var textarea = $('#textarea3');
var words = [];
$("table tbody tr").each(function(i, row) {
words.push({
term: $("td:eq(0)", row).text().trim(),
rel: "#" + $("a", row).attr("id"),
count: 0
});
});
function count() {
var searchText = textarea.val();
$.each(words, function(i, word) {
if (searchText.indexOf(word.term) >= 0) {
var re = new RegExp('(' + word.term + ')', 'gi');
word.count = searchText.match(re).length;
$(word.rel).html(word.count);
} else {
word.count = 0;
if (!$("#noShowZero").is(":checked")) {
$(word.rel).html(word.count);
} else {
$(word.rel).html("");
}
}
});
}
textarea.keyup(count);
$("#count-btn, #noShowZero").click(count);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="noShowZero" type="checkbox">
<label> Don't show zero results</label><br>
<button id="count-btn">Count</button>
<table>
<thead>
<tr>
<th scope="col">Items</th>
<th scope="col">Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>1 sample</td>
<td>
<a id="one"></a>
</td>
</tr>
<tr>
<td>2 sample</td>
<td>
<a id="two"></a>
</td>
</tr>
<tr>
<td>3 sample</td>
<td>
<a id="three"></a>
</td>
</tr>
<tr>
<td>4 sample</td>
<td>
<a id="four"></a>
</td>
</tr>
<tr>
<td>5 sample</td>
<td>
<a id="five"></a>
</td>
</tr>
<tr>
<td>6 sample</td>
<td>
<a id="six"></a>
</td>
</tr>
</tbody>
</table>
<textarea id="textarea3" rows="5">
1 sample
2 sample
3 sample
5 sample
</textarea>
When the User:
Enters text in the textbox
Clicks the checkbox
Clicks the Button
then count function is executed.
Count will review all the words and look for specific keywords. A count of them is also retained, as well as element relationship to show that count.
Using Regular Expressions, we can search for the words in the text and count them using .match(). It returns an Array of the matches. You could also use .replace(), to remove them.
This question already has answers here:
How to get text node after element?
(4 answers)
Closed 3 years ago.
I have a table like so:
<table border="1" width="40%">
<tbody>
<tr class="child-row123" style="display: table-row;">
<td class="monsters">Monster</td>
<td class="monsters">
<a data-name="Megalosmasher X" target="_blank">Megalosmasher X</a> x3<br>
<a data-name="Danger! Nessie!" target="_blank">Danger! Nessie!</a> x2<br>
<a data-name="Kuriboh" target="_blank">Kuriboh</a> x1<br>
<a data-name="Dark Magician" target="_blank">Dark Magician</a> x3<br>
</td>
</tr>
</tbody>
</table>
I am currently using jquery get extract all the names from the data attributes.
However, I also need to see how many times it's referenced (x3, x2 or x1) which are standalone text nodes.
Here is my loop:
jQuery(".child-row123 a[data-name]").each(function(){
var dataname = jQuery(this).data('name');
//Alert
if(!jQuery.isNumeric(dataname)){
alert(dataname);
}
});
Using jQuery, is it possible to get the data-name alongside the text node of x3, x2 or x1? I'm trying figure it out logically and I'm guessing I need to look at the end of each anchor tag?
Try using the DOM function .nextSibling to pick the next node and use nodeValue to get the "referenced (x3, x2 or x1)"
Source: How to get text node after element?
jQuery(".child-row123 a[data-name]").each(function() {
var dataname = jQuery(this).data('name');
var nodetext = jQuery(this)[0].nextSibling.nodeValue;
//Alert
if (!jQuery.isNumeric(dataname)) {
console.log("Data: " + dataname + "\nreferenced: " + nodetext);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" width="40%">
<tbody>
<tr class="child-row123" style="display: table-row;">
<td class="monsters">Monster</td>
<td class="monsters">
<a data-name="Megalosmasher X" target="_blank">Megalosmasher X</a> x3<br>
<a data-name="Danger! Nessie!" target="_blank">Danger! Nessie!</a> x2<br>
<a data-name="Kuriboh" target="_blank">Kuriboh</a> x1<br>
<a data-name="Dark Magician" target="_blank">Dark Magician</a> x3<br>
</td>
</tr>
</tbody>
</table>
You can get the info with .nextSibling
jQuery(".child-row123 a[data-name]").each(function() {
var name = this.getAttribute("data-name"), // as the name is a string we don't really need the magic from jQuerys .data()
refs = this.nextSibling.textContent;
console.log(name, refs);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" width="40%">
<tbody>
<tr class="child-row123" style="display: table-row;">
<td class="monsters">Monster</td>
<td class="monsters">
<a data-name="Megalosmasher X" target="_blank">Megalosmasher X</a> x3<br>
<a data-name="Danger! Nessie!" target="_blank">Danger! Nessie!</a> x2<br>
<a data-name="Kuriboh" target="_blank">Kuriboh</a> x1<br>
<a data-name="Dark Magician" target="_blank">Dark Magician</a> x3<br>
</td>
</tr>
</tbody>
</table>
What I would do and what you could do if possible. Is wrap your texts inside a span and then get the text with next(). With this solution, instead of having floating texts you have a more structured html.
$(".child-row123 a[data-name]").each(function() {
var dataname = $(this).data('name');
//Alert
if (!$.isNumeric(dataname)) {
console.log(dataname + " " + $(this).next().text());
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" width="40%">
<tbody>
<tr class="child-row123" style="display: table-row;">
<td class="monsters">Monster</td>
<td class="monsters">
<a data-name="Megalosmasher X" target="_blank">Megalosmasher X</a> <span>x3</span><br>
<a data-name="Danger! Nessie!" target="_blank">Danger! Nessie!</a> <span>x2</span><br>
<a data-name="Kuriboh" target="_blank">Kuriboh</a> <span>x1</span><br>
<a data-name="Dark Magician" target="_blank">Dark Magician</a> <span>x3</span><br>
</td>
</tr>
</tbody>
</table>
How to find all custom elements in form and convert it to inputs with same value?
Here is the example code: http://jsfiddle.net/irider89/jsL28xno/4/
$(function() {
$(".triggeredit-card-list").click(function() {
var UsrName = $('.card-list-table').find('#nameEditable').html();
console.log(UsrName);
$('.card-list-tabe').find('#nameEditable').html('<input type="text" class="editable-table" name="editname" id="edittext" value="'+ UsrName +'" />');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="flip-scroll" class="table-responsive card-list-table">
<table class="table table-custom">
<thead>
<tr>
<th>Номер карты</th>
<th>Ф.И.О.</th>
<th>Дата выдачи</th>
<th>Состояние</th>
<th>Сумма на карте</th>
<th>Категория</th>
<th>Суточная норма</th>
<th>Месячная норма</th>
<th>Выбранная норма за месяц</th>
<th>Вес карты</th>
<th>Комментарий</th>
</tr>
</thead>
<tbody>
<tr>
<td>5757427</td>
<td class="" id="nameEditable">Петров Иван Иванович 1</td>
<td>25.12.2013</td>
<td>Все</td>
<td>3 300</td>
<td>Дизель</td>
<td>123</td>
<td>26</td>
<td id="monthValue">1</td>
<td>2</td>
<td>Комментарий</td>
<td>
</td>
</tr>
<tr>
<td>69594894</td>
<td id="nameEditable">Константинопольский Яков Аристархович</td>
<td>27.12.2013</td>
<td>Все</td>
<td>3 300</td>
<td>123</td>
<td>123</td>
<td>25</td>
<td>1</td>
<td>2</td>
<td>Комментарий</td>
<td>
</td>
</tr>
<tr>
<td>5757427</td>
<td id="nameEditable">Петров Иван Иванович</td>
<td>25.12.2013</td>
<td>Все</td>
<td>3 300</td>
<td>123</td>
<td>123</td>
<td>25</td>
<td>1</td>
<td>2</td>
<td>Комментарий</td>
<td>
</td>
</tr>
</tbody>
</table>
</form>
<button class="btn btn-info btn-triggeredit triggeredit-card-list"><i class="glyphicon glyphicon-pencil"></i> Редактировать</button>
I need to convert to input Ф.И.О. and Выбранная норма за месяц, but to put this values to the input.
I would use nameEditable as class because you have multiple element with this marker on document and ended up with something like this:
$(function () {
$(".triggeredit-card-list").click(function () {
$('.nameEditable').each(function(index, item){
var content = $(item).html();
$(item).replaceWith('<input type="text" class="editable-table" name="editname" id="edittext" value="' + content + '" />');
})
});
});
JSFiddle
$(function () {
$(".triggeredit-card-list").click(function () {
$('.nameEditable').each(function(index, item){
var content = $(item).html();
$(item).replaceWith('<input type="text" class="editable-table" name="editname" id="edittext" value="' + content + '" />');
})
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="flip-scroll" class="table-responsive card-list-table">
<table class="table table-custom">
<thead>
<tr>
<th>Номер карты</th>
<th>Ф.И.О.</th>
<th>Дата выдачи</th>
<th>Состояние</th>
<th>Сумма на карте</th>
<th>Категория</th>
<th>Суточная норма</th>
<th>Месячная норма</th>
<th>Выбранная норма за месяц</th>
<th>Вес карты</th>
<th>Комментарий</th>
</tr>
</thead>
<tbody>
<tr>
<td>5757427</td>
<td class="nameEditable">Петров Иван Иванович 1</td>
<td>25.12.2013</td>
<td>Все</td>
<td>3 300</td>
<td>Дизель</td>
<td>123</td>
<td>26</td>
<td id="monthValue">1</td>
<td>2</td>
<td>Комментарий</td>
<td>
</td>
</tr>
<tr>
<td>69594894</td>
<td class="nameEditable">Константинопольский Яков Аристархович</td>
<td>27.12.2013</td>
<td>Все</td>
<td>3 300</td>
<td>123</td>
<td>123</td>
<td>25</td>
<td>1</td>
<td>2</td>
<td>Комментарий</td>
<td>
</td>
</tr>
<tr>
<td>5757427</td>
<td class="nameEditable">Петров Иван Иванович</td>
<td>25.12.2013</td>
<td>Все</td>
<td>3 300</td>
<td>123</td>
<td>123</td>
<td>25</td>
<td>1</td>
<td>2</td>
<td>Комментарий</td>
<td>
</td>
</tr>
</tbody>
</table>
</form>
<button class="btn btn-info btn-triggeredit triggeredit-card-list"><i class="glyphicon glyphicon-pencil"></i> Редактировать</button>
its an example of one of your inputs, according to your jsFiddle
You should use replaceWith to replace the elemnt, html just changes the innerHtml of the element
$( "th:contains('Ф.И.О.')" ).replaceWith('<input value="Ф.И.О." />')
if you want just replace the content in th use
$( "th:contains('Ф.И.О.')" ).html('<input value="Ф.И.О." />')
In general it is
var itemToFind = 'Ф.И.О.'
$( "th:contains('"+itemToFind+"')" ).html('<input value="'+itemToFind+'" />')
If you want all th which have class editable to be replaced with input use the code below
$( "th.editable" ).each( function() {
$(this).html('<input value="'+$(this).text()+'" />')
});
I see that you already have given an id to the td you want to turn editable.
Select all td with id "nameEditable"
For each of those:
Cache the text
Create an input
Assign the cached text to the inputs val
Clear the td text
Append the created input to the td
It would be better if you give your button an id.
$("#btn").on("click", function () {
$("td#nameEditable").each(function () {
var txt = $(this).text();
var $tmpl = $("<input type='text' />");
$tmpl.val(txt);
$(this).text('');
$(this).append($tmpl);
});
});
Demo Fiddle: http://jsfiddle.net/jsL28xno/5/
Update:
If you want to search for particular text in th and then use that to convert that column to editable, then:
Search th containing the text
Store the index of that th
Use nth-child selector to select all td with the stored index (+1 actually)
Insert input as mentioned in the above code snippet
.
$("#btn").on("click", function () {
editColumn("Ф.И.О.");
editColumn("Выбранная норма за месяц");
});
function editColumn(whichColumn) {
var idx = $("table th:contains('" + whichColumn + "')").index() + 1;
$('table td:nth-child(' + idx + ')').each(function() {
var txt = $(this).text();
var $tmpl = $("<input type='text' />");
$tmpl.val(txt);
$(this).text('');
$(this).append($tmpl);
});
}
Demo Fiddle 2: http://jsfiddle.net/5rdq5s43/1/
Note 1: Instead of searching for text, you could directly use the column number.
Note 2: It is advisable to provide each input you add, a unique id. You can do that by using the index of the each function.
I want give every element in a table a generated id. See this html table below:
<table>
<tbody>
<tr>
<td>A1</td>
<td>A2</td>
<td>
A3
</td>
</tr>
<tr>
<td>B1</td>
<td>B2</td>
<td>
B3
</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
<td>C3</td>
</tr>
</tbody>
</table>
I want to give each element an id using breadth-first traversal. So, the result becomes like this:
<table>
<tbody id="0">
<tr id="1">
<td id="4">A1</td>
<td id="5">A2</td>
<td id="6">
A3
</td>
</tr>
<tr id="2">
<td id="7">B1</td>
<td id="8">B2</td>
<td id="9">
B3
</td>
</tr>
<tr id="3">
<td id="10">C1</td>
<td id="11">C2</td>
<td id="12">C3</td>
</tr>
</tbody>
</table>
I have tried the each() function in jQuery to generate the id for every element in that table, but the traversal algorithm used in each() function is pre order traversal.
Can anyone suggest me the Javascript code to do this?
var n = 0
var level = $("table");
while (level.children().length) {
level = level.children().each(function(_, el) {
el.id = n++;
})
}
DEMO: http://jsfiddle.net/J5QMK/
If you want to avoid the redundant .children() call, you can do this:
while ((level = level.children()).length) {
level.each(function (_, el) {
el.id = n++;
})
}
DEMO: http://jsfiddle.net/J5QMK/1/
A common way to do a breadth-first search is to use a queue as follows:
jQuery(document).ready(function () {
var ctr = 0;
var queue = [];
queue.push(jQuery("table").children()); // enqueue
while (queue.length > 0) {
var children = queue.shift(); // dequeue
children.each(function (ix, elem) {
queue.push( // enqueue
jQuery(elem).attr("id", ctr++).children();
);
console.log(elem.tagName + ": " + elem.id);
});
}
});