jstree 3 get the position where the target got dropped - javascript

I have created this
http://jsfiddle.net/n82vvvo6/
jQuery(function($) {
$(document).on('dnd_stop.vakata', function(e, data) {
var origin = $(data.element);
var target = $(data.event.target);
// Missing something here to get if the origin is before or after the target
$('#result').html(
'<div><b>Target:</b> ' + target.html() + '</div>' +
'<div><b>Origin:</b> ' + origin.html() + '</div>'
);
})
$('#jstree_demo').jstree({
"core" : {
"check_callback" : true,
"themes" : { "stripes" : true },
},
"plugins" : [
"dnd"
]
});
});
Now if I move fx 1-5 to the top, the target is 1-1
but if I move fx 1-5 to the bottom, the target is 1-8
Is there any method where I can find out if the origin is before or after the target?

This may be a little different then your direct question but this is how I solved the issue of figuring out the position of the drop.
After the 'dnd_stop.vakata' is called the 'move_node.jstree' event is called which does contain the item being moved, old parent, new parent, and index point the item is to be dropped.
$('#AdminTree').on("move_node.jstree", function (e, data) {
//item being moved
var moveitemID = $('#' + data.node.id).find('a')[0].id;
//new parent
var newParentID = $('#' + data.parent).find('a')[0].id;
//old parent
var oldParentID = $('#' + data.old_parent).find('a')[0].id;
//position index point in group
//old position
var oldPostionIndex = data.old_position;
//new position
var newPostionIndex = data.position;
});

Related

fullpage.js - adding links within tooltips

PROBLEM
I've tried adding a link to the navigational tooltips and, based on html, it should be working. However, no matter which tooltip I click, I am taken to the second section - even though the address indicated is correct and should be taking me across all sections.
for (var i = 0; i < $(SECTION_SEL).length; i++) {
var link = '';
if (options.anchors.length) {
link = options.anchors[i];
}
var li = '<li><span></span>';
// Only add tooltip if needed (defined by user)
var tooltip = options.navigationTooltips[i];
if (typeof tooltip !== 'undefined' && tooltip !== '') {
li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + '' + tooltip + '</div>';
}
li += '</li>';
nav.find('ul').append(li);
}
I've tried putting the links into the init file as well, but that has the exact same effect.
Fullpage.js will ignore your link.
See line 1694
function sectionBulletHandler(e){
e.preventDefault();
var index = $(this).parent().index();
scrollPage($(SECTION_SEL).eq(index));
}
And line 567:
.on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler)

Why is the 'active' class not being assigned to the content list items?

