Rangy commonAncestorContainer wrong when using anchor without href - angularjs

I'm using Rangy in conjunction with AngularJS. Angular replaces href with ng-click, so calling a function becomes:
<a ng-click='theFunctionThatCallsRangy()'>Get Range</a>
Unfortunately,
range.commonAncestorContainer
is returning the node of the anchor instead of the selection:
<a ng-click='theFunctionThatCallsRangy()'>Get Range</a>
and
range.collapsed
returns true. This leads me to believe clicking the anchor responsible for generating the range is destroying the selection before the range can be created from the selection.
As soon as I modify the anchor to:
<a href='#' ng-click='theFunctionThatCallsRangy()'>Get Range</a>
the range is created as expected. However, adding href='#' causes Angular to redirect to the root domain ('/'). Swapping out <a> for <button> also works, however this breaks existing CSS.
Why is this happening? Does Rangy expect href to be present in anchor tags? Workarounds?

Rangy is only reporting what the browser tells it about the selection and has no opinion about whether the href attribute is present. As you correctly diagnosed, the problem is that when you click on an <a> element, the existing selection is destroyed by the time the click event fires. Assuming you continue using these <a> elements, your options are:
Use the mousedown event instead
Make the <a> element unselectable, which will obviously have its own consequences
Demo: http://jsfiddle.net/M6AAy/

Related

Angular-ui-router and href='#'

I'm using angular-ui-router and have an issue with empty a tags, like href='#'. I'm using bootstrap, which makes extensive use of href='#' for dropdowns and such. The problem is if a user selects a dropdown item then the router interprets that as a state change, which in this case is to the home page.
Is there an easy way to stop this behavior without having to resort to changing all the href='#' to href=''.
Just remove the href tag completely from your anchor tag. It's still a perfectly valid tag without it.
Or if you're currently using ui-sref in the anchor tag, you could actually use the href attribute instead to go to the route that the state is mapped to.
you can use this, so you can preserve the link and basically do nothing when its clicked
<a ui-sref="state" href="javascript:void(0);">Your link</a>
I use this:
<a href-void>Click me! I don't do anything, but i'm still a link!</a>

put html DIV into a popover content angular UI

Is it possible to put html content into a popover?
this is the string that i need to put into the popover
HTML
$scope.info="sentence " +
"<ul>"+
"<li>first list member</li>"+
"<ul>"+
"<li>element of the first list</li>"+
"</ul>"+
"</li>"+
"<li>second element</li>"+
"<ul>"+
"<li id=\"infoLi\">element of the second</li>"+
"</ul>"+
"<li>third element</li>"+
"<ul>"+
"<li id=\"infoLi\">first element of the third</li>"+
"<li id=\"infoLi\">second element of the third</li>"+
"</ul>"+
"</ul></div>"
I have seen in the documentation of angular-ui-popover, that it is possible to set the option of the popover, and seeing around the web I find someone says that it is possible, in this option, to set a parameter HTML to true and get this result.
I have found no sample of that, and i don't know if it is true, my first problem to attempt this is that i didn't understand how to set the options.
A possible solution for me is even to leave a string in the popover but i need to use the new line tag, that i see it doesn't work in the popup content.
EDIT
maybe i wasn't so clear, i'm trying to do that with angular ui and ui bootstrap.
ok i have found a solution, that as i saw, for the moment it doesn't work for the popover ,while for the tooltip yes.
HTML
<button id="infobtn" tooltip-html-unsafe="<div>first list member
<li>element of the first list</li>
second element
<li id='infoLi'>element of the second</li>
third element
<li id=\"infoLi\">first element of the third</li>
<li id=\"infoLi\">second element of the third</li>
</div>
"tooltip-trigger="mouseenter">
<img src="images/info.png"></button>
The tag tooltip-html-unsafe make possible to insert a DIV or anything else is html, in the tooltip content, i have try to use it in the popover too but for some reason it doesn't work. I don't know if the cause was something that i was doing wrong or else, so i decided to use ui.tooltip module and i have resolved the problem.

