Draggable LI's connected by SVG-Lines using JavaScript - javascript

following is the image of till now done want to connect those parent and child ul li
hi,
will appreciate you help.
I want to create a extendable list, in wich the children-li's are connected to their parant-li's trough a SVG-Line. The li-Elements should also be draggable. Here an example, which is close to my vision.
Here my working code without the SVG-Lines and undraggable li's.
var chidID = 0;
$('body').on('click', '.ul-appending', function() {
var levelID = $(this).attr('data-levelnumber');
var parentID = $(this).attr('data-parentNumber');
createNode(levelID,parentID,chidID,this);
//getParent(this);
});
function createNode(levelID,parentID,chidID,elem){
console.log(levelID,parentID,chidID);
levelID++;
parentID++;
$(elem).parent().append(
$('<ul>').addClass('newul')
.append(
$('<li>')
.append(
$('<button>').addClass('ul-appending').text("Add UL").addClass('marginBottomUl').attr('data-parentNumber',parentID).attr('data-levelnumber',levelID)
)
)
);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul>
<li><button class="ul-appending" data-parentNumber='0' data-levelnumber='0'>Main Parent</button> </li>
</ul>
</div>

Here's a working example for your vision. Not everything works as you want it to, but I think with that, you can go on and solve your issue.
Here the snippet:
$(document).ready(function(){
var chidID = 1;
$('body').on('click', '.ul-appending', function() {
var levelID = $(this).attr('data-levelnumber');
var parentID = $(this).attr('data-parentNumber');
chidID++;
createNode(levelID,parentID,chidID,this);
//getParent(this);
});
function createNode(levelID,parentID,chidID,elem){
levelID++;
parentID++;
var btnNew = $('<button>').addClass('ul-appending').text("Add UL").addClass('marginBottomUl').attr('data-parentNumber',parentID).attr('data-levelnumber',levelID).attr("id", chidID);
$(elem).parent().append(
$('<ul>').addClass('newul')
.append(
$('<li>')
.append(
btnNew
)
)
);
var mySVG = $('body').connectSVG();
mySVG.drawLine({
left_node:'#'+$(elem).prop("id"),
right_node:'#'+chidID,
horizantal_gap:10,
error:true,
width:1
});
$( '#'+$(elem).prop("id") ).draggable({
cancel: false,
drag: function(event, ui){
mySVG.redrawLines();
}
});
$( '#'+chidID ).draggable({
cancel: false,
drag: function(event, ui){
mySVG.redrawLines();
}
});
}
});
button {
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://www.jqueryscript.net/demo/jQuery-Plugin-To-Connect-Two-Html-Elements-with-A-Line/required/script/jquery.svg.min.js"></script>
<script src="http://www.jqueryscript.net/demo/jQuery-Plugin-To-Connect-Two-Html-Elements-with-A-Line/required/script/jquery.connectingLine.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<div>
<ul>
<li><button id="1" class="ul-appending" data-parentNumber='0' data-levelnumber='0'>Main Parent</button>
</li>
</ul>
</div>

Related

Limit the items shown in a ul element

Here's my code to limit the number of visible list items in a ul:
$wnd.$(el)
.find('li:gt(9)')
.hide()
.end()
.append(
$wnd.$('<li>+More</li>').click( function(){
$wnd.$(this).siblings(':hidden').show().end().remove();
})
);
When +More is clicked it will show all the items immediately.
What should be added in the code such when +More is clicked it will not show everything yet, just the next 10 items? Then, when all items are shown, a +Less option should be shown to just show the first 10 items, as it was before.
That's a strange syntax, but something like this maybe
$wnd.$(el)
.find('li:gt(9)')
.hide()
.end()
.append(
$wnd.$('<li>+More</li>').click(function () {
$wnd.$(this).remove().siblings(':hidden').slice(0, 10).show();
if ($wnd.$(el).find('li:hidden').length === 0) {
$wnd.$(el).append(
$wnd.$('<li>+Less</li>').click(function () {
$wnd.$(el).find('li:gt(9)').hide();
})
)
}
})
);
This is one way:
$( 'li:gt(9)' )
.hide()
.parent()
.append(
$( '<li>more</li>' ).on( 'click', function() {
var el = $( this ).siblings( ':hidden' );
if ( el.length ) el.slice( 0, 10 ).show();
else $( 'li:gt(9)' ).not( this ).hide();
$( this ).text( $( this ).siblings( ':hidden' ).length ? 'more' : 'less' );
})
);
FIDDLE
How about this? https://jsfiddle.net/0hyL9ngr/
HTML
<ul id='some-list'>
<li class='list-item'>1</li>
<li class='list-item'>2</li>
<li class='list-item'>3</li>
...
<li class='list-item'>39</li>
<li class='list-item'>40</li>
<li class='list-item'>41</li>
<li id='show-more'>More</li>
<li id='show-first-ten'>Less</li>
</ul>
JavaScript
$('#show-more').on('click', function () {
$('.list-item:hidden:lt(10)').show();
if ($('.list-item:hidden').length == 0) {
$(this).hide();
$('#show-first-ten').show();
}
});
$('#show-first-ten').on('click', function () {
$('.list-item:gt(9)').hide();
$(this).hide();
$('#show-more').show();
});
CSS
#show-more {
cursor: pointer;
}
#show-first-ten {
display: none;
cursor: pointer;
}
.list-item:nth-child(n+11) {
display: none;
}

