Visual feedback for value update - javascript

I have contenteditable td elements in a table. I'm using bootstrap and table-hover (so the colour changes when you hover over a row. On blur of the td I do an ajax request that updates the value on the server and then I get a response that indicates success or the error. On success I want to indicate that the value has updated successfully. Right now I'm doing this:
var trueColor;
trueColor = $(element).css('backgroundColor');
$(element).animate({
backgroundColor: '#cce2ff'
}, {
duration: 100,
complete: function() {
$(element).delay(10).animate({
backgroundColor: trueColor
}, {
duration: 900
});
}
});
So I'm using the complete callback of the first animate to put the colour back to what I want it to be. The code works but the problem is obviously if you're hovering over the element when it sets trueColor. I've thought of using css animations but the main thing was that I didn't know how to get a "flash" kind of effect (I think maybe keyframes would help but I don't know how to use them let alone how browser compatible they are).
So the question is basically how do I achieve the effect? I don't mind whether it's css or javascript and I welcome superior suggestions if you think there's a better way to give this sort of visual feedback to a user.
Update
Thanks to #chiliNUT I am removing the class to get the colour but the problem was then that jquery's animate had styled the element and so hovering was broken on modified cells. So now I also removeAttr("style") to get rid of that once we're done
var trueColor;
$(el).closest('table').removeClass('table-hover');
trueColor = $(el).css('backgroundColor');
$(el).closest('table').addClass('table-hover');
$(el).animate({
backgroundColor: '#cce2ff'
}, {
duration: 100,
complete: function() {
$(el).delay(10).animate({
backgroundColor: trueColor
}, {
duration: 900,
complete: function() {
return $(el).removeAttr("style");
}
});
}
});

You can remove the hover effect while its doing the display update, then restore it once the display update finishes. You can get the table element containing the td with $(element).closest('table') and then remove the hover effect with removeClass('table-hover') and then put it back with addClass('table-hover'), so
var trueColor;
//remove hover
$(element).closest('table').removeClass('table-hover');
//get original color
trueColor = $(element).css('backgroundColor');
//restore hover
$(element).closest('table').addClass('table-hover');
//..rest of your original code

Related

Since updating animejs my javascript no longer functions

Essentially I had an 'animejs' animation trigger when the nav button is clicked and then the same animation would reverse after a second click. It would toggle. Now this no longer works after updating animejs.
I've tried using a variable such as
var playing = true; and to toggle between it but that doesn't possess the same functionality as before.
the code looked something like this (this is simplified)
var navAnimation = anime.timeline({
duration: 100,
});
animation.add({
targets: 'navStuff'
//animation would be here
});
document.querySelector('.nav').onclick = () => {
animation.play();
// animation.play still functions properly
animation.reverse();
// animation.reverse(); is broken
};
//before the update you could simply place a two methods within the onclick function and it would toggle between them but that no longer is the case with animejs
What I want to happen is to be able to use a single target (button) to open my navigation and close it (toggle between the two state). I want to be able to spam the button and not see and glitches (as before).
Please beleive me I've spent an uncessary amount of time trying to get this working and it just refused to giv in.
I've attempted working with heights / transforms / colors, variable diffs, close inspection. Nothing works.
This is how I animate "reverses" now:
const notificationsContainerElement = document.querySelector('#demo-install-notifications-container');
let notificationsContainerAnimation = anime({
targets: notificationsContainerElement,
height: '350px',
easing: 'easeOutElastic(1.5, .5)',
duration: 1500,
delay: 0,
autoplay: false,
});
notificationsContainerElement.addEventListener('click', () => {
if(notificationsContainerAnimation.began === false) {
notificationsContainerAnimation.play();
} else if(notificationsContainerAnimation.began === true) {
notificationsContainerAnimation.began = false;
anime({
targets: notificationsContainerElement,
height: '100px',
easing: 'easeOutElastic(1.5, .5)',
duration: 1500,
delay: 0,
});
}
});
My first animation is autoplay: false, then, when I click an element, I .play() that animation, but notice the checks for the original animation's began. Once you hit play on an animation, the began property keeps changing.
Right...
But just doing notificationsContainerAnimation.reverse() on my animation just doesn't work no matter what. It just doesn't. I strongly believe it has to do with anime not being able to get where it's supposed to actually reverse to - the values.
The logic is sound, there's no way why it shouldn't work...but it doesn't.
So, for now, use 2 animations.

jQuery animate element and hide

I'm building Windows 8 app in JavaScript. What I'm trying to do is to slide the html element out of the screen and then change its "display" property to "none":
var panelContainer = $('#panelContainer');
panelContainer.animate({ right: '-400px' }, 200, function () {
panelContainer.hide();
});
But this code doesn't work correctly: it just immediately hides the element without animation.
I've also tried:
var panelContainer = $('#panelContainer');
panelContainer.animate({ right: '-400px' }, 200, function () {
panelContainer.hide(200);
});
and it works, but it's a hack: I don't want to change the opacity when animating and I don't need to have additional timeout for hiding.
I've found that jQuery UI library has extended show and hide methods that do that, but I would like not to reference this library just for one call. I'm aware that there is a WinJS.UI.Flyout that performs similar operation, but it's not applicable in my case. Any ideas how this can be done?
The problem was that jQuery does not put hide animation into its animation queue by default. That's why my initial code was hiding the html element first and then animating it. The solution for that is to call hide with the parameter that explicitly specifies that hide call should be queued:
panelContainer.hide({queue: true});

Dynamically change the location of the popover depending upon where it displays

I'd like to dynamically change the popover placement (left/right, top/bottom) depending on where the element is located on the screen.
//get_popover_placement(dom_el) returns 'left', 'right', 'top', or 'bottom'
function set_popover(dom_el) {
var the_placement = get_popover_placement(dom_el);
$(dom_el).popover({
offset: 10,
placement: the_placement
}).popover('show');
}
//set the placement on every hover
$('a[data-rel=popover]').hover(function(){
set_popover(this);
}, function(){});
It works the first time, but if the position of the element changes (when the window is resized, for example), the placement is not updated with subsequent calls to set_popover.
I added a little bit of code to get_popover_placement that adds a different color border to the element, depending on the placement. The border color gets updated every time, indicating the code is being called and the calculations are being done correctly, but the placement does not get updated.
It appears as though the placement option can only be set one time. How can I get around this limitation? Is there a variable somewhere that can be cleared to reset popovers?
Try this change, using the .on() function in jQuery to attach an event listener:
Changed this reply by updating Kevin Ansfield's - added code to the placement function.
$('a[data-rel=popover]').popover({
placement: get_popover_placement
});
function get_popover_placement(pop, dom_el) {
var width = window.innerWidth;
if (width<500) return 'bottom';
var left_pos = $(dom_el).offset().left;
if (width - left_pos > 400) return 'right';
return 'left';
}
I just checked the bootstrap source again and realised that functions passed to the placement property get passed arguments. I managed to achieve a similar thing to what you were attempting, try the following and see if it works for you:
$('a[data-rel=popover]').popover({
offset: 10,
placement: get_popover_placement
});
function get_popover_placement(pop, dom_el) {
// your placement function code here
}

grumble.js, jQuery plugin (Bubble popups): how to make it not polute my document body with unremovable trash?

I want to show a popup many on click. I want that many to be in a bubble. So I created a demo: here. But that Bubble generator plugin i use tends to keep tons of trash in the DOM each time it shows a popup. Well so I tried to destroy trash via
$('.grumble-text').remove();
$('.grumble').remove();
$('.grumble-button').remove();
But it somehow brakes it at all=( So how to change grumble-bubble popup plugin code to make it either keep DOM clean or at least make plugin independent of trash it creates?
I've recently updated the plugin to provide better control of positioning and angle. The update also persists the grumble, invoking the plugin more than once on an element will not create extra left over DOM.
Try updating to the latest code. The code below should now work as you expect.
var html = ''
+'Download me'
+'<br/>'
+'Edit me'
+'<br/>'
+'Delete me';
var $grumble = $('#grumble3');
$grumble.mouseup(function(eventObj) {
$grumble.grumble({
text: html ,
angle: (Math.random() * 360 + 150),
distance: 30,
hideOnClick: true,
onShow: function() {
$grumble.addClass("hilight");
},
onBeginHide: function() {
$grumble.removeClass("hilight");
}
});
}).mousedown(function() {
$grumble.addClass("hilight");
});
Thanks for your interest. If there are any further problems please raise them as bugs on the github page. https://github.com/jamescryer/grumble.js
Use the grumble and button parameters on the onHide callback like this:
$('#grumble').grumble({
text: 'Whoaaa, this is a lot of text that i couldn\'t predict',
angle: 85,
distance: 50,
showAfter: 4000,
hideAfter: 2000,
onHide: function(grumble, button) {
grumble.bubble.remove();
grumble.text.remove();
button && button.remove();
}
});
This allows you to remove only the "trash" (I prefer "leftovers") associated with that specific tooltip/popup/bubble. Note that button only exists if hasHideButton is true, hence the button && existence check.
Why do you want to remove it? Is the 'trash' causing problems with browser performance?
In general, the only way to do this is to dig into the plugin source and add a function to remove the plugin, if one is not already present. If you just remove the related DOM elements you will leave behind references to them and events handlers that access them.

make qtip disappear right away

so I want the following behavior out of qtip:
the qtip should show up when I click on the object (I got this working without problem)...but then I want to have it disappear after a few miliseconds without me having to do anything....how would you go about configuring qtip to do this?
i tried
hide: {
when : 'inactive',
delay : 100,
fixed: false
}
but it's not working....
any help would be appreciated...thanks
If you only want the tooltip to flash on screen:
$(".tooltip").qtip({
content: "Test tooltip",
api: {
// As soon as the qtip is fully visible..
onShow: function (event) {
// Keep a reference to the qtip..
that = this;
// After 1ms (to let things settle down)
setTimeout(function () {
// Hide the qtip
that.hide();
}, 1); // change this value to have it stay on screen longer
}
},
show: "mouseover"
});
I know this is an old question but just in case someone passes by, the right way to do it in qTip2 is: (events instead of api)
events: {
show: function(event, api){
var that = this;
setTimeout(function () {
// Hide the qtip
that.hide();
}, 3000); // change this value to have it stay on screen longer
}
}
I think your code is correct, but the delay is causing problems. 100ms is only 0.1 seconds, so maybe the qtip is taking longer than that time to render, in which it won't exist yet when it's told to hide itself (just a guess).
I would increase the delay (you probably want your users to see the tip for a few seconds anyway) and see if that helps. Here's an example that uses 1000ms: http://jsfiddle.net/andrewwhitaker/dVEYq/

Categories

Resources