I am looking for a way to write dynamic codes in Jquery.
Please take a look at these codes below and here is a live sample
Everything works as expected, but Jquery codes repeats and kind of long!
Is there any way to turn this Jquery to dymamic one.
Thanks!
JS
$("#link1").click(function(){
$("#table-filters>ul>li.red").removeClass("red");
$(".link1").addClass('red');
});
$("#link2").click(function(){
$("#table-filters>ul>li.red").removeClass("red");
$(".link2").addClass('red');
});
$("#link3").click(function(){
$("#table-filters>ul>li.red").removeClass("red");
$(".link3").addClass('red');
});
$("#link4").click(function(){
$("#table-filters>ul>li.red").removeClass("red");
$(".link4").addClass('red');
});
$("#link5").click(function(){
$("#table-filters>ul>li.red").removeClass("red");
$(".link5").addClass('red');
});
HTML
<div id="table-filters">
<ul>
<li class="link1">link 1</li>
<li class="link2">link 2</li>
<li class="link3">link 3</li>
<li class="link4">link 4</li>
<li class="link5">link 5</li>
</ul>
</div>
<p>
<button id="link1">link1 Button</button>
<button id="link2">link2 Button</button>
<button id="link3">link3 Button</button>
<button id="link4">link4 Button</button>
<button id="link5">link5 Button</button>
</p>
CSS
.red {
color: red;
}
li {
float:left;
margin-right: 10px
}
p {
float: left;
width: 100%;
margin-top: 50px;
}
button {
corsor: pointer;
}
JS
// a bit more dynamic using a class to capture the click
$(".link").click(function(){
$("#table-filters>ul>li.red").removeClass("red");
$("."+$(this).attr("id")).addClass('red');
});
HTML
<div id="table-filters">
<ul>
<li class="link1">link 1</li>
<li class="link2">link 2</li>
<li class="link3">link 3</li>
<li class="link4">link 4</li>
<li class="link5">link 5</li>
</ul>
</div>
<p>
<button class="link" id="link1">link1 Button</button>
<button class="link" id="link2">link2 Button</button>
<button class="link" id="link3">link3 Button</button>
<button class="link" id="link4">link4 Button</button>
<button class="link" id="link5">link5 Button</button>
</p>
Sure, you can use .each() to iterate through nodes and dynamic selector to set the class for necessary element. Here is jsfiddle: http://jsfiddle.net/kG2AZ/189/
And the snippet:
$("button").each(function(i, item) {
$(item).click(function() {
$("#table-filters>ul>li.red").removeClass("red");
$(".link"+(i+1)).addClass('red');
});
});
.red {
color: red;
}
li {
float: left;
margin-right: 10px;
list-style: none;
}
p {
float: left;
width: 100%;
margin-top: 50px;
}
button {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="table-filters">
<ul>
<li class="link1">link 1</li>
<li class="link2">link 2</li>
<li class="link3">link 3</li>
<li class="link4">link 4</li>
<li class="link5">link 5</li>
</ul>
</div>
<p id="buttons">
<button id="link1">link1 Button</button>
<button id="link2">link2 Button</button>
<button id="link3">link3 Button</button>
<button id="link4">link4 Button</button>
<button id="link5">link5 Button</button>
</p>
Because your button's ids and link's classes name are same, so you can use them to add or remove the red class in the links.
Stack Snippet
$('#buttons button').on('click', function() {
$('#table-filters ul>li').removeClass('red');
$('#table-filters ul>li[class="' + $(this).attr('id') + '"]').addClass('red');
})
.red {
color: red;
}
li {
float: left;
margin-right: 10px;
list-style: none;
}
p {
float: left;
width: 100%;
margin-top: 50px;
}
button {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="table-filters">
<ul>
<li class="link1">link 1</li>
<li class="link2">link 2</li>
<li class="link3">link 3</li>
<li class="link4">link 4</li>
<li class="link5">link 5</li>
</ul>
</div>
<p id="buttons">
<button id="link1">link1 Button</button>
<button id="link2">link2 Button</button>
<button id="link3">link3 Button</button>
<button id="link4">link4 Button</button>
<button id="link5">link5 Button</button>
</p>
I'd suggest the following approach:
// select all elements with an 'id' attribute whose value
// begins with 'link':
$('button[id^=link]')
// bind the anonymous function of the on() method as
// as the event-handler for the 'click' event:
.on('click', function() {
// finding the <li> elements with a class equal to the
// id of the clicked <button> element, contained within
// the #table-filters element:
$('#table-filters li.' + this.id)
// add the 'red' class to that element:
.addClass('red')
// select the siblings of that <li> element:
.siblings()
// remove the 'red' class from those sibling <li> elements:
.removeClass('red');
});
$('button[id^=link]').on('click', function() {
$('#table-filters li.' + this.id).addClass('red').siblings().removeClass('red');
});
.red {
color: red;
}
li {
float: left;
margin-right: 10px;
list-style-type: none;
}
p {
float: left;
width: 100%;
margin-top: 50px;
}
button {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="table-filters">
<ul>
<li class="link1">link 1</li>
<li class="link2">link 2</li>
<li class="link3">link 3</li>
<li class="link4">link 4</li>
<li class="link5">link 5</li>
</ul>
</div>
<p>
<button id="link1">link1 Button</button>
<button id="link2">link2 Button</button>
<button id="link3">link3 Button</button>
<button id="link4">link4 Button</button>
<button id="link5">link5 Button</button>
</p>
This is also possible using plain JavaScript:
// defining a function to handle the 'highlight' functionality:
function highlight() {
// using Array.from() to convert the nodeList returned from
// document.querySelectorAll() into an Array:
Array.from(
// finding all the <li> elements within the
// #table-filters element:
document.querySelectorAll('#table-filters li')
// iterating over that Array of nodes using
// Array.prototype.forEach():
).forEach(
// 'link' is a reference to the current node of the Array
// of Nodes over which we're iterating;here we access the
// Element.classList property, and use a ternary operator
// to determine whether we should use the 'add()' or
// 'remove()' method:
link => link.classList[
// if the classList of the current node ('link') contains
// a class equal to the id attribute of the clicked (this)
// <button> we return the 'add' function-name, otherwise
// we return the 'remove' function-name (using the square-
// bracket syntax to access properties of the current
// Object):
link.classList.contains(this.id) ? 'add' : 'remove'
// we pass the 'red' string as an argument:
]('red')
)
}
// using Array.from() to convert the nodeList returned by
// document.querySelectorAll() into an Array:
Array.from(
// here we find all <button> elements with an 'id' attribute
// whose attribute-value starts with 'link':
document.querySelectorAll('button[id^=link]')
// iterating over the Array of nodes:
).forEach(
// 'button' is a reference to the current node of the
// Array of nodes over which we're iterating; here
// we use the EventTarget.addEventListener() function
// to bind the named function ('highlight') as the event-
// handler for the 'click' event:
button => button.addEventListener('click', highlight)
);
function highlight() {
Array.from(
document.querySelectorAll('#table-filters li')
).forEach(
link => link.classList[link.classList.contains(this.id) ? 'add' : 'remove']('red')
)
}
Array.from(
document.querySelectorAll('button[id^=link]')
).forEach(
button => button.addEventListener('click', highlight)
);
.red {
color: red;
}
li {
float: left;
margin-right: 10px;
list-style-type: none;
}
p {
float: left;
width: 100%;
margin-top: 50px;
}
button {
cursor: pointer;
}
<div id="table-filters">
<ul>
<li class="link1">link 1</li>
<li class="link2">link 2</li>
<li class="link3">link 3</li>
<li class="link4">link 4</li>
<li class="link5">link 5</li>
</ul>
</div>
<p>
<button id="link1">link1 Button</button>
<button id="link2">link2 Button</button>
<button id="link3">link3 Button</button>
<button id="link4">link4 Button</button>
<button id="link5">link5 Button</button>
</p>
References:
CSS:
Attribute selectors.
JavaScript:
Array.from().
Array.prototype.forEach().
Arrow function syntax.
Element.classList API.
EventTarget.addEventListener().
jQuery:
addClass().
on().
removeClass().
siblings().
Related
I am working on project and my goal is to toggle each individual li element by clicking toggle button.
I managed to do this so far but it's working only on first li element.
Can you help me with this code?
<li id="liEl">Target This element</li>
<button id="Btn">toggle</button>
<li id="liEl" >Target This element</li>
<button id="Btn">toggle</button>
<li id="liEl" >Target This element</li>
<button id="Btn">toggle</button>
.done {
text-decoration: line-through;
text-decoration-thickness: 0.2rem;
text-decoration-color:red;
}
Btn= document.getElementById("Btn");
liEl= document.getElementById("liEl");
const toggleDoneClass = () => {
liEl.classList.toggle('done');
};
Btn.addEventListener('click', toggleDoneClass);
id attribute must be unique.
you can use class instead of that.
HTML
<li class="list_element">Target This element</li>
<button class="btn">toggle</button>
<li class="list_element" >Target This element</li>
<button class="btn">toggle</button>
<li class="list_element" >Target This element</li>
<button class="btn">toggle</button>
You must select all buttons and then add Event Listener to each one by a loop.
Javascript
var btns = document.getElementsByClassName("btn");
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", () => {
// Previous is li because li is before button
btns[i].previousElementSibling.classList.toggle("done");
});
}
Now this is Working.
You are giving the same ids to all the buttons and li instead of id use class names
btns= document.getElementsByClassName("btn");
it will select all the classes which contain buttons
for(let index = 0;index < btns.length; index++){
btns[index].onclick = (evt) =>{
evt.target.previousElementSibling.classList.toggle("done")
}
}
looping all the classes on which you will click it will take that element and then get their previous child which is li and toggle class on that
btns= document.getElementsByClassName("btn");
for(let index = 0;index < btns.length; index++){
btns[index].onclick = (evt) =>{
evt.target.previousElementSibling.classList.toggle("done")
}
}
.done {
text-decoration: line-through;
text-decoration-thickness: 0.2rem;
text-decoration-color:red;
}
<li id="" >Target This element</li>
<button class="btn">toggle</button>
<li id="" >Target This element</li>
<button class="btn">toggle</button>
<li id="lEl" >Target This element</li>
<button class="btn">toggle</button>
IDs should be unique in a page so maybe switch those to classes.
If you want the buttons you should add them within the list item elements.
You can attach one listener to the <ul> element and have that catch events from its children as they "bubble up" the DOM. (This is known as event delegation.)
When a click event is fired you can retrieve the specific element that was clicked with event.target, check that it's a button element, find the closest list item element to that button, and then toggle its class.
const list = document.querySelector('ul');
list.addEventListener('click', toggleDoneClass);
function toggleDoneClass(e) {
if (e.target.matches('button')) {
e.target.closest('li').classList.toggle('done');
}
}
.done { text-decoration: line-through; text-decoration-thickness: 0.2rem; text-decoration-color:red; }
li button { margin-left: 0.5em; }
<ul>
<li class="liEl">
Target This element
<button type="button">Toggle</button>
</li>
<li class="liEl">
Target This element
<button type="button">Toggle</button>
</li>
<li class="liEl">
Target This element
<button type="button">Toggle</button>
</li>
</ul>
But, ultimately, you don't really need the buttons.
const list = document.querySelector('ul');
list.addEventListener('click', toggleDoneClass);
function toggleDoneClass(e) {
if (e.target.matches('li')) {
e.target.classList.toggle('done');
}
}
.done { text-decoration: line-through; text-decoration-thickness: 0.2rem; text-decoration-color:red; }
li:hover { cursor: pointer; }
<ul>
<li class="liEl">Target This element</li>
<li class="liEl">Target This element</li>
<li class="liEl">Target This element</li>
</ul>
I have the following code:
<div id="MetricsParentModelList">
<ul>
<li class="cModel" style="">Hello</li>
<li class="cModel" style="">Hello World</li>
<li class="cModel" style="">Hello World 123</li>
</ul>
</div>
I want to add active class to li by comparing the text of the anchor tag. I can't use jQuery's contains because if i want to add active class to "Hello", then active class will be added to all li elements. I have used jQuery's filter but somehow its not working. Code is:
$("#MetricsParentModelList li a").filter(function() {
return $(this).text() === TextToCompare;
}).parent().addClass('active');
You can use jquery's .each function. And your code will be more readable.
var TextToCompare = "Hello World 123";
$("#MetricsParentModelList li a").each(function() {
if($(this).text() === TextToCompare) {
$(this).parent().addClass('active');
}
});
.active { background-color: #ccc; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="MetricsParentModelList">
<ul>
<li class="cModel" style="">Hello</li>
<li class="cModel" style="">Hello World</li>
<li class="cModel" style="">Hello World 123</li>
</ul>
</div>
Most likely you need to wrap your JS in a $(document).ready(function(){}) or $(()=>{}) as a shorthand.
$(() => {
$("#MetricsParentModelList li a").filter(function() {
return $(this).text().toLowerCase() === "hello";
}).parent().addClass('active');
});
.active{
background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="MetricsParentModelList">
<ul>
<li class="cModel" style="">Hello</li>
<li class="cModel" style="">Hello World</li>
<li class="cModel" style="">Hello World 123</li>
</ul>
</div>
I am trying to close a custom jquery drop down on click of outside of dropdown, just like default behavior of HTML select dropdown, I tried to use the window click but that is creating trouble in opening the dropdown it self.
$(".selected").click(function() {
$(".custom-dropdown-list").toggleClass("open");
});
$(".custom-dropdown-list li").click(function() {
var dataVal = $(this).attr("data-val");
var dpText1 = $(this).children('.dp-val1').text();
var dpText2 = $(this).children('.dp-val2').text();
$(".selected").attr("data-val", dataVal);
$(".selected .dp-val1").text(dpText1);
$(".selected .dp-val2").text(dpText2);
$(".custom-dropdown-list").removeClass("open");
});
.custom-dropdown {
width: 300px;
}
.selected {
padding: 5px;
cursor: pointer;
min-height: 37px;
background-color: #ccc;
}
.custom-dropdown-list {
list-style: none;
padding: 0;
margin: 0;
display: none;
}
.custom-dropdown-list.open {
display: block;
}
.custom-dropdown-list li {
padding: 5px;
cursor: pointer;
}
.custom-dropdown-list li:hover {
background: #f2f2f2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="custom-dropdown">
<div class="selected" data-val="">
<div class="dp-val1">
Selected Bank</div>
<div class="dp-val2">
</div>
</div>
<ul class="custom-dropdown-list">
<li data-val="0">
<div class="dp-val1">Option Dp0</div>
<div class="dp-val2">5879464954426 (LKP)</div>
</li>
<li data-val="1">
<div class="dp-val1">Option Dp1</div>
<div class="dp-val2">5879464954426 (LKP)</div>
</li>
<li data-val="2">
<div class="dp-val1">Option Dp2</div>
<div class="dp-val2">5879464954426 (LKP)</div>
</li>
<li data-val="3">
<div class="dp-val1">Option Dp3</div>
<div class="dp-val2">5879464954426 (LKP)</div>
</li>
<li data-val="4">
<div class="dp-val1">Option Dp4</div>
<div class="dp-val2">5879464954426 (LKP)</div>
</li>
</ul>
</div>
JSfiddle
https://jsfiddle.net/5zgyouwL/1/
This will work fine for you:
In this method I have used event.stopPropagation();
Your method was right on the path, it just needed some tweaks - I have used the click on the <html> to but the difference is that I have prevented the body click on the .selected and .custom-dropdown-list li using event.stopPropagation();.
$("html").click(function(event) {
$(".custom-dropdown-list").removeClass("open");
});
$(".selected").click(function() {
event.stopPropagation();
$(".custom-dropdown-list").toggleClass("open");
});
$(".custom-dropdown-list li").click(function() {
event.stopPropagation();
var dataVal = $(this).attr("data-val");
var dpText1 = $(this).children('.dp-val1').text();
var dpText2 = $(this).children('.dp-val2').text();
$(".selected").attr("data-val", dataVal);
$(".selected .dp-val1").text(dpText1);
$(".selected .dp-val2").text(dpText2);
$(".custom-dropdown-list").removeClass("open");
});
.custom-dropdown {
width: 300px;
}
.selected {
padding: 5px;
cursor: pointer;
min-height: 37px;
background-color: #ccc;
}
.custom-dropdown-list {
list-style: none;
padding: 0;
margin: 0;
display: none;
}
.custom-dropdown-list.open {
display: block;
}
.custom-dropdown-list li {
padding: 5px;
cursor: pointer;
}
.custom-dropdown-list li:hover {
background: #f2f2f2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="custom-dropdown">
<div class="selected" data-val="">
<div class="dp-val1">
Selected Bank</div>
<div class="dp-val2">
</div>
</div>
<ul class="custom-dropdown-list">
<li data-val="0">
<div class="dp-val1">Option Dp0</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
<li data-val="1">
<div class="dp-val1">Option Dp1</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
<li data-val="2">
<div class="dp-val1">Option Dp2</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
<li data-val="3">
<div class="dp-val1">Option Dp3</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
<li data-val="4">
<div class="dp-val1">Option Dp4</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
</ul>
</div>
Hope this was helpfull.
I think what you might want is when clicked anywhere else of custom select/dropdown it must close.
So here it is:
$(".selected").click(function(){
$(".custom-dropdown-list").toggleClass("open");
});
$(".custom-dropdown-list li").click(function(){
var dataVal = $(this).attr("data-val");
var dpText1 = $(this).children('.dp-val1').text();
var dpText2 = $(this).children('.dp-val2').text();
$(".selected").attr("data-val", dataVal);
$(".selected .dp-val1").text(dpText1);
$(".selected .dp-val2").text(dpText2);
$(".custom-dropdown-list").removeClass("open");
});
/*Mouse click anywhere but custom select dropdown, will close it. */
$(document).mouseup(function (e) {
var container = $(".custom-dropdown");
if (!container.is(e.target) && container.has(e.target).length === 0) {
$(".custom-dropdown-list").removeClass("open");
}
});
.custom-dropdown { width:300px;}
.selected { padding:5px; cursor:pointer; min-height:37px; background-color:#ccc;}
.custom-dropdown-list { list-style:none; padding:0; margin:0; display:none;}
.custom-dropdown-list.open { display:block;}
.custom-dropdown-list li { padding:5px; cursor:pointer;}
.custom-dropdown-list li:hover { background:#f2f2f2;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="custom-dropdown">
<div class="selected" data-val="">
<div class="dp-val1">
Selected Bank</div>
<div class="dp-val2">
</div>
</div>
<ul class="custom-dropdown-list">
<li data-val="0">
<div class="dp-val1">Option Dp0</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
<li data-val="1">
<div class="dp-val1">Option Dp1</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
<li data-val="2">
<div class="dp-val1">Option Dp2</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
<li data-val="3">
<div class="dp-val1">Option Dp3</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
<li data-val="4">
<div class="dp-val1">Option Dp4</div>
<div class="dp-val2">5879464954466 (LKP)</div>
</li>
</ul>
</div>
The key is Event.stopPropagation()
$('body').on('click', function(){
// close the drop down
});
$('.custom-dropdown').on('click', function(e){
e.stopPropagation();
});
You use Mouse Up Event Also Like this
$(document).mouseup(function(e)
{
var container = $(".custom-dropdown");
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0)
{
container.hide();
}
});
I believe #weBer answered your question , but another way to do this is to have an event handler right on your html element and inside that check if the targeted element or its children are being clicked :
$('html').on('click' , function(e){
if($(e.target).closest('.custom-dropdown').length ) return
$(".custom-dropdown-list").toggleClass("open");
});
FIDDLE HERE
How can make it make
1- open toggle menu when on click menu (not opened by default)
2- close itself - if click other parent menu
trying to make it work for the project
and i copied from cssdesk
$('.inbox li').click(function(e) {
$('.inbox li.active').removeClass('active');
var $this = $(this);
if (!$this.hasClass('active')) {
$this.addClass('active');
}
e.preventDefault();
});
$(document).ready(function () {
$('.tree-toggler').click(function () {
$(this).parent().children('ul.tree').toggle(300);
});
});
<link class="cssdeck" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap-responsive.min.css" class="cssdeck">
<ul class="inbox-nav nav" style="border-top: 1px solid #eef1f5; margin-top:10px;" >
<li class="">
<a href="javascript:;" id="fldr3">menu 1
</li>
<li class="">
<a data-title="Inbox" data-type="important" href="javascript:;">2nd Menu</a>
</li>
<li class="">
<a data-title="Sent" data-type="sent" href="javascript:;">menu2</a>
</li>
<li class="divider"></li>
<li class="active tree-toggler">
Toggle menu</li>
<ul class="nav nav-list tree">
<li class="">Link</li>
<li class="">Link</li>
</ul>
</li>
</ul>
<script class="cssdeck" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script class="cssdeck" src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
If user click is not neccesary you can do it by CSS, this is an example the 4th menu item has sub menu items
.menu,
.menu-item {
display: inline;
cursor: default;
}
.menu-item.has-subItem {
position: absolute;
}
.menu-item ul {
display: none;
position: absolute;
top: 15px;
left: 0;
padding: 0;
}
.menu-item:hover ul {
display: inline;
}
<ul class='menu'>
<li class='menu-item'>Item 1</li>
<li class='menu-item'>Item 2</li>
<li class='menu-item'>Item 3</li>
<li class='menu-item has-subItem'>Item 4
<ul>
<li class='sub-item'>sub 1</li>
<li class='sub-item'>sub 2</li>
<li class='sub-item'>sub 3</li>
</ul>
</li>
</ul>
In your $('.inbox li').click() function use jquery's .hide() function on the ul.tree element. Since .hide() won't do anything if the element is already hidden, you don't need to check if it needs to be hidden.
(Similarly, you can pull the $this.addClass('active'); statement out of the if, since it simply won't do anything if the class is already added!)
I have an assignment that needs to be done in a very specific way. I have all the back end code done, but cant seem to figure this part out, and it's driving me mad. Essentially the UI is required to have 2 tree views one on the right and one on the left. The left tree view will be populated with states, and each state will have multiple children. The right will be empty to start. There will be two buttons. Include, and exclude. when children from the left view are selected, and then include is clicked they will move to the right tree. If the user decides to move them back they need to move to the same place they were under the same parent. Last, but not least, there can only be one of each child so we can't have duplicates when moving the children to new parents.
I can use any combination of html, css, javascript, and jquery.
here is what i have so far. I have tried many other things, but this is just the most recent.
CSS
#menutree li {
list-style: none; /* all list item li dots invisible */
}
li .menu_label + input[type=checkbox] {
opacity: 0; /* checkboxes invisible and use no space */
} /* display: none; is better but fails in ie8 */
li .menu_label {
cursor: pointer; /* cursor changes when you mouse over this class */
} /* could add the many user-select: none; commands here */
li .menu_label + input[type=checkbox] + ol > li
{
display: none; /* prevents sublists below unchecked labels from displaying */
}
li .menu_label + input[type=checkbox]:checked + ol > li
{
display: block; /* display submenu on click */
}
.selected {
background-color:#efefef;
}
jquery
$('#move_left').click(function() {
$('.list1').append($('.list2 .selected').removeClass('selected'));
});
$('#move_right').click(function() {
$('.list2').append($('.list1 .selected').removeClass('selected'));
});
$('body').on('click', 'li', function() {
$(this).toggleClass('selected');
});
HTML
<body>
<ol id="menutree">
<li>
<label class="menu_label" for="c1">Menu Gen14 Am0a1</label>
<input type="checkbox" id="c1" /> <!-- input must follow label for safari -->
<ol>
<li>
<ul class="list1">
<li class="page">Page Ap1a1</li>
<li> Page Ap1a2</li>
</ul>
</ol>
</ol>
</body>
<input type='button' value='<<' id='move_left'/>
<input type='button' value='>>' id='move_right'/>
Stupid example that does not take children ordering under consideration, but logic that you presented should be preserved
Demo
<div class="half">
<ol id="one">
<li id="alaska">
Alaska
<ul>
<li data-id="alaska"><input type="checkbox"> Children 1</li>
<li data-id="alaska"><input type="checkbox"> Children 2</li>
<li data-id="alaska"><input type="checkbox"> Children 3</li>
</ul>
</li>
<li id="washington">
Washington
<ul>
<li data-id="washington"><input type="checkbox"> Children 1</li>
<li data-id="washington"><input type="checkbox"> Children 2</li>
<li data-id="washington"><input type="checkbox"> Children 3</li>
</ul>
</li>
<li id="texas">
Texas
<ul>
<li data-id="texas"><input type="checkbox"> Children 1</li>
<li data-id="texas"><input type="checkbox"> Children 2</li>
<li data-id="texas"><input type="checkbox"> Children 3</li>
</ul>
</li>
</ol>
<button type="button" class="include">Include</button>
</div>
<div class="half">
<ol id="two"></ol>
<button type="button" class="exclude">Exclude</button>
</div>
$(function(){
$('.include').click(function(e){
var $checks = $("input:checked");
$.each($checks, function(k,v){
var tempid = $(this).parent().data('id');
if( !$('#two').find('[data-id="'+tempid+'"]').length ){
var element = $(this).parent().detach();
$('#two').append(element);
}
});
});
$('.exclude').click(function(e){
var $checks = $("input:checked");
$.each($checks, function(k,v){
var tempid = $(this).parent().data('id');
var element = $(this).parent().detach();
$('#one').find('#'+tempid+' ul').append(element);
});
});
});