jQuery Sortable: storing values in an multipledimensional array - javascript

I have a sortable list (jQuery UI) formatted as something like this:
<ul class="baseList">
<li id="3">Item 1
<ul class="childList">
<li id="68">Child 1 of Item 1</li>
<li id="69">Child 2 of Item 1</li>
<li id="70">Child 3 of Item 1</li>
</ul>
</li>
<li id="8">Item 2
<ul class="childList">
<li id="81">Child 1 of Item 2</li>
<li id="83">Child 2 of Item 2</li>
</ul>
</li>
</ul>
What I am trying to achieve is to get an array variable that consists out of something like this:
var entireList = [];
entireList = [[3,[68, 69, 70], 8, [81, 83]]]
So I can post that variable to PHP to process it in the database.
I cant seem to figure out how I can solve this in javascript. What I have so far is the following:
var childList = $('.childList, .baseList').sortable({
placeholder: "ui-state-highlight",
opacity: 0.6,
update: function(event, ui){
var childArray = $('.childList').sortable('toArray');
var parentsArray = $('.baseList').sortable('toArray');
for(p in parentsArray)
{
postChildData[parentsArray[p]] = childArray;
}
console.log(postChildData);
}
});
Now that works for halve, my result is:
[3: Array[3], 8: Array[3]]
Comes down to th point that it only takes the children of the first <li> element.
Can someone here help me to get an array like the one i've written above (entireList)?

Instead of using childArray in your for loop use this:
$('#' + parentsArray[p] + ' > ul').sortable('toArray');

it may not be proper css, but give the second list a different class name, i gave it childList2 in this example. If you do not want to modify the ul you could bump the differentiation up a level to the parent li as well
var childArray = [];
var childArray2 = [];
$.each(childList, function(children) {
childArray.push(children);
});
$.each(childList2, function(children2) {
childArray2.push(children2);
});
If that doesnt work I should stop guessing without a way to test it on my own. You

Ok, I finally found the solution:
I needed to create a new Array, within there I needed to store the Parent ID and also the array with childs.
The way to do that is replace the for loop with the following:
for(p in parentsArray)
{
postListData[p] = Array(parentsArray[p], $('#' + parentsArray[p] + ' > ul').sortable('toArray'));
}

Related

Each function triggers only once

I'm trying to triggers a function on several owl-carousel sliders having the same class. If i do a console.log, it logs twice, but works only on the first slider.
Here's my function:
function setActiveItem(){
var item = $('.owl-item');
var itemLink = $('.owl-item a');
var pos = $('.is-active').parent().parent().index();
$('.slider-mobile').each(function() {
if($(this).find(itemLink).is('.is-active')) {
item.removeClass('active');
$(this).trigger('to.owl.carousel', [pos, 1, true]);
}
})
}
setActiveItem();
And here's a simplified version of my markup:
<ul class="list-container slider-mobile" data-stage-padding-items="200">
<li class="list-item">
item
</li>
</ul>
<ul class="slider-mobile" data-stage-padding-items="200">
<li class="list-item">
item
</li>
</ul>
I'm not sure if i'm using the each() function right, or if it fits my need at all.
Ok i figured it out.
#Reinder Wit you were right i was referencing the item of the first slider only, so both of my sliders were getting the same datas.
I did this:
function setActiveItem(){
$('.slider-mobile').each(function() {
var item = $(this).find('.owl-item');
var itemLink = $(this).find('.owl-item a');
var pos = $(this).find('.is-active').parent().parent().index();
if($(this).find(itemLink).is('.is-active')) {
item.removeClass('active');
$(this).trigger('to.owl.carousel', [pos, 1, true]);
console.log(pos);
}
})
}
setActiveItem();
And it is working now. Thanks for the clue.
You should activate your listener in the document ready like this:
$(document).ready(function(){
setActiveItem();
});

Put Duplicates under Common Element JavaScript/Jquery

