Dragula and DOM-Autoscroller in MVC, no Angular - javascript

Trying to get DOM-Autoscroller to work with Dragula.
We have Dragula up and running. I've managed to get the syntax to Autoscroller correct, so that it doesn't break Dragula. But Autoscroller doesn't appear to be doing anything.
Our Autoscroller call is reasonably close to the example.
$(document).ready(function () {
var drake = dragula({
containers: Array.prototype.slice.call(document.querySelectorAll('[id^="checklistItems-"')),
revertOnSpill: true,
direction: 'vertical',
accepts: function (el, target, source, sibling) {
return target == source;
}
})
.on('drop', function (el, target, sibling) {
var destinationIndex = [].slice.call(el.parentElement.children).indexOf(el);
// call AJAX with element id and destination index
$.ajax(
{
url: "#Url.Action("ReorderTicketChecklist", "Tickets")",
data: { checklist_ID: el.parentElement.dataset.checklistid, checklistItem_ID: el.dataset.id, destinationNum: destinationIndex+1 },
error: function () {
alert("Something went wrong reordering the list. Please refresh and try again.");
}
})
});
var scroll = autoScroll([
//Array.prototype.slice.call(document.querySelectorAll('[id^="checklistRow-"'))
document.querySelector('#checklistRow-100')
], {
margin: 20,
pixels: 10,
scrollWhenOutside: true,
autoScroll: function () {
return this.down && drake && drake.dragging && drake.drake && drake.drake.dragging;
}
});
})
I currently have the first list hard-coded, and I can work on the syntax for the rest, later.
I guess I mostly need some advice on how to debug this. What can I do to shake the box and get some behavior out of Autoscroller, so I can track down what's wrong?

Related

Is my jQuery load request being called twice?

I have this website: http://wearewebstars.dk/poc/index.html
If you click the top menu, then it makes an Ajax request to another page. And if you click again, a new request to another page and so on...
However, it seems, that If I click the top navigation once, then it loads the new page, and then if I click on another link in the top navigation, then it seems that it loads the page twice or something? I cant quite figure out why it does this?
If you start by clicking "Omgivelserne", and after that click "Skriv dig op", then the page "Skriv dig op", seems to be loading twice, judging from the fade transitions?
My JS for the Ajax and Transitions (Edited to only show relevant code):
var DIS = DIS || {};
// create a timeline
var tl = new TimelineMax();
(function($, DIS, window) {
var graphic = $("div.page-transition");
DIS.PageTransitionStart = {
start: function(url) {
$this = $(this);
var pageTransitionStart = new TimelineMax({
onComplete: DIS.loadPage,
onCompleteParams: [url, $this]
});
pageTransitionStart.add(TweenMax.set($("body"), {
className: "animating"
}));
pageTransitionStart.to(graphic, 0.3, {
css: {
scale: 50,
opacity: 0.5,
force3D: true
},
ease: Power1.easeOut
});
pageTransitionStart.to(graphic, 0.5, {
css: {
scale: 130,
opacity: 1,
force3D: true
},
ease: Power1.easeOut
});
//tl.add(pageTransitionStart);
},
toggleSelectedClass: function(el) {
$("#mainmenu").find("a").removeClass("selected");
el.addClass("selected");
}
};
DIS.PageTransitionEnd = {
end: function(el, url) {
var pageTransitionEnd = new TimelineMax();
pageTransitionEnd.add(TweenMax.to(el, 0.3, {
css: {
scale: 1,
opacity: 1
},
ease: Power4.easeOut
}));
pageTransitionEnd.add(TweenMax.to(el, 0.1, {
onComplete: function() {
TweenMax.set($("body"), {
className: ""
}); // then only replace with blue div with new height and width
}
}));
//tl.add(pageTransitionEnd);
}
};
DIS.TopNavigation = function() {
$(".nav a").click(function(event) {
event.preventDefault();
$url = $(this).attr("href");
DIS.PageTransitionStart.start($url);
});
};
DIS.loadPage = function(url, el) {
var div = url + "#pages-container .content";
//var title = el.attr("title").replace(/\s/g, ''); //Remove spaces from Title
$(".content").load(div, function(response, status, xhr) {
if (status == "success") {
//alert("test");
//window.location.hash = title; // Adds a hash to the URL
console.log(xhr.status);
DIS.PageTransitionEnd.end(graphic, $url);
DIS.PageTransitionStart.toggleSelectedClass(el);
DIS.init();
} else if (status == "error") {
alert("Vi kunne desværre ikke hente siden - Kontakt venligst Living Homes");
console.log(xhr.status);
console.log(xhr.responseText);
console.log(response);
return;
}
});
};
DIS.init = function() {
DIS.TopNavigation();
if ($(window).width() > 768) {
DIS.pageNavigation();
}
DIS.TextEffects();
DIS.slider();
};
}(jQuery, DIS, window));
$(function() {
DIS.init();
});
If you change the following, I assume there would be no more "double clicks". This will make sure that TopNavigation() is only fired once, and not binding two click-events to the menu links.
DIS.init = function() {
//DIS.TopNavigation();
if ($(window).width() > 768) {
DIS.pageNavigation();
}
DIS.TextEffects();
DIS.slider();
};
and
$(function() {
DIS.TopNavigation();
DIS.init();
});
Not the best thought out solution, but it's a way to confirm where the problem lies.
Edit: Once confirmed that this is indeed the problem, the next step would be to make sure that DIS.init() is only used to reset states/variables, and that it doesn't create a lot of double bindings or conflicting events.
You can handle this by adding a...
$(".nav a").unbind("click");
But if there is no specific reason to unbind & rebind, it's better to just leave it be and fix the structure instead.
Ok, So I finally figured out the problem. It seems that there was a problem with some naming conventions. I was trying to load .content into .content, and that was caused the problem. I changed the class name on the div I was loading .content into, and that solved the problem.