Below is a plugin I wrote for tabs. I'm sure there's a better approach to writing this, but that will come later when I start to refine this plugin. It's a learning-in-progress personal project. The problem is that when I click one of the tabs, the 'active' class is not being assigned to the corresponding content li tag. I'm assigning the id's to each of the li's using for loops.
If I remove (cEvent + 1) from the loop that assigns the 'active' class to the correct li tag, then it will assign an 'active' class to all li tags - because of this I know the selector is correct. It's when I add (cEvent + 1) in the loop that it doesn't assign anything.
The section in question is: // Click Event: Open New Tab
Thank you all very much for your help.
(function(){
$.fn.sctabs = function(options){
var defaults = {
tabsTheme : 'default',
tabsOrientation : 'horizontal', // horizontal, vertical
tabsClassName : 'tab',
contentClassName: 'tabcontent',
activeClass : 'active',
initActiveItem : ':first-child',
tabsEffOpen : 'slideDown',
tabsEffClose : 'slideUp'
};
var options = $.extend(defaults,options);
console.log('Tabs Plugin Successfully Loaded');
// Add Theme
$(this).addClass(options.tabsTheme);
// Set Tabs Orientation
$(this).addClass(options.tabsOrientation);
// Add Initial Classes
$('ul.popuptabslist li').addClass(options.tabsClassName);
$('ul.popuptabsoutput li').addClass(options.contentClassName);
// Assign Tabs/Content to Var
var tabsList = $('ul.popuptabslist li');
var contentsList = $('ul.popuptabsoutput li');
// Set the stopping point dynamically
tabsLength = tabsList.length;
contentsLength = contentsList.length;
// Tabs Loop: Start the index at 0
t = 0;
for (; t < tabsLength; t++) {
tabsList[t].id = "tab" + (t + 1);
console.log('Tab id' + (t + 1) + ' Created');
}
// Contents Loop: Start the index at 0
c = 0;
for (; c < contentsLength; c++) {
contentsList[c].id = "content" + (c + 1);
console.log('Tab Content id' + (c + 1) + ' Created');
}
// Set Initial Item Open
$('ul.popuptabslist ' + options.initActiveItem + ', ul.popuptabsoutput ' + options.initActiveItem)
.addClass(options.activeClass);
// Click Event: Open New Tab
cEvent = 0;
for (; cEvent < tabsLength; cEvent++){
$('ul.popuptabslist li#tab' + (cEvent + 1)).on('click', function(){
// Remove Active Class on Click
$('ul.popuptabslist li.tab').removeClass(options.activeClass);
$(this).parent().parent().find('ul.popuptabsoutput li.tabcontent').removeClass(options.activeClass);
// Add Active Class to Clicked Tab and Corresponding Content
$(this).addClass(options.activeClass);
$('ul.popuptabsoutput li#content' + (cEvent + 1)).addClass(options.activeClass);
$(this).parent().parent().find('ul.popuptabsoutput li#content' + (cEvent + 1)).addClass(options.activeClass);
console.log($(this).attr('id').toUpperCase() + ' clicked');
});
}
};
})(jQuery);
That is the infamous world of closure that you are dealing with. While you are binding event on the tag, the variable cEvent is getting incremented, which mean that each event will have the last instance of cEvent as id.
You can use a self closing function :
(function(cEvent){
$('ul.popuptabslist li#tab' + (cEvent + 1)).on('click', function(){
// Remove Active Class on Click
$('ul.popuptabslist li.tab').removeClass(options.activeClass);
$(this).parent().parent().find('ul.popuptabsoutput li.tabcontent').removeClass(options.activeClass);
// Add Active Class to Clicked Tab and Corresponding Content
$(this).addClass(options.activeClass);
$('ul.popuptabsoutput li#content' + (cEvent + 1)).addClass(options.activeClass);
$(this).parent().parent().find('ul.popuptabsoutput li#content' + (cEvent + 1)).addClass(options.activeClass);
console.log($(this).attr('id').toUpperCase() + ' clicked');
});
})(cEvent);
Fiddle : http://jsfiddle.net/B8e8W/1/

Switch Positions of Tablerows only work once

I have made a jsfiddle
I have a table with articlepositions. And I would made it able that the User can change the position sort by clicking up or down arrows.
But when I swap once the position, i could not change the position of the changed row anymore.
Here is the function:
function switchPosition( data, direction )
{
var tableName = "artikelposition";
currentPosition = parseInt( data['position'] );
if( direction == "up" )
{
newPosition = currentPosition - 1;
}
else if( direction == "down" )
{
newPosition = currentPosition + 1;
}
var otherTr = $("tr[data-position='" + newPosition + "']").data("artikelid");
console.log("clicked object" + data['artikelid'] + " : current position " + data['position'] + " : new position " + newPosition);
console.log("other objekt" + $("#" + otherTr).data("artikelid") + " : current position " + $("#" + otherTr).data("position") + " : new Position " + currentPosition);
$( "#" + data['artikelid'] )
.data({
"position": newPosition
});
$( "#" + data['artikelid'] + " td.tdArticleNumber span.spanPositionNummer" )
.html( newPosition );
$( "#" + otherTr )
.data({
"position": currentPosition
});
$( "#" + otherTr + " td.tdArticleNumber span.spanPositionNummer" )
.html( currentPosition );
sortTable( tableName );
}
As ASGM has already mentioned, problem is with otherTr. In this line:
var otherTr = $("tr[data-position='" + newPosition + "']").data("artikelid");
I still don't know why this expression always returns data-artikelid of first tr, but if you somewhy want to save your code, than you can use replace this line with something like:
$("#artikelposition tr").each(function()
{
var that = $(this);
if (that.data("position") == newPosition)
{
otherTr = that.data('artikelid');
}
});
As Pawel said there in comments, problem is that data-position is set dynamically. But even his idea to use $("...").attr("data-...", value) seems not to work there.
You can probably accomplish this with a lot less code (see jsfiddle):
$(document).ready(function(){
$(".rowUp,.rowDown").click(function(){
var row = $(this).parents("tr:first");
if ($(this).is(".rowUp")) {
row.prev().find(".spanPositionNummer").html(row.index() + 1);
row.insertBefore(row.prev());
} else {
row.next().find(".spanPositionNummer").html(row.index() + 1);
row.insertAfter(row.next());
}
row.find(".spanPositionNummer").html(row.index() + 1);
});
});
You can attach a click handler to the images and user insertBefore() to move the rows. You can also use the built-in index() function (rather than fiddling with data-position) to set the position number span.
(Based on the answer from How to move table row in jQuery?)
Or if you want to do this with your existing code, the bug seems to be that you're selecting the wrong otherTr.
When you first click the down arrow on the top row, you can see in the console that the selected row is moved from position 1 to 2, and the middle row is moved from 2 to 1:
Angeklicktes Objekt2445 : aktuelle Position 1 : neue Position 2 (index):59
Anderes Objekt2501 : aktuelle Position 2 : neue Position 1 (index):60
But when you click the bottom arrow on what's now the top row, this is what the console logs:
Angeklicktes Objekt2501 : aktuelle Position 1 : neue Position 2 (index):59
Anderes Objekt2501 : aktuelle Position 1 : neue Position 1 (index):60
Note that the top row is (correctly) being moved from position 1 to 2. But immediately afterwards, the same row (Objekt2501, referenced by the same position) is instructed to move from 1 to 1.

