Wrap html element with Divs from custom directive - html

I have an <input /> tag which I want to wrap with some specific Div tags. I'm making custom directive in which I want to implement this functionality. But the problem which I'm facing is, element's prepend() method adds the whole tag i.e. it starts and ends before the targeted input tag. Similarly, append() method on element appends the Div inside the input tag, while what I actually want is,
On html:
<input id="oldinput" custom-textbox /> <!-- custom-textbox is my directive -->
After applying directive, in source, I want this:
<div id="mynewdiv> <!-- added from directive -->
<input id="oldinput" custom-textbox /> <!-- present input tag where I'd apply my directive -->
<div id="othernewdiv" /> <!-- new div to be added from directive -->
</div> <!-- end of newly added div from directive -->
But the result after using append() and prepend() functions:
<div id="mynewdiv> </div> <!-- added from directive, div ends here only -->
<input id="oldinput" custom-textbox > <!-- present input tag where I'd apply my directive, doesn't end here -->
<div id="othernewdiv" /> <!-- new div to be added from directive, it's added inside input tag -->
</div> <!-- end of newly added div from directive -->
</input> <!-- Wraps my newly added div -->
Completely strange behavior. Can someone help me with this?

wrap() does exactly what you want:
// wrap the input with a div
element.wrap('<div id="mynewdiv></div> ')
// add the second div
element.parent().append('<div id="othernewdiv" />')

You should take a look at ngTransclude and also the Developper Guide.
Creating a Directive that Wraps Other Elements
We've seen that you can pass in models to a directive using the
isolate scope, but sometimes it's desirable to be able to pass in an
entire template rather than a string or an object. Let's say that we
want to create a "dialog box" component. The dialog box should be able
to wrap any arbitrary content.

Related

How to manipulate DOM elements inside a TemplateRef without using pure javascript

I have this template in my Component class
<ng-template #thumbnailTemplate>
<div> <!-- top level div of thumbnail. This will have ids thumbnail-1, thumbnail-2 etc.-->
<img> <!-- this will have width, height=80-->
<a></a> <!-- the X button is created using CSS. This will have ids close-button-1, close-button-2. They'll also containn reference to the parent div id (thumbnail-1, thumbnail-2 ) -->
</div>
</ng-template>
<div class="form-group">
<div class="custom-file" id="file-upload" lang="es">
<input type="file" class="custom-file-input" id="question-file-upload" formControlName="image" [ngClass]="validateField('image')" (change)="handleFileSelect($event)" required>
<label class="custom-file-label" for="question-file-upload">
Select file...
</label>
</div>
<div id="image-thumbnail-container">
<ng-container #thumbnailContainer ></ng-container> <!-- This will contain the view created from #thumbnailTemplate. It can have multiple thumbnails. Check .ts file-->
</div>
</div>
</div>
When the use selects an image file from input element, I want to show a thumbnail of the image. I am able to do this using pure javascript code (createElement, setAttribute, addEventListener etc.) but I suppose I shouldn't mix JS code in Angular. So I plan to use ViewChild, Renderer2, ViewContainer and TemplateRef).
So far, I have got to the point where I have got reference of the template and the view container.
#ViewChild("thumbnailContainer",{read:ViewContainerRef}) thumbnailContainerRef:ViewContainerRef;
#ViewChild("thumbnailTemplate",{read:TemplateRef}) thumbnailTemplateRef:TemplateRef<null>;
#ViewChild("image-thumbnail-container",{read:ElementRef}) imageThumbnailContainer:ElementRef;
But I don't know how to get access to the div, img and a inside the template? As a user can select multiple files, the ViewContainer can have multiple Views of the TemplateRef. So I want to give the div and a different ids and also set the src of the img. I suppose I can useRenderer2APIs to set the attributes but for that I need to passnativeElementof thediv,imgandato it. But I don't know how to getnativeElement` of these as they are inside a template.

How to create tooltip directive that will work on any html element with angular 2?

Look at this simple tooltip onMouseOver event:
http://jsfiddle.net/HJf8q/2/
I would like to create a simple tooltip directive in angular 2 that any HTML element that will have that directive, will add dynamicly the innerHTML needed for that tooltip to work.
If I have a simple div:
<div id="mySimpleDiv">Hello div</div>
Than adding tooltip directive should create dynamicly the next innerHTML:
<div id="mySimpleDiv" tooltip>Hello div
<!-- the innerHTML should be added -->
<span id="tooltip-span">
DO THIS
</span>
<!-- the innerHTML should be added -->
</div>
now, I understand directive don't have template, they add behavior, but what if the behavior is innerHTML? Should I use another component with the template? How to approch this?

Styling inside an HTML input tag

Say I have the following text input element:
<input type="text" value="Bruno">
Can I make the "B" in the value Bold? So it looks like Bruno?
I know it is pretty straightforward within <span> and <div> elements:
<span><strong>B</strong>runo</span>
But is this possible with an <input> element? If so, would the value still remain the same regardless of the styling applied to it?
An <input> or <textarea> element on it's own won't support this type of behavior. You could use an approach that would hide your actual element and use a facade to copy the values from your element and output them as raw HTML into a <div> to be displayed :
<!-- An element to handle typing your content that calls a function -->
<input id='input' onkeyup='updateOutput(value);' />
<hr />
<!-- Your output element (to display your content) -->
<div id='output'></div>
<script>
// A function to map your content and output it in your "output" element
function updateOutput(html){
document.getElementById('output').innerHTML = html;
}
</script>
You can see an example of this here and demonstrated below :
A better alternative might be to use a Javascript-based HTML editor like TinyMCE or CKEditor.

Change a div position dynamically in angularjs

I have a (complex) toolbar panel which can be on top or bottom of a page (it's configurable). Is there any way to avoid copy/paste the toolbar in bottom of the page?
Here is code in copy/paste way:
<div id="topToolbar" data-ng-show="configs.toolbarPosition=='TOP'">
<!-- toolbar -->
</div>
<div>
<!-- inner page contents -->
</div>
<div id="bottomToolbar" data-ng-show="configs.toolbarPosition=='BOTTOM'">
<!-- exactly copy/pasted toolbar -->
</div>
Keep the tool bar html in separate file, and include where ever you need.
<ng-include src="'views/toolbar.html'"></ng-include>
Also if you needed add a controller for all functionality. This will help you to reuse your code.
you can check how components are made
and make component <toolbar></toolbar>

Why tag P popups the DIV when contains DIV?

JSBIN
HTML
<p>
<div>123</div>
</p>
CSS
p div{
background:#f00;
}
I have a strange issue. When I code a structure as following HTML. Actually, User agent(browser) parse the code to :
<p></p><div>123</div>
So, the css code is ineffective.you can check it out in JSBIN.I want to know what the reason about this behavior and whether there are another similar tags have this behavior? Thanks.
This is a combination of two features of HTML.
First, the p element is not allowed to contain a div element. The spec gives its content model as "Phrasing content" which does not include div elements.
Second, the end tag for the p element is optional. (See tag omission under the above link to the spec)
<p> <!-- Start P element -->
<div> <!-- Start DIV element. Implicitly end P element -->
123 <!-- Add text node -->
</div> <!-- End DIV element -->
</p> <!-- No open P element so this is discarded by the parser -->