AngularJS fixed list with updating content - javascript

Im in need of some inspiration on how to solve the following:
I'm making an information monitor using AngularJS.
The monitor should list a maximum of 6 rows of information.
A new row will always be put on top of the others and pushed in from the top. If there are already 6 rows, the last row will be pushed out from the bottom.
A row may disappear from the list at any given time.
Visually, I would very much like it to be sort of scrolling, so when a new row is to be displayed, it will slide in from the top, and all the items will slide a row down.
I'm not sure how to implement the above. I've thought about ng-repeat, but I don't know how to move the items when an element appears or is deleted.
I hope somebody can give me some advice.

For add new item in top list, use a unshift method of javascript. For example:
var list = [0,1,2]
list.unshift(3)
// results [3,0,1,2]
remember, add and remove items in $scope of list for update her.
$scope.list = [1,2,3,4,5,6];
$scope.list.unshift(9); // [9,1,2,3,4,5,6];
$scope.list.pop(1); // [9,2,3,4,5,6];
In HTML, continue using ng-repeat normally

You're going to want to look at ngAnimate. It has built-in support for working with ng-repeat including animations on the addition and deletion of items from a list.
https://docs.angularjs.org/api/ngAnimate
The docs for the integrations with ngRepeat are here: https://docs.angularjs.org/api/ng/directive/ngRepeat#animations

Related

Highlight last inserted document in Meteor

I have form and list of objects at the same page. When I insert a new row, it is not very easy to see where the newly inserted row is placed. Therefore, I thought I could color/highlight the newly inserted row (and perhaps remove the highlight after a few seconds).
How can I do this? I think a way to do this could be using a method on the server which returns the inserted id (return Collection.insert(doc);) and on the client use a callback with
Meteor.call('insertDoc', function(err,result) {
// do something with result
});
I think I can use a reactive-var to save the id of the last inserted row and in the loop highlight the row with
{{#each docs}}
<li class="{{isActive}}">{{name}}</li>
{{/each}}
and have a helper to return active if this._id equals the reactive var with the last inserted id.
But is this the best way to do it? How can I remove the color after some seconds? I have seen such behaviour on many pages but I cannot find any tutorials/code snippets to achieve this.
I wrote a package that uses Meteor's UI hooks to fade items in and out of a list as they are added and removed, to help users maintain context as data changes:
https://github.com/mizzao/meteor-animated-each
There is a demo at http://animated-each.meteor.com/. You can see that as items are added and removed, they are faded in and out. If items are inserted off the screen, the visible area does not scroll.
This isn't doing exactly what you want, but you can use the same idea to highlight items as they appear as well, as opposed to the simple fade in.
Note that all of this happens at the UI rendering level - not the template/code level. The UI hooks are also not well documented right now, but they've been around for a while.
I don't know if your method is the best, but that's how I'd go about doing it.
As for the animation, I'd use a CSS3 animation. Plenty to choose from ( https://developer.mozilla.org/en-US/docs/Web/CSS/animation ), and you can easily make them fade to the standard color. The animation would also only be applied to the last inserted item (because of the way you did it, only the last item would have the "active" class)

Transitioning between models on a ng-repeat

I'm building a directive (Angular 1.2) that will toggle between displaying two different lists - think of them as a list of "trending" items on the site and a list of items the user is "following". So we have a toggle that allows the user to choose which list is being displayed, with an ng-repeat below it showing the items.
There will be a good deal of overlap between these lists, and when the user toggles from one list to the other, I'd like items that are contained in both to transition from their places on the "outgoing" list to their places on the new one, rather than disappearing and reappearing.
My question isn't about how to achieve the actual animations (we're using ngAnimate), but about how I should structure the controller/data to. I'm thinking about my directive controller having a trendingList and a followingList (that contain the actual data items), and an activeList that points to whichever of the two are currently being displayed. So the ng-repeat is actually on activeList, and toggling is essentially:
$scope.toggleMode = function(){
if ($scope.mode == 'trending')
$scope.mode = following;
$scope.activeList = followingList;
else {/*the inverse...*/}
}
Is that the most reasonable approach? If so, how do I ensure that angular recognizes the equality of objects present in both lists?
Or is there an easier/cleaner way to do this?
From what I understand, angular isn't tracking the equality of objects in the list it is repeating. The animations are triggered when the DOM is manipulated, not when the data changes (though data changes will change the DOM). As to what you should do, I don't have experience with this problem so hopefully somebody can point you in the right direction!

Changing the height of the object being sorted?

I have a JQuery Sortable list with the ability to multi-select objects inside the list and sort them accordingly. This works fine, and is even interacting with a multi-select draggable list, but the one problem I can't seem to find the answer to is how the placeholder decides its position in the list. I currently set the Sortable helper much like you'd expect:
helper: function (e, element) {
var elements = $(element).parent().children('.highlighted').clone(); //all the items which are highlighted
$(element).data('multidrag', elements);
$(element).siblings('.highlighted').remove();
var helper = $("<div/>");
return helper.append(elements);
}
But when I have more than one item selected, and I want to move them down a position, the placeholder does not change. I would like to solve this without changing the size of the placeholder, since I feel that that wastes space. To illustrate what's happening:
Is it possible to register the size of this object as a single item of the list? Or somehow refresh the list so that the sort works as intended? Once a new placeholder is created, this issue disappears, so maybe it's possible to force a redraw on the placeholder? I've looked into each of these avenues, but none seem to be working for me. If more code is required to reproduce this, please let me know.

Unable to update counter value in Jquerymobile list

I have a element that I am trying to update on each creation of an item.
At the moment, a list is populated via a REST API, and I have a script that takes some info from each item, counts another table, and the answer is to populate the counter bubble of the jquerymobile list.
I have searched, and I understand I need to access 'ui-li-count' but I am unable to get to it. I have searched on here and tried many ways, but none actually give me the answer.
Using google console, this is how the element is drawn:
This is how it should look
This is the code I am trying, and failing badly :
console.log('get count : '+$('li[name=mobilelistitem_9]').find("ui-li-count ui-body-b").text());
I need to set the value, but here I am trying to find it, so I know what syntax to use to set the value.
I need this to fire, each time a new item is added to the list collection. Using $(this) or Appery(this) is not working.
Any suggestions on this would hugely welcomed :)
Thanks in advance.
add a . (dot) in the find filter for both the classes, and leave no spaces between them:
$('li[name=mobilelistitem_9]').find(".ui-li-count.ui-body-b").text())
you are searching for a class, that's why you need the dot. No white space = "both classes"
FIDDLE http://jsfiddle.net/z2zJL/1/
I stole the fiddle from ezanker comment, and modified it a bit: as you can see only the 2nd list item will return a result.

