$(this) issue when defining a function - javascript

I have this code to remove table rows on select. (Fiddle)
$('select').change(function() {
var $this = $(this),
list = $('table tbody tr'),
findoption = $this.find('option:selected'),
selected = findoption.data('hide'),
show_hide_li = $this.find("."+selected);
if (selected == "reset") {
list.show();
}
else {
$('.'+selected).show();
list.not('.'+selected).hide()
}
});
When I move the code out of the change function and define it like the following, I have an issue with the $(this) that prevents the code from working. Can anyone tell me how to define a function when there is $(this) in the code?
var cancel = function(){
var $this = $(this),
list = $('table tbody tr'),
findoption = $this.find('option:selected'),
selected = findoption.data('hide'),
show_hide_li = $this.find("."+selected);
if (selected == "reset") {
list.show();
}
else {
$('.'+selected).show();
list.not('.'+selected).hide()
}
}
$('select').change(function() {
cancel();
});

I think this is what you're trying to do.
function cancel(){
var $this = $(this),
list = $('table tbody tr'),
findoption = $this.find('option:selected'),
selected = findoption.data('hide'),
show_hide_li = $this.find("."+selected);
if (selected == "reset") {
list.show();
}
else {
$('.'+selected).show();
list.not('.'+selected).hide()
}
}
$('select').change(cancel);

You can pass the "this" as a parameter to the function
var cancel = function(param1){
var $this = $(param1),
list = $('table tbody tr'),
findoption = $this.find('option:selected'),
selected = findoption.data('hide'),
show_hide_li = $this.find("."+selected);
if (selected == "reset") {
list.show();
}
else {
$('.'+selected).show();
list.not('.'+selected).hide()
}
}
$('select').change(function() {
cancel(this);
});

Use .on method of jquery
$('select').on('change', cancel);
var cancel = function(){
var $this = $(this),
list = $('table tbody tr'),
findoption = $this.find('option:selected'),
selected = findoption.data('hide'),
show_hide_li = $this.find("."+selected);
if (selected == "reset") {
list.show();
}
else {
$('.'+selected).show();
list.not('.'+selected).hide()
}
}

This very brief, but powerful line, should replace the ones shown after:
$('select').change(cancel);
Replace below lines with above one:
$('select').change(function() {
cancel();
});
Because these three lines are equivalent to:
$('select').change(function() {
//you have access to 'this' here
function() {
//your body
}
});
And as you can see the inner function has no access to this unless you explicitly pass it as a parameter, which your can easily avoid by removing nested functions.

Related

How to limit the number of search results from table records using jQuery?

