tSort on jQuery object - javascript

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

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));

How to loop and set inner content of DOM elements in jQuery and JavaScript?

I'm trying to loop through divs and set the content of a div inside the outer div. I tried this.
Here is the HTML div's I want to loop through and I want to set the content of div with class content-detail with the value for its attribute data-form data.
//the javascript code I used is this
$(function($) {
for (var i of $(".item .content-detail")) {
var container = document.querySelector($(i)[0]);
var formData = $(i).attr("data-formdata");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div class="item">
<div class="down-div"> </div>
<div class="detail">
<h4>Detail</h4>
<div id="div_" class="content-detail" data-formdata="my Item">
</div>
<div class="text-center">
<button class="btn btn-blue center"> SET !</button>
</div>
</div>
</div>
<div class="item">
<div class="down-div"> </div>
<div class="detail">
<h4>Detail</h4>
<div id="div_" class="content-detail" data-formdata="my Item">
</div>
<div class="text-center">
<button class="btn btn-blue center"> SET !</button>
</div>
</div>
</div>
But am stuck at this point var container = document.querySelector($(i)[0]);
I don't know how to get the jquery selector of that current div to a variable.
This may need some tweaks, but it should be close...
$(function ($) {
$(".item .content-detail").each(function(index, element) {
element.text($(element).attr("data-formdata"))
})
});
Take a look at the .each() method
$(function($) {
for (var i of $(".item .content-detail")) {
//var container = document.querySelector($(i)[0]);
var container = i;
var formData = $(i).attr("data-formdata");
}
});
I just needed the element
If you want to set the content of each DIV, you don't need a for loop. The .text() method takes a callback function, and it will be called on each element that matches the selector. The returned value is used as the new content.
$(".item .content-detail").text(function() {
return $(this).data("formdata");
});
This works.
$(function($) {
$(".item .content-detail").text(function(){
return $(this).attr("data-formdata");
})
});
Can you not just use JS like this:
[UPDATED]
function test() {
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
var divsSub = divs[i].getElementById("div_").querySelectorAll(".content-detail");;
for (var iS = 0; iS < divsSub.length; iS++) {
var x = divsSub[iS].getAttribute("data-formdata");
divsSub[iS].innerHTML = x;
}
}
}

Check Div Elements by name fast

I have some Divs:
<div id="content">
<div class="c" id="1">
<div id="xyz">dont care</div>
<div id="texts1">
<div name="check"> ContentText </div>
</div>
</div>
<div class="c" id="2">
<div id="xuyz">dont care</div>
<div id="texts2">
<div name="check"> ContentText </div>
</div>
</div>
</div>
I want to iterate through all elements of the "c" class.
Then I want to check, if the Div elements named "check" of each "c" element contains special text.
If true, then manipulate the "c" element (which contains the special text)
I tried something like this:
var ele = document.getElementsByClassName("c");
for(var i=0;i<ele.length;i++)
{
var check = ele[i].getElementsByName("check");
if(check.innerHTML ....)
}
But thats not working :/
Log from Firefox:
TypeError: ele[i].getElementsByName is not a function
Where is my mistake?
A simple querySelectorAll() should do the trick:
var check = document.querySelectorAll('.c [name="check"]');
And as stated in a comment already, only document has getElementsByName method.
With jQuery this is very simple -
$('[name="check"]:contains("your special text")')
With jQuery (you have tagged it with it as well)
$(document).ready(function () {
$('div.c').find('div[name="check"]').each(function(){
// here check HTML and do needed manipulations
if($(this).html() == 'ContentText'){
$(this).closest('div.c').children().first().html('I CARE');
}
});
});
see jSFiddle -> http://jsfiddle.net/ApfJz/32/
Here is a modification of your code to make it work as intended
var ele = document.getElementsByClassName("c");
for (var i = 0; i < ele.length; i++)
{
if (ele[i].getAttribute('name') === "check") {
// do something with matching elements here
}
}

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>

jQuery basic: How to create a loop with this structure?

This is a really simple question but I'm not sure how to search for it on the internet.
I have an empty <div id="wrap"></div> that needs to end up looking as following:
<div id="wrap>
<div class="container">
<div class="apples"></div>
</div>
<div class="container">
<div class="banana"></div>
</div>
<div class="container">
<div class="orange"></div>
</div>
<div class="container">
<div class="grapes"></div>
</div>
</div>
In jquery I have:
$(#wrap).html(''); // need this bit
var fruitArray = ['apples','banana','orange','grapes'];
for (fruit in fruitArray) {
$('<div class="'+fruitArray[fruit]+'"></div>').appendTo('#wrap').doSomething();
}
Because I need the div with the fruitArray class to do something, I can't just wrap it around with the container class:
$('<div class="container"><div class="'+fruitArray[fruit]+'"></div></div>').appendTo...
How can I go about generating the container class in this situation?
The .wrap method returns the original set of elements for chaining purposes.
$('<div class="'+fruitArray[fruit]+'" />')
.appendTo('#wrap')
.wrap('<div class="container" />')
.doSomething();
Try this:
var fruitArray = ['apples','banana','orange','grapes'];
for (fruit in fruitArray) {
$('<div class="' + fruitArray[fruit] + '"></div>').appendTo('#wrap').wrap('<div class="container"></div>');
}
Example fiddle
var fruitArray = ['apples','banana','orange','grapes'];
for (fruit in fruitArray) {
$('<div class="'+fruitArray[fruit]+'" />').wrap('<div class="container" />').appendTo('#wrap').doSomething();
}
OR you can also do it like
var fruitArray = ['apples','banana','orange','grapes'];
for (fruit in fruitArray) {
$('<div class="'+fruitArray[fruit]+'" />').appendTo('#wrap').doSomething().wrap('<div class="container" />');
// this will work if the doSomething is a jquery/plugin method that is using chaining (usually they do)
}

Categories

Resources