Sorting of divs in Jquery - javascript

My code have divs of movies which are used to display movie with poster, now i want jquery to sort divs for me on basis of title,
<!-- Movie -->
<div class="movie" title="Reservoir Dogs">
<div class="movie-image">
<span class="play"><span class="name">Reservoir Dogs |
Reservoir Dogs</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMTQxMTAwMDQ3Nl5BMl5BanBnXkFtZTcwODMwNTgzMQ##._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Saw">
<div class="movie-image">
<span class="play"><span class="name">Saw |
Saw</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMjAyNTcxNzYwMV5BMl5BanBnXkFtZTgwMzQzNzM5MjE#._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Scarface">
<div class="movie-image">
<span class="play"><span class="name">Scarface |
Scarface</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMjAzOTM4MzEwNl5BMl5BanBnXkFtZTgwMzU1OTc1MDE#._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Signs">
<div class="movie-image">
<span class="play"><span class="name">Signs |
Signs</span></span><img src="http://ia.media-imdb.com/images/M/MV5BNDUwMDUyMDAyNF5BMl5BanBnXkFtZTYwMDQ3NzM3._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in3">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Stir of Echoes">
<div class="movie-image">
<span class="play"><span class="name">Stir of Echoes |
Stir of Echoes</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMTU0OTAyMDQzNV5BMl5BanBnXkFtZTcwNTg1NjYyMQ##._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
Now here is my current code
$(document).ready(function () {
var desc = false;
document.getElementById("sort").onclick = function () {
sortUnorderedList("movie", desc);
desc = !desc;
return false;
}
});
function sortUnorderedList(ul, sortDescending) {
if (typeof ul == "string")
var lis = document.getElementsByClassName("movie");
var vals = [];
for (var i = 0, l = lis.length; i < l; i++)
vals.push(lis[i]);
debugger;
vals.sort(function (a, b) { return a.title - b.title });
//vals[].title.sort();
if (sortDescending)
vals.reverse();
for (var i = 0, l = lis.length; i < l; i++)
lis[i].innerHTML = vals[i].innerHTML;
}
above code is not giving desired result
can u suggest better way to do it

You can significantly simplify your code if you use more jQuery, anyway you are using it. Entire code in this case will be:
$(document).ready(function () {
var desc = false;
$("#sort").click(function () {
sortUnorderedList("movie", desc);
desc = !desc;
});
});
function sortUnorderedList(ul, sortDescending) {
$('.' + ul).sort(function(a, b) {
return sortDescending ? a.title.localeCompare(b.title) : b.title.localeCompare(a.title);
}).appendTo('body');
}
Just note that instead of appendTo('body'), you should append to appropriate container that holds .movie elements. I'm appending to body because this is a container for movie divs in my demo.
Demo: http://jsfiddle.net/212oc0kw/

Related

JavaScript, HTML search engine - how to get parent of an element?