Bootstrap's tabs with data-toggle cause reload in angularjs

I've just migrated to AngularJS 1.2. And I've realized that all my menu/navigation elements that were configured with data-toggle, for instance:
<li>Additional Selection</li>
are not working any more. They should toggle element with id="additionalSelection" - and this is how Angular & Bootstrap worked when I was using version 1.0.8 of Angular.
But now, when I click anchor element, Angular intercepts this click and tries to go to route additionalSelection and it causes page refresh...
Is there a way to fix it?
The solution is as simple as replacing href attribute with data-target. That solves the issue:
<li><a data-target="#additionalSelection" data-toggle="tab">Additional Selection</a></li>
As dragonfly pointed out, data-target works fine instead of href.
There is a small difference in CSS. When data-target is used vs href, the cursor is not a pointer anymore. If you don't want to add extra CSS, you can do the following:
Selection
This is just a suggestion, not an elegant solution. But if you want to use href for some reason, add onclick="return false;"
Simply replace href attribute from data-target
<li><a data-target="#switchTabs" data-toggle="tab">Tabs</a></li>
The solution preserving the cursor (while still relying on data-target instead of href to navigate) is:
<li>Additional Selection</li>
the addition of href causes the cursor to switch to the hand, but leaving it blank as "" doesn't cause any page reloads.

Dynamic binding of ng-click?

When a user takes a certain action, I insert a link into the text of a contenteditable field:
var newElement = document.createElement('span');
newElement.innerHTML = "<a id='123' class='cite' href='' data-ng-click='review(123);'>[‡]</span>";
range.insertNode(newElement);
$compile($(newElement).contents())($scope);
When the user clicks onthe new field, I want to execute the review method of the activate controller. ($scope.review = function(id) {...};)
Instead the page navigates to '#', without calling review();
I am assuing the click method doesn't get 'bound' to $scope.review() by a call to range.insertNode(newElement); ? I tried wrapping in an $apply, but that didn't work.
Use href="" instead of href="#" with Angular. The default action is always prevented if the href is empty. http://docs.angularjs.org/api/ng.directive:a
Also make sure to $compile that element. Ideally this would be a case for ng-repeat if what you're doing is essentially making a list of elements.
In the code of your template, you can remove the href attribute altogether. If you want it to navigate, include that in the ng-click expression.
You don't need an href tag at all in the element for ng-click to work. If you want the pointer to change on hover, you can use an inline style or css.

href="#" causes location address to change, can we avoid it?

I have a number of tabs that I handle special logic so no location bar address change should occur. I have the following
Home
This behaves as expected, i.e. it gives me the hand mouse pointer when hovering over the buttons but clicking on then starts the route change. I want to be able to stop this.
I tried just remove the href or setting href="", seemed to have some success but it gave unexpected results when hovering.
What is the best practice here? Do I have to remove the href? So then I will need to style the tab using CSS to give me the mouse pointer when hovering? If I do leave the href="#" in the link then this causes a change of routing which is not what I was looking for.
I actually handle my login in a ngClick for each tab. This logic must not change the route.
Any ideas?
Try doing:
Home
If you don't use the <base> tag, you can simply use:
Home
Indeed, according to the documentation:
[...] the default action is prevented when href attribute is empty.
Well, the documentation is wrong, and the real behaviour is actually to prevent the default action when the href attribute is equal to page location. That's a problem when you're using <base>. In this case, you have two choices:
Forget the href attribute. That works fine, but your page will not be valid anymore, since the href attribute is mandatory for a <a> tag.
Create your own directive, for instance aEmpty, whose goal is simply to fill the href attribute of a real <a> with the current value of $location.path().
In all cases, you'd better to actually use CSS to style your link, because that's always a bad idea to rely on the default behaviour of the browsers.
Replace href with ng_click.
To get the hand mouse pointer, add the css style:
a { cursor: pointer ; }
a:hover { color: #00c } /* user hovers */

Resources