I am using JQuery nested sortable to display a tree of items and I would like to disable first TWO levels from changes.
Here is jsfiddle: http://jsfiddle.net/YgF4k/18/
HTML:
<ul id='menusList'>
<li class='sortable_false'>
<div> <span class='menu_name'>
root1
</span>
</div>
<ol class='sortable'>
<li class="sortable_false" id="menu_161">
<div> <span class='menu_name'>
Child 1
</span>
</div>
</li>
<li class="sortable_false" id="menu_163">
<div> <span class='menu_name'>
Child 2
</span>
</div>
<ol>
<li class="sortable_true" id="menu_162">
<div> <span class='menu_name'>
Grandchild 1
</span>
</div>
</li>
<li class="sortable_true" id="menu_158">
<div> <span class='menu_name'>
Grandchild 2
</span>
</div>
</li>
<li class="sortable_true" id="menu_160">
<div> <span class='menu_name'>
Grandchild 3
</span>
</div>
</li>
</ol>
</li>
<li class="sortable_false" id="menu_159">
<div> <span class='menu_name'>
Child 3
</span>
</div>
</li>
</ol>
<li class="sortable_false" id="menu_2">
<div> <span class='menu_name'>
root2
</span>
</div>
</li>
</li>
</ul>
JQuery:
$('.sortable').nestedSortable({
handle: 'div',
items: 'li',
toleranceElement: '> div',
protectRoot: true,
update: function (event, ui) {
$.post("/sort", $(this).nestedSortable('serialize'));
}
});
In more details what I am still missing is:
Moving Grandchildren into Children level and vice verse should not be allowed.
Reordering of Children should not be allowed.
Moving Grandchildren between root1 Children and root2 Children should be allowed (ideally).
I've played some time with protectRoot and items options of nestedSortable, but without success.
you just need to set the items as li.sortable_true...
$('.sortable').nestedSortable({
handle: 'div',
items: 'li.sortable_true',
toleranceElement: '> div',
protectRoot: true,
update: function (event, ui) {
$.post("/sort", $(this).nestedSortable('serialize'));
}
});
See updated fiddle: http://jsfiddle.net/f9LyM/1/
also check out the jQuery UI docs, this extension inherits it: http://api.jqueryui.com/sortable/#option-items
Using newest version of jQuery.ui.nestedSortable (which currently is 2.0) solves problems with protectRoot.
Related
I have a component to show a sort of Table of Contents. I'm struggling with react for it is creating a span tag where, in my understanding, it shouldn't.
The rendering functions is:
render() {
return(
<ul>
{
this.state.contents.map(function(li, i) {
let subItems = li.subItems.map(function(subLi, j) {
return (
<li>
<span>{subLi.title}</span>
</li>
)
}, this);
return (
<li tabIndex={i}>
<span><i class="fa fa-caret-right" />{li.title}</span>
<ul class="subitens">
{subItems}
</ul>
</li>
);
}, this)
}
</ul>
);
The line <span><i class="fa fa-caret-right" />{li.title}</span> is creating the following structure:
<span>
<i></i>
<span>Parent 1</span>
</span>
And I would like:
<span><i></i> Parent 1</span>
That span around my text is messing with my CSS.
I wrapped it up on a fiddle: https://jsfiddle.net/fpcvzsLo/
Any ideas on what am I getting wrong?
Thanks!
As #degr told, this is a known issue with old react versions. It emits tags along with every text.
All I did was to update my React to 0.15 and it works.
Thanks!
Try the following:
return (
<li tabIndex={i}>
<span className="fa fa-caret-right">
{li.title}
</span>
<ul className="subitens">
{subItems}
</ul>
</li>
);
https://jsfiddle.net/fpcvzsLo/4/ (included Font Awesome to show)
Output:
<span class="fa fa-caret-right" data-reactid=".0.1.0">Parent 2</span>
I am working on a project and facing a problem. It's a jQuery problem and I am not good in jQuery. I want when someone clicked on list item(<ul id="res-menu-filters"><li></li></ul>) the value will change on h3(<h3 id="menu-title-layout-text">Change Value</h3>) tag with the value of div#menu-extend-title (<div id="menu-extend-title">Breakfast</div>).
I tried a jQuery but it's not working.
Below is my html code and jQuery code.
How should i make this work?
Thanks in advance.
<div class="menu-title-layout-change">
<h3 id="menu-title-layout-text">Breakfast</h3>
</div>
<ul id="res-menu-filters">
<li class="filter">Category 1
<div id="menu-extend-title">
Breakfast
</div>
</li>
<li class="filter">Category 2
<div id="menu-extend-title">
Launch
</div>
</li>
<li class="filter">Category 3
<div id="menu-extend-title">
Dinner
</div>
</li>
jQuery code:
jQuery('#restaurant-menu-content-tab').on('click', '#res-menu-filters li', function(e)
{
var value = jQuery('#menu-extend-title').text();
jQuery('#menu-title-layout-text').text(value);
return false;
});
Use common class instead if you used duplicated ids
<ul id="res-menu-filters">
<li class="filter">Category 1
<div class="menu-extend-title">
Breakfast
</div>
</li>
<li class="filter">Category 2
<div class="menu-extend-title">
Launch
</div>
</li>
<li class="filter">Category 3
<div class="menu-extend-title">
Dinner
</div>
</li>
jquery
jQuery('#restaurant-menu-content-tab').on('click', '#res-menu-filters li', function(e){
var value = jQuery(this).find('.menu-extend-title').text();
jQuery('#menu-title-layout-text').text(value);
return false;
});
ID of an element must be unique, so need to use class to group similar elements, also in the click handler you need to find the title element which is a descendant of the clicked li
jQuery('#restaurant-menu-content-tab').on('click', '#res-menu-filters li', function(e) {
var value = jQuery(this).find('.menu-extend-title').text();
jQuery('#menu-title-layout-text').text(value);
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="restaurant-menu-content-tab">
<div class="menu-title-layout-change">
<h3 id="menu-title-layout-text">Breakfast</h3>
</div>
<ul id="res-menu-filters">
<li class="filter">Category 1
<div class="menu-extend-title">Breakfast</div>
</li>
<li class="filter">Category 2
<div class="menu-extend-title">Launch</div>
</li>
<li class="filter">Category 3
<div class="menu-extend-title">Dinner</div>
</li>
</ul>
</div>
It doesn't work because of the following issues:
HTML menu-extend-title is an ID. It should be unique for elements.
Change menu-extend-title to class and use .menu-extend-title.
Use the following code:
<li class="filter">Category 1
<div class="menu-extend-title">
Breakfast
</div>
</li>
<li class="filter">Category 2
<div class="menu-extend-title">
Launch
</div>
</li>
<li class="filter">Category 3
<div class="menu-extend-title">
Dinner
</div>
</li>
jQuery('#restaurant-menu-content-tab').on('click', '#res-menu-filters li', function(e) {
var value = jQuery('.menu-extend-title', this).text();
jQuery(this).find('div').text(value);
return false;
});
As arun pointed out, IDs should be unique. You should rather use classname. also you can use current li context to get the required div in it using current clicked context and find selector:
jQuery('#restaurant-menu-content-tab').on('click', '#res-menu-filters li', function(e){
var value = jQuery(this).find('div').text();
jQuery('#menu-title-layout-text').text(value);
return false;
});
Do you mean something like this:
here a better html code:
<div class="menu-title-layout-change">
<h3 class="menu-title-layout-text">Breakfast</h3>
</div>
<ul class="res-menu-filters">
<li class="filter">Category 1
<div class="menu-extend-title">
Breakfast
</div>
</li>
<li class="filter">Category 2
<div class="menu-extend-title">
Launch
</div>
</li>
<li class="filter">Category 3
<div class="menu-extend-title">
Dinner
</div>
</li>
Make sure your html id's are unique!
And this jquery:
$(document).on('click','.res-menu-filters',function(){
$('.menu-title-layout-text').text($(this).find('.menu-extend-title').text());
})
I want to find the 3rd p tag of each category, based on first p tag's value.
e.g. The first p tag value is Tie, then find the quantity of it.
If the html element tree should be formatted in a better way, I am open to it. The html for all ul is written from code behind at C# to load items from database.
$("#wel div ").each(function(index, element) {
if ($(this).('p:nth-of-type(1)').html() == "Tie")
{
$(this).('p:nth-of-type(3)').css('background-color','red');
}
}
<div id="fel">Category1
<ul>
<li>
<div >
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p> <!--find this?-->
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</ul>
</div>
<div id="wel">Category2
<ul>
<li>
<div >
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p><!--find this?-->
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</ul>
</div>
JSFiddle
You can 2 top level elements with different ids fel and wel so need to use #wel div, #fel div to find the category div elements, then need to use .find() to find the p
$("#wel div, #fel div").each(function (index, element) {
if ($(this).find('p:nth-of-type(1)').html().trim() == "Tie") {
$(this).find('p:nth-of-type(3)').css('background-color', 'red');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="fel">Category1
<li>
<div>
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
<!--find this?-->
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</div>
<div id="wel">Category2
<li>
<div>
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
<!--find this?-->
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</div>
You can also do
$("#wel div, #fel div ").each(function (index, element) {
var $ps = $(this).find('p');
if ($ps.eq(0).html().trim() == "Tie") {
$ps.eq(2).css('background-color', 'red');
}
})
Demo: Fiddle
Here's the generic way of doing it
$(document).ready(function(){
var div = $('p:contains("Tie")').parent()
$('p:contains("Tie")').parent()
var price = $(div).find("p:contains('Price')").css('background-color','red');
console.log(price)
});
Please refer the fiddle here
I want to delete list items who do not have a parent of ul
This is my HTML:
<div class="yamm-content">
<div class="row">
<li> Should be deleted
</li>
<li> Should be deleted
</li>
<ul id="randomid" class="col-xs-12 col-sm-4">
<li> menu item
</li>
<li> menu item
</li>
<li> menu item
</li>
</ul>
<ul id="randomid2" class="col-xs-12 col-sm-4">
<li> menu item
</li>
<li> menu item
</li>
<li> menu item
</li>
</ul>
</div>
</div>
and my current script:
if (!$('.nav .yamm-content row li').closest('ul').length == 0) {
$(this).remove();
}
jsFiddle
The first two list items don't have ul's as parents. So they should be deleted.
Simple: $('li:not(ul > li)').remove();
Demo http://jsfiddle.net/46NdQ/3/
$('li').filter(function(){return !$(this).closest('ul').length}).remove();
Or
$('li').not($('ul li')).remove();
Here i used Javascript only and it may take some lines of coding. I suggest this may be useful some times when you don't want to go for jquery.
var len = document.getElementsByTagName('li').length;
for (var i=0;i<len;i++)
{
if (document.getElementsByTagName('li')[i].parentNode.nodeName != "UL")
{
document.getElementsByTagName('li')[i].remove();
i--;
}
}
Here is the fiddle
I have this html code:
<div id="menu">
<ul id="menuFuncionalidades">
<li>
<div class="menuFuncionalidades_categoria">
Index</div>
</li>
<li>
<div class="menuFuncionalidades_categoria">
Cadastros</div>
<div class="menuFuncionalidades_content_links">
<div class="menuFuncionalidades_content_links_descricao">
<span class="menuFuncionalidades_content_links_descricao_titulo">Descrição</span>
<div class="menuFuncionalidades_content_links_descricao_texto">
Lorem Ipsum...
</div>
</div>
<div class="menuFuncionalidades_content_links_links">
<ul><b>Acesso Usuario</b>
<li>Pesquisar </li>
<li>Incluir </li>
<li>Alterar </li>
<li>Consultar </li>
</ul>
<ul><b>Produto</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul><b>Perfil</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
</div>
</div>
</li>
<li>
<div class="menuFuncionalidades_categoria">
Coletores</div>
<div class="menuFuncionalidades_content_links">
<div class="menuFuncionalidades_content_links_descricao">
<span class="menuFuncionalidades_content_links_descricao_titulo">Descrição</span>
<div class="menuFuncionalidades_content_links_descricao_texto">
Lorem Ipsum...
</div>
</div>
<div class="menuFuncionalidades_content_links_links">
<ul>
<b>Coletor 1</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul>
<b>Coletor 2</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul>
<b>Coletor 3</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
</div>
</div>
</li>
</ul>
</div>
My objective is when i click in a menuFuncionalidades_categoria i close all menuFuncionalidades_content_links that is opened, and opened the right one that is in the same level of the menuFuncionalidades_categoria that i click. So, i try this, but i have no success:
$(document).ready(function () {
$('#menuFuncionalidades > li > .menuFuncionalidades_categoria').click(function () {
$("#menu").children().find('.menuFuncionalidades_content_links').each(function () {
// I need a code here to close only the tags that are opened but is not the current
if ($(this).css('display') == 'block') {
$(this).hide();
}
});
$(this).parent().find('.menuFuncionalidades_content_links').slideToggle('normal').css('width', $('#menu').css('width'));
});
});
What am i missing or doing wrong?
OBS: The behavior that i want, is similar with accordion menu.
DEMO here: http://fiddle.jshell.net/ry9dz/1/
As #karim79 says, you can't check "display" that way - it's a css attribute, not an html attribute.
On the other hand, if you want to close all other entries, then just do that - no need to check if they are visible first! I also suggest you use a more efficient event handler for all your items, instead of binding it to all of them. Using jQuery 1.7, something like this would work:
$(document).ready(function () {
$("#menuFuncionalidades").on("click", ".menuFuncionalidades_categoria", function(event) {
var selectedMenu = $(event.target).parents("li").find(".menuFuncionalidades_content_links")
, visible = selectedMenu.is(":visible");
// Hide all others
$("#menuFuncionalidades .menuFuncionalidades_content_links").hide();
// Show this one unless it was already visible
if(!visible) {
selectedMenu
.slideToggle('normal')
.css('width', $('#menu').css('width'));
}
// Prevent the default action
event.preventDefault();
});
});
You can hide multiple elements without iterating though all of them to see which ones aren't hidden.
Replace;
$("#menu").children().find('.menuFuncionalidades_content_links').each(function () {
if ($(this).attr('display') == 'block') {
$(this).hide();
}
});
with;
$("#menu").find('.menuFuncionalidades_content_links').hide();
$(this).attr('display') is invalid as there are no "display" attribute and instead of using .css('display') == 'block' you could simply use the psuedo selector :visible.
You want the display css property:
if ($(this).css('display') == 'block') {
$(this).hide();
}
or:
if ($(this).is(':visible')) {
$(this).hide();
}