Toggle ng-click attribute - html

I have a span with an ng-click="..." attribute. The ng-click slightly modifies the span's CSS within the DOM so that it is more button-like. Within my application I wish to toggle whether or not that span is clickable or not. I can make the ng-click not do anything easy enough but what I would prefer is to just remove/disable the attribute altogether. This is to avoid all "buttonizing" that the ng-click does to the element. It would also be nice if the attribute were re-enabled if the clickable variable becomes true again.
I would like a solution that avoids using $scope.$watches because my application is pretty large and watches are slow.
Thanks!

I think you can have two spans with and without ng-click attribute and based on that clickable variable you control those two spans with ng-if or ng-show

Simple solution suggested by to Achu!
Just use two spans rather than toggle the attribute on a single span.
<span ng-if="clickable" ng-click="...">Click me!</span>
<span ng-if="!clickable">Cant click me!</span>

If I were in such a situation, I would not try to enable or disable ng-click attribute. Rather, I would use some flag variable with the $scope to see if click function should perform its functionality or not like in your controller you have a method like
$scope.spanClick = function(){
if(!$scope.shouldClick){
return;//simply do nothing
}
//Do button click logic
}

Related

V-onclick evt.target gets the button inside the span; what should I do?

I have a button with a span inside it that is set to run a function v-on:click. I try to pick up the value1 value attached to the button (naming convention aside) by catching it as an evt.
The problem I'm getting is if I click the side of the button it runs as expected. But if I click the span inside it, I can't pick up the value1 because the evt.target is the span.
I'm converting an existing project to Vue, and this isn't the behavior I expected. What is the best way to deal with this?
Thanks!
<button id="touch-button" class="button float-center" value1="19" v-on:click="emit_values">
<span>19</span>
</button>
emit_values(evt){
$(evt.target).attr("value1")
}
Apparently this is a generic html/javascript issue.
Solution is here: Missing click event for <span> inside <button> element on firefox
I've changed it to target evt.currentTarger, then used css to add the pointer-events: none; styling to all children of those buttons.

Tracking Link Click on Google Tag Manager

I want to track clicks on the following button/link with Google Tag Manager. I created a trigger in Google Tag Manager that triggers when the element_id = 100. This works fine, except that when I click exactly on the text, it doesn't do anything, the link looks like a button, with the text in the middle of it. I can't change anything to the html or css, otherwise I can think of multiple things, so I need to find a solution without changing the html. Also, the 'myclass' class and the 'label' class get used in other elements.
<a class="myclass" id="100" href="http://www.url.com">
<span class="label">Text</span>
</a>
Anyone an idea?
Thanks a lot,
The following workaround worked:
Create trigger when element text contains "Text". This will trigger events on the button and the label on the button, of all buttons with "Text" as label.
Create tag for that trigger that checks with simple javascript if either the id of the current element = 100, which will happen when you click the button but not the label, or that the id of the parent = 100, which happens when you click the label. You can get the element that triggered the tag using the built-in variable "Click Element". Which you need to access the parent element.
Technically, you shouldn't have a CSS ID that starts with (or is) a number, so not sure if your code example is accurate or not. Whatever the case, you're probably better off using "matches CSS selector" so that you don't need to use any custom JS.
If indeed your HTML uses id="100", then the above will work. If it's anything else that doesn't start with a number, then you can use
#whatever > span

Fire onmouseover event when element is disabled

I have some controls that I need to disable when users don't have edit privileges, but are sometimes not wide enough to show the entire text of the selected option element. In which case I've added a tool tip with ASP.NET and the following code
ddl.Attributes.Add("onmouseover", "this.title=this.options[this.selectedIndex].title")
This works when the control is enabled, but doesn't work when it is disabled.
The following alert will not fire when a mouse is over the select element:
<select disabled="disabled" onmouseover="alert('hi');">
<option>Disabled</option>
</select>
See this fiddle.
Q: Can I fire the onmouseover event for controls that are disabled?
Disabled elements do not fire events, e.g. users cannot hover or click them to trigger a popover (or tooltip). You can however wrap the disabled element with a DIV and listen to the event fired on that element instead.
Update: Please see nathan william's comment for some serious limitations to this approach. I've updated the fiddle to illustrate the problem areas more clearly.
Expanding on what #Diodeus said, you can use jQuery to automatically create the div container for you and wrap it around any disabled elements.
Use the :disabled selector to find all disabled elements.
Then call the .wrap() method with a function callback
You can use this to refer to the current element in the set.
Then use .attr() method to get the onmouseover value from the parent element and apply the same value to the new div.
$(':disabled').wrap(function() {
return '<div onmouseover="' + $(this).attr('onmouseover') + '" />';
});
Demo in jsFiddle
I know this is an old post, but hopefully this answer will clarify how #Diodeus answer can be implemented!
Disabled elements do not fire events, e.g. users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you can however wrap a <DIV> or <span> around the disabled element and listen to the event fired on that element instead.
NOTE! Using onmouseover and onmouseout in the wrapper <DIV> will not work as expected in Chrome (v69). But will however work in IE. Which is why I recommend users to use onmouseenter and onmouseleave instead, which is working great both in IE and in Chrome.
<select disabled="disabled" onmouseover="alert('hi');">
<option>Disabled</option>
</select>
<div onmouseenter="alert('hi');">
<select disabled="disabled" onmouseover="alert('hi');">
<option>Disabled with wrapper</option>
</select>
</div>
I've put together a JS fiddle with some examples here: http://jsfiddle.net/Dr4co/tg6134ju/
Why can't you add a title on the target element?
title looks like the same as tool tip.
And title works on disabled elements.
when you set the value of your select, also set title:
element.value=value;
element.title = element.options[element.selectedIndex].text;
I know this is an old post, but in chrome you can set css property pointer-events to all and it should allow for events. I haven't checked in other browsers.
button[disabled] {
pointer-events: all;
}
Edit:
Actually I think setting the property to auto is sufficient. As #KyleMit commented, support it's pretty good.
I just used this in project where I needed to disable an button until some validation rules where met, but I also needed to trigger the validation on hover over the button. So adding the pointer-events did the trick. I think it's the easiest way get over the problem stated in the OP.
there are two solutions for this
<Tooltip title="Tooltip" placement="bottom">
<div>
<IconButton disabled>
<Done />
</IconButton>
</div>
</Tooltip>
or this one if you dont want miss the view
<Tooltip title="Tooltip" placement="bottom">
<IconButton component="div" disabled>
<Done />
</IconButton>
</Tooltip>
reference

