#shadow-root in angular template - angularjs

I have an an input box in my angular template that looks like below:
<input type="text"
name="growth"
label="Growth"
ng-model="mySettings.growth"
class="input-mini text"
required
integer
min="0"
max="4"
tooltip
tooltip-trigger="{{{true: 'mouseenter', false: 'never'}[mySettings.growth.$invalid]}}"
tooltip-placement="right"
/>
When this is rendered by angular, it looks like below:
<input type="text" name="growth" label="Growth" ng-model="mySettings.growth" class="input-mini text ng-scope ng-pristine ng-valid ng-valid-required ng-valid-integer" required="" integer="" min="0" max="4" tooltip="" tooltip-trigger="never" tooltip-placement="right">
#shawdow-root (user-agent)
<div id="inner-editor">10</div>
</input>
What is this #shadow-root element that's showing up above ?

The #shadow-root is not really an element, but an annotation added by the browser to make clear that the following element (the .inner-editor div element) is the Shadow DOM added by the browser to display the input field.
Consider a more complex form element like a slider. As a developer you simply set the input type to "range" and have a functional slider which is represented by a single input tag.
The knob and the slider track is rendered by the browser as well, but hidden for any CSS selectors or JavaScript DOM traversal functions since you only add a single input tag it would break things if the browser silently attaches DOM nodes to render the slider correctly. This "hidden DOM elements" are called Shadow DOM.
In Chrome Browser the visibility of the Shadow DOM in the Elements tab can be switched by an option under Settings > General > Elements > 'Show user agent shadow DOM'.
For further information about Shadow DOM I found this link from HTML5 Rocks and this resource were very helpful for me.
This Shadow DOM elements can be found inside a normal input tag as well, it does not relate to the AngularJS input directive you have in your example.
For CSS selection there is a ::shadow pseudo class and also a JavaScript Shadow DOM traversal API - see the HTML5 Rocks link above.
The upcomming WebComponents make use of the shadow DOM. If you are interested in implementations you may have a look at thePolymer project and its sources which makes heavy use of the Shadow DOM.

Related

Angular Translate Href _blank doesnt work

I've implemented angular translate and it's working well so far.
I do have one problem with the following code though:
REGISTER_RULES_ACCEPT : ' I have read the Rules and hereby accept them.<span class="registration-important">*</span>',
Html Implementation:
<input id="checkbox" type="checkbox" name="checkbox" value="rules"><a translate="REGISTER_RULES_ACCEPT"></a></input>
It displays correctly and everything, when going over the link with my mouse it shows the link in the bar. However when I click it, nothing happens. I can right mouse or mid mouse click it and open it in another tab, but left clicking it does nothing. Any idea whats the problem here?
You already have anchor a tag in translation then just bind it in span or paragraph element in view code. So, your template code can be:
<input id="checkbox" type="checkbox" name="checkbox" value="rules" />
<span translate="REGISTER_RULES_ACCEPT"></span>
Plunker Example

How can I reliably set focus on elements inside of my AngularStrap tooltip?

My team uses AngularStrap to integrate Bootstrap modals (e.g. popover, tooltip, etc.) into our Angular 1.5 app. Unfortunately, I have found it extremely difficult to reliably set focus on elements inside of these modals because of the funky way in which AngularStrap shows them. This logic lives here:
https://github.com/mgcrea/angular-strap/blob/b13098d9d658da9408930b25f79182df920718d2/src/tooltip/tooltip.js
Essentially, all AngularStrap modals start off in the hidden state:
// Set the initial positioning. Make the tooltip invisible
// so IE doesn't try to focus on it off screen.
tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});
They are then made visible in response to some internal Angular requestAnimationFrame service callback:
$$rAF(function () {
// Once the tooltip is placed and the animation starts, make the tooltip visible
if (tipElement) tipElement.css({visibility: 'visible'});
...
});
Unfortunately, this means that at the time all of the tooltip's DOM elements are constructed the tooltip is typically not yet visible and any attempts to call focus() on these elements fail. Do note that in my experience this happens intermittently (~20% of the time for me).
I tried disabling animations on the tooltip but it doesn't seem to be smart enough to skip this whole hidden/visible dance in that case. I could obviously try something super hacky (e.g. use an arbitrary timeout before attempting to set focus) but I am looking for a more reliable option.
Why not use the onShow event? It is documented a little bit wrong, but you can attach a handler that focus elements to bs-on-show. Furthermore you could make the handler generic, looking for an element with a focus-me attribute and focus that :
<div bs-popover
data-content='this input should be focused: <input type="text" focus-me>'
data-placement="bottom"
bs-on-show="setFocus"
data-html="true">
click me to show popover
</div>
<div bs-tooltip
data-title='this input should be focused: <input type="text" focus-me style="color:#000;">'
data-placement="bottom"
data-trigger="click"
bs-on-show="setFocus"
data-html="true">
click me to show tooltip
</div>
generic handler
$scope.setFocus = function(e) {
e.$element.find('[focus-me]').focus()
}
http://plnkr.co/edit/3wTinmNb5zsKnfUZQ9tT?p=preview

