What are HTML DOM #text elements? - javascript

I'm learning knockout.js and trying to use an afterRender callback to apply behaviour to elements.
I don't understand what these #text elements are that show up in my console.log().
So UI looks like this:
Knockout binding like this:
<div id='categoriesTree' style="color:black">
<table class='categoriesEditor'>
<tbody data-bind="template: { name: 'itemTmpl', foreach:children, afterRender: myPostProcessingLogic2 }"></tbody>
</table>
</div>
Template:
<script id="itemTmpl" type="text/html">
<tr>
<td>
<div class="input-group cat-block" style="margin-left: 3px; margin-bottom: 12px;">
<label id="may-search-tags-lbl" style="background-color:beige;visibility:hidden;margin:0;">Category Name</label>
<input data-bind='value: Name' id="maynavsearchphrase" type="text" class="form-control"
placeholder="Category name" name="maynavsearchphrase"
value="" />
<div class="input-group-btn btn-grp-70 cat-meth-off">
<button id="may-nav-tags-search-btn" class="btn btn-default btnIcon may-tipped"
type="button" data-toggle="tooltip" title="Delete Category">
<i class="glyphicon glyphicon-remove"></i>
</button>
<button id="may-nav-search-search-btn" class="btn btn-default btnIcon may-tipped"
data-toggle="tooltip" title="Add subcategories"
data-bind='click: $root.addCategory'
type="button">
<i class="glyphicon glyphicon-expand"></i>
</button>
</div>
</div>
</td>
<td data-bind="visible: children().length">
<table>
<tbody data-bind="template: { name: 'itemTmpl', foreach: children }"></tbody>
</table>
</td>
</tr>
</script>
Callback function:
self.myPostProcessingLogic2 = function (elements) {
console.log(elements);
}
And then chrome dev tools console output:
What are the "text" elements in text, tr, text? There is no text element that is a sibling of tr. tbody can only contain tr's right?
If I drill into text I can see that it has an attribute of cells : HtmlCollection[2] both nodes of which are td. So it's almost like text = tr but if thats the case then why am I getting 3 sibling nodes to represent one row?

"What are the "text" elements in text, tr, text? There is no text element that is a sibling of tr..."
Everything in the DOM is represented by a node. Including plain text.
In your case, the text nodes are coming from the whitespace you have around your elements for formatting. That text is counted just like any other text.
<table>
<tbody>
<tr>
<td>foo</td>
</tr>
</tbody>
</table>
All that empty whitespace around the opening/closing tags gets represented as text nodes. This is true for all elements in the DOM, not just tables.
Table elements have special collections for you to use, which allow you to access just the table elements.
table.tBodies[] // to get the tbody elements of a table
table.rows[] // to get the rows of a table
tbody.rows[] // to get the rows of a tbody
row.cells[] // to get the cells of a row
Or you can use the generic .children to avoid text nodes.
tbody.children[]

The text nodes are the ones you write with "" inside your HTML.
Run this in your console, then scroll to the bottom, right-click and click inspect element:
document.body.appendChild(document.createTextNode("Some text node"))

Please print the value of #text in the console if it is node console.log(nodes.item(i).nodeValue)
This may occur due a space between the html element assign value.

Related

Delete the parent row not the child row in jQuery