My problem is:
Search script is working, but it only hides h3 elements from the code.
<h3 class="post-subtitle" style="display: flex;">Protokoły tunelowania VPN</h3>
<h3 class="post-subtitle" style="display: flex;">Certyfikat cyfrowy</h3>
I need the code to hide the whole div with "post" ID instead of just h3 element.
How do i do that?
HTML Code for Search Bar:
<div id="kontener" class="container">
<div style="text-align:center" id="search-bar">
<input type="text" id="searchbar" onkeyup="searchBar()" class="shadow-lg">
</div>
</div>
HTML Code on Website
<!-- First element -->
<div id="post">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview">
<a href="URL">
<h2 class="post-title"><i class="far fa-sticky-note fa-xs" aria-hidden="true"></i> ASO</h2>
<h3 class="post-subtitle" style="display: flex;">Protokoły tunelowania VPN</h3>
</a>
<p class="post-meta">11 Maj, 2021</p>
</div>
</div>
</div>
<hr>
</div>
<!-- End of First element -->
<!-- Second element -->
<div id="post">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview">
<a href="URL">
<h2 class="post-title"><i class="far fa-sticky-note fa-xs" aria-hidden="true"></i> ELSK</h2>
<h3 class="post-subtitle" style="display: flex;">Certyfikat cyfrowy</h3>
</a>
<p class="post-meta">26 Kwiecień, 2021</p>
</div>
</div>
</div>
<hr>
</div>
<!-- End of Second element -->
JavaScript code:
<script>
function searchBar() {
let input = document.getElementById('searchbar').value
input=input.toLowerCase();
let x = document.getElementsByClassName('post-subtitle');
for (i = 0; i < x.length; i++) {
if (!x[i].innerHTML.toLowerCase().includes(input)) {
x[i].style.display="none";
}
else {
x[i].style.display="flex";
}
}
}
</script>
You just need to target couple of parent nodes, either by .parentElement / .parentNode or use .closest function.
Example:
<script>
function searchBar() {
let input = document.getElementById('searchbar').value
input=input.toLowerCase();
let x = document.getElementsByClassName('post-subtitle');
for (i = 0; i < x.length; i++) {
if (!x[i].innerHTML.toLowerCase().includes(input)) {
x[i].closest('#post').style.display="none";
// Or this below (note each parentElement targets parent tag)
// x[i].parentElement.parentElement.parentElement.parentElement.parentElement.style.display="none";
}
else {
x[i].closest('#post').style.display="flex";
}
}
}
</script>

pure JS handling if content text length < 0 then hide

I tried to handling,
if content text length < 0
then set class match-name & divider style to display none.
it seem like not working with below code.
var newsMatchName = document.querySelectorAll(".match-name");
var newsMatchNameDivider = document.querySelectorAll(".divider");
for (var i = 0; i < newsMatchName.length; i++) {
if (newsMatchName[i].length < 0) {
console.log(newsMatchName[i].length)
for (var i = 0; i < elem.length; i++) {
newsMatchName[i].style.display = "none";
newsMatchNameDivider[i].style.display = "none"
}
}
}
<div class="news-content">
<div class="match-name"></div>
<div class="divider"></div>
<div class="title">Title Text</div>
<div class="footer">
<span class="author">Author</span>
<span class="spacer"></span>
<div class="timeline">
<span class="date">2021-04-01</span>
<span class="time">12:15</span>
</div>
</div>
</div>
I have corrected the code for you:
var newsMatchName = document.querySelectorAll(".match-name");
var newsMatchNameDivider = document.querySelectorAll(".divider");
for (var i = 0; i < newsMatchName.length; i++) {
if (newsMatchName[i].innerText.length <= 0) {
newsMatchName[i].style.display = "none";
newsMatchNameDivider[i].style.display = "none"
}
}
<div class="news-content">
<div class="match-name"></div>
<div class="divider"></div>
<div class="title">Title Text</div>
<div class="footer">
<span class="author">Author</span>
<span class="spacer"></span>
<div class="timeline">
<span class="date">2021-04-01</span>
<span class="time">12:15</span>
</div>
</div>
</div>
I test the length of the text in match-name
Length can be 0 or more, not <0, so use
newsMatchName[i].textContent.length === 0
but I suggest this:
var newsMatchName = document.querySelectorAll(".match-name");
var newsMatchNameDivider = document.querySelectorAll(".divider");
newsMatchName.forEach((name, i) => {
const textLen = name.textContent.trim().length;
name.classList.toggle("hide", textLen === 0);
newsMatchNameDivider[i].classList.toggle("hide", textLen === 0);
})
.hide {
display: none;
}
<div class="news-content">
<div class="match-name"></div>
<div class="divider">This will be hidden</div>
<div class="title">Title Text</div>
<div class="footer">
<span class="author">Author</span>
<span class="spacer"></span>
<div class="timeline">
<span class="date">2021-04-01</span>
<span class="time">12:15</span>
</div>
</div>
</div>

jQuery callback function to check number of child elements on element click

