VueJS how to double doubleclick - javascript

I have a table with columns of different widths. I use sticky headers for which I have to calculate the column widths.
Now I wrote a function to increase the column width by double clicking the header. This works for the first double click. But if I click on it 4 or 6 times nothing happens after the first double click.
How can I reset the event so that after 2 more clicks the event is triggered again?
When I move the mouse I can do several double clicks one after the other. But that is not the goal.
Here is the code snippet:
<th
v-for="c in data.columns"
v-if="visiblecolumns.includes(c)"
v-on:dblclick="COLUMN_DEFINITION[c]+=50"
:style="{ 'min-width': COLUMN_DEFINITION[c] + 'px', 'max-width': COLUMN_DEFINITION[c] + 'px' }">
{{ c }}
</th>

<th
v-for="c in data.columns"
v-if="visiblecolumns.includes(c)"
#click="changeColumnDefinition"
:style="{ 'min-width': COLUMN_DEFINITION[c] + 'px', 'max-width': COLUMN_DEFINITION[c] + 'px' }">
{{ c }}
</th>
From: vue.js: how to handle click and dblclick events on same element, and as suggested by #JBDouble05
new Vue({
el: '#app',
data: {
counter: 0, // count the clicks
timer: null // Needs to be specified here so it can be accessed on both clicks
},
methods: {
changeColumnDefinition: function(event){
var self = this
this.counter++
if(this.counter == 1) {
this.timer = setTimeout(function() {
// DO NOTHING BUT RESET IN CASE THERES JUST ONE CLICK
self.counter = 0
}, 500); // increase delay as you like
}else{
clearTimeout(this.timer);
// COLUMN_DEFINITION[c]+=50
self.counter = 0;
}
}
}
});
NOTE This goes beyond the question, but:
I would personally wrap this up in a component, since you probably will have more than one header. If you need to call an outside function just use:
this.$emit('someEvent', someValue);
To emit an event and then access it in your component as
<my-awesome-component #someEvent="someFunction"></my-awesome-component>

What you should do is make a modulo variable, and attach an incrementational statement to your v-on:dblclick attribute, that adds one to (increments) the value of a variable, and then, add an event listener in your JavaScript file, and when this happens, perform a modulus operation upon that variable: if it's divisible by two (counter % 2 == 0), then the user has double-clicked twice. If it's not divisible by two (counter % 2 != 0) then they've clicked on it an odd number of times, and you can re-engage the event that occurred when they first double-clicked on it. That was a mouthful, but hopefully you got it, and just ask if you need simplification or further explanation.

Related

Vue how to trigger click on links based on interval

In my vue-app I have a list of links, which I want to be triggered automatically one by one by a default interval, lets say after 3 seconds, the first link gets triggered, then after another 3 seconds, link 2 gets triggered... so its kind of a carousel/autoplay with links I want to achieve, but I don't really know how to solve that.
here is my code:
<li v-for="(slide, index) in slides" :key="index" :class="slideIndex === index ? 'active' : ''" #click="slideIndex = index" ref="slide">
{{ slide.title }}
</li>
and then I thought somethinbg like this:
mounted() {
Object.keys(this.$refs.slide).forEach((el) => {
setInterval(() => {
this.$refs.slide[el].click();
}, 3000);
});
},
but this triggers all links and does not seem to be right at all, but its just a slight idea...
Can someone help me out?
I would not recommend doing this by simulating a click on the link.
How about setting the element you want to be active in your code?
I assume slideIndex is the current selected slide?
You could try something like this:
setInterval(() => {
this.slideIndex = this.slideIndex < this.slides.length - 1 ? (this.slideIndex += 1) : 0;
}, 3000);
So you add +1 every time the interval is triggered and cycle through the slides. If it's at the end slideIndex gets reset and starts at 00

Current slide number of total in Vue Slick Carousel