This is the result of a datatable on a specific screen size. If all the columns are displayed, there is no problem deleting the row using
$(this).closest('tr').remove();
But when screen size became smaller, this will be the result. I cannot use the above code anymore. Now if I hit the button with the class deleteRow, I want to delete the tr with the class parent and its child (though the child row is not inside the parent row), not just the closest row. There could be many rows that have class parent so I just want to delete the row associates to the childs' row.
I want to delete the tr with the class parent, not just the closest row.
Then include that extra info .parent in the selector like so:
$(this).closest('tr.parent').remove();
Try
$(this).closest('tr.child')
You can have a look at the samples I've put together here, I've tried to split into many cases that you can reference and re-apply to your project.
Let me know which's suitable for you and I can explain it clearer.
$(document).ready(function() {
$('.delete-single-parent').each(function(index) {
var $this = $(this);
$this.click(function() {
// $(this) = the element button clicked
// Try row 1,3,5
$(this).closest('tr.parent').remove();
// Try row 2,4,6. Assuming "parent" is always a sibling of current `child`
$(this).closest('tr.child').prev().remove();
})
});
// This queries to the top (table), and find all parent rows to remove
// Will remove row 1,3,5 only
$('.delete-all-parents').click(function() {
$(this)
.closest('table')
.find('tr.parent')
.remove();
})
})
table {
border: 1px solid grey;
}
table tr:nth-child(odd) {
background-color: #f3f3f3;
}
table tr td {
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class="parent">
<td>
<div>1</div>
<button class="delete-single-parent">Delete Direct parent</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="child">
<td>
<div>2</div>
<button class="delete-single-parent">Delete Parent (row 1)</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="parent">
<td>
<div>3</div>
<button class="delete-single-parent">Delete Direct parent</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="child">
<td>
<div>4</div>
<button class="delete-single-parent">Delete Parent (row 3)</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="parent">
<td>
<div>5</div>
<button class="delete-single-parent">Delete Direct parent</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="child">
<td>
<div>6</div>
<button class="delete-single-parent">Delete Parent (row 5)</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
</table>
Just fixed my own issue. I added attribute to the parent row upon page loading.
<tr data_id = {{ $item->id }}>
this will make the tr unique so that I can call this later to delete the parent as well as the child row.
to delete the child where the button is placed
$(this).closest('tr.child').remove();
and added code to delete the parent row through attribute as selector.
$('[data_id="'+ row_id +'"]').remove();
so upon ajax success, I will call these two.
$tr.find('td').fadeOut(1000,function(){
$(this).closest('tr.child').remove();
$('[data_id="'+ row_id +'"]').remove();
});

Knockout JS: Validation of Textboxes inside the table for-each

I have html table whose columns are dynamically generated, where each column is a textbox. I am struggling to work out is how to validate these textboxes.
Here is my jsfiddle:
https://jsfiddle.net/aman1981/4djn2zee/
So on the save button click I want to validate user input.
The requirement is:
I want to make all but one column required field.
I want to apply regex to certain columns (based on column name) as some columns are chars only whereas some only numbers.
Here is my construct of the texbox:
<tbody data-bind="foreach: { data: valuesData, as: 'rowData'}">
<tr data-bind="foreach: { data: $parent.columns, as: 'column' }">
<!-- NEW: bind to the corresponding property/observable in ValuesData -->
<td><input type="text" class="form-control textbox" data-bind="textInput: rowData[column.Property]" /> </td>
</tr>
<tr>
<td>
<input type="button" value="Remove Row" data-bind="click: $parent.removeRow" class="btn btn-danger" />
</td>
</tr>
</tbody>
Its a little complex requirement and have been struggling to gets head up on this.
Any pointers to this ?
Anyone/??

How to get the dynamic id by its name

I am having a table with so many rows which is also having a button in each row , so I put its Id dynamically like id=#gunDetails.SerialNo(for each row its different) and its name I gave as name="popoverselect" So now I want to get this dynamic Id . How can i get it I need the Id in my popup which will open when I click on that button.
I have tried `
var getVal = $('[name="popoverselect"]').attr(id);
but its not working, any help will be appreciated.
Edit
<td class="text-center">
<div class="btn-group">
<i class="fa fa-pencil"></i>
</div>
</td>
This is my button which will show the popover so when I am trying
var getVal = $('[name="popoverselect"]').attr("id");
I am only getting the id of my first row
`
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<button id="1593" onclick="alert($(this).attr('id'))">Button 1</button>
</td>
</tr>
<tr>
<td>
<button id="1678" onclick="alert($(this).attr('id'))">Button 2</button>
</td>
</tr>
</table>
You can select element by name like this
$("[name='popoverselect']");//select all elements with name equal to 'popoverselect'
$("[name*='popoverselect']");//select all elements with name contains 'popoverselect'
$("[name^='popoverselect']");//select all elements with name start with 'popoverselect'
And to get id use $("[name='popoverselect']").attr("id");
so for your example .attr(id) JQuery will look to id as variable witch not defined
var id = "id";
$("[name='popoverselect']").attr(id);//this will work

Traversing up, then back down the DOM

I have a click event setup and inside its code block I'm storing the value of certain sibling elements. Right now if I wanted the text inside the .title span after clicking the .play button I have to work my way up two levels and back down to the .title.
I was wondering what would be a better way to access information from sibling elements wrapped in two or more parent divs?
HTML
<table>
<tr>
<td>
<button class="play">Play</button>
</td>
<td>
<span class="number">01.</span>
</td>
<td>
<span class="title">Track 1</span>
</td>
</tr>
<tr>
<td>
<button class="play">Play</button>
</td>
<td>
<span class="number">02.</span>
</td>
<td>
<span class="title">Track 2</span>
</td>
</tr>
</table>
JS
$(function() {
$(".play").on("click", function() {
var number = $(this).parent().parent().find(".number").text(),
title = $(this).parent().parent().find(".title").text();
console.log(number + title);
});
});
You could use jQuery's closest() function.
var number = $(this).closest('tr').find(".number").text(),
title = $(this).closest('tr').find(".title").text();
You can use closest() to go back to a common parent
var number = $(this).closest('tr').find(".number").text(),
title = $(this).closest('tr').find(".title").text();
fiddle

Getting the text value of a hidden span tag

I have a table with columns of data (name, age, email) and I have a single modal window that is hidden and only appears when the user clicks "Detail" along side each row.
The data that needs to be populated in the modal is in hidden span tags with classes such as hide-name etc.
HTML:
<tr class="xrow row-2">
<td>Fisher, Baker</td>
<td>2 notes</td>
<td>Review</td>
<span class="hide hidden-name">Fisher, Baker</span>
<span class="hide hidden-date">2014-03-20</span>
<span class="hide hidden-time">14:00:00</span>
</tr>
This is my JS that I have used, however when I call on the name variable it returns nothing.
$('.xrow').on("click", '.btn-review', function () {
var name = $(this).closest('span.hidden-name').text();
// alert(name);
}
this in your code refers to the .btn-review element not the tr, you should at first select the closest tr element:
var name = $(this).closest('tr').find('span.hidden-name').text();
edit: Your markup is invalid, tr element can only have td child element, you should wrap the span elements with td elements, browsers will render this markup differently. After changing the markup the above snippet should work.
I would suggest moving the spans to the td element that has the button as it's child and then use $(this).siblings('span.hidden-name').text() which is more efficient than using closest and then find.
<tr class="xrow row-2">
<td>Fisher, Baker</td>
<td>2 notes</td>
<td>
Review
<span class="hide hidden-name">Fisher, Baker</span>
<span class="hide hidden-date">2014-03-20</span>
<span class="hide hidden-time">14:00:00</span>
</td>
</tr>
I think I've figured what you want:
$('.xrow').click(function () {
var name = $(this).find('span.hidden-name').text();
})
You just have to search the element you want, within the contents of the element you clicked on.
you should wrap your spans with any td. for example last td.
<td>
Review
<span class="hide hidden-name">Fisher, Baker</span>
<span class="hide hidden-date">2014-03-20</span>
<span class="hide hidden-time">14:00:00</span>
</td>
and you can reach with:
$('.xrow').on("click", '.btn-review', function () {
var name = $(this).parents('.xrow').find('span.hidden-name').text();
alert(name);
});
http://jsfiddle.net/V4z8S/2/

Categories