Vue event modifiers prevent vs. stop - events

Reading the Vue documentation about events, they mention the event modifiers like prevent or stop. They mention that on stop: <!-- the click event's propagation will be stopped -->. I am assuming this will stop the event from bubbling. What about prevent. What does it exactly do? I am assuming it will prevent the event from being triggered twice (on a double click for example). Are these assumptions correct? I just couldn't find more specific info on the web.
What I read:
https://v2.vuejs.org/v2/guide/events.html
How to prevent/stop propagation of default event (click) in directive (vue 2.x)

.prevent or event.preventDefault() – It stops the browsers default behaviour (A example is reload when you hit <button type="submit"> in <form>)
.stop or event.stopPropagation() – It prevents the event from propagating (or “bubbling up”) the DOM
.once - The event will be triggered at most once

Here is a practical example in VueJs 2:
var stopEx = new Vue({
el: '#stop-example',
methods: {
elClick: function(event) {
alert("Click from "+event.target.tagName+"\nCurrent Target: "+event.currentTarget.tagName);
}
}
})
#stop-example > div {
max-width: 300px;
min-height: 150px;
border: 2px solid black;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="stop-example">
<h3>without stop propagation</h3>
<div #click="elClick($event)">
<button #click="elClick($event)">Click Me</button>
</div>
<h3>with stop propagation</h3>
<div #click="elClick($event)">
<button #click.stop="elClick($event)">Click Me</button>
</div>
</div>
Here is how it works
On the first div element, (click) event for (div) element is handled by (div) and by the children of (div) because we did not stop propagation.
So once you click on button, the click event for button is triggered first then bubbling is done by moving on the ancestors of button.
The target is the element that handles the event while the currentTarget may be element that handles the event or ancestors of the element.
For this reason when you click on button on the first (div), the click event triggers twice due to handling click event of the parent.

Related

Prevent row click in list when button is pressed