How to make my JQuery code work properly for multiple ID's

I have the following code to show and hide menu items on hover:
jQuery( "#menu-item-11215" ).hover(
function() {
jQuery('#menu-item-11215 .sub-menu').show();
},
function() {
jQuery('#menu-item-11215 .sub-menu').hide();
}
);
jQuery( "#menu-item-11233" ).hover(
function() {
jQuery('#menu-item-11233 .sub-menu').show();
},
function() {
jQuery('#menu-item-11233 .sub-menu').hide();
}
);
jQuery( "#menu-item-11211" ).hover(
function() {
jQuery('#menu-item-11211 .sub-menu').show();
},
function() {
jQuery('#menu-item-11211 .sub-menu').hide();
}
);
jQuery( "#menu-item-11268" ).hover(
function() {
jQuery('#menu-item-11268 .sub-menu').show();
},
function() {
jQuery('#menu-item-11268 .sub-menu').hide();
}
);
jQuery( "#menu-item-11243" ).hover(
function() {
jQuery('#menu-item-11243 .sub-menu').show();
},
function() {
jQuery('#menu-item-11243 .sub-menu').hide();
}
);
jQuery( "#menu-item-11239" ).hover(
function() {
jQuery('#menu-item-11239 .sub-menu').show();
},
function() {
jQuery('#menu-item-11239 .sub-menu').hide();
}
);
Rather than repeat the same code over and over, is there a way to trigger the JQuery to work for any of the IDs that have a child ? Here is the relevant HTML code for just one of these. They are all set up the same way:
<ul class="fusion-megamenu fusion-megamenu-row-2 fusion-megamenu-row-columns-1 fusion-megamenu-border">
<li id="menu-item-11215" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-11215 fusion-megamenu-submenu fusion-megamenu-columns-1 col-lg-12 col-md-12 col-sm-12">
<h3 class='fusion-megamenu-title'>
Families & Individuals
</h3>
<ul class="sub-menu">
<li id="menu-item-11275" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-11275">
<a href="http://someurl">
<span class="fusion-megamenu-bullet"></span>Tax & Advisory
</a>
</li>
<li id="menu-item-11277" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-11277">
<a href="http://someurl">
<span class="fusion-megamenu-bullet"></span>Trust & Estates
</a>
</li>
</ul>
</li>
</ul>
Knowing that the parent of each child has an ID and I can select the child to show and hide using this code:
jQuery('#menu-item-11211 .sub-menu')
How can I make this more generic to save lines of code?
Reduce everything you have to:
jQuery( "ul.fusion-megamenu > li" ).hover(
function(){
jQuery(this).find('ul.sub-menu').show();
},
function(){
jQuery(this).find('ul.sub-menu').hide();
}
);
By using jQuery(this).find() you only search the list relative to the list you hover over.
Use this selector: $('[id^="menu-item"]') to act on every item that has ID starting with menu-item.
In your function it would be $('.sub-menu',this)
jQuery('[id^="menu-item"]').hover(
function() {
jQuery('.sub-menu',this).show(); // <--- this selects .sub-menu with parent of menu-item it is reffering to.
},
function() {
jQuery('.sub-menu',this).hide();
}
);
If you really need to find each element based on the id's then put them in a comma separated string like below
menuitems = "#menu-item-11215, #menu-item-11233";
jQuery( menuitems ).hover(
function(){
$(this).children(".sub-menu").show();
},
function(){
$(this).children(".sub-menu").hide();
}
);
I've used .children because it should be faster than .find, but it will only search the immediate children of your menu-items and won't go any deeper.
There are many ways to refactor this code in order to reduce duplication. Most of them have nothing to do with jQuery but with the JavaScript langauge itself. For example:
var itemNumbers = [
"11215",
"11233",
"11211",
"11268",
"11243",
"11239"
];
for(var i=0; i<itemNumbers.length; i++){
var menuItem = jQuery("#menu-item-" + itemNumbers[i]);
var subMenu = menuItem.find(".sub-menu");
menuItem.hover(subMenu.show, subMenu.hide);
}
or:
var itemNumbers = [
"11215",
"11233",
"11211",
"11268",
"11243",
"11239"
];
var menuItems = $();
for(var i=0; i<itemNumbers.length; i++){
menuItems = menuItems.add("#menu-item-" + itemNumbers[i]);
}
menuItems.hover(
function(){
$(this).find(".sub-menu").show();
},
function(){
$(this).find(".sub-menu").hide();
}
});
then just pass-in the elements in elm and what set would be show or hide
function MyToggle(elm,set){
if(set=="show"){
$(elm+' .sub-menu').show();
}else{//hide
$(elm+' .sub-menu').hide();
}
}

