Switch Positions of Tablerows only work once - javascript

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.

Related

Modifying an X and Y variable, based on position in For Loop

EDIT - I don't think I explained it very well the first time.
I have a lot of data - it's in an Array, with each item in the array being an object. In the system I am working in (a control system for A/V devices, which uses JavaScript as the programming language), I am generating buttons based on the length of the array. I want to be able to position a button, and essentially know the X and Y coordinates for each button in the array - with X and Y being Row/Column. (which I then translate to a X/Y pixel position on my UI.
My initial code, which is below, is within a for loop, and I manually calculated the button position. But this is tedious, as I use this same function to show off different groups/sizes of buttons.
Anywhere there is mirage.log = console.log.
The code below is part of a For Loop
button.element.style.position = 'absolute'; //Do to all Buttons.
if (i == 0) //First Item
{
button.element.style.left = btn_Info.startLeft + 'px'; button.element.style.top = btn_Info.startTop + 'px';
}
else if (i <= btn_Info.numRow-1) //First Column.
{
mirage.log('Setting Position of First Column');
button.element.style.left = btn_Info.startLeft + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * i + btn_Info.startTop + 'px';
}
else if (i > btn_Info.numRow - 1 && i <= btn_Info.numRow * 2 - 1)
{
mirage.log('Setting Second column ' + i);
button.element.style.left = btn_Info.startLeft + btn_Info.width + btn_Info.hOffset + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * (i-btn_Info.numRow) + btn_Info.startTop + 'px';
}
else
{
mirage.log('Setting Third column ' + i);
button.element.style.left = btn_Info.startLeft + ((btn_Info.width + btn_Info.hOffset)*2) + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * (i - (btn_Info.numRow*2)) + btn_Info.startTop + 'px';
}
Thanks in advance for the help - I have grabbed so many answers from this forum over the last year, you guys are awesome!
EDIT -
I was able to get some adjustment if I generate rows first then columns:
I was able to get a little close with the help of a friend, and be able to adjust for a 2 column layout by doing the following:
encoder = {
'buttonVals':{'width':125,'height':50,'numCols':2,'numRows':null;'vOffset':10,'hOffset':10}
var posLeft;
var posTop;
posLeft = (i % encoder.buttonVals.numCols) * (encoder.buttonVals.width + encoder.buttonVals.hOffset) + encoder.buttonVals.startLeft;
posTop = Math.floor(i / encoder.buttonVals.numCols) * (encoder.buttonVals.height + encoder.buttonVals.vOffset) + encoder.buttonVals.startTop;
After working on this for a bit - here is the code that I got to work. This prints out both the row position, and the column position.
testFunction = function(incRow, incCol){
var myFunc = {
'testLength':0,
'numRows':incRow,
'numCols':incCol,
'array':[],
};
myFunc.testLength = incRow * incCol;
for(var c=0, posCol = 0, posRow = 0; c < myFunc.testLength; c++)
{
var whichRow;
posRow = Math.floor(c/myFunc.numRows);
whichRow = Math.floor(c/myFunc.numRows) + c;
if (whichRow > myFunc.numRows)
{
whichRow = whichRow - (myFunc.numRows * posRow) - posRow;
if (whichRow === 0)
{
posCol = posCol + 1;
}
}
console.log(c + ' : ' + whichRow + ' : ' + posCol);
}
};
testFunction(6,4);

Find the last element that has appeared DOM html

I have a code that puts images on a table(html), and I want to focus on the image that has just appeared.
I know that i have to use $(this) but i don't know how, here is my code
function positioning(year, mon) {
$('#' + year + ' .' + mon).prepend('<img class="black_point" src="./images/circle.png"/>');//that adds the image
var table = document.getElementById("table");
var images = table.getElementsByTagName("img");
//here I need the current image I had just add to send to that function
function connect(images) {
var tabBcr = table.getBoundingClientRect();
var imgBcr = image.getBoundingClientRect();
x = imgBcr.left + (imgBcr.width / 2) - tabBcr.left;
y = imgBcr.top + (imgBcr.height / 2) - tabBcr.top;
}
}
I hope I have explained well .
I think it will work, add this where you want to get that img element:
var imgelem=$('#' + year + ' .' + mon).find("img:first");

jstree 3 get the position where the target got dropped

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;
});

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/

Button image change on a timer

In my project I have a page which contains 5 image buttons laying horizantally.
When the page loads image on the Button1 should change(remaining 4 buttons remains same).
After 3 seconds Button1 comes back to its original image and image on Button2 will change.
After 3 seconds Button2 comes back to its original image and image on Button3 will change.
And so on..
But After the Button5 is done , It should come back to the Button1 image again.
This should go on in a continuous loop.
Here is my code.But its not working I don't know the reason why its not working.
any help will be appreciated.
Here is my code
$(document).ready(function (){
BeginRotation();
});
function BeginRotation() {
rotateButton(0);
}
function rotateButton(buttonIndex) {
var previousIndex = (buttonIndex + 4) % 5;
var previousCurrentClass = 'main-nav-button' + (previousIndex + 1) + '-on';
var previousNewClass = 'main-nav-button' + (previousIndex + 1);
var currentClass = 'main-nav-button' + (buttonIndex + 1);
var newClass = 'main-nav-button' + (buttonIndex + 1) + '-on';
// alert('Previous Current Class: ' + previousCurrentClass + '\nPrevious New Class: ' + previousNewClass + '\nCurrent Class: ' + currentClass + '\nNew Class: ' + newClass);
$('.' + currentClass).removeClass(currentClass).addClass(newClass);
$('.' + previousCurrentClass).removeClass(previousCurrentClass).addClass(previousNewClass);
window.setTimeout(rotateButton((buttonIndex + 1) % 5), 3000);
}
One thing that is incorrect for sure
window.setTimeout(rotateButton((buttonIndex + 1) % 5), 3000);
It should be
window.setTimeout("rotateButton(" + ((buttonIndex + 1) % 5) + ")", 3000);
I didn't test this code, but something like this should work:
jQuery(function($){
var $btns = $('a.btn');
var index = 0;
setInterval(function() {
$btns.removeClass('rotateThis');
$btns[index].addClass('rotateThis');
index = (index + 1 >= $btns.size()) ? 0 : index + 1;
}, 3000);
});
$('a.btn') being whatever selector works to grab your image buttons of course.

Categories

Resources