Event Listeners for multiple objects in a row

I am building a Titanium iOS app. I have a tableview that has two images and some other labels on each row. I want to be able to click on each one of the images and swap for other images and I want to be able to click on a label like a phone number and bring up the dialer. So far, a click anywhere in the row swaps the image. Here is some of my code:
//First I create my table and then call a php file to return some JSON data, then I create my row and define an image
row = Ti.UI.createTableViewRow({
backgroundImage : 'images/openmatchesrowbackground.png',
selectionStyle : Titanium.UI.iPhone.TableViewCellSelectionStyle.NONE,
width : '100%',
height : '180pt',
rowId : i
});
var acceptmatchView = Ti.UI.createView({
left : '0pt',
top : '0pt',
width : '60pt',
height : '60pt'
});
var acceptmatch = Ti.UI.createImageView({
image : 'images/nomatch.png',
left : '0pt',
top : '0pt',
width : '60pt',
action: 'swapImages',
height : '60pt'
});
//Then I add some labels and add everything to the row - Now create my event listener
tableview.addEventListener('click', function(e) {
var imageView = e.row.children[0].children[0];
if (imageView.image == 'images/nomatch.png') {
imageView.image = 'images/match.png';
var matchSelected = json.openmatches[e.rowData.rowId];
var alertWindow = Titanium.UI.createAlertDialog({
title : 'Accept This Match?',
message : 'Are you sure you want to accept this match?' + '\n' + matchSelected.matchtype + '\n' + 'Time: ' + matchSelected.datetime + '\n' + 'At: ' + matchSelected.courtname,
cancel : 1,
buttonNames : ['Yes', 'Cancel']
});
alertWindow.addEventListener('click', function(ev) {
Titanium.API.info("cancel " + ev.cancel);
Titanium.API.info("index " + ev.index);
switch(e.source.action){
//switch(ev.index) {
//case 0:
case 'swapImages':
break;
case 'swapImages':
imageView.image = 'images/nomatch.png';
break;
}
});
alertWindow.show();
} else {
imageView.image = 'images/nomatch.png';
var alertWindow = Titanium.UI.createAlertDialog({
title : 'Cancel This Match?',
message : 'Are you sure you want to cancel this match?',// + '\n' + matchSelected.matchtype + '\n' + 'Time: ' + matchSelected.datetime + '\n' + 'At: ' + matchSelected.courtname,
cancel : 1,
buttonNames : ['Yes', 'Keep Match']
});
alertWindow.addEventListener('click', function(ev) {
Titanium.API.info("cancel " + ev.cancel);
Titanium.API.info("index " + ev.index);
switch(e.source.action) {
case 'swapImages':
break;
case 'swapImages':
imageView.image = 'images/match.png';
break;
}
});
alertWindow.show();
}
});
tableview.setData(tableData);
},
How do I write my code so it can work on each object in the row?
In addition to Dawson Toth's answer, try resetting the bubbleParent property to false. In your case the event might be propagated to the parent. Here you have added eventlistener to the tableViewRow. So each click on the child will be propagated tothe parent. Default value for bubbleParent is true. Setting bubbleParent to false will not propagate the action.
var acceptmatchView = Ti.UI.createView({
left : '0pt',
top : '0pt',
width : '60pt',
height : '60pt',
bubbleParent: false
});
var acceptmatch = Ti.UI.createImageView({
image : 'images/nomatch.png',
left : '0pt',
top : '0pt',
width : '60pt',
action: 'swapImages',
height : '60pt',
bubbleParent: false
});
One approach is to add a property such as action: 'swapImages' to the objects that, when clicked, should swap an image. You can add other ones such as action: 'dial'. Then in your click listener: switch (e.source.action) { case 'swapImages': ... break; ... etc }. This pattern has worked well for me in a number of apps.

