Jquery: Sort by inner element's attribute - javascript

I have following code:
<div>
<div id="1">
<h3>Price: 50</h3>
<span id="price" min-price="50"></span>
</div>
<div id="2">
<h3>Price: 30</h3>
<span id="price" min-price="30"></span>
</div>
<div id="3">
<h3>Price: 40</h3>
<span id="price" min-price="40"></span>
</div>
</div>
I need to sort these 3 divs based on min-price attribute. Is it possible in Jquery? I found sort() function, but I was not able to use it correctly. Thank you.

Try this :
$(document).ready(function() {
$("div[id]").each(function(number,ele) {
$("div[id]").not($(ele)).each(function(index,el){
a = $(ele).find("span").attr("min-price");
b = $(el).find("span").attr("min-price");
if( parseFloat(a) > parseFloat(b) )
$(ele).insertAfter($(el));
})
})
})
<div>
<div id="1">
<h3>Price: 50</h3>
<span id="price" min-price="50"></span>
</div>
<div id="2">
<h3>Price: 30</h3>
<span id="price" min-price="30"></span>
</div>
<div id="3">
<h3>Price: 40</h3>
<span id="price" min-price="40"></span>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

You can use .sort() function:
$('div[id]').sort(function (a, b) {
var minprice1 = parseInt( $(a).find('span').attr('min-price'));
var minprice2 = parseInt( $(b).find('span').attr('min-price'));
return (minprice1 < minprice2 ) ? -1 : (minprice1 > minprice2 ) ? 1 : 0;
});

