shorter way to check if a title exists - javascript

Checking if a title already exists. Is there a shorter way? Something like:
if(test.exists.inside('.title'){...
var x = 0;
var test = $('#test').text();
$('.title').each(function(){
if($(this).text() == test){x = 1;}
});
if(x == 1){console.log('exists');}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='title'>lorem</div>
<div class='title'>ipsum</div>
<div class='title'>lorema</div>
<div class='title'>ipsuma</div>
<div id='test'>lorem</div>

a lot of ways to do this :contains , filter() with indexOf() and filter() with text equal test.. depending on what you're trying to do
var x = 0;
var test = $('#test').text();
var Exists = $('.title:contains("'+test+'")').length;
console.log('Yes '+Exists+ ' title with text '+test);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='title'>lorem</div>
<div class='title'>ipsum</div>
<div class='title'>lorema</div>
<div class='title'>ipsuma</div>
<div id='test'>lorem</div>
you can check also with for contains text check
$('.title:contains("'+test+'")').length > 0
OR for exact text check
$('.title').filter(function(){
return $(this).text().trim() == test;
}).length > 0
Note: :contains and .indexOf search for the text contains text not the exact text .. by using $(this).text().trim() == test; this
will return the exact text element

If you're just looking for shorter code, one option would be to invoke Array.prototype.some, and rather than store the result of .text() in a variable, invoke it every time, to save on characters typed:
if ([].some.call($('.title'), d => $(d).text() === $('#test').text())) {
console.log('exists');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='title'>lorem</div>
<div class='title'>ipsum</div>
<div class='title'>lorema</div>
<div class='title'>ipsuma</div>
<div id='test'>lorem</div>
Personally, I'd prefer readability over code length:
const textToFind = $('#test').text();
const exists = Array.prototype.some.call(
$('.title'),
title => $(title).text() === textToFind
);
if (exists) {
console.log('exists');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='title'>lorem</div>
<div class='title'>ipsum</div>
<div class='title'>lorema</div>
<div class='title'>ipsuma</div>
<div id='test'>lorem</div>

Related

Problem using .sort to sort elements alphabetically

Am having a problem with sorting using jquery.The elements not getting sorted.I used javascript .sort but this works fine with me if the attribute is numbers but not text.
I can solve the issue using append but this is not what am willing to use.
Can some one please trouble shoot this code.
jQuery(document).ready(function($) {
var divList = $(".listing-item");
var gg = divList.get().sort(function(a, b) {
return $(a).data("listing-title") < $(b).data("listing-title");
});
console.log(gg);
$("#list").html(divList);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="listing-item" data-listing-title="a">
a
</div>
<div class="listing-item" data-listing-title="z">
z
</div>
<div class="listing-item" data-listing-title="b">
b
</div>
<div class="listing-item" data-listing-title="c">
c
</div>
</div>
Try using .localeCompare(). I have pull this working content from jQuery - Sorting div contents
<!DOCTYPE html>
<htm>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
var divList = $(".listing-item");
divList.sort(function(a, b) {
return $(a).data("listing-title").toUpperCase().localeCompare($(b).data("listing-title").toUpperCase());
});
$("#list").html(divList);
});
</script>
</head>
<body>
<div id="list">
<div class="listing-item" data-listing-title="a">a</div>
<div class="listing-item" data-listing-title="z">z</div>
<div class="listing-item" data-listing-title="b">b</div>
<div class="listing-item" data-listing-title="c">c</div>
</div>
</body>
</html>
See also similar question How may I sort a list alphabetically using jQuery?
you just need to return a number in the sorting function. Return -1 if the first should be placed before the second. So sort ascending
You can add more conditions.
if($(a).data("listing-title") > $(b).data("listing-title")) return 1 -> descending
if($(a).data("listing-title") = $(b).data("listing-title")) return 0 -> no sorting
and put in the HTML the sorted list ( gg instead of divList)
jQuery(document).ready(function($) {
var divList = $(".listing-item");
var gg = divList.get().sort(function(a, b) {
if($(a).data("listing-title") < $(b).data("listing-title")) {
return -1 ;
}
});
console.log(gg);
$("#list").html(gg);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div class="listing-item" data-listing-title="a">
a
</div>
<div class="listing-item" data-listing-title="z">
z
</div>
<div class="listing-item" data-listing-title="b">
b
</div>
<div class="listing-item" data-listing-title="c">
c
</div>
</div>
you don't need jQuery for this, and I think the problem is your comparison function, something like this, should make the job for you:
//First select the items
const items = document.querySelectorAll('div#list > .listing-item');
//Next, transform this to an array using `from`, then compare
//using `sort`, finally iterate over the sorted array using `forEach`,
//and append element in the sorted array to the `#list`.
//
Array
.from(items)
.sort((x,y) => {
const valueX = x.dataset.listingTitle;
const valueY = y.dataset.listingTitle;
if(valueX > valueY) return 1;
else if(valueX < valueY) return -1;
else return 0;
})
.forEach(element => document.getElementById('list').appendChild(element));

Combining TextContent and information from elements with jQuery

How can I combine text content and content of elements with jQuery?
function getText(key, node) {
if (node.tagName == 'INPUT') {
return node.value;
} else {
return node.textContent;
}
}
console.log($("div").find('*').map(getText).get().join(' ').trim().replace(/\s+/g, ' '));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span>A</span>
<div>
B
<input value='4'>
<span>C</span>
</div>
</div>
should be rendered to the string "A B 4 C".
It is no problem to get just the textContent with .text() or render the values of the input elements with .map(function(){return $(this).val();}).get().join(' ') but getting both combined in the right order is difficult.
EDIT: The implementation should work on every depth of nesting elements. It is used to get a comparable output for unit testing parts of a web page where some visible texts like labels are rendered into span and other parts like editable values are in input elements.
Depending on what you want to do with it you can just loop through all the elements in the top level div ignoring the text of child elements and append it to where you want it getting the text or value. Something like this
$(".top *").each(function(){
$(".holder").append($(this).clone().children().remove().end().text() || $(this).val());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="top">
<span>A</span>
<div>
B
<input value='4'>
<span>C</span>
</div>
</div>
<div class="holder">
</div>
NOTE: I added a class of top to the top level div to be able to select it
One way to do it is just to coalesce the values using an OR if the val() is something use it, otherwise get the text().
$(function() {
var a = [];
a = $.map($(".read *"), function(elem) {
return $(elem).val() ||
$(elem)[0].childNodes[0].nodeValue.trim();
});
console.log(a.join(" "));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='read'>
<span>A</span>
<div>
B
<input value='4'>
<span>C</span>
</div>
</div>
With the ideas of the others I created this answer. Perhaps it could be optimized in some way, but at least it works like expected.
function getText(key, node) {
if (node.tagName == 'INPUT') {
return node.value;
} else {
let result = "";
for(var child=node.firstChild; child!==null; child=child.nextSibling) {
if (child.nodeType === 3) {
result = result + " "+ child.nodeValue;
}
}
return result;
}
}
console.log($("div").find('*').map(getText).get().join(' ').trim().replace(/\s+/g, ' '));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span>A</span>
<div>
B
<input value='4'>
<span>C</span>
</div>
</div>
EDIT: In fact it also doesn't work correctly if C is not inside of a span.

Javascript increment through elements within div?

Ok, so I have the following HTML:
<div class="calculator-section">
<p class="x"></p>
<p class="y"></p>
</div>
<div class="calculator-section">
<p class="z"></p>
<p class="a"></p>
</div>
<div class="calculator-section">
<p class="b"></p>
<p class="c"></p>
</div>
I need to increment through each of these divs and compare classes that each <p> has.
How would I go about doing this?
Currently I have this:
$('.calculator-section').each(function(i, obj) {
$(this).$('p').each(function(i, obj) { //This bit doesn't work
//Check classes for $(this) here?
});
});
But I'm not sure what to do for that inner loop. Any ideas?
Add p to your initial each loop and use the className property within the loop
$('.calculator-section p').each(function(i, obj) {
if(this.className == "x") {
$(this).css('background', 'green')
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="calculator-section">
<p class="x">x</p>
<p class="y">y</p>
</div>
Alternatively, if you are using the multiple loops for a reason:
Select p within the iteration of specific section with $('p', this) or $(this).children('p') etc
$('.calculator-section').each(function(i, obj) {
// $(this) = section
$('p', this).each(function(i, obj) {
// $(this) = p within above section
});
});
Use single each() instead of double each(). Example here..
$('.calculator-section p').each(function(i, obj) {
var className = $(this).attr('class');
if(className == 'expected value'){
//do something
//return false;
}
});
You're going to get too many results. <p class="x"><p> should be <p class="x"></p> (with a forward slash to indicate closing the paragraph.
<div class="calculator-section">
<p class="x"></p>
<p class="y"></p>
</div>
<div class="calculator-section">
<p class="z"></p>
<p class="a"></p>
</div>
<div class="calculator-section">
<p class="b"></p>
<p class="c"></p>
</div>
Once that's fixed,
//you can grab the class couples this way
var results = $('.calculator-section').map(function(i, obj) {
return $(obj).find('p').map(function(i, obj) {
return obj.className;
});
});
//and then do what you want with them later
results.each(function(i, obj) {
console.log(obj[0] + ',' + obj[1]);
});
>> x,y
>> z,a
>> b,c

tSort on jQuery object

I'm trying to sort the results of a jQuery selection with tSort.
HTML:
<div sort="2"></div>
<div sort="3"></div>
<div sort="1"></div>
<div sort="4"></div>
<div sort="6"></div>
<div sort="5"></div>
Javascript:
<script>
$sort_order = $('div').tsort({attr:'sort'});
</script>
I want the result to be: 1,2,3,4,5,6 in the jQuery object, not yet inserted into the page.
Is this possible with tSort, or should I write my own algorithm?
It is easier to do it if there is a wrapper of all the div elements.
HTML:
<div id="wrapper">
<div sort="2">2</div>
<div sort="3">3</div>
<div sort="1">1</div>
<div sort="4">4</div>
<div sort="6">6</div>
<div sort="5">5</div>
</div>
Javascript (with jQuery):
var $wrapper = $('#wrapper');
$wrapper.find('div').sort(function (a, b) {
return +a.getAttribute('sort') - +b.getAttribute('sort');
})
.appendTo($wrapper);
Working demo.
In response to #Tim's comment, you can place the elements that do not have the sort attributes at the back of the wrapper element easily, even without jQuery.
Assuming that this is your HTML:
<div id="wrapper">
<div style="color:red;">red color, without sort attribute</div>
<div style="color:red;" sort="7">red color (sort attribute=7)</div>
<div sort="2">2</div>
<div sort="3">3</div>
<div sort="1">1</div>
<div sort="4">4</div>
<div sort="6">6</div>
<div sort="5">5</div>
</div>
You can place the element(s) that do not have the sort attribute by having this as your Javascript:
// As shown earlier above,
var $wrapper = $('#wrapper');
$wrapper.find('div').sort(function (a, b) {
return +a.getAttribute('sort') - +b.getAttribute('sort');
})
.appendTo($wrapper);
// New code to add:
var divs = document.getElementsByTagName('div');
for(var i = 0; i < divs.length; i++) {
if(divs[i].getAttribute('sort') == null || divs[i].getAttribute('sort') == undefined) {
divs[i].parentNode.appendChild(divs[i]);
}
}
Working demo.
clone it before using .tsort
$sort_order = $('div').clone().tsort({attr:'sort'});
DEMO

JQuery get a contiguous sequence of elements

I'm trying to get a contiguous array of elements using JQuery. For example for the this html:
<div class="parent">
<div class="childType2">1</div>
<div class="childType2">2</div>
<div class="childType2">3</div>
<div class="childType1">4</div>
<div class="childType1">5</div>
<div class="childType1">6</div>
<div class="childType1">7</div>
<div class="childType2">8</div>
<div class="childType1">9</div>
<div class="childType1">10</div>
<div class="childType1">11</div>
<div class="childType1">12</div>
</div>
I want it to return the div's containing 4,5,6,7 (The first sequnce of the divs with the class="childType1").
I tried to do
$("<div>test</div>")($('.parent .childType2').siblings('.childType1').addBack());
But this of course will add the div with the text test after the last childType1 (12).
I'm not so good with JQuery.
Edit:
Since the div's are dynamically generated, I ended up adding for each "group" a special class post-fix of the id related to his group, and used the method described in suspectus's answer. Not exactly what i had in mind, but it works :D.
You can use either .each (docs) or .filter (docs). If you use .filter() you can chain another jQuery method after it.
var state = 0;
var elements = [];
$('.parent div').each( function( i, elem ) {
if( state != 2 && elem.className === "childType1" ) {
state = 1;
elements.push( elem );
} else if ( state == 1 ) {
state = 2;
}
} );
console.log( elements );
Or more jQuery approach:
var state = 0;
$('.parent div').filter( function() {
if( state != 2 && $(this).hasClass( "childType1" ) ) {
state = 1;
return true;
} else if ( state == 1 ) {
state = 2;
}
return false;
} ).css( 'background-color', 'red' );
<div class="parent">
<div class="childType2">1</div>
<div class="childType2">2</div>
<div class="childType2">3</div>
<div class="childType1 inner">4</div>
<div class="childType1 inner">5</div>
<div class="childType1 inner">6</div>
<div class="childType1 inner">7</div>
<div class="childType2">8</div>
<div class="childType1">9</div>
<div class="childType1">10</div>
<div class="childType1">11</div>
<div class="childType1">12</div>
</div>
$(".inner") // gives the elements required
You could use filter for this :
var $elements = $(".childType1").filter(function() {
var no = parseInt($(this).text(), 10)
return (( no > 3) && ( no < 8))
});
now $elements will contain only those matched elements between 3 and 8 ie., 4 to 7.
You can use .each() method for looping all the divs having class="childType1"
Following is the complete code. Modify it according to your need.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$(".childType1").each(function (i) {
if ( $(this).html() == "4" ||$(this).html() == "5" || $(this).html() == "6" ||$(this).html() == "7") {
alert($(this).html());
}
});
});
</script>
</head>
<body>
<div class="parent">
<div class="childType2">1</div>
<div class="childType2">2</div>
<div class="childType2">3</div>
<div class="childType1">4</div>
<div class="childType1">5</div>
<div class="childType1">6</div>
<div class="childType1">7</div>
<div class="childType2">8</div>
<div class="childType1">9</div>
<div class="childType1">10</div>
<div class="childType1">11</div>
<div class="childType1">12</div>
</div>
</body>
</html>

Categories

Resources