Finding the closest, previous element with specific data attribute jquery

This has been troubling me for the passed few hours now.
I have a table. Within that table i'm looking for the closest, previous table row with a specific data attribute. I'm doing this search right after a successful use of jquery sortable. I've tried almost everything and it ALWAYS comes up with the wrong thing.
Here's what i'm using
var newIndex = ui.item.index();
var menuLevel = parseInt($("#menu-table").find("[data-menu-nesting='" + newIndex + "']").attr("data-menu-level"));
var menuId = $("#menu-table").find("[data-menu-nesting='" + newIndex + "']").attr("data-menu-id");
if (menuLevel == 2) {
var findAboveRowName = $(".menu-table-rows[data-menu-nesting='" + newIndex + "']").prev(".menu-table-rows").data("menu-level","1").attr("data-menu-name");
alert(findAboveRowName);
}
if (menuLevel == 3) {
var findAboveRowName = $(".menu-table-rows[data-menu-nesting='" + newIndex + "']").prev(".menu-table-rows").data("menu-level","2").attr("data-menu-name");
alert(findAboveRowName);
}
Essentially, the variable "newIndex" is supposed to grab the new position of the row after being sorted, menuLevel is supposed to grab the data attribute "menu-level" of that table row, and menuId is grabbing another data attribute of that table row.
It's specifically looking for the nearest, previous menu-level attribute in the table rows. So if a table row with a menu-level attribute of 2 is moved, it's looking for the nearest table row with a menu-level attribute of 1.
The full jquery sortable script i'm using if needed
$("#sortable").sortable({
update: function(event, ui) {
var serial = $('#sortable').sortable('serialize');
var newIndex = ui.item.index();
var menuLevel = parseInt($("#menu-table").find("[data-menu-nesting='" + newIndex + "']").attr("data-menu-level"));
var menuId = $("#menu-table").find("[data-menu-nesting='" + newIndex + "']").attr("data-menu-id");
if (menuLevel == 2) {
var findAboveRowName = $(".menu-table-rows[data-menu-nesting='" + newIndex + "']").prev(".menu-table-rows").data("menu-level","1").attr("data-menu-name");
alert(findAboveRowName);
// $.post("./menu-controller.php", { adjustParent: true, id: menuId, parent: findAboveRowName });
}
if (menuLevel == 3) {
var findAboveRowName = $(".menu-table-rows[data-menu-nesting='" + newIndex + "']").prev(".menu-table-rows").data("menu-level","2").attr("data-menu-name");
alert(findAboveRowName);
// $.post("./menu-controller.php", { adjustParent: true, id: menuId, parent: findAboveRowName });
}
$.ajax({
url: "./menu-controller.php",
type: "post",
data: serial,
success: function() {
$("#sortable").load("./menu-manager.php #menu-table", function() {
$.get('./menu-admin.js');
});
},
error: function(){
alert("A problem occurred when moving this menu item. Please try again or contact support.");
}
});
},
handle:'.move-item',
connectWith:'#menu-table',
placeholder: "highlight",
containment: "parent",
revert: true,
tolerance: "pointer",
items: 'tbody > *'
});
JSFIDDLE
.prev only returns the immediately previous element, it doesn't keep looking for the nearest element that matches the selector. Use .prevAll to find all the elements matching a selector, and then use .first() to narrow it down to the first one, which is the nearest. And if you want to search for a specific data-menu-level attribute, you have to put that in the selector; calling .data("menu-level", 1) sets the attribute, it doesn't search for it.
if (menuLevel == 2) {
var findAboveRowName = $(".menu-table-rows[data-menu-nesting='" + newIndex + "']").prevAll(".menu-table-rows[data-menu-level=1]").first().data("menu-name");
alert(findAboveRowName);
}

Categories

Resources