I ve dynamically generated spans which are inside a div. so structure is like this:
<div >
<span>
<span style="padding: 6px 11px;background: #FFFFFF;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="8" t-att-data-slot_plans="12:45">12:45</span>
</span>
<span>
<span style="padding: 6px 11px;background: #e9ecef;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="7" t-att-data-slot_plans="12:00">12:00</span>
</span>
</div>
shows like this:
From jquery:
var bk_class = $('.bk_slot_div1');
bk_class.append('<span><span style="padding: 6px 11px;background: #FFFFFF;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="8" t-att-data-slot_plans="12:45">12:45</span></span><span><span style="padding: 6px 11px;background: #e9ecef;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="7" t-att-data-slot_plans="12:00">12:00</span></span>');
when appying sort:
$(".bk_slot_div1 span > span").sort(function (elem1, elem2) {
return parseInt(elem1.id) > parseInt(elem2.id);
}).each(function () {
var element = $(this);
element.remove();
$(element).appendTo(".bk_slot_div1");
});
It produces multiple repetition of same span. Also the parent span is gone missing. Any idea what i am doing wrong? Sorry for bad English.
This post is also related to my requirement. Bt i still failed to find what i m doing wrong.
Sort dynamically created div based on their id using jquery
Example
var bk_class = $('.bk_slot_div1');
bk_class.append('<span><span style="padding: 6px 11px;background: #FFFFFF;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="8" t-att-data-slot_plans="12:45">12:45</span></span><span><span style="padding: 6px 11px;background: #e9ecef;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="7" t-att-data-slot_plans="12:00">12:00</span></span>');
$(".bk_slot_div1 span > span").sort(function (elem1, elem2) {
return parseInt(elem1.id) > parseInt(elem2.id);
}).each(function () {
var element = $(this);
element.remove();
$(element).appendTo(".bk_slot_div1");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<span>
<span style="padding: 6px 11px;background: #FFFFFF;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="8" t-att-data-slot_plans="12:45">12:45</span>
</span>
<span>
<span style="padding: 6px 11px;background: #e9ecef;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="7" t-att-data-slot_plans="12:00">12:00</span>
</span>
</div>
CodePudding user response:
The main issue in your code is because you're sorting the child span
elements, not the parent span
elements.
The each()
loop is also redundant as you can just append()
the content back to its original parent after sorting it.
Finally, you should return an integer value from the sort()
handler function, not a boolean:
let $container = $('.bk_slot_div1');
$container.children('span').sort((a, b) => {
let aId = parseInt($(a).children('span').prop('id'), 10);
let bId = parseInt($(b).children('span').prop('id'), 10);
return aId > bId ? 1 : aId < bId ? -1 : 0;
}).appendTo($container);
.bk_slot_div {
padding: 6px 11px;
background: #FFFFFF;
font-size: 14px;
color: #555555;
text-align: center;
border: 1px solid #979797;
border-radius: 4px;
cursor: pointer
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div >
<span>
<span id="8" t-att-data-slot_plans="12:45">12:45</span>
</span>
<span>
<span id="7" t-att-data-slot_plans="12:00">12:00</span>
</span>
</div>
CodePudding user response:
- When doing
.each()
make sure to.append()
the wrapping parent SPANs of the sorted SPANs by using.parent()
. - Alternatively, sort the wrapper SPANs instead (given their child SPANs ID). Then you only need
.appendTo()
instead of foreaching every child one by one. - Make sure to return an integer in your
.sort()
method:
Example 1: Sorting parent SPANs:
const $bkSlot1 = $(".bk_slot_div1");
$("> span", $bkSlot1)
.sort((a, b) => $("> span", a).attr("id") - $("> span", b).attr("id"))
.appendTo($bkSlot1);
.bk_slot_div1 span>span {
padding: 6px 11px;
background: #FFFFFF;
font-size: 14px;
color: #555555;
text-align: center;
border: 1px solid #979797;
border-radius: 4px;
cursor: pointer
}
<div >
<span>
<span id="8">8</span>
</span>
<span>
<span id="2">2</span>
</span>
<span>
<span id="5">5</span>
</span>
<span>
<span id="7">7</span>
</span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Example 2: Sorting children SPANs:
const $bkSlot1 = $(".bk_slot_div1");
$("span > span", $bkSlot1)
.sort((a, b) => a.id - b.id)
.each((i, el) => $bkSlot1.append($(el).parent()));
.bk_slot_div1 span>span {
padding: 6px 11px;
background: #FFFFFF;
font-size: 14px;
color: #555555;
text-align: center;
border: 1px solid #979797;
border-radius: 4px;
cursor: pointer
}
<div >
<span>
<span id="8">8</span>
</span>
<span>
<span id="2">2</span>
</span>
<span>
<span id="5">5</span>
</span>
<span>
<span id="7">7</span>
</span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
I would highly discourage to use numeric (non-prefixed) IDs. Get the habit and it's matter of time you'll end up having duplicated IDs in your application.
Use the time as a sort factor instead (the one stored inside a valid HTML5 data-* attribute):
const $bkSlot1 = $(".bk_slot_div1");
$("> span", $bkSlot1)
.sort((a, b) => {
const timeA = $("> span", a).data("time");
const timeB = $("> span", b).data("time");
return timeA.localeCompare(timeB);
})
.appendTo($bkSlot1);
.bk_slot_div1 span>span {
padding: 6px 11px;
background: #FFFFFF;
font-size: 14px;
color: #555555;
text-align: center;
border: 1px solid #979797;
border-radius: 4px;
cursor: pointer
}
<div >
<span>
<span data-time="12:00">12:00</span>
</span>
<span>
<span data-time="14:15">14:15</span>
</span>
<span>
<span data-time="10:00">10:00</span>
</span>
<span>
<span data-time="10:45">10:45</span>
</span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
CodePudding user response:
Did u try removing > sign and additional span from your selector?
$(".bk_slot_div1 span ")
Example:
var bk_class = $('.bk_slot_div1');
bk_class.append('<span><span style="padding: 6px 11px;background: #FFFFFF;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="8" t-att-data-slot_plans="12:45">12:45</span></span><span><span style="padding: 6px 11px;background: #e9ecef;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="7" t-att-data-slot_plans="12:00">12:00</span></span>');
$(".bk_slot_div1 span").sort(function (elem1, elem2) {
return parseInt(elem1.id) > parseInt(elem2.id);
}).each(function () {
var element = $(this);
element.remove();
$(element).appendTo(".bk_slot_div1");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<span>
<span style="padding: 6px 11px;background: #FFFFFF;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="8" t-att-data-slot_plans="12:45">12:45</span>
</span>
<span>
<span style="padding: 6px 11px;background: #e9ecef;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="7" t-att-data-slot_plans="12:00">12:00</span>
</span>
</div>