I am trying to make current number and total number of slides using vue-slick-carousel.
This is what I tried so far.
<VueSlickCarousel ref="carousel">
<div>1 <button tabindex="-1">11</button></div>
<div>2 <button tabindex="-1">22</button></div>
<div>3 <button tabindex="-1">33</button></div>
<div>4<button tabindex="-1">44</button></div>
</VueSlickCarousel>
methods: {
customPaging: function (slider, i) {
var slideNumber = i + 1,
totalSlides = slider.slideCount;
return (
'<a class="custom-dot" role="button" title="' + slideNumber + ' of ' + totalSlides + '"><span class="string">' + slideNumber + '</span></a>'
);
},
},
But this is not working.
And this is vue-slick-carousel API url below.
https://github.com/gs-shop/vue-slick-carousel/blob/master/docs/API.md#methods
What do i need to fixed the code to show a current slide number and total slide.
ex) "3/10"
I had the same problem recently.
This probably comes late, but to whom it may still concern:
If you want to display current page numbers instead of the default dots, there is an example at the bottom of this VueSlickCarousel documentation page and you should be good.
If you want to display the current page number only once anywhere on your page, I found a solution that worked for me:
this.$refs solution did not work for me, but this was likely due to v-if that I was using to render the <VueSlickCarousel>.
v-if and this.$refs don't like each other very much - see also Vue.js refs are undefined, even though this.$refs shows they're there.
Eventually I tried looking at the events that the children emitted in Vue Devtools and I found this afterChange event.
The afterChange event is fired each time you move your carousel to the next page (regardless of whether you drag-slide or click the arrow) and contains a very useful param - the current page index. In my case, this param starts at 0 and for each change it is incremented or decremented by 3 - that is because my carrousel settings are set to slidesToScroll : 3.
So my solution was to:
Add event listener like this:
<VueSlickCarousel #afterChange="afterPageChange">
Create the sliderPageIndex in your data with the initial value 0.
data() {
return {
sliderPageIndex: 0;
}
}
Create the afterPageChange in methods: {}.
methods: {
afterPageChange(page) {
this.sliderPageIndex = page;
}
}
Create the currentPage in computed: {} with some additional logic to compensate for the abovementioned slidesToScroll setting and for the sliderPageIndex starting at 0, like this:
computed: {
currentPage() {
// always display 1 if page index is 0
if (this.sliderPageIndex == 0) {
return 1;
} else {
// compensate for slidesToScroll settings and compensate the shift by 1
return this.sliderPageIndex / this.carouselSettings.slidesToScroll + 1;
}
},
}
Now you should have access to the currentPage computed property and can use it anywhere in your <template>.
When it comes to the totalPages, I compute it from the length of the picture array that I send to the carousel instead of taking it from the carousel directly. Here, I also compensate for carouselSettings - if this requires further explanation, let me know.
You can read more about the VueSlickCarousel events here.
Hope this will be of use to someone! :)
Cheers and have a nice day.

how to get text to disappear after few seconds

Hi guys I am building my game right now and trying to get some text to disappear after a few seconds. I am using Phaser and I am not to sure how to do this.
Currently I have:
Asteroid.time.events.remove(Phaser.Timer.SECOND - 3, this.startInstructions3, this);
My text appears on the page fine:
if (!this.rockmodel.countLiving()) {
Asteroid.time.events.add(Phaser.Timer.SECOND * 3, this.levelIncrease, this);
var startInstructions3 = 'NEXT LEVEL! ';
this.gametext3 = Asteroid.add.text(Asteroid.world.centerX, Asteroid.world.centerY, startInstructions3, lifefont3.thefont3);
this.gametext3.align = 'center';
this.gametext3.anchor.set(0.5, 0.5);
}
Then when I go back to my levelIncrease function i have :
if (this.rockcount < rocksincoming.max) {
this.rockcount += rocksincoming.astup;
}
Asteroid.time.events.remove(Phaser.Timer.SECOND * 3, this.startInstructions3, this);
this.randomrock();
},
endofgame: function () {
Asteroid.state.start(gameobjectstouse.menu);
},
My question is, is it like -3 or is there a set thing you can do in Phaser like duration or something like that? I can't seem to find anything about it.
Thanks.
There's actually an official example that covers this scenario for you.
Your Asteroid.time.events.remove() would actually remove an event, not add a removal event. For example, if you had an event that looped and wanted to remove that event, you would use time.events.remove.
So you want to add an event that triggers after three seconds, so something like the following, instead of your Asteroid.time.events.remove line:
Asteroid.time.events.add(Phaser.Timer.SECOND - 3, this.nameOfFunctionToHideText, this);
Where nameOfFunctionToHideText (or whatever new function you create) would be the one that would remove the text.