I have the following code.Now I am building the list using Jquery. How do I do this using Javascript/JQuery?
Html(raw)after completion should look like this
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="listOne">
<li class="columnItem">John</li><!--will be removed and put under CommonLister-->
<li class="columnItem">James</li>
<li class="columnItem">Mary</li><!--will be removed and put under CommonLister-->
</ul>
<ul id="listTwo">
<li class="columnItem">John</li><!--will be removed and put under CommonLister-->
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li><!--will be removed and put under CommonLister-->
</ul>
<ul id="CommonLister">
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
</ul>
</div>
Jquery/JavaScrpit
function myFunctioner(){
$(() => {
let names = [];
let nameSet = new Set();
$("li.columnItemer").each((idx, ele) => {
nameSet.add($(ele).html())
});
var $common = $("<ul>").addClass("commmonLister");
nameSet.forEach((name) => {
if ($("li:contains(" + name + ")").length > 1) {
$("li:contains(" + name + ")").remove();
$("<li>").addClass("columnItemer").html(name).appendTo($common);
}
});
$common.appendTo($(".CommonLister"));
});
}
The above code only works if the list already exists on HTML not when dynamically creating the list. I will be building the list by Ajax query. really appreciate in if you guys can show me how to implement the above code dynamically as the list is built on click event.
Here is what I've got. I don't use the new Javascript notation (not really a fan of it), though I'm sure you could transcribe what I've written into ES if you want to keep it consistent in your project.
I took a very similar approach to you, however I did not dynamically create the element. If you know this element will exist on the page anyway, my personal philosophy is just let it exist there and be empty so that you don't have to create it on your own.
If these lists are being loaded dynamically (something I couldn't really test out while using codepen) then put this into a function called after the list elements have been created. Preferably you would simply go through the data when it is loaded and make the applicable DOM changes only once, but sometimes we do what we must
$(function() {
$('#run-code').on('click', function(e) {
e.preventDefault();
//What were you doing? nope.
var currentItems = {}; //Blank object
var $mergeColumn = $('#CommonLister'); //Common list reference
$('.columnItem').each(function(i, el) {
var $el = $(el); //Notation I use to differentiate between the regular HTML Element and jQuery element
if (!currentItems.hasOwnProperty($el.html())) {
//Has this name come up before? if not, create it.
currentItems[$el.html()] = []; //Make it equal to a brand spanking new array
}
currentItems[$el.html()].push(el);
//Add the item to the array
});
$.each(currentItems, function(name, data) {
//Loop through each name. We don't actually use the name variable because we don't care what someone's name is
if (data.length > 1) {
//Do we have more than 1 element in our array? time to move some stuff
$.each(data, function(i, el) {
var $el = $(el); //See note above
if (i == 0) {
//If this is the first element, let's just go ahead and move it to the merge column ul
$el.appendTo($mergeColumn);
} else {
$el.remove(); //Otherwise, we've already got this element so delete this one.
} //end if/else
}); //end $.each(data)
} //end if data.length >1
}); //end $.each(currentItems)
}); //end $.on()
}); //end $()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="run-code" class="btn btn-success">Click Me</button>
<h4>List 1</h4>
<ul id="listOne">
<li class="columnItem">John</li>
<!--will be removed and put under CommonLister-->
<li class="columnItem">James</li>
<li class="columnItem">Mary</li>
<!--will be removed and put under CommonLister-->
</ul>
<h4>List 2</h4>
<ul id="listTwo">
<li class="columnItem">John</li>
<!--will be removed and put under CommonLister-->
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li>
<!--will be removed and put under CommonLister-->
</ul>
<h4>Common List</h4>
<ul id="CommonLister">
</ul>

How to move lists

I have something like this:
<ul>
<li id="li1">1</li>
<li id="li2">2</li>
<li id="li3">3</li>
</ul>
And I wonder if there is possible to move the list number 3, to the place of the list number 1 using javascript or jquery, like this:
<ul>
<li id="li3">3</li>
<li id="li2">2</li>
<li id="li1">1</li>
</ul>
Thanks for you time!
No jQuery solution :
var list = document.getElementsByTagName('ul')[0],
items = list.getElementsByTagName('li'),
i = items.length;
while (i--) list.appendChild(items[i]);
Here is a demo : http://jsfiddle.net/wared/tJaJ9/.
Based on cookie monster's suggestion :
var list = document.getElementsByTagName('ul')[0],
i = list.children.length;
while (i--) list.appendChild(list.children[i]);
Just for fun :
var list = document.getElementsByTagName('ul')[0],
items = Array.prototype.slice.call(list.children);
while (items.length) list.appendChild(items.pop());
A jQuery one :
$('ul').append($('li').get().reverse());
You can use ajax sortable jquery plugin. One of my recommendation tutorial is Sortable Lists Using jQuery UI .
Here user can re-order list using cursor pointer.
This should do the trick for you.
var length = $('ul li').length;
while (length--) $('ul').append($('ul li')[length]);
Here is a working jsfiddle

How to get the current ul li's length in javascript , when i tried to sort them?

<ul id="types" style="list-type:none;">
<li id="categories" style="list-type:none;">1
<ul>
<li style="list-type:none;">1</li><br/>
<li style="list-type:none;">1</li>
</ul>
</li>
<li id="categories" style="list-type:none;">2
<ul>
<li style="list-type:none;">2</li><br/>
<li style="list-type:none;">2</li>
</ul>
</li>
<li id="categories" style="list-type:none;">3
<ul>
<li style="list-type:none;">3</li><br/>
<li style="list-type:none;">3</li>
</ul>
</li>
</ul>
i am moving the li up and down ,when i am doing like this i have written the code for calling one jquery _mouseStop function(event,noPropagation))
in this function i am writing
var tagetNode = this.currentItem[0].parentNode.id
if (this.element[0].id == "categories") {
var targetlistlength = document.getElementById(targetListId).getElementsByTagName("li").length;
// var targetlistlength = this.parentNode.getElementsByTagName("li").length;
var PageIds = "";
for (var i = 0; i < targetlistlength; i++) {
PageIds += document.getElementById(targetListId).getElementsByTagName("li")[i].getAttribute("value") + ",";
}
}
when i am sorting the child li's the above function get called but it is always getting the first child ul of first li length only.. i want the current ul li's length which i am trying to sort
i have tried with the commented line also to get the length of li's but iam getting error as this.parentNode is undefined
anyone please suggest me what can i do
As there is no working demo available, you can check what you get when you use console.log($(this)); inside that function when mouseStop event occurs in console. If you get the expected li in the console then you can executing the following code to get the length of its parent's childs.
alert($(this).parent().children().length);
There mustn't be multiple elements with the same id.
Try to replace them with classes or make them unique.
The if-condition could be the following if you have unique id's (e.g. categories-1, categories-2, ...)
if (this.element[0].id.match("^categories") != null) { ... }
Or if you use classes the if-condition could be:
if (this.element[0].className.match("(^| )categories( |$)") != null) { ... }

