Replace old value with new value excluding the children - javascript

The initial text of A, B, C, D, and the number need to be removed in the frontend because I require it in the backend.
The HTML structure of table row is like this:
<tr ng-repeat="(key, field) in nbd_fields" ng-show="field.enable && field.published" class="ng-scope">
<td class="ng-binding">A,B,C,D: 1 - Auswahl Wunschkarte : <b class="ng-binding">Wähle eine Option</b>
</td>
<td ng-bind-html="field.price | to_trusted" class="ng-binding"></td>
</tr>
Before Input:
Current Output:
If you notice that the selected option is also not visible. Is it because of the $(window).load() ?
Required Output:
Code that I am using:
jQuery(".ng-scope td.ng-binding:first-child").text(function(i, oldVal) {
return oldVal.replace(/^[^-]+ - /,"");
});
});
How can I make it so that it does not affect the <b> tag inside?
I used the above code for the steps heading with a different selector on the same page* and it worked because it did not have any children to alter.
I had to wrap it around $(window).load() so that the changes are applied after the table is loaded. $(document).ready() did not work with it. Not sure why?

(Edit: Modified to accommodate restated requirement in comment below.)
To strip "everything up to and including the '-'" from the text of first column table cells while leaving the rest untouched:
// strip "everything up to and including the '-'"
// from table cell contents
function stripPrefix(tblCell) {
// only evaluate first td in tr
if (tblCell.previousElementSibling) {
return;
}
const tNode = tblCell.firstChild;
// ignore if table cell is empty
if (!tNode) {
return;
}
const chars = tNode.nodeValue.split('');
const iFirstDash = chars.indexOf('-');
if (iFirstDash === -1) { return; }
tNode.nodeValue = chars.slice(iFirstDash+1).join('');
}
function stripAllPrefixes() {
const tds = document.getElementsByTagName('td');
for (const td of tds) {
stripPrefix(td);
}
}
td {
border: 1px solid gray;
}
<h4>Strip "everything up to and including the '-'" from Table Cells</h4>
<table>
<tr>
<td>A,B,C,D: 1 - Auswahl Wunschkarte : <b>Wähle eine Option</b></td>
<td></td>
</tr>
<tr>
<td>B,C,D,E: 20 - A different leader : <b>should also be stripped</b></td>
<td></td>
</tr>
<tr>
<td>Oops no dash here <b>Just checking</b></td>
<td></td>
</tr>
</table>
<button onclick="stripAllPrefixes();">Strip All</button>

It does not effect the b tag, your code is working, you just need to use the right method and do the replacement to the HTML code and not the text nodes:
jQuery(".nbd-field-header label, .nbo-summary-table .ng-binding").html(function(i, oldVal) {
return oldVal.replace(/^[^-]+ - /,"");
});

Related

onclick add inner text to table td's

Currently I'm working on my React Tic-Tac-Toe App and I'm facing problem which I don't understand.
My file is very simple. I'm using one state and one function which is in useEffect. This function is supposed to choose whenever use X sign or O sign depending on current state value.
Everything was working just fine (X and O were switching on click) until I've added this condition to the checkPlayer function
if(e.target.innerText === ''){
//add mark to the TD
}else{
return;
}
This condition was supposed to prevent rewriting old inner text of td (For example when 1st player clicks on that td, X mark was added. But when 2nd player clicks that same td, it was rewriten to O mark).
But now, It's not switching between X and O and only writing X. Console is not throwing any errors and I don't get why is this happening.
Obviously, my goal is to prevent clicking on td, which already has some mark inside, so it won't be rewriten, state won't be changed and player won't be switched.
My State and useEffect with function
const [sign,setSign] = useState(true)
useEffect(()=>{
function checkPlayer(e){
if(e.target.innerText === ''){
//1st player
if(sign === true ){
e.target.innerText = 'X';
setSign(false)
}
//2nd player
if(sign === false){
e.target.innerText = 'O'
setSign(true)
}
}else{
return;
}
}
//Convert HTML collection to an array, then add eventListener to every item in array
let all = document.getElementsByTagName('td');
let tds = Array.from(all);
tds.forEach(td => {
td.addEventListener('click',checkPlayer)
})
},[sign])
HTML part of App
<div className="App">
<div className="container">
<table>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>

My assign on a table row not reflecting on the front end

I have finally filtered and retrieved the rows I want in my table and assigned it a value, it outputs to the console properly but not rendered on the web page itself.
I have retrieved my rows into a variable row and assigned it another variable
var rows = [...$(".table td")].map(e => $(e).text().trim()).filter(e => e);
console.log(rows);
for (i = 0; i < rows.length; i++) {
//I have assigned it in the line below
rows[i].text = dateArr[i];
console.log(rows[i]);
}
as you can see in your console.log(rows);
you only get a new array of string with all TD values, not a pointer on each TD with a useless complicated code
const newVals = [111,222,333];
document.querySelectorAll('#myTable td').forEach( (elmTD, idx)=>{
elmTD.textContent=newVals[idx].toString()
})
td { border:1px solid grey }
<table id="myTable">
<tr>
<td> aaa </td>
<td> bbb </td>
<td> ccc </td>
</tr>
</table>
All I can say is "forget jQuery and use javascript ES6" only because you already use arrow functions