jQuery UI Tooltip - Return Position Values

I'm trying to do what seems to be a simple task that would, in theory, return the "my" and "at" values of the position method for the tooltip based on the parent of the hovered element that initializes the tooltip but I'm not sure exactly how to do this.
var s,
TooltipController = {
settings: {
tooltips: '[data-tooltip]'
},
init: function () {
s = this.settings;
this.bind_ui_actions();
},
bind_ui_actions: function () {
$(s.tooltips).tooltip({
content: function () {
// Only return a tooltip if the content is truncated
return ((this.offsetWidth < this.scrollWidth) ? $(this).data('tooltip') : false);
},
items: '[data-tooltip]',
open: function (event, ui) {
// If tooltip resides in a <th /> then use animations else dontuse animations
var parent = TooltipController.get_tooltip_parent($(this));
return ((parent == 'TH') ? ui.tooltip.animate({ top: ui.tooltip.position().top + -10 }, "fast") : false);
},
position: function(event, ui) {
var parent = TooltipController.get_tooltip_parent($(this));
var top_pos = ((parent == 'TH') ? '+10' : '');
return { my: 'center bottom', at: 'center top' + top_pos };
},
show: { duration: 0 },
tooltipClass: 'tooltip'
});
},
get_tooltip_parent: function ($this) {
return $this[0].nodeName;
}
}
If I add console.logs to each of the methods I can see that the position method doesn't even get hit and I'm not exactly sure why. I'm sure this is a simple noob mistake but I'm just not understanding whats happening. Thanks in advance!

Jquery: Uncaught RangeError: Maximum call stack size exceeded