I want to limit the number of search results from table records to 12 or any number less than 15 etc. This is how far I got with the code. What am i doing wrong?
I tried posting a JS Fiddle in Stack Overflow, but the code is just too long to post.
I prepared a Js Fiddle for better understanding.
Jquery part alone below:
$("#search").on("keyup", function() {
var value = $(this).val();
$("table tr").each(function(index) {
if (index !== 0) {
$row = $(this);
$row.find('td').each (function() {
var id = $(this).text();
if (this.innerHTML.toLowerCase().indexOf(value.toLowerCase()) !== 0) {
$row.slice(0,12).hide();
}
else {
$row.slice(0,12).show();
return false;
}
});
}
});
});
Here is the JSFiddle link which i prepared for better understanding.
https://jsfiddle.net/5g3yxrz4/
You can do it like this: https://jsfiddle.net/5g3yxrz4/5/
$("#search").on("keyup", function() {
var value = $(this).val();
var showRowsLimit = 12;
var rowsShowing = 0;
$("table tr").each(function(index) {
if (index !== 0) {
$row = $(this);
$row.find('td').each (function() {
var id = $(this).text();
if (this.innerHTML.toLowerCase().indexOf(value.toLowerCase()) !== 0 || rowsShowing>=showRowsLimit) {
$row.hide();
}
else {
$row.show();
rowsShowing++;
return false;
}
});
}
});
});
Try this one
const max = 12; // Maximum to show
...
var i = 0;
...
else if(i++ < max) {
...
https://jsfiddle.net/5g3yxrz4/3/
Just added counter for showed "tr"

modify javascript to find first letter in a value

I know little about javascript. From what I can see, this shows a set of rows that contain a value (in this case, the author of a WP plugin).
What I'd like to do, instead of finding the data-name value in the row, is find if the first letter of this value is "A". And hopefully I should be able to work on the preceding code to get to this part... :)
Thanks so much.
<script>
var authors = [];
$('.pba-id').each(function () {
var author = $(this).attr('data-author');
if (-1 == $.inArray(author, authors))
authors.push(author);
});
$.each(authors, function (i, author) {
$select.append($('<option>').html(author));
});
$select.change(function(){
var value = $(this).val();
if ('__pba_none' == value) {
$('#the-list tr').show();
return;
}
$('#the-list tr').each(function(){
var $row = $(this);
if ($row.find('.pba-id[data-author="' + value + '"]').length)
$row.show();
else
$row.hide();
});
</script>
Use Attribute Starts With Selector [name^=”value”] selector.
Selects elements that have the specified attribute with a value beginning exactly with a given string.
$('#the-list tr').each(function() {
var value = "A";
var $row = $(this);
if ($row.find('.pba-id[data-name^="' + value + '"]').length) {
//---------------------------^^^
$row.show();
} else {
$row.hide();
}
});
Try this :
$('#the-list tr').each(function() {
// var value = "any value" ;
var $row = $(this);
if ($row.find('.pba-id[data-name^="' + value[0] + '"]').length) {
$row.show();
} else {
$row.hide();
}
});

Code returns all the items in Checkboxes

In here i want to get allRefItems but it should be checked & NOT disabled.But in here always get
all the Id's
var allRefItems = [];
$('table#reftable > tbody > tr').each(function () {
if ($(this).find('td:eq(0) input', this).is(':checked')) {
if ($(this).find('td:eq(0) input', this).not(':disabled')) {
itId = $(this).find('td:eq(0) input', this).attr('id');
allRefItems.push(itId);
}
}
});
If you want to get all checkboxes in table i think you could do it easier:
var allRefItems = [];
$('table#reftable > tbody input[type="checkbox"]') //get all checboxes
.filter(function() { // filter them only checked and not disabled
return !this.disabled && this.checked;
}).each(function () { //getting your ids
itId = $(this).attr('id');
allRefItems.push(itId);
});
Here is an jsFiddle example.
You can use,
var allRefItems = $('table#reftable > tbody > tr input[type="checkbox"]:checked:not(:disabled)').map(function() {
return this.id;
}).get();

Find value in all TD with Highlighting

I have this script for searching in table with Highlighting value from "input". But only for first TD in all TR.
Function remove Highlighting
function removeHighlighting(highlightedElements){
highlightedElements.each(function(){
var element = $(this);
element.replaceWith(element.html());
})
}
Function add Highlighting
function addHighlighting(element, textToHighlight){
var text = element.text();
var highlightedText = '<em>' + textToHighlight + '</em>';
var newText = text.replace(textToHighlight, highlightedText);
element.html(newText);
}
Searching in table but only in first TD in TR
$("#search").on("keyup", function() {
var value = $(this).val();
removeHighlighting($("table tr em"));
$("table tr").each(function(index) {
if (index !== 0) {
$row = $(this);
var $tdElement = $row.find('td:first');
var id = $tdElement.text();
var matchedIndex = id.indexOf(value);
if (matchedIndex != 0) {
$row.hide();
}
else {
addHighlighting($tdElement, value);
$row.show();
}
}
});
});
I don´t know how can I searching in all TD and How can I write e.g. some alert if "matchedIndex == -1" (if not found some value from input)
Try looping in all TDs of TR
$("table tr").each(function(index) {
if (index !== 0) {
row = $(this);
$("td", this).each(function(idx) {
var id = $(this).text(); //or $(this).innerText
var matchedIndex = id.indexOf(value);
if (matchedIndex != 0) {
$row.hide();
}
else {
addHighlighting($tdElement, value);
$row.show();
}
}
}
});
A short way
$("table tr > td em").each(function(){
$( this ).replaceWith( $( this ).text() );
});
Adding a span tag with a highlight class is the way to go like suggested in the comments.
Please find a working demo below and in this jsFiddle.
There is a really useful function to remove all the wrapping of the spans. You can do this with $('span.highlight').contents().unwrap().
For finding the text you can use string.search(searchText) or string.match(searchText). The search method will return -1 if nothing is found and the position of the text if found. And match would return occurences in the searchText.
For testing that it finds the first occurence I have added TestY in the table. The flag matched is responsible for this behavior. If you would remove it, it would highlight both TestY elements.
(function () {
var removeHighlight = function () {
$('span.highlight').contents().unwrap();
};
var wrapContent = function (index, $el, text) {
var $highlight = $('<span class="highlight"/>')
.text(text.substring(0, index));
//console.log(text.substring(0, index));
var normalText = document.createTextNode(text.substring(index, text.length));
//console.log(index, $highlight.text(), normalText);
$el.html($highlight).append(normalText);
};
var highlightTextInTable = function ($tableElements, searchText) {
// highlights if text found (during typing)
var matched = false;
//remove spans
removeHighlight();
$.each($tableElements, function (index, item) {
var $el = $(item);
if ($el.text().search(searchText) != -1 && !matched) {
//console.log("matched", $el, $el.html());
wrapContent(searchText.length, $el, $el.html());
//console.log(searchText, $el.text());
if (searchText == $el.text()) {
// found the entry
//console.log("matched");
matched = true;
}
}
});
};
$(function () {
//load table into object
var $tableRows = $('table tr');
var $tableElements = $tableRows.children();
//console.log($tableRows, $tableElements);
$('#search').on('keyup', function (e) {
var searchText = $(this).val();
if (searchText.length == 0) {
// catches false triggers with empty input (e.g. backspace delete or case lock switch would trigger the function)
removeHighlight(); // remove last remaining highlight
return;
}
highlightTextInTable($tableElements, searchText);
});
});
})();
.highlight {
background-color: #00FFFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search" />
<table>
<tr>
<td>TestX</td>
<td>Test1.2</td>
<td>Test1.3</td>
<td>Test1.4</td>
</tr>
<tr>
<td>Test2.1</td>
<td>TestY</td>
<td>Test2.3</td>
<td>Test2.4</td>
</tr>
<tr>
<td>Test3.1</td>
<td>TestY</td>
<td>Test3.3</td>
<td>Test3.4</td>
</tr>
</table>

jquery remove duplicate li

<ul id="myid">
<li>microsoft</li>
<li>microsoft</li>
<li>apple</li>
<li>apple</li>
</ul>
I want to remove duplicates from li by using jquery.
How can I do that?
example
I find that the script is faster
var liText = '', liList = $('#myid li'), listForRemove = [];
$(liList).each(function () {
var text = $(this).text();
if (liText.indexOf('|'+ text + '|') == -1)
liText += '|'+ text + '|';
else
listForRemove.push($(this));
})​;
$(listForRemove).each(function () { $(this).remove(); });
uniqueLi = {};
$("#myid li").each(function () {
var thisVal = $(this).text();
if ( !(thisVal in uniqueLi) ) {
uniqueLi[thisVal] = "";
} else {
$(this).remove();
}
})
This build an index (an object) of unique values. For your example, uniqueLi will look like this afterwards:
{
"microsoft": "",
"apple": ""
}
So whenever a value is encountered that has been added to the index before, the associated <li> gets removed.
You could use
var inner = [];
$('li').each( function(index, Element){
if (jQuery.inArray(this.innerHTML, inner) == -1){
inner.push(this.innerHTML);
}
else {
$(this).remove();
}
});
Here's a function that will do it, a slightly different way:
function removeDuplicateItems(id) {
var ul = $('#' + id);
$('li', ul).each(function() {
if($('li:contains("' + $(this).text() + '")', ul).length > 1)
$(this).remove();
});
}
Call with removeDuplicateItems('myid');
I have used #Thariama solution in the past, but I have compatibility problems with IE6 (I still needs to support this dinosaur).
If the item repeats, so remove it from ul. It works with dynamic added li.
var seen = {};
$("ul#emails_exclusion_list").find("li").each(function(index, html_obj) {
txt = $(this).text().toLowerCase();
if(seen[txt]) {
$(this).remove();
} else {
seen[txt] = true;
}
});

Categories