I have a set of "div" whose children count I want to check when a user fadeOut images under that div block, if the all childrens have be closed out i want to call the function: kind of like:
edited: the current code always alerts YES whenever the div is faded,
how do i destroy the DOM entirely without having to use :visible
filter. getting rid of the entire card class after fading out
considering the HTML:
<div class='scrolling-wrapper'>
<div class='card'>
<div class='panel panel-primary'>
<div class='panel-body'>
<div class='img-wrap'>
<span class='close-x'> × </span>
<img width='100%' id='3' class='' src='resizer/resizer.php?file=profiles/images/default_cover.jpg&width=700&height=400&action=resize&watermark=bridgoo&watermark_pos=tl&color=255,255,255&quality=100' />
</div>
<div class='title h5'>
<span class='user-popover'>
<a href='/groupstomason/'><b>tomason</b></a>
</span>
<br/>
<small class='small-text'>for max tomason
</small>
</div>
</div>
<div class='panel-heading'>
<button class='btn btn-primary'> <span class='fa fa-plus-circle fa-fw'> </span>Join </button>
</div>
</div>
<div class='card-group-holder' style='width:250px; background-color:inherit;'>
</div>
<div class="card"> another card</div>
<div class="card"> another card</div>
<div class="card"> another card</div>
</div>
and the jquery below:
$('.img-wrap .close-x').on('click', function() {
var card = $(this).closest('.card');
card.fadeOut('slow', function() {
var cardWrapper = $(this).closest('.card').closest('scrolling-wrapper');
var cardcount = cardWrapper.children('.card');
if (cardcount.length < 1) alert('yes');
});
});
when the <span class = 'close-x'> × </span> is clicked the
entire <div class='card'> is fadedOut, then on fadeout, if no more
cards exist or the last cards have been faded, then alert('yes');
Assuming that multiple .card elements are nested in the same parent, you can check if all the siblings have faded out.
In your original markup, you have an unclosed </div>, which causes the .card elements not to be siblings of each other, I believe this is a typo on your part, since it is the most parsimonious explanation.
Since .fadeOut() hides the element, you can simply check if the filtered set of :visible returns a length of 1 or more:
$('.img-wrap .close-x').on('click', function() {
var card = $(this).closest('.card');
card.fadeOut('slow', function() {
var cardWrapper = $(this).closest('.scrolling-wrapper');
var cardcount = cardWrapper.children('.card');
if (cardcount.filter(':visible').length < 1) {
console.log('All cards have faded out');
}
});
});
Here is a proof-of-concept example:
$(function() {
$('.close').on('click', function() {
var card = $(this).closest('.card');
card.fadeOut('slow', function() {
// Get wrapping ancestor
var cardWrapper = $(this).closest('.scrolling-wrapper');
var cardcount = cardWrapper.children('.card');
// Filter out those that are not visible, and check for remaining visible cards
if (cardcount.filter(':visible').length < 1) {
console.log('All cards have faded out');
}
});
});
});
/* Just styles for a dummy call-to-action element in .card */
span.close {
cursor: pointer;
color: steelblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scrolling-wrapper">
<div class="card">Card 1. <span class="close">Click to hide me.</span></div>
<div class="card">Card 2. <span class="close">Click to hide me.</span></div>
<div class="card">Card 3. <span class="close">Click to hide me.</span></div>
<div class="card">Card 4. <span class="close">Click to hide me.</span></div>
<div class="card">Card 5. <span class="close">Click to hide me.</span></div>
</div>
In your callback you may simply test if at least a card is visible:
if ($(this).closest('.card').siblings('.card:visible').length < 1) alert('yes');
$('.img-wrap .close-x').on('click', function () {
var card = $(this).closest('.card');
card.fadeOut('slow', function () {
if ($(this).closest('.card').siblings('.card:visible').length < 1) console.log('yes');
});
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class='scrolling-wrapper'>
<div class='card'>
<div class='panel panel-primary'>
<div class='panel-body'>
<div class='img-wrap'>
<span class='close-x'> × </span>
<img width='100%' id='3' class=''
src='resizer/resizer.php?file=profiles/images/default_cover.jpg&width=700&height=400&action=resize&watermark=bridgoo&watermark_pos=tl&color=255,255,255&quality=100'/>
</div>
<div class='title h5'>
<span class='user-popover'>
<a href='/groupstomason/'><b>tomason</b></a>
</span>
<br/>
<small class='small-text'>for max tomason
</small>
</div>
</div>
<div class='panel-heading'>
<button class='btn btn-primary'><span class='fa fa-plus-circle fa-fw'> </span>Join</button>
</div>
</div>
<div class='card-group-holder' style='width:250px; background-color:inherit;'>
</div>
</div>
<div class='card'>
<div class='panel panel-primary'>
<div class='panel-body'>
<div class='img-wrap'>
<span class='close-x'> × </span>
<img width='100%' id='3' class=''
src='resizer/resizer.php?file=profiles/images/default_cover.jpg&width=700&height=400&action=resize&watermark=bridgoo&watermark_pos=tl&color=255,255,255&quality=100'/>
</div>
<div class='title h5'>
<span class='user-popover'>
<a href='/groupstomason/'><b>tomason</b></a>
</span>
<br/>
<small class='small-text'>for max tomason
</small>
</div>
</div>
<div class='panel-heading'>
<button class='btn btn-primary'><span class='fa fa-plus-circle fa-fw'> </span>Join</button>
</div>
</div>
<div class='card-group-holder' style='width:250px; background-color:inherit;'>
</div>
</div>
</div>

call Load more function for active tab

I'm trying to develop a load more function for a specific tab pane, in this case, the active tab pane. I'm having issues with this jquery function because I'm calling the load more in the end of all tabs, and in my JS function I can't figure out how to load after the pane that is active, in which the button was clicked. This way I keep loading the questions in the last pane, but I couldnt print without var lastItem = $('div.question-col .question-summary:last');
$(document).ready(function () {
$(".load-more").on('click', function (e) {
var tab = $(this).data('tab');
var next_page = $(this).data('next-page');
console.log(next_page);
console.log(tab);
$.get($(this).data('url') + '?tab=' + tab + '&page=' + next_page, function (data) {
addNewQuestions($.parseJSON(data));
});
$(this).data('next-page', parseInt(next_page) + 1);
});
siteStats();
});
function addNewQuestions(objects) {
$.each(objects, function (i, object) {
console.log(object);
var lastItem = $('div.question-col .question-summary:last');
var newLine = lastItem.clone(true);
var newObject = newLine.find('.question-info');
updateTitleAndLink(newObject.find('.summary a'), object);
updateCreationDate(newObject.find('.question-updated-at'), object);
updateQuestionAnswers(newObject.find('.question-answers'), object);
updateAnswerCount(newObject.find('.answers-count'), object);
updateViewsCount(newObject.find('.views-count'), object);
updateVotesCount(newObject.find('.votes-count'), object);
updateSolvedStatus(newObject.find('.status'), object)
lastItem.after(newLine);
});
}
The update functions are not relevant to this case, I guess.
<div id="tabs" class="tab-content">
<ul>
<li>Recent Questions</li>
<li>Unanswered Questions</li>
<li>Top Scored Questions</li>
</ul>
{if empty($recent_questions)}
<div class = "col-sm-12" style = "text-align: center"><strong>No questions to load!</strong></div>
{/if}
{if !empty($recent_questions)}
<div id="recent_questions" class="question-col">
<!-- Questions come here -->
<div class = "load-more"
data-next-page = "1"
data-url = "{url('controller/api/questions/load_more_questions')}"
data-tab = "recent_questions">
<a id="loadMore">
Load More...
</a>
</div>
</div>
{/if}
<div id="unanswered_questions">
<!-- Questions come here -->
<div class = "load-more"
data-next-page = "1"
data-url = "{url('controller/api/questions/load_more_questions')}"
data-tab = "unanswered_questions">
<a id="loadMore">
Load More...
</a>
</div>
</div>
<div id="top">
<!-- Questions come here -->
<div class = "load-more"
data-next-page = "1"
data-url = "{url('controller/api/questions/load_more_questions')}"
data-tab = "top_scored_questions">
<a id="loadMore">
Load More...
</a>
</div>
</div>
//Questions come here - Question template
<div class="question-summary narrow">
<div class="question-info col-md-12">
<div class="votes">
<div class="votes-count">
<span title="{$question['votes_count']} votes">
{if $question['votes_count']}
{$question['votes_count']}
{else}
0
{/if}
</span>
</div>
<div>votes</div>
</div>
<div {if $question['solved_date']}
class="status answered-accepted"
{else}
class="status answer-selected"
{/if}
title="one of the answers was accepted as the correct answer">
<div class="answers-count">
<span title="{$question['answers_count']} answer">{$question['answers_count']}</span></div>
<div>answer</div>
</div>
<div class="views">
<div class="views-count">
<span title="{$question['views_counter']} views">{$question['views_counter']}</span></div>
<div>views</div>
</div>
<div class="summary question-title">
<h3>
<a href="{questionUrl($question['publicationid'])}"
data-base-question-url = "{questionUrl('')}"
style="font-size: 15px; line-height: 1.4; margin-bottom: .5em;">
{$question['title']}
</a>
</h3>
</div>
<div class = "statistics col-sm-12 text-right" style="padding-top: 8px">
<span>
<i class = "glyphicon glyphicon-time"></i>
<span class="question-updated-at">{$question['creation_date']}</span>
</span>
<span>
<i class = "glyphicon glyphicon-comment"></i>
<span class="question-answers">{$question['answers_count']}</span>
</span>
</div>
</div>
</div>
My question is: is there any way to put my loaded content after the last item of the active pane?
Kind regards

convert HTML List to JSON

I have a little problem with my HTML template for convert to JSON. I wish convert a list of HTML messages to JSON. Thank you in advance for your response.
HTML Template
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">Name</h4>
<span class="date">MM/DD/YYYY</span>
<span class="time">HH:MM</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
Message here
</div>
</div>
</div>
<!-- Others .message -->
JSON Render
{
"list": [
{
"pseudo": "Name",
"date": "MM/DD/YYYY",
"time": "HH:MM",
"message": "Message here"
},
/* ... */
]
}
even if it doesn't look that cool I think this will be much faster:
var pseudo = document.getElementsByClassName("pseudo");
var date = document.getElementsByClassName("date");
var time = document.getElementsByClassName("time");
var message = document.getElementsByClassName("message-text");
var list = [];
for(var i=0, l=pseudo.length;i<l;i++) {
list.push({
pseudo: pseudo[i].textContent,
data: date[i].textContent,
time: time[i].textContent,
message: message[i].textContent
})
}
console.log(list);
.. depending on your file structure this may not be the best solution
You can use jQuery to simply extract your date from html:
var result = [];
$(".message").each(function() {
var obj = {
pseudo: $(this).find(".pseudo").text(),
date: $(this).find(".date").text(),
time: $(this).find(".time").text(),
message: $(this).find(".message-text").text(),
};
result.push(obj);
})
console.log(result)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">Name</h4>
<span class="date">MM/DD/YYYY</span>
<span class="time">HH:MM</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
Message here
</div>
</div>
</div>
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">John</h4>
<span class="date">09/11/2011</span>
<span class="time">HH:MM</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
World Disaster
</div>
</div>
</div>
Simply get all your .message elements, and cycle through them to add their properties to the resulting Array (I used trim() to remove extra spaces at the beginning and the end of the message texts):
console.log( messagesToJSON() );
function messagesToJSON(){
var messages = [],
elements = $('.message');
for(var i=0; i<elements.length; i++){
messages.push({
"pseudo": elements.eq(i).find('.pseudo').text(),
"date": elements.eq(i).find('.date').text(),
"time": elements.eq(i).find('.time').text(),
"message": elements.eq(i).find('.message-text').text().trim()
});
}
return {list: messages};
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">Kevin</h4>
<span class="date">08/01/2016</span>
<span class="time">14:52</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
Hi there!
</div>
</div>
</div>
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">Robert</h4>
<span class="date">08/01/2016</span>
<span class="time">15:03</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
Hello
</div>
</div>
</div>

Categories

Resources