function sortElements(element, prop, sortDescending) {
var arrElements = [], origElements = [];
$.each(element, function(){
arrElements.push($(this).attr(prop));
origElements.push($(this).attr(prop));
});
arrElements.sort();
if(sortDescending)
arrElements.reverse();
for(var i = 0, l = arrElements.length; i < l; i++)
$("#sortDiv").append($("#"+arrElements[i]));
$("#divOrig").html($("#sortDiv").html());
$("#sortDiv").remove();
}
sortElements($("#divOrig span"), "min-price", true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divOrig">
<div id="50">
<h3>Price: 50</h3>
<span id="price" min-price="50"></span>
</div>
<div id="30">
<h3>Price: 30</h3>
<span id="price" min-price="30"></span>
</div>
<div id="40">
<h3>Price: 40</h3>
<span id="price" min-price="40"></span>
</div>
</div>
<div id="sortDiv" style="display:none" ></div>

Related

Filtering divs (with different 'data' attributes) based on multiple different checkboxes

As shown below, I tried to make a script to filter posts based on different checkboxes' values but I ended up having untargeted posts.
The problem I'm having is located in the match() method (I guess). I tried using the '&&' operator but that couldn't help.
I want to have posts based on the checkboxes I checked.
Thanks in advance!
Link: https://codepen.io/resourceful_geek/pen/JjvWLEj
var $filterCheckboxes = $('.filter-container input[type=checkbox]');
var posts = ".post";
$filterCheckboxes.on("change keyup", function() {
//var filteredCheckboxesSample = ['translation', 'proofreading', 'intermediate', 'expert', '1'];
//var textStringSample = filteredCheckboxes.toString();
var selectedFilters = {};
var textString = "";
$filterCheckboxes.filter(':checked').each(function() {
if (!selectedFilters.hasOwnProperty('filter')) {
selectedFilters['filter'] = [];
}
selectedFilters['filter'].push(this.value);
textString = selectedFilters['filter'].toString();
})
$(posts).hide().filter(function() {
var rtnData = "";
regExAll = new RegExp(textString.split(",").map(x => x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|'), 'i');
rtnData = (
$(this).attr("data-category").match(regExAll) || $(this).attr("data-level").match(regExAll)
);
return rtnData;
}).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Filtered Posts</h1>
<div class="post-container">
<div class="post" data-id="1" data-job="translator" data-name="John" data-date="2021" data-level="beginner" data-price="20" data-rate="1" data-verified="1" data-category="translation">Translation | Beginner</div>
<div class="post" data-id="2" data-job="proofreader" data-name="Peter" data-date="2021" data-level="expert" data-price="20" data-rate="5" data-verified="1" data-category="proofreading">proofreading | expert</div>
<div class="post" data-id="3" data-job="translator" data-name="Steve" data-date="2021" data-level="intermediate" data-price="20" data-rate="1" data-verified="1" data-category="translation">Translation | intermediate</div>
<div class="post" data-id="4" data-job="content_crafting" data-name="Bil" data-date="2021" data-level="beginner" data-price="20" data-rate="2" data-verified="0" data-category="content_crafting">content_crafting | Beginner</div>
<div class="post" data-id="5" data-job="translator" data-name="Noah" data-date="2021" data-level="intermediate" data-price="20" data-rate="1" data-verified="0" data-category="translation">Translation | intermediate</div>
</div>
<h1>Filtering Area</h1>
<div class="filter-container">
<p>Filter by Category</p>
<div>
<input class="translation" type="checkbox" id="translation" name="service_categories" value="translation"></label>
<label for="translation">translation
</div>
<div>
<input class="proofreading" type="checkbox" id="proofreading" name="service_categories" value="proofreading"></label>
<label for="proofreading">proofreading
</div>
<div>
<input class="content_crafting" type="checkbox" id="content_crafting" name="service_categories" value="content_crafting"></label>
<label for="content_crafting">content_crafting
</div>
<p>Filter by Level</p>
<div>
<input class="beginner" type="checkbox" id="beginner" name="service_categories" value="beginner"></label>
<label for="beginner">beginner
</div>
<div>
<input class="intermediate" type="checkbox" id="intermediate" name="service_categories" value="intermediate"></label>
<label for="intermediate">intermediate
</div>
<div>
<input class="expert" type="checkbox" id="expert" name="service_categories" value="expert"></label>
<label for="expert">expert
</div>
</div>

jQuery selector value returns undefined

I'm getting undefined of my variable 'base' which is basic $('slider').value. I have added a console.log(base) to test what is returned, but the value is undefined.
Here is my html:
jQuery(document).ready(function($) {
let precentage = 17.5;
let commision = 0.2746;
function cost() {
let base = $('#slider').value;
let precentAmout = base * (precentage / 365 * 30);
let commisionAmout = base * commision;
let totalCost = commisionAmout + precentAmout;
let totalSum = base + commisionAmout + precentAmout;
console.log(base);
$('#cost').text(totalCost);
$('#sum').text(totalSum);
}
$('#slider').on('change', function() {
$('#amout').text(this.value);
cost();
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="calc">
<div class="range-title">
<h2 class="range-label">Ile chcesz pożyczyć?</h2>
<div class="display-wrap">
<span id="amout">500</span><span class="currency"> zł</span>
</div>
</div>
<div class="range-wrap">
<button class="buttons-change-value">-</button>
<input id="slider" class="range-input" type="range" min="500" max="1500" step="50" value="500">
<button class="buttons-change-value">+</button>
</div>
<div class="summary-container">
<div class="summary-box">
<h3>Koszt:<br>
<span id="cost">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>Do zwrotu:<br>
<span id="sum">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>RRSO:<br>
<span id="rrso">200</span><span class="percentage"> %</span></h3>
</div>
</div>
</div>
Do You have an idea why this is happening?
In JQuery, .val() function is available to get value of textbox.
let base = $('#slider').val()
jQuery(document).ready(function($) {
let precentage = 17.5;
let commision = 0.2746;
function cost() {
let base = $('#slider').val();
let precentAmout = base * (precentage / 365 * 30);
let commisionAmout = base * commision;
let totalCost = commisionAmout + precentAmout;
let totalSum = base + commisionAmout + precentAmout;
console.log(base);
$('#cost').text(totalCost);
$('#sum').text(totalSum);
}
$('#slider').on('change', function() {
$('#amout').text(this.value);
cost();
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="calc">
<div class="range-title">
<h2 class="range-label">Ile chcesz pożyczyć?</h2>
<div class="display-wrap">
<span id="amout">500</span><span class="currency"> zł</span>
</div>
</div>
<div class="range-wrap">
<button class="buttons-change-value">-</button>
<input id="slider" class="range-input" type="range" min="500" max="1500" step="50" value="500">
<button class="buttons-change-value">+</button>
</div>
<div class="summary-container">
<div class="summary-box">
<h3>Koszt:<br>
<span id="cost">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>Do zwrotu:<br>
<span id="sum">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>RRSO:<br>
<span id="rrso">200</span><span class="percentage"> %</span></h3>
</div>
</div>
</div>
jQuery objects don't have a value property, they have a val() method.
You can always pass the base variable value as a parameter to the cost function like this cost(this.value). That would make more sense since you are already fetching the slider value once via onChange no need to do it again inside the cost function.
Please take a look at the working snippet below.
jQuery(document).ready(function ($) {
let precentage = 17.5;
let commision = 0.2746;
function cost(sliderValue) {
let base = sliderValue;
let precentAmout = base * (precentage / 365 * 30);
let commisionAmout = base * commision;
let totalCost = commisionAmout + precentAmout;
let totalSum = base + commisionAmout + precentAmout;
console.log(base);
$('#cost').text(totalCost);
$('#sum').text(totalSum);
}
$('#slider').on('change', function () {
$('#amout').text(this.value);
cost(this.value);
});})
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="calc">
<div class="range-title">
<h2 class="range-label">Ile chcesz pożyczyć?</h2>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<div class="display-wrap">
<span id="amout">500</span><span class="currency"> zł</span>
</div>
</div>
<div class="range-wrap">
<button class="buttons-change-value">-</button>
<input id="slider" class="range-input" type="range" min="500" max="1500" step="50" value="500">
<button class="buttons-change-value">+</button>
</div>
<div class="summary-container">
<div class="summary-box">
<h3>Koszt:<br>
<span id="cost">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>Do zwrotu:<br>
<span id="sum">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>RRSO:<br>
<span id="rrso">200</span><span class="percentage"> %</span></h3>
</div>
</div>
</div>
</body>
</html>

Hide filter element

I'm having trouble hiding relevant data with JS.
In my code I have data-type = "power" and data-type = "grill" which are added to the products.
I want the script to check sort filters and hide those that are not present on the page.
Unfortunately, when I have two cases, it doesn't work as it should.
Grill filters do not appear even though they should.
$('.stat').on('click', function() {
var $stats = $('.stat:checked');
var $items = $('.list .product');
$items.show();
if ($stats.length == 0)
return;
var $vstats = $.map($stats, function(o) {
return $(o).data('id');
});
$stats.each(function() {
var $stat = $(this);
$items.filter(function() {
var $currentitem = $(this).data($stat.data('type'));
if ($currentitem.toString().indexOf(",") > -1) {
var $item = $currentitem.split(",");
var hit = 0;
$item.forEach(function(m) {
if ($vstats.indexOf(m) > -1) {
hit++;
}
});
if (hit > 0) {
return false;
} else {
return true;
}
} else {
if ($vstats.indexOf($currentitem) > -1) {
return false;
} else {
return true;
}
}
}).hide();
})
});
var powers = $('[data-power]').map(function() {
return this.dataset.power;
}).get();
var grills = $('[data-grill]').map(function() {
return this.dataset.grill;
}).get();
$('[data-id]').filter(function() {
return !powers.includes(this.dataset.id)
return !grills.includes(this.dataset.id)
}).closest("label").hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="power">
<h2>power</h2>
<div class="checkbox">
<label>
<input data-id="750" data-type="power" class="stat power" type="checkbox">750
</label>
<label>
<input data-id="800" data-type="power" class="stat power" type="checkbox">800
</label>
<label>
<input data-id="1200" data-type="power" class="stat power" type="checkbox">1200
</label>
</div>
</div>
<div class="grill">
<h2>grill</h2>
<div class="checkbox">
<label>
<input data-id="yes" data-type="grill" class="stat grill" type="checkbox">yes
</label>
<label>
<input data-id="no" data-type="grill" class="stat grill" type="checkbox">no
</label>
</div>
</div>
<div class="list">
<div class="col-6 col-lg-3 product" data-power="750" data-grill="yes">
<a href="/href/freh">
<div class="product-page__container product-container text-center">
<div class="product-page__name">
<h2><span class="d-block">Product Name</span> Product 1</h2>
</div>
</div>
</a>
</div>
<div class="col-6 col-lg-3 product" data-power="800" data-grill="yes">
<a href="/href/freh">
<div class="product-page__container product-container text-center">
<div class="product-page__name">
<h2><span class="d-block">Product Name 2</span> Product 2</h2>
</div>
</div>
</a>
</div>
</div>
You have to change your filter function. You are returning two values but it stops on first return.
Change
return !powers.includes(this.dataset.id) and return !grills.includes(this.dataset.id)
to
return !powers.includes(this.dataset.id) && !grills.includes(this.dataset.id);
I hope this will solve you problem.

how to filter my check box when I write in input in jquery in below code?

I want to filter my check box in below code.when I am writing in the input with class "js-filter-input" , I want to show only the check box with value of "js-filter-input" input .for example I write uni 1 in input and I want to show only checkbox with the value of unni 1 and the other ckeckbox are become hide.but my code don't work correctly.
$( document ).on( 'keyup', '.js-filter-input', function () {
var val;
var $content =$( this ).parent().next().find( ".search-filter-con" ).find( '.label-name' ).text() + " ";
if ( val = $( this ).val() ) {
$( '.group-checkbox .label-name', $content ).each( function () {
var patt = new RegExp( val, 'i' );
if ( patt.test( $( this ).data( 'en' ) ) || patt.test( $( this ).data( 'fa' ) ) || patt.test( $( this ).data( 'search' ) ) ) {
$( this ).parent().show();
} else {
$( this ).parent().hide();
}
} );
} else {
$( '.group-checkbox', $content ).show();
}
} );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="search-container2">
<input class="search_box js-filter-input" placeholder="" name="" type="text">
<button value="" class="search_submit" name="search_submit" type="submit"><i class="fa fa-search"></i></button>
</div>
<div class="searchList">
<div class="sampleContainer mCustomScrollbar _mCS_3 mCS-dir-rtl mCS_no_scrollbar">
<div class="mCustomScrollBox mCS-light-thin mCSB_vertical mCSB_inside">
<div class="mCSB_container mCS_y_hidden mCS_no_scrollbar_y" dir="rtl">
<div class="search-filter-con">
<div class="group-checkbox">
<div class="squaredFour">
<input type="checkbox" value="None" id="uni1" name="check" />
<label for="uni1"></label>
</div>
<label class="label-name" for="uni1" data-fa="uni1" data-en="uni1" data-search="uni1>uni1</label>
</div>
<div class="group-checkbox">
<div class="squaredFour">
<input type="checkbox" value="None" id="uni2" name="check" />
<label for="uni2"></label>
</div>
<label class="label-name" for="uni2" data-fa="uni2" data-en="uni2" data-search="uni2">uni2</label>
</div>
</div>
</div>
</div>
</div>
</div>
In your example .. .search-filter-con element has two label-name not
just one .. so the code will return both of them ..
$(this).parent().next().find(".search-filter-con").find('.label-name').text()
To get a separated text you need to use .each() to loop through the labels
$(this).parent().next().find(".search-filter-con").find('.label-name').each(function(){
console.log($(this).text() + ',');
});
I don't know what is the purpose of using $(this).parent().next() Unless you've multiple inputs and divs with the same classes and you want to refer to each one of them
To use input to filter you can use .filter() with indexOf()
$(document).on('input', '.js-filter-input', function() {
var val = $(this).val().trim();
if (val !== '') {
$(this).parent().next().find(".group-checkbox").hide().find('.label-name').filter(function(){
var FaData = $(this).data('fa');
var EnData = $(this).data('en');
return FaData.indexOf(val) > -1 || EnData.indexOf(val) > -1;
}).closest('.group-checkbox').show();
}else{
$('.group-checkbox').show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="search-container2">
<input class="search_box js-filter-input" placeholder="" name="" type="text">
<button value="" class="search_submit" name="search_submit" type="submit"><i class="fa fa-search"></i></button>
</div>
<div class="searchList">
<div class="sampleContainer mCustomScrollbar _mCS_3 mCS-dir-rtl mCS_no_scrollbar">
<div class="mCustomScrollBox mCS-light-thin mCSB_vertical mCSB_inside">
<div class="mCSB_container mCS_y_hidden mCS_no_scrollbar_y" dir="rtl">
<div class="search-filter-con">
<div class="group-checkbox">
<div class="squaredFour">
<input type="checkbox" value="None" id="uni1" name="check" />
<label for="uni1"></label>
</div>
<label class="label-name" for="uni1" data-fa="امير كبير" data-en="امير كبير" data-search="uni1">امير كبير</label>
</div>
<div class="group-checkbox">
<div class="squaredFour">
<input type="checkbox" value="None" id="uni2" name="check" />
<label for="uni2"></label>
</div>
<label class="label-name" for="uni2" data-fa="تهران" data-en="تهران" data-search="uni2">تهران</label>
</div>
</div>
</div>
</div>
</div>
</div>

Adding and removing numbers from the total box onchange

I am trying to add and remove the price when the check box is checked and unchecked. I am using an event listener function but it is not working how I want it to. How will I be able to click on either of the check boxes to add to the total and remove when unchecked?
HTML:
window.addEventListener('load', function() {
'use strict';
const form = document.getElementById('orderForm');
form.addEventListener("change", function() {
var total = 0;
const checkboxes = form.querySelectorAll('input[data-price][type=checkbox]');
const checkboxCount = checkboxes.length;
for (let i = 0; i < checkboxCount; i++) {
const checkbox = checkboxes[i];
if (checkbox.checked) {
total += parseFloat(checkbox.dataset.price);
form.total.value = total;
var boxTotal = parseFloat(total);
boxTotal = boxTotal.toFixed(2);
form.total.value = boxTotal;
} else {
form.total.value -= this.value;
}
}
});
});
<form id="orderForm">
<section id="selectRecords">
<div class="item">
<span class="price">10.80</span>
<span class="chosen"><input type="checkbox" data-price="9.80"></span>
</div>
<div class="item">
<span class="price">15.70</span>
<span class="chosen"><input type="checkbox" data-price="12.70"></span>
</div>
<div class="item">
<span class="price">18.20</span>
<span class="chosen"><input type="checkbox" data-price="8.20"></span>
</div>
</section>
<section id="checkCost">
Total <input type="text" name="total" size="10" readonly="">
</section>
</section>
</form>
Because you're summing up all checkboxes associated prices on change, you shouldn't have the } else { form.total.value -= this.value; - not only does this refer to the form (which doesn't have a .value), you also don't care at all about the unchecked prices, because they don't affect final value after a change event anyway.
You can select only the checked checkboxes in your query string with the :checked psuedo-selector - this will let you leave out the if (checkbox.checked) part.
You also might consider coming up with the total number once, and then assigning to the input's value once, rather than on every iteration:
const form = document.getElementById('orderForm');
form.addEventListener("change", function() {
let total = 0;
const checkboxes = form.querySelectorAll('input[data-price][type=checkbox]:checked');
const checkboxCount = checkboxes.length;
for (let i = 0; i < checkboxCount; i++) {
const checkbox = checkboxes[i];
total += Number(checkbox.dataset.price);
}
form.total.value = total.toFixed(2);
});
<form id="orderForm">
<section id="selectRecords">
<div class="item">
<span class="price">10.80</span>
<span class="chosen"><input type="checkbox" name="record[]" value="973" data-price="9.80"></span>
</div>
<div class="item">
<span class="price">15.70</span>
<span class="chosen"><input type="checkbox" name="record[]" value="974" data-price="12.70"></span>
</div>
<div class="item">
<span class="price">18.20</span>
<span class="chosen"><input type="checkbox" name="record[]" value="975" data-price="8.20"></span>
</div>
</section>
<section id="checkCost">
Total <input type="text" name="total" size="10" readonly="">
</section>
</section>
</form>
Also, to be a bit more functional, you might use Array.prototype.reduce to calculate the total, rather than a for loop:
const form = document.getElementById('orderForm');
form.addEventListener("change", function() {
const total = Array.prototype.reduce.call(
form.querySelectorAll('input[data-price][type=checkbox]:checked'),
(a, checkbox) => a + Number(checkbox.dataset.price),
0
);
form.total.value = total.toFixed(2);
});
<form id="orderForm">
<section id="selectRecords">
<div class="item">
<span class="price">10.80</span>
<span class="chosen"><input type="checkbox" name="record[]" value="973" data-price="9.80"></span>
</div>
<div class="item">
<span class="price">15.70</span>
<span class="chosen"><input type="checkbox" name="record[]" value="974" data-price="12.70"></span>
</div>
<div class="item">
<span class="price">18.20</span>
<span class="chosen"><input type="checkbox" name="record[]" value="975" data-price="8.20"></span>
</div>
</section>
<section id="checkCost">
Total <input type="text" name="total" size="10" readonly="">
</section>
</section>
</form>

Categories

Resources