How to reload element attribute inside jQuery droppable()

I have an inventory and every time a user deletes an item (drags it to the trash bin) I check if this item is a stack and remove 1 if it is.
The problem is that the stack number stays the same each time the user drops it
$('#trash-wrapper').droppable({
accept: ".item",
drop: function(event, e){
// If the trashed item has a stack that is bigger than 1, do not remove the element but remove 1 from the stack and return the item back
if(e.draggable.find('.inventory-stack').data('stack-count') > 1){
var count = e.draggable.find('.inventory-stack').data('stack-count');
e.draggable.find('.inventory-stack').attr('data-stack-count', (count - 1)).html(count - 1);
_ajaxFetch("php/ajax/game/conq-delete-item.php", {dby : 'l', id: e.draggable.attr('data-loot-id')});
}
// Otherwise destory the element
else{
e.draggable.remove();
_ajaxFetch("php/ajax/game/conq-delete-item.php", {dby : 'i', id: e.draggable.attr('data-item-id')});
}
}
});
The problem is that Count stays always the same. If there is stack of 20, the first drop works, it changes the attribute and html to 19, but all other drops still use the count variable declared first - 20, so it never goes more than 1 below.
I even tried
e.draggable.find('.inventory-stack').attr('data-stack-count', (e.draggable.find('.inventory-stack').data('stack-count') - 1)).html(e.draggable.find('.inventory-stack').data('stack-count') - 1);
Doesnt work as well
Ughhhhhh
data('stack-count');
Seems to save this globally and will not be replaced on new call
attr('data-stack-count');
Fixed it :/

jquery return value of input to var

I'm trying to make a variable equal the value of the text box. I have the text box value being set to a variable and returned as an alert (for now) but I can't figure out how to call that variable from other functions.
$('#max_char').keyup(function () {
var max_char = $(this).val();
alert(max_char + ' Handler for .keyup() called.');
});
var count_options = {
'maxCharacterSize': max_char,
'originalStyle': 'originalDisplayInfo',
'warningStyle': 'warningDisplayInfo',
'warningNumber': 40,
'displayFormat': '#input Characters | #left Characters Left | #words Words'
};
$('#textinput').textareaCount(count_options);
});
HTML
<textarea cols="68" rows="21" name="textinput" id="textinput"></textarea><br/>
<input type="textbox" id="max_char" name="max_char" value="-1" /> Max Characters <br/>
Any help would be great. Trying to add the var max_char to the maxCharacterSize of count_options
All you need to do is declare max_char in a higher scope, i.e. outside of the keyup function:
var max_char;
$('#max_char').keyup(function () {
max_char = +$(this).val();
alert(max_char + ' Handler for .keyup() called.');
});
Also note that I put a + in front of $(this).val() to convert it from a string into a number, since "1" + 1 == "11".
Update:
The reason the textareaCount plugin isn't working is because it is initialised once, on document ready. At this time, max_char is nothing because the user hasn't typed anything yet.
You'd have to either reconfigure or re-initialise the plugin on every keyup to get the effect you're after. Unfortunately the plugin doesn't document an easy way to do this. After digging through the plugin's source code, I think there are only 3 events it binds that you need to revert, before you can simply re-initialize it again. Try this out:
var count_options = {
'maxCharacterSize': 100, // Just some default value
'originalStyle': 'originalDisplayInfo',
'warningStyle': 'warningDisplayInfo',
'warningNumber': 40,
'displayFormat': '#input Characters | #left Characters Left | #words Words'
};
// Initialise the plugin on document ready
$('#textinput').textareaCount(count_options);
$('#max_char').keyup(function () {
var max_char = +$(this).val();
count_options.maxCharacterSize = max_char;
// Unbind the 3 events the plugin uses before initialising it
$('#textinput')
.next('.charleft').remove().end()
.unbind('keyup').unbind('mouseover').unbind('paste')
.textareaCount(count_options);
});
If I understand you correctly, if you declare the var within the global scope of javascript
Or if you directly access the input with
$("#max_char").val()
parseInt($('#max_char').val())

Categories

Resources