what am I doing wrong? The transition happens but it's instant. The time set in animate function is not being applied
trigger('showMenu', [
state('active', style({
marginLeft: '0px'
})),
state('inactive', style({
marginLeft: '-230px'
})),
transition('inactive => active', animate('2s')),
transition('active => inactive', animate('2s'))
])
<div [#showMenu]="showMenuState" id="menu-side-wrapper">
MENU
<div id="close-menu">
CLOSE
</div>
</div>
I fixed the exact problem in my project by removing the import of NoopAnimationsModule in my main module. This one seems to mock the animations, but actually doesn't do a thing.
I've checked the code you've pasted here and it works fine. Could you add any other relevant code? Maybe the code for 'showMenuState'?
Related
I'm currently trying to save a PDF for a web application with many pages. I call the partial views into one main page and use KendoUI to save the DOM into the PDF. Because some of these pages are very long and are variant depending on user input, I need the data to display over multiple pages. Whenever forcePageBreak is not called, KendoUI naturally does this by displaying all the data over multiple pages. Although when I turn on forcePageBreak and set page breaks at the beginning of each Partial in the main page, each Partial will only display one page in the pdf, and the rest of the data is cut off.
Here is an example of the main page's code:
<div class="myCanvas" id="myCanvas">
<div class="page-break">#{Html.RenderPartial("_Page1", Model._VM_Page1);}</div>
<div class="page-break">#{Html.RenderPartial("_Page2", Model._VM_Page2);}</div>
<div class="page-break">#{Html.RenderPartial("_Page3", Model._VM_Page3);}</div>
<div class="page-break">#{Html.RenderPartial("_Page4", Model._VM_Page4);}</div>
<div class="page-break">#{Html.RenderPartial("_Page5", Model._VM_Page5);}</div>
<div class="page-break">#{Html.RenderPartial("_Page6", Model._VM_Page6);}</div>
</div>
<script>
function ExportPdf() {
kendo.drawing
.drawDOM("#myCanvas",
{
forcePageBreak: ".page-break",
paperSize: "A4",
margin: { top: "1cm", bottom: "1cm" },
scale: 0.6,
height: 500,
multiPage: true
})
.then(function (group) {
kendo.drawing.pdf.saveAs(group, "exportFile.pdf");
});
}
I've tried putting page breaks within the beginning of each partial, to no avail. I've looked into trying to set groups, but I'm not exactly sure I understand if that will solve my problem. And CSS page-break-before: always isn't working. I'm unsure what to do.
The answer seems to be dive deeper for the lowest possible class that can have a page break before.
I generally solved this issue by putting the page breaks on the header classes within each Partial View. For example:
function ExportPdf() {
kendo.drawing
.drawDOM("#myCanvas",
{
forcePageBreak: ".page-header",
paperSize: "A4",
margin: { top: "1cm", bottom: "1cm" },
scale: 0.6,
height: 500,
multiPage: true
})
.then(function (group) {
kendo.drawing.pdf.saveAs(group, "exportFile.pdf");
});
}
Where the logic of my code would be similar to:
<div class="main">
<div class="page-header>
Header
</div>
<div class="ContentContainer">
Content
</div>
</div>
It was weird because I had set the page breaks at the global level where the partials were being called and also at the local level where main was being called, but I needed to dive even deeper to the page-header items to get it to work.
Here is my example working properly
Step 1: All CDNs
<script src="https://kendo.cdn.telerik.com/2020.2.617/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.2.617/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.2.617/js/kendo.all.min.js"></script>
Step 2: Add div to data div which you have created
<div data-uid="#= uid #" class="#= (id%10 == 0 ? 'page-break' : '') #">
</div>
Step 3: JS code
kendo.drawing.drawDOM("#downloadPDF", {
paperSize: "A4",
margin: {
left: "1cm",
top: "1cm",
right: "1cm",
bottom: "1cm"
},
scale: 0.8,
forcePageBreak: ".page-break"
})
.then(function(group) {
kendo.drawing.pdf.saveAs(group, "plagiarism.pdf")
});
at first I'm css beginner
I was trying to make vue.js animation for some items and it worked well but I got wrong animation
-We have button to add element to the array randomly
-We can click at element to remove it
problem:
-The animation always run on the last item
I expected that vue js should apply animation on the item which added or removed
What is the wrong in code that make the animation go wrong ??
What should i change or add to make the animation work correctly ??
new Vue({
el: "#app",
data: {
myNumbers: [1, 2, 3, 4],
highestNumberInMyNumbers: 4
},
methods: {
addNumber() {
this.highestNumberInMyNumbers++;
this.myNumbers.splice(Math.floor(Math.random() * this.myNumbers.length), 0, this.highestNumberInMyNumbers);
},
removeNumber(element) {
this.myNumbers.splice(element, 1)
}
}
})
.mix-enter {
opacity: 0;
}
.mix-enter-active {
transition: opacity 500ms;
animation: mixing-in 600ms ease-in forwards;
}
.mix-leave {}
.mix-leave-active {
transition: opacity 1000ms;
animation: mixing-out 0.4s ease-in forwards;
opacity: 0;
}
#keyframes mixing-in {
from {
transform: translateX(-20px) translateY(20px);
}
to {
transform: translateX(0px) translateY(0px);
}
}
#keyframes mixing-out {
from {
transform: translateX(0px) translateY(0px);
}
to {
transform: translateX(-20px) translateY(-20px);
}
}
<script src="https://vuejs.org/js/vue.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div id="app">
<h2>group transition for directive v-for </h2>
<hr>
<button #click="addNumber">Add number</button>
<br>
<br>
<div class="row">
<ul class="col-xs-4 col-sm-4 col-md-4 col-lg-4 col-xs-offset-4">
<transition-group name="mix" mode="out-in">
<li class="alert alert-success list-unstyled" style="height: 40px; padding: 10px 15px;margin-bottom: 8px;cursor: pointer;" v-for="(number,index) in myNumbers" #click="removeNumber(index)" :key="index">{{number}}
</li>
</transition-group>
</ul>
</div>
</div>
There is a bug in transition-group!
When you bind the key of li as the index, every time you remove a li, the animation always happend at the last li element.
So, if you want to use the animation with li , you can bind the key with number in your case.
<transition-group name="mix"
mode="out-in">
<li class="alert alert-success list-unstyled"
style="height: 40px; padding: 10px 15px;margin-bottom: 8px;cursor: pointer;"
v-for="(number,index) in myNumbers"
#click="removeNumber(index)"
:key="index">
{{number}}
</li>
</transition-group>
vs
<transition-group name="mix"
mode="out-in">
<li class="alert alert-success list-unstyled"
style="height: 40px; padding: 10px 15px;margin-bottom: 8px;cursor: pointer;"
v-for="(number,index) in myNumbers"
#click="removeNumber(index)"
:key="number">
{{number}}
</li>
</transition-group>
Finally, if you use animation with transition-group , do not bind the key to index , instead of item or number (in your case).
No matter what , make sure the key has the unique value.
Solution
Don't use index anywhere in the v-bind:key when using transition or transition-group.
Explanation
There is a bug/missing documentation, as well as bad documentation in the cookbook on vuejs.org, but there's a detailed explanation in the comments [1] on how indexes work, but no recognition this is a problem for developers in it's current state.
I have posted a few times to github, but the Vue.js developers there seem dismissive at best and refuse to either document this behavior or recognize this as a problem.
Reproduction of bug/error
There are three examples in the codepen below. The #1 works, the #2 uses :key="index" (your specific error above) and #3 uses :key="item +'_'+ index".
#2 and #3 give the error you are experiencing.
https://codepen.io/megacromulent/pen/wEzWNL
Summary of codepen:
This one works: (using item as :key)
<transition-group name="fade" tag="ol">
<li v-for="(item, index) in items"
v-bind:key="item">
{{item}}
</li>
</transition-group>
This one fails: (using index as :key)
<transition-group name="fade" tag="ol">
<li v-for="(item, index) in items"
v-bind:key="index" >
{{item}}
</li>
</transition-group>
This one fails worse: (concatenating index with string in :key)
<transition-group name="fade" tag="ol">
<li v-for="(item, index) in items"
v-bind:key="item + '_' + index" >
{{item}}
</li>
</transition-group>
Bug report (rejected)
I submitted this bug report to Vue.js devs here:
"Transition-group animates only last element if using index as the key"
https://github.com/vuejs/vue/issues/8718
It got closed instantly, so based on their input (requested I do a PR for comment, but that is not in my wheelhouse) I followed up with this feature request for the dev build to give an error, which would solve the problem at it's root.
Feature request (follow up, also rejected)
"Dev build console error when using index in :key value with v-for and transitions"
https://github.com/vuejs/vue/issues/8730
It seems reasonable to put a dev error on this issue, but the vue.js developers seem to think we should be able to figure this out on our own. I hope they come around and see this as a real issue. It's cost me hours of testing and reporting time to figure out.
I hope this helps other devs wasting time with this issue.
References
[1] https://github.com/vuejs/vue/issues/8718#issuecomment-416909724
My solution for this case:
create a random generated string for your array, then use this randomly generated string as the key.
template
<div v-for="(row, index) in rows" :key="row.randomKey">
...
</div>
script
export default {
data() {
return {
rows: [],
}
},
methods: {
add() {
this.rows.push({
id: null,
name: '',
randomKey: this.generateRandomKey()
})
},
remove(index) {
this.currency_exchange.splice(index, 1)
},
generateRandomKey() {
let length = 10
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}
}
}
Megacromulent
Good research!
For those who, like me, came here looking for:
It is likely that the animation occurs when the key is changed i.e. When deleting and creating an element, if the key does not change, then there will be no animation.
When the array changes, all the elements are rebuilt, which means the keys are also rewritten, and if they change on the element, this will make the element go away and appear.
Megacromulent let's see:
In the second case, the option with index - we remove the first element of the array, new keys are placed over all the remaining elements in the component - but in the beginning they will be the same 0,1,2 ... i.e. The keys of the first list will not change and therefore the elements will not be destroyed and therefore will not be animated.
In the third version, the key for all elements will change every time, i.e. All elements will be redrawn i.e. Removed and rebuilt, animation will work for all elements
Well, in the first version. If the items are the same, it will be the same as with the index because the key will not change, which means, in the case of all the same, only the last one will be animated, i.e. When adding and removing items to the end of the list.
I'm using Reveal to show more info and within that there's a carousel using Slick. The content inside the Reveal modal is pulled in via AJAX.
The problem I'm seeing is that when Reveal opens up, the carousel loads without the first image, moves to the second image (where there's a delay in loading), and then works normally after that. Here's a short video as an example: http://cl.ly/323s1T1x3I21
I'm not sure how to get the images to load faster.
My code looks something like the following...
Page code:
<div class="row">
<div class="large-16 columns right">
<h4>...</h4>
<p>... Learn More »</p>
</div>
<div class="large-8 columns left">
...
</div>
Code for page that gets pulled into :
<div class="inner-carousel">
<div><img src="blah..."></div>
<div><img src="blah..."></div>
</div>
<!-- not including this results in slick not working at all -->
<script>
$(document).ready(function() {
$('.inner-carousel').slick({
autoplay: true,
autoplaySpeed: 4000,
arrows: false,
centerMode: true,
dots: true,
fade: true,
speed: 1000,
swipeToSlide: true
});
}); // end ready
</script>
Not sure how to fix. Would appreciate any help.
So JS had to be changed as follows:
$("#modal-vineyard").on("opened", function() {
// $(".inner-carousel").slick("setPosition", 0);
$('.inner-carousel').slick({
setPosition: 0,
autoplay: true,
autoplaySpeed: 4000,
arrows: false,
centerMode: true,
dots: true,
fade: true,
speed: 1000,
swipeToSlide: true
});
});
More info here: http://foundation.zurb.com/forum/posts/23183
I have the following in my code. Having the option
legend: {show:true}
messes up the chart badly. The legend section is so long
and there is no chart.
I have pasted the image here of how the chart looks :
http://tinypic.com/view.php?pic=2eqgbgy&s=7
It shows fine without the legend option though, but chart is of course without the legend.
In Chrome I see the following exception
Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1
<script type="text/javascript">
line2 = [['Living Expenses',1000], ['Loans',2000], ['Credit
Card',500]];
$j(document).ready(function() {
$j.jqplot.config.enablePlugins = true;
$j.jqplot('piechartdiv', [line2], {
title: 'Where is my money going?',
seriesDefaults:{renderer:$j.jqplot.PieRenderer,
rendererOptions:{sliceMargin:8}}, legend:{show:true}
});
});
</script>
<div style="width: 450px;margin: 0px auto;">
<div id='piechartdiv'></div>
</div>
Any help appreciated.
Are you using Bootstrap or some other CSS reset library?
If you go into firebug, and select the <table class="jqplot-table-legend" ...> element, you'll probably see that there is a width:100% default property set the table elements. You can fix it in your CSS layout:
#piechartdiv table.jqplot-table-legend {
width:auto;
}
The only thing that seems weird to me is this:
$j.jqplot
Why are there some J's on your code?, besides that, everything seems to be fine, maybe try putting a location on the legend to see if that fix the issue, here is an example:
plot = $.jqplot('chart2', [arr], {
grid: {
drawBorder: true,
drawGridlines: false,
background: '#FFFFFF',
shadow: true
},
seriesDefaults: {
renderer: $.jqplot.PieRenderer,
rendererOptions: {
showDataLabels: true
}
},
legend: {
show: true,
location: 'e'
}
});
Have you included the jqplot.css file in your code.
Make sure that it is included in the code, and that the file is also present in the directory you are referring to.
Thank you
I came across something similar.
try checking css property text-align:left
<div id='piechartdiv' style="text-align:left;"></div>
I'm afraid I don't know why but these fixed the error for me
can we use google AJAX Language API with EXTjs?????
i have tried example for translitration i have one html file
and typemarathi.js
google.load("elements", "1", { packages: "transliteration" });
function onLoad() {
var options = {
sourceLanguage: google.elements.transliteration.LanguageCode.ENGLISH,
destinationLanguage: [google.elements.transliteration.LanguageCode.MARATHI],
shortcutKey: 'ctrl+g',
transliterationEnabled: true
};
// Create an instance on TransliterationControl with the required
// options.
var control = new google.elements.transliteration.TransliterationControl(options);
// Enable transliteration in the editable DIV with id
// 'transliterateDiv'.
control.makeTransliteratable([myname]);
}
google.setOnLoadCallback(onLoad);
it works fine.
but if i write the textfield in extjs
Ext.onReady(function(){
var form1=new Ext.FormPanel({
renderTo:document.body,
frame:true,
title:'My First Form',
widyh:250,
items:[{ xtype:'textfield', fieldLabel:'First name', name:'firstname'}]
});
});
and try to pass firstname (name attribute to control.makeTransliteratable([firstname])) then it does not work... it says invalid id error
but if i pass->(html textfiled name to it) control.makeTransliteratable([myname]) it works fine
(i want to type and display multiple nonEnglish languages data
programatically frontend i used EXTjs is there any another way to do so if yes the suggest me. pls..
Yes you can.
Besides someone should clean his code, thats hurrible.
Yes, you can. But you should know that ExtJs automatically generates identifiers for html elements:
html:
<div class="x-form-item x-form-label-left x-box-item" id="ext-gen27" style="left: 0px; top: 0px;">
<label style="width: 55px;" class="x-form-item-label" id="ext-gen28">Send To:</label>
<div style="padding-left: 60px; width: 668px;" class="x-form-element" id="ext-gen26">
<div class="x-form-field-wrap x-form-field-trigger-wrap x-trigger-wrap-focus" id="ext-gen24" style="width: 668px;">
<input type="text" name="to" id="ext-comp-1002" autocomplete="off" size="24" class=" x-form-text x-form-field x-form-focus" style="width: 651px;">
</div>
</div>
</div>
js:
....
items: [{
xtype: 'combo',
store: ['test#example.com', 'someone-else#example.com' ],
plugins: [ Ext.ux.FieldReplicator, Ext.ux.FieldLabeler ],
fieldLabel: 'Send To',
name: 'to'
}]
As I understand you need to translate the label. In order to do this you should get the id of the label. To do this you can use TextField's label property (myField.label.id). If you want to translate a lot of elements then probably it'll be better for you to use something like this:
var control = new google.elements.transliteration.TransliterationControl(options);
var labelIds = [];
Ext.each(Ext.select('label'), function(item){
labelIds.push(item.id);
});
control.makeTransliteratable(labelIds);
But be aware that you should call this only after rendering all elements. Also you can write a some plugin that will inject this functionality into 'render' method. Writing a plugin is a better but a bit more harder way.