Unable to get <li> ID

I'm using this code to get ID of li, but I am able to get only ul ID. Below is the code. Can anyone help me.
$("#trash ul li").click(function(event) {
var $item = $(this),
$target = $(event.target);
//recycleImage($item);
alert($(this).attr('id'));
{
alert($(this).attr('id'));
});
var $item = $(this),
Remove comma from the end of the above line
try this
html
<div id='trash'>
<ul id='ul'>
<li id="li">
list1
</li>
</ul>
</div>
javascript
$("#trash ul li").click(function( event ) {
var $item = $( this )
$target = $( event.target );
alert($(this).attr('id'));
{
alert($(this).attr('id'));
}
});
fiddle

Sync two div using javascript

In my fiddle , you can see two parent div and child div in each parent !
The child div from First parent div can drag and resize ( Using JQueryUI ).
I have dragEnd and resizeEnd event for this div .
What I want to do is , after dragEnd , to set the location of child div of Second Parent div , same as first's child div .
And also , after resizeEnd , to set the size of child div of Second Parent div , same as first's child div .
Want to synchronize two child div.
Thanks !
html
<div id="resizable" class="ui-widget-content">
This is text Line 1<br/>
</div>
<img src="http://www.psdgraphics.com/file/abstract-background.jpg" width="400" height="150" />
</div>
<br/>
Second<br/>
<div id="previewContainer">
<div id="previewText" class="ui-widget-content2">
This is text Line 1<br/>
</div>
<img src="http://www.psdgraphics.com/file/abstract-background.jpg" width="400" height="150" />
</div>
<br/>
JavaScript
var DEF_HEIGHT = 100; // the #resizable default height
$( "#resizable" ).resizable({
containment: 'parent',handles: "se",stop:resizeStop,
aspectRatio: true,
resize: function( event, ui ) {
var curHeight = (ui.size.height/ DEF_HEIGHT) * 100;
$(this).css('font-size', curHeight + '%');
}
}).draggable({containment: 'parent'
});
$( "#resizable" ).draggable({
start: function() {
},
drag: function() {
},
stop: function() {
alert("Drag End");
}
});
$("#resizable").resizable({
stop: function(event, ui) {
alert('Resize End');
}
});
function dragStop(event, ui){
}
function resizeStop(event, ui){
}
You can do it like this:
$("#resizable").resizable({
...
stop: function (event, ui) {
$preview.css({width: this.style.width, height: this.style.height});
}
})
.draggable({
...
stop: function (e, ui) {
$preview.css($(this).position());
}
});
Demo: http://jsfiddle.net/YxcS8/6/

jQuery ui selectable: function does not react to deselection when there is only one element selected

The following is a code for jQuery ui´s selectable plugin. The code allows me to select more than one selectable object with the mouse without the lasso and without the keyboard. The console.log message does come up in firebug when I select. It also comes up when I have more than one selectable selected and deselect some of them.
The problem is, when there is only one element selected and I deselect it, nothing happens. I need the console.log message to come up also in that situation.
Any help appreciated
<style>
#feedback { font-size: 1.4em; }
#selectable .ui-selecting { background: #FECA40; }
#selectable .ui-selected { background: #F39814; color: white; }
#selectable { list-style-type: none; margin: 0; padding: 0; width: 60%; }
#selectable li { margin: 3px; padding: 0.4em; font-size: 1.4em; height: 18px; }
</style>
<script type="text/javascript">
$(function() {
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
stop: function() {
var result = $( "#select-result" ).empty();
$( ".ui-selected", this ).each(function() {
var index = $( "#selectable li" ).index( this );
result.append( " #" + ( index + 1 ) );
console.log("test")
});
}
});
});
</script>
<p id="feedback">
<span>You've selected:</span> <span id="select-result">none</span>.
</p>
<ol id="selectable">
<li class="ui-widget-content">Item 1</li>
<li class="ui-widget-content">Item 2</li>
<li class="ui-widget-content">Item 3</li>
<li class="ui-widget-content">Item 4</li>
<li class="ui-widget-content">Item 5</li>
<li class="ui-widget-content">Item 6</li>
</ol>
Your problem is that your console.log function fires only for each of the selected items because the selector there is ".ui-selected". When you deselect the last one, there aren't any selected so the function doesn't fire at all.
You can bind another function for each of the non-selected items, like this:
$(function() {
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
stop: function() {
var result = $( "#select-result" ).empty();
$( ".ui-selected", this ).each(function() {
var index = $( "#selectable li" ).index( this );
result.append( " #" + ( index + 1 ) );
console.log("selected");
});
$( ".ui-selectee", this ).each(function() {
var index = $( "#selectable li" ).index( this );
result.append( " #" + ( index + 1 ) );
console.log("not selected");
});
}
});
});
You can make it more dynamic by firing a function for each item that you just selected or unselected. For this you can use the selected and unselected events of selectable. This fires at the same time as stop and fires for each item that you just selected or unselected, depending on which one you use. So for example:
$(function() {
$("#selectable").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
stop: function() {
// fires at stop
var result = $( "#select-result" ).empty();
},
selected: function(event, obj) {
// this function will fire for each item that was just selected
// obj is the selected object
console.log("selected");
console.log(obj);
// Not sure if this bit will work, could try this instead of obj
var index = $( "#selectable li" ).index(obj);
$('#result').append( " #" + ( index + 1 ) );
},
unselected: function(event, obj) {
// this function will fire for each item that was just deselected
// obj is the unselected object
console.log("deselected");
console.log(obj);
// Not sure if this bit will work
var index = $( "#selectable li" ).index(obj);
$('#result #" + ( index + 1 )').remove();
}
});
});

Categories