How can I use bootstrap's grid columns to set the width of X-Editable inputs?

I'm using angular-xeditable, the Angular flavor of X-Editable. I'm trying to adjust the input width using Bootstrap's grid column classes.
A similar question, x-editable - adjusting the width of input field, offers solutions that change the width using custom styles/classes, but I want to incorporate Bootstrap's grid system.
Bootstrap
Wrap inputs in grid columns, or any custom parent element, to easily enforce desired widths.
<div class="row">
<div class="col-xs-4">
<input type="text" class="form-control">
</div>
</div>
col-xs-4 exists on the parent div, and not the input itself.
X-editable
X-Editable renders a structure of form:
<a>hidden</a>
<form>
<div>
<input/>
</div>
</form>
and applies custom styling to the input.
Demo (JSFiddle)
I've created a fiddle to demonstrate the problem here: http://jsfiddle.net/NfPcH/10908/.
How can I incorporate Bootstrap's column grid widths with X-Editable?
There are several gotchas that I ran into, but I managed to find a solution.
First, we cannot use form-inline with Bootstrap's column grid system. To remove this, we must override the form template in X-Editable. We also need to add a configurable way to apply the bootstrap column class.
yourAppName.run(function(editableOptions, editableThemes) {
editableOptions.theme = 'bs3';
editableThemes.bs3.formTpl = '<form class="editable-wrap" role="form" ng-class="xformClass"></form>';
});
Because we removed form-inline, we cannot use X-Editable's built-in buttons. We can remove them by applying buttons="no" to the editable element.
Finally, we assign the form class in our controller (the caveat is that all inputs will have the same column count per scope):
$scope.xFormClass = "col-sm-12";
This gets us most of the way there, but there's some padding weirdness. This is because both the form and its parent have column classes. I hacked it out by adding the row class to the input's parent:
editableThemes.bs3.controlsTpl = '<div class="editable-controls form-group row" ng-class="{\'has-error\': $error}"></div>';
The updated fiddle is here: http://jsfiddle.net/NfPcH/10933/. Hope this helps!

Angular-Material: Md-slider dots not showing within directive template

I am using the MD-Slider with the md-discrete option to display the ticks on the track.
Strangely though the ticks of the slider within a directive template are not displayed. But outside the directive it works.
I have added a screenshot to show you. See the JADE code for this example:
div.sliding-footer-panel(ng-class="{ open: openFooter}" layout="column")
div.trigger(layout="column" layout-align="center center" ng-click="openFooter=!openFooter")
md-icon(ng-hide="openFooter" md-svg-icon="hardware:ic_keyboard_arrow_up_24px")
md-icon(ng-show="openFooter" md-svg-icon="hardware:ic_keyboard_arrow_down_24px")
md-slider.md-primary(md-discrete flex min="-0.5" max="4" step="0.5" aria-label="Change play rate")
div.footerContent(layout="column" flex)
audio-player
The directive audio-player loads the <audio> tag and the slider next to it.
The slide above the footerContent div is rendered correctly in the main view and renders the dots.
When I look at the canvas tag within the track element I see that its dimensions are 0. The one loaded outside the directive has normal dimensions.
So I recon the CANVAS tag is not loaded correctly via the directive. Anyone an idea how to fix this?

Icon on AngularJS input type button

I can't find any info on this but I'm sure there must be a simple solution. How do you insert an icon in AngularJS input type button. Something like this (although it obviously won't work):
<input type="button" ng-click="someAction()"/>
<i class="fa some-icon"></i>
</input>
I know how to do it with normal button elements, but is it possible with AngularJS?
The input tag doesn't allow tags inside it, but it's easy to make it look like there's an icon in the input. Bootstrap and Angular Material include this in their components.
Bootstrap Input Group
Angular Material input prefixes

Resources