reorder list elements - jQuery? [duplicate]

This question already has answers here:
How may I sort a list alphabetically using jQuery?
(10 answers)
Closed 5 years ago.
Is it possible to reorder <li> elements with JavaScript or pure jQuery. So if I have a silly list like the following:
<ul>
<li>Foo</li>
<li>Bar</li>
<li>Cheese</li>
</ul>
How would I move the list elements around? Like put the list element with Cheese before the list element with Foo or move Foo to after Bar.
Is it possible? If so, how?
var ul = $("ul");
var li = ul.children("li");
li.detach().sort();
ul.append(li);
This is a simple example where <li> nodes are sorted by in some default order. I'm calling detach to avoid removing any data/events associated with the li nodes.
You can pass a function to sort, and use a custom comparator to do the sorting as well.
li.detach().sort(function(a, b) {
// use whatever comparison you want between DOM nodes a and b
});
If someone is looking to reorder elements by moving them up/down some list one step at a time...
//element to move
var $el = $(selector);
//move element down one step
if ($el.not(':last-child'))
$el.next().after($el);
//move element up one step
if ($el.not(':first-child'))
$el.prev().before($el);
//move element to top
$el.parent().prepend($el);
//move element to end
$el.parent().append($el);
One of my favorite things about jQuery is how easy it is to write tiny little add-ons so quickly.
Here, we've created a small add-on which takes an array of selectors, and uses it to order the children of the target elements.
// Create the add-on
$.fn.orderChildren = function(order) {
this.each(function() {
var el = $(this);
for(var i = order.length - 1; i >= 0; i--) {
el.prepend(el.children(order[i]));
}
});
return this;
};
// Call the add-on
$(".user").orderChildren([
".phone",
".email",
".website",
".name",
".address"
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="user">
<li class="name">Sandy</li>
<li class="phone">(234) 567-7890</li>
<li class="address">123 Hello World Street</li>
<li class="email">someone#email.com</li>
<li class="website">https://google.com</li>
</ul>
<ul class="user">
<li class="name">Jon</li>
<li class="phone">(574) 555-8777</li>
<li class="address">123 Foobar Street</li>
<li class="email">jon#email.com</li>
<li class="website">https://apple.com</li>
</ul>
<ul class="user">
<li class="name">Sarah</li>
<li class="phone">(432) 555-5477</li>
<li class="address">123 Javascript Street</li>
<li class="email">sarah#email.com</li>
<li class="website">https://microsoft.com</li>
</ul>
The function loops backwards through the array and uses .prepend so that any unselected elements are pushed to the end.
Here is a jQuery plugin to aid with this functionality: http://tinysort.sjeiti.com/
something like this?
​var li = $('ul li').map(function(){
return this;
})​.get();
$('ul').html(li.sort());
demo
I was somewhat lost you may be wanting something like this...
$('ul#list li:first').appendTo('ul#list'); // make the first to be last...
$('ul#list li:first').after('ul#list li:eq(1)'); // make first as 2nd...
$('ul#list li:contains(Foo)').appendTo('ul#list'); // make the li that has Foo to be last...
more of it here1 and here2
Have a look at jquery ui sortable
http://jqueryui.com/demos/sortable/

Categories

Resources