I am using a v-list with a click event on v-list-tile. I would also like to have a button in v-list-tile-action with a click event. My problem is that both events fires when I press the button in v-list-tile-action.
I would like to have both event, one for the row and one for the button but how can I prevent the v-list-tile / row click to fire when the button is pressed?
Thanks for answering but I figure it out, just use #click.stop=""
A script of example of How prevent events propagation
$(document).ready(function(){
$("span").click(function(event){
event.stopPropagation();
alert("The span element was clicked.");
});
$("p").click(function(event){
alert("The p element was clicked.");
});
$("div").click(function(){
alert("The div element was clicked.");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height:100px;width:500px;padding:10px;border:1px solid blue;background-color:lightblue;">
This is a div element.
<p style="background-color:pink">This is a p element, in the div element. <br><span style="background-color:orange">This is a span element in the p and the div element.</span></p></div>
<p><b>Note:</b> Click on each of the elements above. When clicking on the <b>div</b> element, it will alert that the div element was clicked. When clicking on the <b>p</b> element, it will return both the p and the div element, since the p element is inside the div element.
But when clicking on the <b>span</b> element, it will only return itself, and not the p and the div element (even though its inside these elements). The event.stopPropagation() stops the click event from bubbling to the parent elements.
</p>
<p><b>Tip:</b> Try to remove the event.stopPropagation() line, and click on the span element again (the click event will now bubble up to parent elements).</p>
As you can see the event has a method called stopPropagation, I am using JQuery, Javascript native is the same.

How to find selected tab on KendoTabStrip on page load?

I am using Kendo UI MVC and i have a kendoTabStrip on acshtml page. By default I am selecting the first tab on page load. All other tabs are loaded dynamically using AJAX.
Issue: I am trying to find the selected tab so i can find its children?
one way to find active tab is by calling select() method without parameter, or anotherway is by checking classname 'k-state-active' however both methods doesnt work
<section class="tpt-tabstrip">
#(Html.Kendo().TabStrip()
.Name("MyTabStrip")
.Animation(false)
.Items(items =>
{
foreach (var revision in Model.MyCollection)
{
items.Add()
.Text(revision.Name)
.LoadContentFrom("MyActionMethod", "MyController", Model.ID);
}
})
)
</section>
<script src="~/Scripts/MyScript.js"></script>
Note that above in cshtml that the script tag is at the end of the page.
Below is the script code
$(function(){
var tabStrip = $("#MyTabStrip").getKendoTabStrip();
if (tabStrip != null && tabStrip.tabGroup.length > 0) {
tabStrip.select(0); // this line is getting executed for sure
}
// the line below returns -1 here why?????
var index = tabStrip.select().index();
// another way to find active tab is by checkikng class name 'k-state-active' however it didnt work either.
// jQuery couldnt find any element with class 'k-state-active'
$('.k-state-active')
})
UPDATE1
The activate event of tabstrip would not work for me because it get fired each time i select tab. I need an event which gets fired only once. Ultimately i want to find NumericTextBox controls on selected tab and attach 'change' event handlers to those controls. like below
$(function(){
var tabStrip = $('#MyTabStrip').data("kendoTabStrip");
tabStrip.bind('activate', function (e) {
$('[data-role="numerictextbox"]').each(function(){
$(this).getKendoNumericTextBox().bind("change",function(e){
alert('changed');
})
})
});
})
here the change event handler will get attach to NumericTextBox everytime i select the tab
$('.k-state-active') works fine it will return the two elements from DOM. You are trying to select element in $(document).ready that's the reason you are not getting element as tab control is not rendered yet.
Try to write your code onActivate event of kendo tab strip control.
OnActivate event is triggered after a tab is being made visible and its animation complete. Before Q2 2014 this event was invoked after tab show, but before the end of the animation. This event is triggered only for tabs with associated content.
See more at http://docs.telerik.com/kendo-ui/api/javascript/ui/tabstrip#events-activate
1st Tab name
<li class="k-item k-state-default k-first k-tab-on-top k-state-active" role="tab" aria-controls="RoleTabs-1" style="" aria-selected="true">
<span class="k-loading k-complete k-progress"></span>
<a class="k-link">Tab Name</a>
2nd Tab Content
<div class="k-content k-state-active" id="RoleTabs-1" style="display: block; height: auto; overflow: auto; opacity: 1;" role="tabpanel" aria-expanded="true">

JS/JQuery: Can't trigger an event associated with an element that is above another element

I have an element, #i1, that is below another element, .close_button, and they each have a click event associated with them...the former's is called clickFade() while the latter's event is a anonymous function that is defined within the execution of the aforementioned clickFade().
When clickFade() is called by clicking on #i1, the parent div,#welcome, is fadedTo opacity .1 and #A is fadedIn. Also, unbind() is called for #i1 and the anonymous function mentioned above that is associated with a click event on .close_button is defined. This function just reverses the effects that clickFade() has when a close_button image is clicked.
I don't think the problem is a z-index issue (because I've tried it already and the close_button image is always visible on top). I also don't think it's a binding issue because the button works, but only when there's nothing underneath of it...for example, if the button is half overlapping one of the background images like #i1, the half that isn't on top of #i1 will trigger the event while the other half will not.
What's the problem here and how can I fix it?
Here are the gists for the HTML, CSS, and JS; here's the relevant code:
HTML:
<div id="welcome">
<p id="welcomeText">Welcome</p>
<img src="imgs/img1.jpg" id="i1" alt=null/>
</div>
<div id="A">
<img src='imgs/close_button.gif' class='close_button' alt=null
style="width: 10%; height: 10%"/>
</div>
JS:
function clickFade() {
$('#welcome').fadeTo('slow',.1);
$('#i1').unbind('click',clickFade);
$('#i1').unbind('mouseover',mouseOverFunc);
switch (this.id) {
case "i1":
$('#A').fadeIn('slow');
$('.close_button').click(function() {
$('#A').fadeOut('slow');
$('#welcome').fadeTo('slow',1);
$('#i1,#i3,#i5').click(clickFade).mouseover(mouseOverFunc);
});
break;
.
.
.
}
}
So you both have to set the z-index AND set position:relative for this to work.
z-index not working with fixed positioning and others. Good luck!

How to close other expanded rows when some other row is expanded

I am working on Jqgrid in ASP.NET MVC.
I have managed to have a server side paging and sorting for a subgrid.
Scenario
I have a collection of rows each with a open subgrid option, I go and click on the '+' expand first row the subgrid for first expands, now I click on the '+' expand third row.
Here I want the first row's subgrid to collapse.
In Short : This mean that only row's subgrid should stay expanded.
I am not sure how to get going about this.
Please help me out on this.
You can create all expanders with same class + class that will determine weather it is expanded or not. On expander click you will fire event which will remove expanded and collapsed classes from elements which have expander class and attach collapsed and only clicked expander will get expanded class. I will post example
<div class="expander collapsed">
<div class="expander-title" onclick="$('expander').removeClass('expanded collapsed').addClass('collapsed'); $(this).removeClass('collapsed').addClass('expanded')">
title here
</div>
<div class="content">
content here
</div>
</div>
CSS:
.expanded > .content {
display: block;
}
.collapsed > .content {
display: none;
}
This is one expander

How to find some certain event handlers with jQuery?

As many browsers do not show tooltips on disabled form elements (as Opera does), I decided to emulate disabled button with jQuery.
When disabling I just set control's class to disabled and for buttons/submit controls I add an event handler click(function(){return false;})
and I can unbind it later when reenabling the control.
Now the problem is - I need to remove all attached event handlers (click, enter key) from the disabled control, except 'mouseenter' and 'mouseleave' because I am using a custom jQuery based tooltip which needs those events.
And after re enabling the button, I need to restore all handlers back.
I know that I can store the attached event handlers in $.data() but I have no idea, how to gather all the event handlers except 'mouseenter' and 'mouseleave'.
Can you help me?
try this:
<script>
$(function() {
//Lets attach 2 event handlers to the div
$("#el").click(function(){ alert("click"); });
$("#el").mouseover(function(){ alert("mouseover"); });
//We iterate on the div node and find the events attached to it
$.each($("#el").data("events"), function(i, event) {
output(i);
$.each(event, function(j, h) {
output(h.handler);
//DO your unbind here if its not a mouse-enter or a mouseleave
});
});
});
function output(text) {
$("#output").html(function(i, h) {
return h + text + "<br />";
});
}
</script>
<div id="el" style="width: 200px; height: 200px; border: solid 1px red;">Test</div>
<span id="output"></output>
unbind - http://api.jquery.com/unbind/
I wouldn't go to all that work.
Since you have a .disabled class on the disabled elements, I'd just use that as a flag to disabled/enable the functionality by testing for that class in an if() statement, and returning false if the element has the disabled class.
So using the click handler you gave, instead of:
$('someElement').click(function(){return false;});
I'd do this:
$('someElement').click(function() {
if( $(this).hasClass( 'disabled' ) ) {
return false;
} else {
// run your code
}
});
Now when you remove the .disabled class, the input will work again. No unbind/bind or tracing using .data(). Much simpler.

Resources