How can I remove the div tags from a html table using jquery or javascript?

I'm looking to remove the divs from a html table but retain the content?
<table id="datatable">
<thead>
<tr>
<th></th>
<th>Jane</th>
<th>John</th>
</tr>
</thead>
<tbody>
<tr>
<th>Apples</th>
<td><div>3</div></td>
<td><div>4</div></td>
</tr>
</tbody>
</table>
I have tried:
alert($('#datatable').html().replace('<div>', ''));
But what is alerted still contains the
<div>
tags
I can't remove them from the source because they are used for other purposes.
To keep the DOM unmodified (IE: Leave the <div> tags in the source) and only modify the HTML variable you can do:
var html = $('#datatable').html();
var tags = ["<div>", "</div>"];
for (var i = 0; i < tags.length; i++) {
while (html.indexOf(tags[i]) > -1) {
html = html.replace(tags[i], "");
}
}
alert(html);
This is available as a demo at this fiddle.
The problem with your initial solution, is that JavaScript replace only removes the first occurrence of the specified string. Hence the while loop.
Use $('#datatable div').contents().unwrap() to remove the divs from the table and alert($('#datatable').html()) to show the remaining elements of the table.
var backup = $('#datatable').html();//Keep the html
$('#datatable div').contents().unwrap();//Remove divs
alert($('#datatable').html());//Show the table (without divs)
$('#datatable').html(backup);//Bring the old, full html back
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="datatable">
<thead>
<tr>
<th></th>
<th>Jane</th>
<th>John</th>
</tr>
</thead>
<tbody>
<tr>
<th>Apples</th>
<td><div>3</div></td>
<td><div>4</div></td>
</tr>
</tbody>
</table>
Try this
$('#datatable').find('div').remove();
If you want to keep content try this
$('#datatable').find('div').replaceWith(function(){
return $(this).text()
});
$('#datatable').find('div').replaceWith(function(){
return $(this).text()
});
alert($('#datatable').html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="datatable">
<thead>
<tr>
<th></th>
<th>Jane</th>
<th>John</th>
</tr>
</thead>
<tbody>
<tr>
<th>Apples</th>
<td><div>3</div></td>
<td><div>4</div></td>
</tr>
</tbody>
</table>
actually there are 3 common ways
1. Using the .html('') method
$("#my_element").html(''); // the quotes are important as just .html() returns the html DOM container within the target element
2. Using the .remove() method
$("#my_element #my_element_child").remove(); // removes the targeted child element
3. Using the .empty() method
$("#my_element").remove(); // similar to the .html('') method it removes all children divs
Edit It seams i have made a mistake in understanding the OP's original intention as pointed out by #JosephGarrone and hence i made the following edit.
var dom = $("#my_element").html() // get the elements DOM structure
var regex = /(<div>|<\/div>)/g; // a regex to pickup the <divs in the DOM
var div_less_dom = dom.replace(regex, '') // do something with the "<div>" free DOM
One approach, in plain JavaScript is:
// a descriptive, but ridiculously named, function,
// htmlString: String, the string of HTML from which
// you wish to remove certain element-types,
// toRemove: String, the element-type you wish to remove,
// this is passed to querySelectorAll(), so a
// CSS selector is fine, although to guard against
// '<div>' I have removed '<' and '>' characters:
function removeElementFromHTMLString(htmlString, toRemove) {
// here we create a <div> element:
let div = document.createElement('div'),
// and declare an 'empty' variable for
// later use:
parent;
// here we convert the supplied selector to lower-caase,
// and remove the '<' and '>' characters to prevent
// errors from the user supplying '<div>', converting it
// to 'div'; this does mean that the child combinator '>'
// cannot be used in the selector (as currently written):
toRemove = toRemove.toLowerCase().replace(/<|>/g,'');
// assigning the htmlString as the innerHTML of the
// created-<div>:
div.innerHTML = htmlString;
// passing the supplied selector to querySelectorAll(),
// converting the Array-like NodeList to an Array, and
// iterating over that Array with Array.prototype.forEach():
Array.from(div.querySelectorAll(toRemove)).forEach(function(elem){
// 'elem' refers to the current element in the Array of
// elements over which we're iterating:
// assigning the elem.parentNode to a variable for reuse:
parent = elem.parentNode;
// while the found element has a first child:
while (elem.firstChild) {
// we insert that first child ahead of the
// current element:
parent.insertBefore(elem.firstChild, elem);
}
// and then, once the element has no child
// elements, we remove the element from its
// parent:
parent.removeChild(elem);
});
// and then, assuming you want a HTML String without
// those elements matching the selector, we return
// the innerHTML to the calling context:
return div.innerHTML;
}
console.log(removeElementFromHTMLString(document.getElementById('datatable').outerHTML, 'div'));
function removeElementFromHTMLString(htmlString, toRemove) {
let div = document.createElement('div'),
parent;
toRemove = toRemove.toLowerCase().replace(/<|>/g, '');
div.innerHTML = htmlString;
Array.from(div.querySelectorAll(toRemove)).forEach(function(elem) {
parent = elem.parentNode;
while (elem.firstChild) {
parent.insertBefore(elem.firstChild, elem);
}
parent.removeChild(elem);
});
return div.innerHTML;
}
console.log(removeElementFromHTMLString(document.getElementById('datatable').outerHTML, 'div'));
td {
color: orange;
}
td > div {
color: limegreen;
}
<table id="datatable">
<thead>
<tr>
<th></th>
<th>Jane</th>
<th>John</th>
</tr>
</thead>
<tbody>
<tr>
<th>Apples</th>
<td>
<div>3</div>
</td>
<td>
<div>4</div>
</td>
</tr>
</tbody>
</table>

Dynamically remove tableDatas from table

Update Code working Here
I have a table populated with teacher's disciplines that has: day of the week and it's time period, of course it also have the disciplines.
Now I need to remove those items.
Table:
<table id="prof-table">
<tbody><tr>
<th>HORÁRIO</th>
<th data-dia="mon">Monday</th>
<th data-dia="tue">Tuesday</th>
<th data-dia="wed">Wednesday</th>
<th data-dia="thu">Thursday</th>
<th data-dia="fri">Friday</th>
</tr>
<tr>
<td>08:30 ~ 10:30</td>
<td><ol><li data-id="6" data-prof="4">Calculo A</li></ol></td>
</tr>
<tr>
<td>10:30 ~ 12:30</td>
td></td><td><ol><li data-id="2" data-prof="4">Lab II</li></ol></td>
</tr>
<tr>
<td>14:30 ~ 16:30</td>
</tr>
<tr>
<td>16:30 ~ 18:30</td>
</tr>
<tr>
<td>18:30 ~ 20:30</td>
<td></td><td></td><td></td><td></td><td><ol><li data-id="5" data-prof="4">Estatistica</li></ol></td>
</tr>
<tr>
<td>20:30 ~ 21:30</td>
</tr>
<tr>
<td>21:30 ~ 23:30</td>
</tr>
</tbody></table>
What I did so far is to get the <td> from the rows but I don't know how to work with it, tried to use .each() from JQuery but I just cant do it.
Javascript:
var myRow = document.getElementById("prof-table").rows[range.index + 1];
var test = $(myRow.getElementsByTagName('td')).not(':first-child');//Skip the first td because its the time period of the discipline.
console.log(teste);
Now if you check the console.log() this is what is shown:
As you can see, there are three lines. Each line/obj has the exactly number of <td>s from the row.
What I need to do is loop through each of these lines. Also I need to reset the index for each loop.
EX: While interacting with the first line of the image, my Index goes from 0 ~ 1. Then when start the second line I need to start my index from 0 again untill 4 (because it has 5 elements td)
Tried something like:
$.each(teste, function(index, obj){
if($(obj).text() == "")
myRow.deleteCells(index);
});
But as the index doesnt "reset" for each of those lines in the picture, I get error about overflowing the row index limite. Because while the first row has only one <td> member, the last has 5, as the index is always growing ++ I get that error. And I have no idea how to work around it.
Because I don't understand you situation well, I create two function
To delete data based on "data-prof" attribute of "li" inside the "td"
To delete all data of the table.
In my oppinion, if you assign "data-prof" value to the "td" instead of "li", it'll boost performance.
Hope it's help.
Function to delete data based on "data-prof" attribute:
function resetTableData(dataProf) {
// Get cell list by data-prof
var $cellList = $("#prof-table").find("li[data-prof = " + dataProf + "]").closest("td");
$cellList.each(function(){
$(this).html(""); //Remove inner HTML of cells.
});
}
Function to delete data of all cells:
function resetTableData() {
// Get row list
var $rowList = $("#prof-table").find("tr").not(":first"); // First row is the header, don't need to select.
// Loop row list and get cell list of each
$rowList.each(function(){
// Cell list
var $cellList = $(this).find("td").not(":first"); // First column is time period, don't delete it.
// Loop cell list and delete content
$cellList.each( function() {
$(this).html(""); //Remove inner HTML of cells.
});
});
}

How to select a row from dynamic table on mouseclick event

How can get a row's value on mouse click or checking the checkbox preferably from the below given html table?
Here is the js for getting values for my table from a xml using spry
var ds1 = new Spry.Data.XMLDataSet("xml/data.xml", "rows/row");
var pv1 = new Spry.Data.PagedView( ds1 ,{ pageSize: 10 , forceFullPages:true, useZeroBasedIndexes:true});
var pvInfo = pv1.getPagingInfo();
Here is the Div with spry region containing the table that gets populated from pv1 (see js part)
<div id="configDiv" name="config" style="width:100%;" spry:region="pv1">
<div spry:state="loading">Loading - Please stand by...</div>
<div spry:state="error">Oh crap, something went wrong!</div>
<div spry:state="ready">
<table id="tableDg" onclick="runEffect('Highlight', 'trEven', {duration: 1000, from: '#000000', to: '#805600', restoreColor: '#805600', toggle:true}, 'Flashes a color as the background of an HTML element.')"
style="border:#2F5882 1px solid;width:100%;" cellspacing="1" cellpadding="1">
<thead>
<tr id="trHead" style="color :#FFFFFF;background-color: #8EA4BB">
<th width="2%"><input id="chkbHead" type='checkbox' /></th>
<th width="10%" align="center" spry:sort="name"><b>Name</b></th>
<th width="22%" align="center" spry:sort="email"><b>Email</b></th>
</tr>
</thead>
<tbody spry:repeat="pv1">
<tr class="trOdd"
spry:if="({ds_RowNumber} % 2) != 0" onclick="ds1.setCurrentRow('{ds_RowID}');"
style="color :#2F5882;background-color: #FFFFFF">
<td><input type="checkbox" id="chkbTest" class = "chkbCsm"></input></td>
<td width="10%" align="center"> {name}</td>
<td width="22%" align="center"> {email}</td>
</tr>
<tr class="trEven" name="trEven" id="trEven"
spry:if="({ds_RowNumber} % 2) == 0" onclick="ds1.setCurrentRow('{ds_RowID}');"
style="color :#2F5882;background-color: #EDF1F5;">
<td><input type="checkbox" class = "chkbCsm"></input></td>
<td id="tdname" width="10%" align="center"> {name}</td>
<td width="22%" align="center"> {email}</td>
</tr>
</tbody>
</table>
</div>
</div>
I am trying the below code but still I am not getting the alert and hence none of the answers are also not working. I know the syntax n all are everything correct, but i am not able to figure out what is the problem here!
//inside $(document).ready(function()
$("#chkbHead").click(function() {
alert("Hi");
});
My page has other tables too for aligning some contents. So when I use the below code it works perfectly on those tables except the one in the question. It might be the problem because there are only 2 tr in the table which gets populated by a spry dataset and hence not getting identified properly. May be, I am not sure, just trying to help improve my understanding
$('tr').click(function() {
alert("by");
});
The values of a Row you will get with:
$('#tableDg tbody tr').live( 'click', function (event) {
$(this).find('td').each( function( index, item ) {
if ( $(this).has(':checkbox') ) {
alert( $(this).find(':checkbox').val() );
} else {
alert( $(this).text() );
}
};
});
What exactly do you mean by value of a table row? You can get the inner html of a table row like this:
var html = '';
$('tr').click(function() {
html = $(this).html();
});
You can get attributes of the table row (e.g. it's Id) like so:
var id = '';
$('tr').click(function() {
id = $(this).attr('id');
});
Alternatively you can get the value of nested elements such as a text input like so:
var text = '';
$('tr').click(function() {
text = $(this).find('#myTextBox').val();
});
EDIT
This is how to change the checked attribute of a checkbox nested in a table row:
$('tr').click(function() {
$(this).find('input:checkbox').attr('checked', 'checked');
// alternatively make it unchecked
$(this).find('input:checkbox').attr('checked', '');
});
EDIT
As the table rows are being loaded dynamically - the $().click() event binding method will not work, because when you are calling it - the table rows do not exist, so the click event cannot be bound to them. Instead of using $().click use the jQuery live method:
$('tr').live('click', function() {
// do stuff
});
This binds the click event to all current table rows and all table rows that may be added in the future. See the jQuery docs here
you have to use Spry Observer,
something like this:
function funcObserver(notificationState, notifier, data) {
var rgn = Spry.Data.getRegion('configDiv');
st = rgn.getState();
if (notificationState == "onPostUpdate" && st == 'ready') {
// HERE YOU CAN USE YOUR JQUERY CODE
$('#tableDg tbody tr').click(function() {
$(this).find('input:checkbox').attr('checked', 'checked');
// alternatively make it unchecked
$(this).find('input:checkbox').attr('checked', '');
});
}
}
Spry.Data.Region.addObserver("configDiv", funcObserver);

Categories

Resources