In my Meteor template, I am using each to iterate over a helper array variable named asks whose array contents are dynamically changing. This is displaying properly in Meteor, however, by default, there is no animation to it. The changes are sudden, so it's hard to see exactly what is changing when. I would like to animate these data changes in the template. If asks[1] is the same, do nothing. But if asks[2] has changed, fade out the old <tr> for asks[2] and fade in the new <tr> with the new asks[2] values. How can this be achieved? Thanks!
{{#each asks}}
<tr class="ask">
<td>{{price}}</td>
<td>{{amount}}</td>
</tr>
{{/each}}
Use the _uihooks - here's a great article describing it:
http://www.webtempest.com/meteorjs-animation
Also, this package may be of help: https://github.com/gwendall/meteor-template-animations It is DOM based and internally uses uiHooks, but simpler to use.
Another option added to the mix for animations, which imports Animate.css can be found here https://github.com/webtempest/meteor-animate.
Related
I've been a C/C++ coder for a long time, but am new to Angular2 and TypeScript. I have a TypeScript class (call it Node) which has a type: string property that specifies what sort of node it is. (The data comes as JSON from a server, and is basically being parsed out as a syntax tree.)
What I'm doing now in the view template in order to choose the view for each Node object is using an ngSwitch to check the value of node.type, and then inserting the appropriate selector using ngSwitchCase for each possible case, e.g.:
<div [ngSwitch]="node.type">
<node-type-a-view *ngSwitchCase="'a'" [(node)]="node"></node-type-a-view>
<node-type-b-view *ngSwitchCase="'b'" [(node)]="node"></node-type-a-view>
<node-type-c-view *ngSwitchCase="'c'" [(node)]="node"></node-type-a-view>
<div class="debug" *ngSwitchDefault>
TODO: View for type "{{node.type}}" is missing
</div>
</div>
The problem is that there are over a hundred different node types, and so this is going to be very unwieldy, very quickly.
What I'd like to do is something like this (but obviously this doesn't work in Angular2):
<node-type-{{node.type}}-view [(node)]="node"></node-type-{{node.type}}-view>
Or, using an attribute selector:
<div node-type-{{node.type}}-view [(node)]="node"></div>
Is there any functionality that comes close to what I'm looking for? I don't need to dynamically create the node-type-*-view views themselves, just the template that references them.
Also, apologies if I'm getting this architecture completely wrong. I'm still wrapping my head around the way Angular2 does things!
Thanks for any assistance you can give!
if it's jquery, we can do like $('table-row').clone().preprenTo($('table'));
I know it's just push a new value into an object in adding new data but I want to first insert the empty row and field first, how to add that html with angularjs?
John added a link to a famous question/answer regarding AngularJS. I would advice you to read that.
That said, to answer your question - in angular you do not tell it how to manipulate the dom. You tell it what data you have and how you want it presented.
I can only guess to what you are trying to do, but if you have a template (your 'table-row') and a 'destination' ('table') you would describe it in AngularJS like this:
<table ng-controller="PersonsController">
<tr ng-repeat="person in persons">
<td>{{person.Name}}</td>
<td>{{person.Address}}</td>
</tr>
</table>
That is great, but how do you add a row? Well you don't "add a row" - you add a person and AngularJS will do the adding of rows for you. You already explained how you want a person displayed.
To add a person you would have to add a person to a list/array of persons and that list would be in the scope of your view/application.
persons.push({Name: 'Bill', Address: 'Somewhere'});
You will need to attach the persons to your scope, which you will do in a controller. A controller would have to be associated with the code above with the ng-controller directive.
app.controller('PersonsController', function ($scope) {
$scope.persons = [];
});
In the above code i assume you have a variable app pointing to your angular application. There is a small learning curve you will have to overcome, going from jquery to angular. Mostly, the way i see it, is moving your mindset from a imperative coding style to a declarative coding style.
I suspect you need a paradigm shift. Read "Thinking in AngularJS" if I have a jQuery background.
Then, if you still think that your problem is best solved by adding a row to the DOM, consider using an AngularJS directive.
In JavaScript we can create <style> element dynamically and append to <head> section in order to apply CSS rule for huge number of elements.
What is advantages or disadvantages of this approach?
If it is really gives performance gain comparing to javascript iteration over elements. What goes behind the scene (inside of browser)?
Which one is faster or slower? Javascript iteration over elements or adding css dynamically in browser?
What about processing time? processing load?
For better understanding the issue where I used this approach see following example:
Example: If I have table with 20 or more columns and 1000 rows or more as following html:
<table border="1" class='no-filter'>
<thead>
<tr>
<th data-title='id'>Id</th>
<th data-title='name'>Name</th>
<th data-title='family_name'>Family Name</th>
<th data-title='ssn'>SSN</th>
//Other table data
</tr>
</thead>
<tbody>
<tr data-id='1' data-name='nick' data-famil_name='jackson' data-ssn='123456'>
<td class="column column1">1</td>
<td class="column column2">Nick</td>
<td class="column column3">Jackson</td>
<td class="column column4">123456</td>
//Other table data
</tr>
//Other rows
<tr data-id='809' data-name='helga' data-famil_name='jhonson' data-ssn='125648'>
<td class="column column1">809</td>
<td class="column column2">Helga</td>
<td class="column column3">Jhonson</td>
<td class="column column4">125648</td>
//Other table data
</tr>
//Other rows
<tr data-id='1001' data-name='nick' data-famil_name='jhonson' data-ssn='216458'>
<td class="column column1">1001</td>
<td class="column column2">Nick</td>
<td class="column column3">Jhonson</td>
<td class="column column4">216458</td>
//Other table data
</tr>
//Other rows
</tbody>
</table>
If somebody needs jsFiddle example I can create one later.
Case 1: If i want to dynamically hide only table column which contain SSN data. I can apply several approach to do this. This approach can be divided into two major category. In first category solutions I can iterate over td elements and dynamically change the style for the column. In second approach I can apply CSS by dynamically creating oneor use predefined CSS rules as given here by #Frits van Campen. (Note: #Frits van Campen is good solution for given case. But I want to discuss further more then manipulating table row showing and hiding.)
I can create dynamic CSS rule as following:
td:nth-child(3)
{
display:none;
}
Or apply predefined CSS rule:
table.no-filter td.column3
{
display:block;
}
table.filter3 td.column3
{
display: none;
}
Here are jsFiddly examples:
Iteration
CSS on fly
Here is time comparison using console.time method which I found here.
Left is dynamic css and right is iteration approach.
Perhaps, it is not appropriate one because it calculates appending style element vs iterating over elements. All iteration over element in dynamic CSS will be done by browsers internals. However if we think our script response time dynamic css is faster. Note: iteration approach will be faster in pure JavaScript comparing to jQuery. But how much faster i do not have results. So you can more in your answers.
Case 2: Now, I want to highlight table row <tr> which contains user with name 'Nick'. Here you can note that table row has data attributes like name, family_name, id and etc. So, here again I can iterate over elements using javascript or any other library tools or can apply some dynamic rule (I do not know whether it is possible or not apply predefined filters as in case 1.)
CSS rule:
tr[data-name ~='nick']
{
background-color:red;
}
In this case I can do a lot of fun filtering by applying CSS rule dynamically.
Update: Example given here is for simple overview of the problem. And some optimized iterations can perform equally fast in javascript. However I consider only table which does not have dipper child elements comparatively nested ul elements where traversing in order to select element can be difficult.
Important: I only give tabel example here to make clarification with what kind of issue I faced if it is irrelevant feel free to edit the question and delete this part. Also please state your answers clearly in scope of question. Here I am not asking about 'Did I implemented in good way or not?' I am asking what is of advantages or disadvantages of dynamically creating style elements has in terms of browser internal mechanisms.
P.S. and example: Why I came with this idea? I answer recently for 'How to hide columns in very long html table' question. In this question OP asks about applying CSS rule for certain table columns in long table. I suggest to create style element with rules on fly and it works fine. I think this is because style applied by browsers internal mechanisms and gives better performance than iterating through elements and applying style to each item.
Apart from some scoping issues (there might be more tables on the page...) there is nothing inherently wrong with this approach - the style elements are there in the DOM to be edited as you see fit, the browsers are following standards by respecting it. In your test case, there's not really a valid other approach since indeed colgroup has extremely messy support - there are 78 duplicate bugs on the subject in Bugzilla, and Mozilla has been refusing to implement it properly since the first related bug report in 1998.
The reason it's faster is simply one of overhead - once the complete DOM is assembled a relatively minor stylesheet can be applied in native C++ much faster than a Javascript interpreter can ever loop over all rows and cells. This is because historically CSS rules are applied in reverse, and the browser keeps a dictionary inside quickly allowing it to find all td elements. Native C++ will always beat more complex interpreter-based code.
In the future, the scoping issue can also be resolved with scoped styles (currently only in FF, rather typical), you'd be coding like this:
<table>
<style id="myTableStyle" scoped>
td:nth-child(1) { display:none }
</style>
<tbody>
...
</tbody>
</table>
The scoped attribute makes the contained styles only valid for its containing element, the table in this case, and of course all its contained elements. And since you can access it by ID the contents are easily replaced/reconstructed.
While this would be preferable to your approach, as long as there's no universal browser support for this creating style elements in the head is the best workaround.
Dynamically generating CSS is bad. Don't do it.
A solution that works by generating dynamic CSS can converted to a solution that doesn't require dynamic CSS.
If you need an example, see my answer here: jQuery to update actual CSS
To respond directly about the case you linked:
This seems like a very strange use-case to me. A page that has a table with 1000 rows is already a bad starting position. You can't reasonably fit 1000 rows on your screen and expect any kind of useful interaction. CSS is not the problem here. If the table were smaller the performance concerns disappear.
There are possibly other approaches than the on OP suggests. You don't need to (dynamically) add a class to each cell, you can put the class there on generation time, like:
<table class="no-filter">
...
<td class="filter1 filter2"></td>
...
</table>
Then have something like:
table.filter1 td.filter2 { display: none; }
table.filter2 td.filter1 { display: none; }
You only change the class on the table to say which filter applies.
CSS is more than just a hammer, it's a whole tool-set of very refined and very powerful tools. Make sure you use the right ones.
The advantages of having static CSS should be self-apparent:
Much easier to understand, test, debug and maintain.
The CSS is actually in CSS (not in JavaScript).
You can do templating, maybe add some visual regression tests.
There are also some performance concerns. I can see browser vendors optimizing AGAINST dynamic CSS. By this I mean if there is an optimization for static CSS that reduces performance of dynamic CSS you just might make this tradeoff.
There's a library called less.js which lets you manipulate css with variables in in your.css file.It's a very good library and you might want to take a look into that.
http://www.lesscss.org/
I have one knockoutjs observable variable called "state" and i am using that variable to hide and show content in knockout with if condition like below:
<--if: state()=="login" -->
login content
<--/if-->
<--if: state()=="registration" -->
registration content
<--/if-->
whenever state variable changes it shows or hides the content. So my question is that i want to add animation of toggling behavior when it hides or shows for this. how would i be able to do it?
I did a quick fiddle for you.
http://jsfiddle.net/ujSvb/1/
for a more dynamic example
http://jsfiddle.net/ujSvb/2/
I further updated Anders' fiddle to add the state condition:
http://jsfiddle.net/ujSvb/3/
First, I think you may have some error in your code there(may have just copied it over wrong) but it should be:
<-- ko if: state()=="login" -->
login content
<--/ko-->
<-- ko if: state()=="registration" -->
registration content
<--/ko-->
Second, if you can use jQuery along with binding on elements instead of using virtual elements such as:
<div data-bind="if: state()=="login">
You can utilize Knockout's bindingHandlers. I have created an ifTransition binding which does what you want. Here's a fiddle with the bindingHandler and a sample of it in action:
http://jsfiddle.net/Rynan/vtPT8/
Update
Okay, I updated my fiddle to utilize the virtual elements but you will still have to wrap your login and registration content within a div to get the transition affect you are looking for. Keeping with your comment, that div won't be rendered until the state has changed to whatever it needs to be to display those certain contents so it won't take much memory while it isn't in the correct state.
Top voted answer isn't a solution since it doesn't unrender the elements.
Austins answer doesn't appear to work at all.
See my response in:
Animation before 'with' binding update
for a clean workaround I've discovered, replacing 'if' and 'with' with roughly equivalent 'template' bindings.
I have a list being displayed on a JSP. On mouse hover on any of the value i need to show a description corresponding that value. Need to show description not as an alert and also cannot make the values as hyperlink.
eg.
suppose the value is ABC so on mouse hover should show AppleBoyCat.
need to use onmouseover. let me know how to do it..
What do you want to do? If you just want to show a tooltip, you can set the title attribute of any element and it will be displayed as a tooltip.
Also, the abbr tag can be used as tooltips too:
<abbr title="test">stuff</abbr>
You can go about it in two ways:
1 - a hidden dom object (a div for instance) which reveals itself when you roll over whatever
or
2 - you can rewrite the html of the particular element you're mousing over.
You can load this data in when you load everything else (either as Javascript objects, or as markup, though that's much bulkier) or you can asynchronously load the description data from a service when you mouse over (though you'll have more lag).
jQuery is a quick and dirty way to achieve this (more quick than dirty), but straight JS or pretty much any other JS library will do as well.
Perhaps not the cleanest solution but something like this:
<a class='hover' rel='tooltip'>Link</a>
//Some hidden div, putting css inline just for example
<div id='tooltip' style='display:none;'>Content</div>
$(function() {
$('.hover').mouseover(function() {
var tooltip = $(this).attr('rel');
$('#' + tooltip).fadeIn();
});
});
And offcourse add a callback hiding it again. It just takes the value from rel of the link and use as an id for the div to show.
This is a quick and dirty solution, can be made alot smoother if you just work with it a little;)
There also alot of plugins out there allowing the same functionality in a cleaner fashion.
*Edit: Just noticed you added a comment on another post that you can't use jQuery.. shouldn't tag a post with something you're not intending to use.
As TJHeuvel already said, you can simply use the title attribute.
Best approach is to build the list with both the value and title attribute from within JSP, if not possible for some reason, you can build client side array of each value and its corresponding description then using JavaScript dynamically assign the title on mouseover.
Show us some more code to get more/better help.
For simple tooltips, the title attribute is most effective, as pointed out by TJHeuvel
If you need more advanced tooltips with HTML and CSS formatting, I'd suggest you use an external library.
One that works nicely without jQuery ist wz_tooltip download here, documentation here
When included correctly, you can add tooltips by calling the functions Tip() and UnTip() as follows:
Homepage