Pagination : Remove element using jquery? - javascript

I have a section where i have to paginate records.
Now the issue is the number gets added but i want to remove the prev number
I have currently having something as below:
Prev 1 2 3 Next
When i click on next 4 gets added and it becomes
Prev 1 2 3 4 Next
When i click on next again 5 gets added and it becomes
Prev 1 2 3 4 5 Next
What i am trying to do and what should be having
Prev 1 2 3 Next
When i click on next 4 gets added and it should become
Prev 2 3 4 Next
When i click on next again 5 gets added and it becomes
Prev 3 4 5 Next
When i click on Previous Now it should be
Prev 2 3 4 Next
Please find my runnable code below:
$('ul.pagination').on('click', 'a', function() { // listen for click on pagination link
if($(this).hasClass('active')) return false;
var active_elm = $('ul.pagination a.active');
if(this.id == 'next'){
var _next = active_elm.parent().next().children('a');
if($(_next).attr('id') == 'next') {
// appending next button if reach end
var num = parseInt($('a.active').text())+1;
active_elm.removeClass('active');
$('<li><a class="active" href="#">'+num+'</a></li>').insertBefore($('#next').parent());
return;
}
_next.addClass('active');
}
else if(this.id == 'prev') {
var _prev = active_elm.parent().prev().children('a');
if($(_prev).attr('id') == 'prev') return false;
_prev.addClass('active');
} else {
$(this).addClass('active');
}
active_elm.removeClass('active');
});
ul.pagination {
display: inline-block;
padding: 0;
margin: 0;
}
ul.pagination li {display: inline;}
ul.pagination li a {
color: black;
float: left;
padding: 8px 16px;
text-decoration: none;
transition: background-color .3s;
border: 1px solid #ddd;
}
ul.pagination li a.active {
background-color: #4CAF50;
color: white;
border: 1px solid #4CAF50;
}
ul.pagination li a:hover:not(.active) {background-color: #ddd;}
div.center {text-align: center;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="center">
<ul class="pagination">
<li><a id="prev">«</a></li>
<li><a id="test1" href="#">1</a></li>
<li><a id="test2" class="active" href="#">2</a></li>
<li>3</li>
<li>»</li>
</ul>
</div>

Use this after adding next number
$('#prev').parent().next().remove();
Codepen http://codepen.io/mastersmind/pen/ZBJZjo

Here is how I would do it.
I would add a class to the 3 <li> tags with the numbers inside for easy access with the jQuery selector.
Inside the if-statement where you check weather the next button has the id next, remove the first child like so:
$('.three_links').first().remove();
and add the next number after the last child like so:
$('.three_links').last().after('<li class="three_links"><a class="active" href="#">'+num+'</a></li>');
and if the id is prev remove the last child and add the previous number before the first child but only if the previous number is greater than 1:
if(num > 0){
active_elm.removeClass('active');
$('.three_links').last().remove();
$('.three_links').first().before('<li class="three_links"><a class="active" href="#">'+num+'</a></li>');
}
Here is a working jsfiddle.
html:
<div class="center">
<ul class="pagination">
<li>«</li>
<li class="three_links"><a id="test1" href="#">1</a></li>
<li class="three_links"><a id="test2" class="active" href="#">2</a></li>
<li class="three_links"><a id="test3" href="#">3</a></li>
<li>»</li>
</ul>
</div>
js:
$('ul.pagination').on('click', 'a', function() { // listen for click on pagination link
if($(this).hasClass('active')) return false;
var active_elm = $('ul.pagination a.active');
if(this.id == 'next'){
var _next = active_elm.parent().next().children('a');
if($(_next).attr('id') == 'next') {
// appending next button if reach end
var num = parseInt($('a.active').text())+1;
active_elm.removeClass('active');
$('.three_links').first().remove();
$('.three_links').last().after('<li class="three_links"><a class="active" href="#">'+num+'</a></li>');
return;
}
_next.addClass('active');
}
else if(this.id == 'prev') {
var _prev = active_elm.parent().prev().children('a');
if($(_prev).attr('id') == 'prev'){
var num = parseInt($('a.active').text())-1;
if(num > 0){
active_elm.removeClass('active');
$('.three_links').last().remove();
$('.three_links').first().before('<li class="three_links"><a class="active" href="#">'+num+'</a></li>');
}
return;
}
_prev.addClass('active');
} else {
$(this).addClass('active');
}
active_elm.removeClass('active');
});

Use below script:
$('ul.pagination').on('click', 'a', function() { // listen for click on pagination link
if($(this).hasClass('active')) return false;
var active_elm = $('ul.pagination a.active');
if(this.id == 'next'){
var _next = active_elm.parent().next().children('a');
if($(_next).attr('id') == 'next') {
// appending next button if reach end
var num = parseInt($('a.active').text())+1;
active_elm.removeClass('active');
$('<li><a class="active" href="#">'+num+'</a></li>').insertBefore($('#next').parent());
var hidenum = parseInt($('a.active').text())-2;
if(hidenum > 0){
$('#next').parent().prev().prev().prev().prev().hide();
}
return;
}
_next.addClass('active');
}
else if(this.id == 'prev') {
var _prev = active_elm.parent().prev().children('a');
if($(_prev).attr('id') == 'prev') return false;
_prev.addClass('active');
} else {
$(this).addClass('active');
}
active_elm.removeClass('active');
});

Related

creating a rolling menu: rolling just once

[EDIT]
I rebuild my code after numbtongue hint. It looks totally different now, and is working pretty well. Except that it is working once only ! After one roll, it doesn't roll anymore...
I have two functions : one for transitions and the other one for replacing content. In the 'transition' function, I chose to add classes to the element to transit, and add some CSS for these classes.
When I run my code, it seems that everything goes perfectly all the time, except that the transitions don't happen. What's wrong ??
JSFIDDLE : jsfiddle.net/arnaudambro/ode8bowb/2/
[ORIGINAL]
I am trying to create a "rolling menu", looking quite like the one from this awwwarded website : north-east-venture.com on the right side of the page (no advertising from me at all, just for you to know what I am refering too, for a better understanding of the issue I am confronted with).
What I am looking for is: when someone click on one item of the menu, this item goes directly up, and the items which were above would go under the stack.
I made something up which is quite working here :
JS Fiddle : jsfiddle.net/arnaudambro/7s6ncxyp/
But as you can see, there are no transitions.
Here is the code showing the "working" transition :
JSFiddle : jsfiddle.net/arnaudambro/xtrvsgor/
To make the transitions working, I had to comment the lines 84, 153, 172 and 174 in the JS.
I tried everything I could to make the transitions working in the whole menu, but it seems that when I "populate the new menu", every transition is killed.
What i wrong with my code ?
Hint: clicking on links loses menu position (sets it to array size currently = 5), instead should be cycling trough (see attached) for other links..
Success !
With some timeouts, I did the trick. Unfortunately, it is working but still a bit jerky, because it seems there is no other choice with timeouts. I tried to measure time spent to repopulateMenu to do its job, and put it as a setTimeout value, but it didn't work, the time was too short.
Anyway, it's quite working already, nice !
/*------------------------------ Variables -----------------------------------*/
const menu = document.querySelector('.menu');
const items = [...document.querySelectorAll('.item')];
const itemsLink = [...document.querySelectorAll('.item-link')];
const itemsContent = [...document.querySelectorAll('.item-content')];
let translateYHeight = itemsLink[0].offsetHeight;
console.log(translateYHeight)
let textContentItemAtTheTopOfTheStack;
let transitionInSeconds;
let transitionInMilliSeconds;
let clickedItemIndex;
/*--------------------------- Functions - callbacks --------------------------*/
//Get the index. Called in the STEP 1.
function getTheIndexOfTheClickedItem(e) {
//Variable
let clicked;
//We select the <p> only
if (e.target.tagName == "LI") {
clicked = e.target.firstElementChild.firstElementChild;
} else if (e.target.tagName == "A") {
clicked = e.target.firstElementChild;
} else if (e.target.tagName == "P") {
clicked = e.target;
} else {
return false;
}
//Nothing happen if we clicked on the first item
if (clickedItemIndex === 0) {
return;
}
//We get the index of the clicked item
clickedItemIndex = items.indexOf(clicked.parentElement.parentElement);
//We get the textContent of the clicked item, so that when the textContent
//of the first item in the menu is the proper textContent, we are done
textContentItemAtTheTopOfTheStack = itemsContent[clickedItemIndex].textContent;
//We set the total transition time to 1 second
transitionInSeconds = 1 / clickedItemIndex;
transitionInMilliSeconds = transitionInSeconds * 1000;
translateAndFade();
}
/*--------------------------- STEP 1 --------------------------*/
function translateAndFade() {
//We put the proper transition depending on when the translateAndFade function
//is called
let transitionStyle;
if (clickedItemIndex === 1) {
transitionStyle = 'ease-in-out';
} else if (itemsLink[1].textContent.trim() === textContentItemAtTheTopOfTheStack) {
transitionStyle = 'ease-out';
} else if (itemsLink[clickedItemIndex].textContent.trim() === textContentItemAtTheTopOfTheStack) {
transitionStyle = 'ease-in';
} else {
transitionStyle = 'linear';
}
//We add the transitions and fadings we want
itemsLink.forEach(link => {
if (itemsLink.indexOf(link) === 0) {
//We add the fade-out for the first menu-item
link.style.opacity = 0;
link.style.transform = `translateY(-${translateYHeight}px)`;
link.style.transition = `all ${transitionInSeconds}s ${transitionStyle}`;
} else if (itemsLink.indexOf(link) === (itemsLink.length - 1)) {
//We add the fade-in for the last menu-item
link.firstElementChild.textContent = itemsLink[0].textContent.trim();
link.style.opacity = 1;
link.style.transform = `translateY(-${translateYHeight}px)`;
link.style.transition = `all ${transitionInSeconds}s ${transitionStyle}`;
} else {
//We translate every menu-item one step up
link.style.transform = `translateY(-${translateYHeight}px)`;
link.style.transition = `all ${transitionInSeconds}s ${transitionStyle}`;
}
});
//We call repopulateMenu, to repopulate the menu, with enough timeout to
//let the transition happening
window.setTimeout(repopulateMenu, transitionInMilliSeconds);
}
/*--------------------------- STEP 2 --------------------------*/
function repopulateMenu() {
//We remove the transitions
itemsLink.forEach(link => {
if (itemsLink.indexOf(link) === 0) {
//We remove the fade-out for the first menu-item
link.style.opacity = 1;
link.style.transform = ``;
link.style.transition = ``;
} else if (itemsLink.indexOf(link) === (itemsLink.length - 1)) {
//We remove the fade-in for the last menu-item
link.style.opacity = 0;
link.style.transform = ``;
link.style.transition = ``;
} else {
//We remove the translation of all of them
link.style.transform = ``;
link.style.transition = ``;
}
});
//We update the textContents
itemsContent.forEach(item => {
// We put back emptiness for the last menu-item
if (itemsContent.indexOf(item) === (itemsContent.length - 1)) {
item.textContent = '';
} else {
//We replace the content of the item by the one below it
item.textContent = itemsContent[itemsContent.indexOf(item) + 1].textContent.trim();
}
});
//We do all again until the proper item-menu is on top of the stack.
if (itemsContent[0].textContent != textContentItemAtTheTopOfTheStack) {
window.setTimeout(translateAndFade, 20);
} else {
return;
}
}
/*--------------------------- Event listeners --------------------------------*/
menu.addEventListener('click', getTheIndexOfTheClickedItem);
html,
body {
font-family: sans-serif;
font-weight: 100;
color: rgba(41, 44, 45, 1.00);
}
.menu {
margin-top: 50px;
margin-left: 50px;
list-style: none;
/*border: 1px solid #000;*/
}
.transition-translateY {
transition: all 1s;
transform: translateY(-44px);
}
.transition-fadeIn {
transition: all 1s;
transform: translateY(-44px);
opacity: 1;
}
.transition-fadeOut {
transition: all 1s;
transform: translateY(-44px);
opacity: 0;
}
.item {
padding-top: 2px;
padding-bottom: 2px;
font-size: 0.75em;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
text-align: left;
/*border: 1px solid #000;*/
}
.item-link,
.item-link:hover {
height: 25px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
text-decoration: none;
color: inherit;
}
<body>
<ul class="menu">
<li class="item">
<a href="#" class="item-link">
<p class="item-content" data-menu-position="0">Item 1</p>
</a>
</li>
<li class="item">
<a href="#" class="item-link">
<p class="item-content" data-menu-position="1">Item 2</p>
</a>
</li>
<li class="item">
<a href="#" class="item-link">
<p class="item-content" data-menu-position="2">Item 3</p>
</a>
</li>
<li class="item">
<a href="#" class="item-link">
<p class="item-content" data-menu-position="3">Item 4</p>
</a>
</li>
<li class="item">
<a href="#" class="item-link">
<p class="item-content" data-menu-position="4">Item 5</p>
</a>
</li>
<li class="item">
<a href="#" class="item-link" style="opacity:0">
<p class="item-content" data-menu-position="5"></p>
</a>
</li>
</ul>
</body>

Change Background color of Active list item in bootstrap

I have item group list
<div id="MainMenu">
<div class="list-group panel">
Menu 1
<div class="collapse" id="why">
Menu 1 a
Menu 1 b
Menu 1 c
Menu 1 d
Menu 1 e
Menu 1 f
</div>
Menu 2
<div class="collapse" id="joinus">
Menu 2 a
Menu 2 b
Menu 2 c
Menu 2 d
Menu 2 e
</div>
</div>
</div>
I want to change background of active list item, I Know how to change background, but I am unable to get which list is active, or inactive by JavaScript, tried lots of solution given on others but didn't woJrk.
JsFiddle
UPDATE:
Don't know why bootstrap isn't doing it, but here's some jQuery on a fiddle for you. The alert is displaying the href that is active.
Is that what you're after?
Update - 09/01/2022
Edited the old fiddle, here's the new one http://jsfiddle.net/dh7t3cbp/1/
$('.list-group').on('click', '> a', function(e) {
var $this = $(this);
$('.list-group').find('.active').removeClass('active');
$this.addClass('active');
alert($this.attr('href') + ' is active');
});
$('.list-group .collapse').on('click', '> a', function(e) {
var $this = $(this),
$parent = $this.parent('.collapse');
$parent.find('.active').removeClass('active');
$this.addClass('active');
alert($this.attr('href') + ' is active');
});
.list-group panel.active, .list-group panel.active a.active {
background-color: #030;
border-color: #aed248;
}
Add the following css in your code as :
.list-group-item[aria-expanded="true"]{
background-color: black !important;
border-color: #aed248;
}
Demo
What i does it assign and id to every link in list that is also the page name, and made a js function that is called on body load of the page. the function get the current file name from url and determines which page is this, then by js i made that link class active. this solve my problem. however i share this solution for others to improvement.
function get_current_page() {
var pathArray = window.location.pathname.split("/");
var current_page = pathArray[pathArray.length - 1];
current_page_array = current_page.split(".");
current_page = current_page_array[0];
if (
current_page == "students" ||
current_page == "my-profile" ||
current_page == "faqs" ||
current_page == "forecast-career"
) {
document.getElementById("joinuslist").className += " active";
document.getElementById("joinus").className += " in";
if (current_page == "students") {
document.getElementById("students").className += " active";
} else if (current_page == "faqs") {
document.getElementById("faqs").className += " active";
} else if (current_page == "forecast-career") {
document.getElementById("forecast-career").className += " active";
} else if (current_page == "my-profile") {
document.getElementById("my-profile").className += " active";
} else {
}
} else if (
current_page == "values" ||
current_page == "ambassadors" ||
current_page == "documentary"
) {
if (current_page == "values") {
document.getElementById("values").className += " active";
} else if (current_page == "ambassadors") {
document.getElementById("ambassadors").className += " active";
} else if (current_page == "documentary") {
document.getElementById("documentary").className += " active";
} else {
}
}
}
.list-group-item.active:hover {
background-color: #aed248 !important;
border-color: #aed248 !important;
}
.list-group-item.active,
.list-group-item.active:hover {
background-color: #007715 !important;
border-color: #aed248 !important;
}
#joinus .list-group-item.active,
.list-group-item.active:hover {
background-color: #adce1b !important;
border-color: #adce1b !important;
}
#whyptcl .list-group-item.active,
.list-group-item.active:hover {
background-color: #adce1b !important;
border-color: #adce1b !important;
}
.panel {
margin-bottom: 20px;
background-color: transparent !important;
border: 0px solid transparent;
border-radius: 5px;
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
}
<body onload="get_current_page()">
<div id="MainMenu">
<div class="list-group panel">
<a
id="whylist"
href="#why"
class="list-group-item"
data-toggle="collapse"
data-parent="#MainMenu"
>Menu 1</a
>
<div class="collapse" id="why">
<a
id="values"
href="values.html"
onclick="activate(this)"
class="list-group-item"
data-toggle="collapse"
data-parent="#SubMenu1"
>Menu 1 a</a
>
<a
id="ambassadors"
href="ambassadors.html"
onclick="activate(this)"
class="list-group-item"
>Menu 1 b</a
>
<a
id="documentary"
href="documentary.html"
onclick="activate(this)"
class="list-group-item"
>Menu 1 c</a
>
</div>
<a
id="joinuslist"
href="#joinus"
class="list-group-item"
data-toggle="collapse"
data-parent="#MainMenu"
>Menu 2</a
>
<div class="collapse" id="joinus">
<a
id="my-profile"
href="my-profile.html"
onclick="activate(this)"
class="list-group-item"
>Menu 2 a</a
>
<a
id="students"
href="students.html"
onclick="activate(this)"
class="list-group-item"
>Menu 2 b</a
>
<a
id="forecast-career"
href="forecast-career.html"
onclick="activate(this)"
class="list-group-item"
>Menu 2 c</a
>
<a
id="faqs"
href="faqs.html"
onclick="activate(this)"
class="list-group-item"
>Menu 2 e</a
>
</div>
</div>
</div>
</body>
The solution is simple but maybe not obvious.
You can pass this (the clicked element) to an onclick event handler and then set the active class on the selected menu.
var activate = function(el) {
var current = document.querySelector('.active');
if (current) {
current.classList.remove('active');
}
el.classList.add('active');
}
I created this Fiddle to answer your question
http://jsfiddle.net/Ltp9qLox/9/
The script can be greatly improved, this is just an example. I'm not aware of any non-JS way to achieve the same result.
You can also store the old activated element so you don't have to use query selector every time, in this way the script would be
var current;
var activate = function(el) {
if (current) {
current.classList.remove('active');
}
current = el;
el.classList.add('active');
}
Bu then you have to initialize currentwith the value of the starting element.
Adding Persistency
Of course any change to the style of an element can't survive after a refresh without implementing some kind of persistency that is something completely different than the simple implementation. Keep in mind that there are hundreds of different ways to achieve this, one of which is NOT refreshing at all the page.
Anyway if you prefer the quick and dirt way then using localStorage is probably the best solution. This is a simple implementation
var currentHref = localStorage.getItem("currentSelected");
var current = currentHref ? document.querySelector('[href="'+currentHref+'"]') : null;
function activate(el) {
if (current && current !== el) {
current.classList.remove('active');
}
current = el;
current.classList.add('active');
localStorage.setItem("currentSelected", current.getAttribute('href'));
}
Basically you save something that you can use to recognize the element that was selected, in this case i used the href attribute value because in our case that is unique, but you could also assign id or other attributes to the elements and use that.
Then on load i read the localStorage to retrieve the saved href and if found i get the element inside the page using a simple querySelector.
Just remember that copy-pasting this kind of solution doesnt help you building better websites, you should read articles on the internet and implement what solution is best for your own use case.
Just to change the active item background color, (I've changed to grey from default - blue) add this to your css:
.list-group-item.active {
background-color: grey;
border-color: grey; }
You can add these Bootstrap classes;
.list-group-item-dark
.list-group-item-success
.list-group-item-warning
.list-group-item-primary
.list-group-item-danger
.list-group-item-secondary
.list-group-item-info

Control Show/Hide multiple DIV using CSS, Javascript, and Anchor without unique ID

I have an older JavaScript/CSS file that used to (no longer works in current browsers) toggle the display properties for multiple divs by way of anchor tags. The CSS document.stylesheets would toggle based on value "rules", that required the style to be in a specific sequence to control the "none" to "block" toggling (or the reverse). Here is a link to the JSFiddle example:
JSFiddle
Here is the JavaScript:
function NorB(arg){
if (arg=="n") {
document.styleSheets[0].rules[0].style.display=='block';
document.styleSheets[0].rules[1].style.display=='none';
} else {
document.styleSheets[0].rules[0].style.display=='none';
document.styleSheets[0].rules[1].style.display=='block';
}
}
Here is the HTML:
<table>
<tr>
<td>
<div class="narrative" id="rpmAct1">
<div class="buttons">
<div class="narButton">Narrative ></div>
<div class="bulButton">List View ></div>
</div>
<div class="narrativeContent">
<div class="n">Narrative text</div>
<div class="b">
<ul>
<li>List Item A</li>
<li>List Item B</li>
<li>List ITem C</li>
</ul>
</div>
</div>
</div>
</td>
</tr>
<tr>
<td>
<div class="narrative" id="rpmAct2">
<div class="buttons">
<div class="narButton">Narrative 2></div>
<div class="bulButton">List View 2></div>
</div>
<div class="narrativeContent">
<div class="n">Narrative 2 text</div>
<div class="b">
<ul>
<li>List 2 Item A</li>
<li>List 2 Item B</li>
<li>List 2 ITem C</li>
</ul>
</div>
</div>
</div>
</td>
</tr>
</table>
And lastly, the CSS:
.n {
display:block;
}
.b {
display:none;
}
.b ul {
margin-left:3px;
margin-top:0px;
margin-right:10px;
margin-bottom:-2px;
}
.b ul li {
list-style-type:square;
list-style-position:outside;
line-height:12px;
}
.buttons {
position:relative;
width:300px;
}
.narButton {
width:80px;
float:left;
padding:2px 0px 2px 5px;
}
.bulButton {
width:80px;
float:left;
padding:2px 0px 2px 5px;
}
.bulButton a, .narButton a {
font-size:14px;
font-style:normal;
text-decoration:none;
}
.narrativeContent {
border-top:1px solid #CCC;
border-bottom:1px solid #CCC;
padding:5px;
}
Since there is a large number of div/anchor elements on the page, the goal is to avoid creating unique IDs for each, and continue to use basic CSS/JavaScript (avoid using jQuery and the like). Thoughts on how to keep this simple?
Append these CSS
.b-mode .b, .n-mode.n {
display:block;
}
.b-mode .n, .n-mode.b {
display:none;
}
Modify onclick action
<a href="#" onclick="NorB(this,'n')">
Modify Javascript
function NorB(e, arg) {
var wrapper = e.parents('.narrative');
var rm = arg == 'n' ? 'b' : 'n';
wrapper.classList.add(arg + '-mode');
wrapper.classList.remove(rm + '-mode');
}
Object.prototype.parents = function (selector) {
if (selector.length == 0) return;
var prefix = selector.substr(0, 1);
if (prefix != '#' && prefix != '.') return;
var selector = selector.substr(1);
var p = this.parentNode;
while (p !== null) {
switch (prefix) {
case "#":
if (p.getAttribute('id') == selector) return p;
break;
case ".":
if (p.classList.contains(selector)) return p;
break;
}
p = p.parentNode;
}
return null;
};
http://jsfiddle.net/ypnospae/
Parfait's script is exactly what was needed:
function NorB(e, arg) {
var wrapper = e.parents('.narrative');
var rm = arg == 'n' ? 'b' : 'n';
wrapper.classList.add(arg + '-mode');
wrapper.classList.remove(rm + '-mode');
}
Object.prototype.parents = function (selector) {
if (selector.length == 0) return;
var prefix = selector.substr(0, 1);
if (prefix != '#' && prefix != '.') return;
var selector = selector.substr(1);
var p = this.parentNode;
while (p !== null) {
switch (prefix) {
case "#":
if (p.getAttribute('id') == selector) return p;
break;
case ".":
if (p.classList.contains(selector)) return p;
break;
}
p = p.parentNode;
}
return null;
};
Learning every day, and the mentoring is greatly appreciated!

How to sort a list with two items

Hello I want to make this two items sortable without using plugins and stuff, only HTML5 and pure javascript:
<ul ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)"
ondragover="return dragOver(event)">
<li draggable="true" ondragstart="return dragStart(event)">Item 1</li>
<li draggable="true" ondragstart="return dragStart(event)">Item 2</li>
</ul>
well i've tried:
function dragStart(ev) {
ev.dataTransfer.effectAllowed = 'move';
ev.dataTransfer.setData("Text", ev.target.getAttribute('class'));
return true;
}
function dragEnter(ev) {
event.preventDefault();
return true;
}
function dragOver(ev) {
return false;
}
function dragDrop(ev) {
var src = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(src));
ev.stopPropagation();
return false;
}
Would you like to order alphabetically? Here is a solution without any library.
var items = document.getElementsByTagName("li");
var values = [];
for(var i = 0; i < items.length; i++) {
values.push(items[i].innerHTML);
}
values.sort();
for(var i = 0; i < items.length; i++) {
items[i].innerHTML = values[i];
}
http://jsfiddle.net/GG9gG/
jsfiddle:
http://jsfiddle.net/pMcmL/6/
HTML:
<ul id="sortable">
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 1
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 2
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 3
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 4
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 5
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 6
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 7
</li>
</ul>
CSS:
http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/base/jquery-ui.css
+
li {
margin: 1px;
width: 130px;
padding:2px;
vertical-align:middle;
}
li span {
color: gray;
font-size: 1.1em;
margin-right: 5px;
margin-left: 5px;
cursor: pointer;
height:100%;
}
input[type="text"] {
width: 32px;
margin-right: 5px;
border: 1px solid lightgay;
color: blue;
text-align: center;
}
Javascript:
sort_ul = $('#sortable'); // * sortable <ul>
itemsCount = $('#sortable li').length; // * total number of items
function updateIndexes() { // * function to update
$('#sortable li input').each( // items numbering
function(i) {
$(this).val(i + 1);
});
}
updateIndexes(); // * start by update items numbering
sort_ul.sortable({handle: 'span', // * apply 'sortable' to <ul>
stop: function(event, ui){
updateIndexes(); // * when sorting is completed,
} // update items numbering
});
$('#sortable li input').keyup( // * watch for keyup on inputs
function(event) {
if (event.keyCode == '13') { // * react only to ENTER press
event.preventDefault(); // * stop the event here
position = parseInt($(this).val());// * get user 'new position'
li = $(this).parent(); // * store current <li> to move
if (position >= 1 // * proceed only if
&& position <= itemsCount){ // 1<=position<=number of items
li.effect('drop', function(){ // * hide <li> with 'drop' effect
li.detach(); // * detach <li> from DOM
if (position == itemsCount)
sort_ul.append(li); // * if pos=last: append
else // else: insert before position-1
li.insertBefore($('#sortable li:eq('+(position - 1)+')'));
updateIndexes(); // * update items numbering
li.effect('slide'); // * apply 'slide' effect when in
}); // new position
}else{ li.effect('highlight'); } // * if invalid position: highlight
}}});
Reference Link