jQuery UI Sortable doesn't refresh after cloning and appending a new sortable list

OK, what I'm trying to do here is to have jQuery UI update the sortables that are displayed on the page when a new column is dynamically added to the page by cloning it. If you clone a column (demo page) the new column should be able to receive both items from the existing column lists as well as new items that can be dragged from list A at the top into one of the sortables. This works fine for the initial setup, but as soon as you clone and append a new column, things break; the newly cloned column is not recognized as a droppable target and I can also not drag new items from list A to the newly cloned column list.
Intuitively the sortable('refresh') command should be enough for the sortable to check if anything in the setup is changed and enable new elements to receive and handle sortable items. However, I try to do this when the button is clicked, but there seems to be no effect.
I also tried to bluntly call the whole sortable() plugin on the '.columnlist' selector again, hoping that it would initialize on new matched elements and would simply skip over the elements that have the sortable already.
Oh and of course I use clone(true, true) to make sure events and data come with it.
Please see the demo page here: http://labs.shifthappens.nl/dragsort/
Try the following:
Drag an item from list A to column list A or B. The drag to sortable works
Re-order items in column list A. Sortable works.
Click on the clone button. A clone of column C appears.
Try to drag any item (be it from list A or from another column list) to the cloned column C and behold: it does not respond. It is as if it doesn't exist.
Funny thing: if you already put items in the original column C and then clone it, the items that are in the cloned column CAN be moved to other lists, but once out, can't be moved back to the cloned list. As if it rejects its own offspring.
How can I make the cloned list(s) to be sortable and valid dropzones as well?
As pointed out by jaredhoyt it indeed was about deep cloning. Apparently jquery ui doesn't need deep cloned elements and in fact breaks if you do that and expect the new elements to be droppable targets too.
However I did find the need to do another $('selector').sortable() on the columns for the cloned list to be recognized. This is what jaredhoyt also did in his fiddle. This while for me intuitively the 'refresh' method would be the most elegant solution, no?
Anyway, case closed. I'm happy it was as simple as not cloning the column with data and events, just the HTML.

Categories

Resources