HTML why do buttons in forms send data?

This is a very rudimentary question, but I am sure someone out there knows why. In HTML, when I make a button element by itself, and do not give it and onclick and no jQuery .click() the button will just do nothing. Perfect. But when I do this and but the button inside a <form> element, it tries to send GET data of all the form elements to the root address of my website? Why is it doing that? I didn't make it a submit button or even define a method or action on that form??
Thanks for the info in advance!
** EDIT **
This is what I did to fix the problem. For buttons inside the <form>, use:
<button type="button"></button>
And it will not do anything by default.
As can be seen at the respective MDN entry, the default value for the type property of a button element is submit. So if you omit it or don't change it to button or reset, the default behaviour will kick in and the form gets submitted.
<form action="">
<button type="button">Nothing will happen</button>
<button>Form gets submitted</button>
</form>
I didn't make it a submit button
<button> elements have a type attribute. The default value is submit. Set type="button" if you don't want it to submit a form.
or even define a method
method defaults to GET
or location on that form??
action defaults to the current URI.
It was designed that way because you sometimes need to know WHICH button was pressed on the server-side. If you want button functionality without a button, use a styled A-tag.
Buttons are treated as submit controls in forms, not sure why.
The reason it gets posted to your root is because you didn't specify an action and so the default is used.
The reason it used GET is because that's the default method.
To prevent it happening, add return false; to the end of your button's onclick.

mootools event listener disappears after element.innerHTML is changed

I putting together a page that will display a set of stored values. I am using mootools and AJAX calls to update the values without needing to refresh the page each time the user selects a new item from the drop down menus.
the HTML each line looks something like:
<div class="selections">
<input class="checkbox selector" type="checkbox" CHECKED />
<span class="b_name">
<select class="b_n selector">
<!-- options -->
</select>
</span>
<span class="b_level">
<select class="b_l selector">
<!-- options -->
</select>
</span>
<span class="values">
<!-- the values -->
</span>
</div>
In the head I have set up an event listener like:
$$('.selector').addEvent('change', function(event){changeValues(this);});
My problem is that when the "b_name" select changes I have to update the list of options in the "b_level" select. I accomplish that by getting a list of the possible options from my database through a PHP script on another page and replacing "b_level"'s innerHTML. Once I do that, the event listener attached to "b_l selector" no longer works.
I tried to resolve this issue by explicitly attaching an event listener to "b_l selector" each time "b_name" changes like so:
row.getElement('.b_l').addEvent('change', function(event){changeValues(row.getElement('.b_l'));});
where 'row' is the html element 'div.selections'.
It still isn't working and I have no idea what's going on. Can anyone offer a suggestion as to how I can get this resolved? or perhaps a better way to do what I'm doing.
This is how JavaScript works, it's not a bug.
What you need to use is Element Delegation - you attach an event to the parent element, in the same time specifying the element that the event should be delegated to.
Here's a basic example of Element Delegation in action: http://jsfiddle.net/oskar/ENR3E/
And the documentation: http://mootools.net/docs/more/Element/Element.Delegation
When you set innerHTML on an element, the element's contents are completely cleared and replaced with a new set of elements -- the ones parsed from the innerHTML property. Any events set on the old elements will not apply to the new ones.
jQuery provides a solution to this problem with live() events. I found a solution here that apparently achieves the same with mootools.
Your approach is correct, there's probably just a bug in your addEvent() code. The reason the event handler disappears when you replace the innerHTML is straightforward enough - you are removing the elements that the handlers are on, so the handlers are removed as well. But your approach to re-add the handler should work.
I think it's possible that it's a scoping issue. What happens if you reference the div explicitly, like this:
row.getElement('.b_l').addEvent('change', function(event){
{
changeValues($$('div.selections .b_l'));
});