Sortable list + ability to re-order each item by inputting rank #

I've searched and searched about how to do this, but to no avail.
Basically I have a pretty standard jQuery sortable list, using a gripper to allow users to rearrange the list
What I would like to add is an input box to each list item, autofilled with that item's #, that allows users to enter any number (so long as it is <== the total # of items in the list)< and then hit "Enter" or press a button to re-order the list.
Please see the YouTube Playlist tool or Netflix Queue as an example of what I am referring to:
http://img195.imageshack.us/img195/7715/youtubeplaylistrearrangc.png
http://www.thedigeratilife.com/images/netflix-queue-big.jpg
I cannot figure this out - Any assistance would be greatly appreciated!
Dave
jsfiddle:
http://jsfiddle.net/pMcmL/6/
HTML:
<ul id="sortable">
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 1
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 2
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 3
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 4
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 5
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 6
</li>
<li class="ui-state-default">
<span>⇅</span><input type="text"/>Item 7
</li>
</ul>
CSS:
http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/base/jquery-ui.css
+
li {
margin: 1px;
width: 130px;
padding:2px;
vertical-align:middle;
}
li span {
color: gray;
font-size: 1.1em;
margin-right: 5px;
margin-left: 5px;
cursor: pointer;
height:100%;
}
input[type="text"] {
width: 32px;
margin-right: 5px;
border: 1px solid lightgay;
color: blue;
text-align: center;
}
Javascript:
sort_ul = $('#sortable'); // * sortable <ul>
itemsCount = $('#sortable li').length; // * total number of items
function updateIndexes() { // * function to update
$('#sortable li input').each( // items numbering
function(i) {
$(this).val(i + 1);
});
}
updateIndexes(); // * start by update items numbering
sort_ul.sortable({handle: 'span', // * apply 'sortable' to <ul>
stop: function(event, ui){
updateIndexes(); // * when sorting is completed,
} // update items numbering
});
$('#sortable li input').keyup( // * watch for keyup on inputs
function(event) {
if (event.keyCode == '13') { // * react only to ENTER press
event.preventDefault(); // * stop the event here
position = parseInt($(this).val());// * get user 'new position'
li = $(this).parent(); // * store current <li> to move
if (position >= 1 // * proceed only if
&& position <= itemsCount){ // 1<=position<=number of items
li.effect('drop', function(){ // * hide <li> with 'drop' effect
li.detach(); // * detach <li> from DOM
if (position == itemsCount)
sort_ul.append(li); // * if pos=last: append
else // else: insert before position-1
li.insertBefore($('#sortable li:eq('+(position - 1)+')'));
updateIndexes(); // * update items numbering
li.effect('slide'); // * apply 'slide' effect when in
}); // new position
}else{ li.effect('highlight'); } // * if invalid position: highlight
}}});
here is something that moves the li items around by changing the numbers:
function setOrder() {
$.each($('ul li input'), function(index, el) {
el.value = (index + 1);
});
}
setOrder();
$('ul li input').live('change', function() {
var change = (parseInt(this.value) - 1);
if(change > ($('ul li input').length - 1)){
change = $('ul li input').length - 1;
}
var index = $(this).index('ul li input');
var move = $('ul li')[change];
var arr = [];
$.each($('ul li'), function(ind, el) {
arr[ind] = $(this).clone();
})
arr[index] = move;
$('input', move).val(index + 1);
arr[change] = $(this).parent()[0];
arr.sort();
$('ul li').remove();
var indexAt = 0;
$.each(arr, function(index, el) {
$('ul').append(el);
});
setOrder();
})
$('ul').sortable({
stop: function(a, b) {
var arr = [];
var i = 0;
$.each($('ul li'), function(ind, el) {
arr[i] = $(this).clone();
i++;
})
$('ul li').remove();
$.each(arr, function(index, el) {
$('ul').append(el);
});
setOrder()
}
});
html:
<ul>
<li><input/>lijrfxgjh</li>
<li><input/>ghhgfhj</li>
<li><input/>lijrjh</li>
<li><input/>gfreydjgj</li>
<li><input/>rey</li>
<li><input/>gfjgf</li>
</ul>
fiddle: http://jsfiddle.net/maniator/bDvK8/
it is a bit glitchy, but it is a start

Categories

Resources