Triple-click selects the next element with Angular Bootstrap modal - angularjs

I have an Angular application using (UI) Bootstrap and I'm displaying a URL in a modal-body inside well and code elements. The modal-footer just has a Close button. Now if one triple-clicks the URL to copy it, the Close button text in the footer is also selected and one can not paste it to another tab as usual.
Fiddle here
<div class="modal-body">
<div class="well">
<code>http://www.google.com/</code>
</div>
</div>
<div class="modal-footer">
<button type="button" ng-click="close()" class="btn btn-primary" data-dismiss="modal">Close</button>
</div>
I have searched a lot but cannot come up with a solution (have tried CSS's user-select, wrapping it in different elements, which do not seem to work).

Replace <button> by <input> to disable text selection:
<input type="button" ng-click="close()" class="btn btn-primary" data-dismiss="modal" value="Close"></input>
Updated Fiddle

Not exactly a scientific or technical answer (as I don't fully grasp the browser's Selection API); but what I have observed is that when you triple click the last child element in a DOM branch, it creates a hanging selection (for lack of a better term).
By hanging selection, I mean that it tries to look for the next selectable text element, but since it's the last child that was selected, it traverses the DOM to find the next text element. In my specific case, I was dealing with something like this:
<div>
<h2>Section Header</h2>
<div>
<p>foo</p>
<p>bar</p><!-- triple clicking this would select the next h2 content!! -->
</div>
</div>
<div>
<h2>Next Section Header</h2>
...
</div>
The solution I arrived at came from the naive thought of "give it something else to select" so that it wouldn't go looking elsewhere in the DOM. So this definitely feels more like a hacky workaround, but simply inserting 0-height <br> elements (so as not not affect the existing layout) immediately after any content that I expect users may try to triple click solved all of my issues.
So in OP's case
<div class="modal-body">
<div class="well">
<code>http://www.google.com/</code>
<div style="line-height: 0px;"><!-- line-height is what affects br height, and you can't apply line-height directly on br tags for whatever reason -->
<br />
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" ng-click="close()" class="btn btn-primary" data- dismiss="modal">Close</button>
</div>
At the time of posting this, there isn't much info about these types of issues so I figured I would share what worked for me in hopes that it helps someone else.
One good source of info I did find was in the form of a github issue comment here
It turns out there are a bunch of ways to cause hanging selections (because of the nature of the functionality I'm building, I could only verify that my solution works for #1 and #4):
triple-click on a paragraph
place the cursor at the beginning of a paragraph, shift-arrow-down past the end of the paragraph
place the cursor at the beginning of a paragraph, shift-arrow-right to the end of the paragraph (selects the text within the paragraph), then shift-arrow-right again (selects the whole paragraph)
drag the cursor from the beginning of a paragraph to the end (selects the text within the paragraph), then drag a little further / down (selects the whole paragraph)

Related

Tampermonkey Remove specific Content

I would like to remove things from the main page but the information I need is stored on the next site. How do I approach this?
This is stored on the first page where I can see all articles and all links in href have different numbers, sometimes numbers and letters.
<div class="NewsArticle">
<div class="featured-content-image">
<a href="/27312/72410214/" rel="bookmark">
<img class="imageclass" referrerpolicy="no-referrer" data-original"https/domainname.com/2021/0/Article01.jpg" src="https/domainname.com/2021/0/Article01.jpg" alt="Article01" style="display: inline;">
<div class="link-overlay"></div>
</a>
<span class"article-views">170392 Views</span>
</div>
This is on the second site where, for example, "military" is stored for whatever reason. Is it possible to remove the articles that contain "military"?
<a title="military" href="/category/military" rel="tag" style="margin-right:3px;margin-bottom:3px;" class="btn btn-info btn-md">military</a>
using jquery you can do something like
$("div").remove()
this selects all the divs and removes them
or you can do
$( "div:contains('military')" ).remove()
this looks at all divs if the divs have military in it it is then removed
IMPORTANT:
Make sure to have
// #require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
And declare the variable
/* globals jQuery, $, waitForKeyElements */

How to click on a parent whose child contains a particular text

I am new to webdriver and I am automating a site. In which I have to find a text on that page and I want to click on its parent div. Can anyone please help?
Below is the HTML code.
<div class="col-md-6 col-sm-6 col-lg-6">
<p>
<strong class="detailShow ng-binding" ng-click="showJobs('NonInvite',item.taskId)"> TEST CR1 START DATE </strong>
</p>
</div>
The easiest way to achieve this is directly using xpath.
You can choose the 'more ugly' way like this:
.//strong[contains(#class,'detailShow')]/../..
Explanation:
/.. - this is how you get the parent element. Having just one, means that you'll get the <p> tag, so to get the <div> you need another one.
Or, you can go in a better manner like this:
.//strong[contains(#class,'detailShow')]/ancestor::div[#class='col-md-6 col-sm-6 col-lg-6']
Explanation:
ancestor::div - this one goes up until and returns all parent that are <div> tags. Since you need only the first <div> parent, you need to specify which one, therefore: ancestor::div[#class='col-md-6 col-sm-6 col-lg-6']
Now, if the bootstrap class is your only identifier, and there is a chance you may be inside a <table> you can also go with ancestor::div[1]

Angular-Elements are not refreshing after aborted drag&drop

I have the following angular-List (reduced the content to make it better readable):
<div ng-repeat="element in bigBlock.Elements track by $index"
class="singleBlockElement"
ng-drop="dragSource=='Block'"
ng-drop-success="To($index, $data, bigBlock)">
<div class="bbRange"> </div>
<i class="fa {{GetImage(element)}}" />
<div ng-drag="element.ElementType!=='placeholder'"
ng-drag-data="element"
ng-drag-start="Start()"
ng-drag-success="From(element,bigBlock, $index, bigBlock.$index)"
ng-drag-stop="Stop(element, bigBlock, $index, bigBlock.$index)"
class="cutOff">
{{element.Title}}
</div>
<div class="edit ng-show="GetLinkText(element, true)">
<span class="isvisible">
<i title="{{element.Present?'Präsentieren':'Nicht präsentieren'}}" class="fa fa-{{element.Present?'eye':'eye-slash'}}"></i>
</span>
{{GetLinkText(element,true)}}
</div>
</div>
This is how it looks like:
This is while dragging:
And this is how it looks like when I simply don't drop like described below:
I can now (successfully) drag & drop the two elements ("Welcome" and "Go Away") inside that block changing the order of these two.
But if I abort the drag/drop. e.g. Dragging "Welcome" and not moving it downwards or moving it to an area where I cannot drop (outside the block) the text "Welcome" disappears.
There are no errors. The drop is just not happing (as expected), but Angular seems to be unable to redisplay the text of that element. ({{element.Title}})
I event tried forcing a refresh using $apply(), but this did not change a thing (not creating an error either).
However, if I do ANYTHING on the page like clicking on an edit-button or anything else that causes an event, the date is correctly shown again.
So it looks like a refresh issue for me.
I am using ngDraggable for this (https://github.com/fatlinesofcode/ngDraggable)
(Update: Analyzing the page source in Developer Console of Chrome the text still seems to be there and even "should" be visible (display:block), so this might be more of a browser-issue (chrome) than an angular-issue)
This seems to be a pure Browser/CSS-Issue and not an Angular-Issue. I solved this by forcing the browser to refresh the parent container:
$('.mm-Right')[0].style.display = 'none';
$('.mm-Right')[0].offsetHeight;
$('.mm-Right')[0].style.display = 'block';
where my structure is
<div class='mm-Right'>
<div class='singleBlockElement>[..]</div>
<div class='singleBlockElement>[..]</div>
<div class='singleBlockElement>[..]</div>
</div>
That did solve the problem but looks like cheating for me. I would prefer that this bug not even appears instead of hiding the symptoms. So I am happy to accept any better answer for that problem.

Model update not triggering consistently

I'm experiencing some very peculiar behaviour--I'm new to angular, to spare you the noob questions, I tired my best to find the solution but after many hours, I think it's time to give in and ask.
Code Summary: Alphabet array, is looped(ng-repeat) and each letter is linked to a function called clickLetter(), this function sets a $scope variable that reflects the current chosen alphabet letter.
Problem: the model/variable in charge of displaying the current active letter is not updating ALL the time, it only appears to update sometimes, randomly it seems.
Code (plunker)
My guess is, angular is not updating the model (two-way data-binding?) as fast as it should?
It looks like the <a> tag is triggering a route change. Either add an $event.preventDefault() to it or remove the <a> altogether. (doesn't seem like it's adding any value)...
<div class="ui icon button padding5" ng-class="{'active': letter == activeLetter}" ng-repeat="letter in letters" ng-click="clickLetter(letter, $event)">
{{letter}}
</div>
or
<div class="ui icon button padding5" ng-class="{'active': letter == activeLetter}" ng-repeat="letter in letters" ng-click="clickLetter(letter, $event)">
{{letter}}
</div>
The problem is, when you click on letter and not on button,the link stops the propagation of your mouse click.
Add this class in your css file and apply to <a> tag, which holds the letter:
.ignore-mouse-event {
pointer-events: none;
}
<a> tag should be changed to this:
{{letter}}

angular ui-router maintaining state between tabs

Would like to know the best way to preserve state between tabs. I use bootstrap tabs and angular ui-router. I've a google map in one of the tabs and don't want to reload the map when user selects that tab. Please advise.
Thanks
I think what you are looking for is discussed in this issue: https://github.com/angular-ui/ui-router/issues/63
They are mostly discussing iframes but I believe the same should hold for Google Maps. Unfortunately in the thread they decided that this isn't something that should be implemented in the core release. I haven't tried out the directive they provide (if I get a chance I'll let you know how it goes) but you may be able to get something working with that.
I have actually come across the exact problem you had. My solution was to use styled buttons as my tabs and ng-show for the map tab:
<div id="info-btns">
<button class="btn" ng-model="view" btn-radio="'info'">
Info
</button>
<button class="btn" ng-model="view" btn-radio="'map'" ng-click="loadMap()">
Map
</button>
</div>
<div class="content" ng-show="view != map">
<div ui-view="info"></div>
</div>
<div id="map-container" ng-show="view == 'map'">
<div id="map" class="content" sitemap>
</div>
</div>
ng-show simply uses display:none to hide the map and hence doesn't cause a refresh. You will need to trigger the map to load the first time it is not hidden otherwise it will render incorrectly, hence loadMap()
If I get a chance I'll set up a jsfiddle of this in practice.

Resources