Here is my javascript. It was working well prior to conducting a Git Pull from my partner. On a click the hint loads with fancy box. The load does not work now.
Game = {
loadLevel: function(levelNum) {
$("#level").load("/level/" + levelNum + "/", function() {
// disable all hints except the first
$("#level .hint:not(:first)").prop('disabled', true);
// clicking a hint displays the hint
$("#level .hint").each(function(index, el) {
$(el).fancybox({
href : $(el).attr("data-url"),
type : 'ajax',
});
});
// enable next hint when clicking on a hint
$("#level .hint").on("click", function() {
$(this).next().prop('disabled', false);
});
// if answer is correct load next level
$("#answer").on("click", function() {
$.get("/answer/" + levelNum + "/", {
guess : $('.guess').val()
}, function(answer) {
console.log(answer);
if (answer) {
Game.loadLevel(levelNum+1);
}
});
});
});
},
}
From the error message, it sounds like your partner's code either has an infinatly looping recursive call somewhere or is calling too many functions deep.
Try this:
loadLevel: function(levelNum) {
if (levelNum > 5) return;
$("#level").load("/level/" + levelNum + "/", function() {
I think the problem might be here -- but it could be in code you don't show:
Game.loadLevel(levelNum+1);
This will recurse but there is no way to stop it.

Backbone events not firing after on demand loading element

I'm using backbone and lazy loading views in a single page application as I need them. However, it appears doing this seems to be confusing the way backbone knows what my 'el' is when setting up events. Using the view definition below, I'm trying to get the code that fires on the submit button click or the input fields changing but right now, neither appear to work.
$(document).ready(function () {
editaddressView = Backbone.View.extend({
elementReady: false,
initialize: function () {
this.model = window.AccountData;
this.listenTo(this.model, "change", this.render);
if ($('#section-editaddress').length == 0) {
// Load UI
$('#ajax-sections').prepend('<div class="section" id="section-editaddress" style="display: none;"></div>');
}
this.el = $('#section-editaddress');
},
events: {
"click #edit-address-submit": "beginSaving",
"change input": "updateModel",
"change select": "updateModel"
},
render: function () {
$(this.el).find("[name=address]").val(this.model.get('owner_address1'));
// ...
return this;
},
switchTo: function () {
// Set menu state
$('.js-NavItem').removeClass('active');
$('#sN-li-personal').addClass('active');
if (this.options.isPreLoaded)
this.elementReady = true;
if (this.elementReady) {
this.renderSwitch();
}
else {
var model = this;
$('#section-editaddress').load('/ajax/ui/editaddress', function (response, status, xhr) {
if (status == "error") {
$('#page-progress-container').fadeOut('fast', function () {
$('#page-load-error').fadeIn('fast');
});
} else {
$('#section-editaddress').find('.routedLink').click(function (e) {
window.Router.navigate($(this).attr('href'), true);
return false;
});
model.delegateEvents();
model.elementReady = true;
model.render(); // First render
model.renderSwitch();
}
});
}
},
renderSwitch: function () {
// Abort showing loading progress if possible
if (window.firstRunComplete) {
clearTimeout(window.pageHide);
// Change screen - Fade progress if needed
$('#page-progress-container').fadeOut('fast', function () {
$('#page-load-error').fadeOut('fast');
var sections = $(".section");
var numSections = sections.length;
var i = 0;
sections.hide('drop', { easing: 'easeInCubic', direction: 'left' }, 350, function () {
i++;
if (i == numSections) {
$('#section-editaddress').show('drop', { easing: 'easeInExpo', direction: 'right' }, 350).removeClass('hidden');
$.scrollTo($('#contentRegion'), 250, { margin: true });
}
});
});
}
// Switch complete
window.changingPage = false;
},
updateModel: function () {
var changedItems = {};
if (this.model.get('csrf') != $(this.el).find("[name=csrf]").val())
changedItems.csrf = $(this.el).find("[name=csrf]").val();
// ...
},
beginSaving: function () {
alert('test');
}
});
});
Can anyone see what I've missed?
Whenever you need to change or modify the DOM element of a BackboneJS view manually, you should use setElement rather than setting the property directly. It moves all of the event handlers to the newly attached DOM element and also sets the $el property. In addition, the function also detaches any existing event handlers.
So, in the code you pasted, you'd just change it to:
this.setElement($('#section-editaddress'));

jsTree drag_check not working

I have a jsTree using the dnd plugin to allow for drag and dropping of tree items to change their position. However I have noticed that the index is wrong depending on whether you drop the item before or after an object and after googling for many hours about how to fix the index issue, I have come to the conclusion that it would be easier to disable the after unless it is the last tree node of the subset
I am using the following code to call the configure the dnd plugin:
'dnd': {
'drop_finish': function (data) {
alert("hi");
},
'drag_check': function (data) {
alert('hi1');
if (data.r.attr('id') == 'RootNode') {
return false;
} else if (data.r.hasClass('jstree-last')) {
return {
after: true,
before: true,
inside: true
};
} else {
return {
after: false,
before: true,
inside: true
};
}
}
}
however, the hi1 never gets alerted (but the hi does after I have dropped the item) so I can still drop after elements. I have tried finding out how to get the drag check to be called and tried many things like adding the jstree-drop class and other things that have been suggested on this site but I just can't get the hi1 to be alerted.
Any help would be appreciated in solving this problem
Thanks
it looks like "dnd" plugin is using for external drag and drop.
You can use check_move to prevent moving to the last position in node:
"crrm": {
"move": {
"check_move": function(m) {
var length = $(m.np).find("ul:first > li").length,
afterLast = length == m.cp;
if (length > 0 && afterLast) {
return false;
}
return true;
}
}

Categories

Resources