This question already has answers here:
Include another HTML file in a HTML file
(41 answers)
Closed 3 years ago.
I want to insert a navigation div inside all of my HTML documents. Is there a way to do so without putting the entire div inside of every document? I figured the solution would be similar to a CSS stylesheet.
I don't know of anyway of doing this without Javascript or jQuery, which I want to avoid using if possible.
<html>
<body>
<div>
//CONTENT//
<div>
</body>
</html>
I want to put the div inside of a separate document and put in a link of some sort to substitute that in every document that contains the div.
Edit: I Haven't notice that you also don't want to use JS.
I'll leave this answer as a partial solution for you problem.
The Solution:
If you don't want to use ANY Library like JQuery or frameworks like Angular/React/Vue then you have the option to use Web components (I've added the description from the link below).
Notice: Don't forget to check for Browser support.
With that you can choose HTML templates or Custom elements.
Let's take an example of HTML template:
<table id="producttable">
<thead>
<tr>
<td>UPC_Code</td>
<td>Product_Name</td>
</tr>
</thead>
<tbody>
<!-- existing data could optionally be included here -->
</tbody>
</table>
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
Now that the table has been created and the template defined, we use JavaScript to insert rows into the table, with each row being constructed using the template as its basis:
// Test to see if the browser supports the HTML template element by checking
// for the presence of the template element's content attribute.
if ('content' in document.createElement('template')) {
// Instantiate the table with the existing HTML tbody
// and the row with the template
var template = document.querySelector('#productrow');
// Clone the new row and insert it into the table
var tbody = document.querySelector("tbody");
var clone = document.importNode(template.content, true);
var td = clone.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";
tbody.appendChild(clone);
// Clone the new row and insert it into the table
var clone2 = document.importNode(template.content, true);
td = clone2.querySelectorAll("td");
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans 2";
tbody.appendChild(clone2);
} else {
// Find another way to add the rows to the table because
// the HTML template element is not supported.
}
What is web components (From the developer.mozilla.org docs)?
As developers, we all know that reusing code as much as possible is a good idea. This has traditionally not been so easy for custom markup structures — think of the complex HTML (and associated style and script) you've sometimes had to write to render custom UI controls, and how using them multiple times can turn your page into a mess if you are not careful.
Web Components aims to solve such problems — it consists of three main technologies, which can be used together to create versatile custom elements with encapsulated functionality that can be reused wherever you like without fear of code collisions.
Custom elements: A set of JavaScript APIs that allow you to define custom elements and their behaviour, which can then be used as desired in your user interface.
Shadow DOM: A set of JavaScript APIs for attaching an encapsulated "shadow" DOM tree to an element — which is rendered separately from the main document DOM — and controlling associated functionality.
In this way, you can keep an element's features private, so they can be scripted and styled without the fear of collision with other parts of the document.
HTML templates: The <template> and <slot> elements enable you to write markup templates that are not displayed in the rendered page. These can then be reused multiple times as the basis of a custom element's structure.
Related
I'm setting HTML returned from the API in my Angular component:
<div [innerHTML]="content"></div>
content in this example is something like this:
<table>
<tr>
<td>[audioPlayer:file.mp3]</td>
</tr>
</table>
Now I would like to inject the actual component inside the table cell.
If I make a certain container, I can create the component with createComponent:
audioPlayerComponentRef: ComponentRef<AudioPlayerComponent>;
#ViewChild('placeholder', { read: ViewContainerRef }) container;
const factory: ComponentFactory<AudioPlayerComponent> =
this.componentFactoryResolver.resolveComponentFactory(AudioPlayerComponent);
this.audioPlayerComponentRef = this.container.createComponent(factory);
Then I can inject it into a container in the template:
<div #placeholder></div>
However, going back to my original goal, I can't use such a container, as the component needs to be injected into a specific position into an innerHtml block.
I've been brainstorming all day, but I can't see any way to achieve this.
Generally speaking, this is contrary to the way Angular works. [innerHTML] is not parsed for any Angular functionality. No component selectors or even a ViewContainerRef can be found there. Rather, even remotely suspicious HTML, CSS and JS is removed as a security measure as Angular only trusts its own templates.
So InnerHTML is a no-go. But I was in the same boat myself and have written a library to solve this exact problem. With it, you can freely load dynamic components into strings without compromising security. If you're still stuck on this, you might wanna have a look at it.
In codedUI I am unable to traverse by GetChildren() method in an html page with HTML5 tags.
My Html structure is like this.
HTML
|-BODY
|-DIV id="pagetop"
|- HEADER class="headerclass"
|- NAV class="navclass"
|- SECTION class="sectionclass"
|- FOOTER class="footerclass"
|- DIV id="lastdiv"
Issue: On doing GetChildren() on "pagetop" div control, only 1 result is returned having "lastdiv" div control in it.
It should return 5 controls instead.
I am able to capture the UIMap for SECTION(or other HTML5 tags) and able to traverse backward by GetParent() method, but the other way is not working.
SECTION.GetParent() = DIV id="pagetop" [Works as expected]
SECTION.GetParent().GetChildren() = Only 1 result [This is wrong, should be 5]
Is there an issue with traversing HTML5 tags in codedui?
Try looking at the child controls of the one control that is found. I am not aware of anything that says the HTML structure you show MUST be represented with exactly the same number of levels. Phrasing that differently, the UI Controls might have extra levels than the minimum that appear to be necessary for the HTML structure.
To understand how the HTML is represented you could use the Coded UI cross-hairs tool. Start with one of the five sections (or a child of theirs) and then use the four navigation arrows to move up through the hierarchy to see what items Coded UI can see at each level.
Another approach might be to use recursive code that calls GetChildren() to descend the hierarchy and show exactly what is present at each level. You might use code based on the recursive routine in my answer to this question Recursively locating a UIElement with InnerText in C# but using a small maxDepth and adding some Console.Writeline() or other print statements to display the controls found.
I have filed one bug in VS2013 feedback forum for this issue.
It can be tracked here: https://connect.microsoft.com/VisualStudio/feedback/details/898599/
Based on suggestions from AdrianHHH, I am currently doing this to get all the children of a control. This returns all controls including HTML5 controls as HtmlCustom.
private List<UITestControl> GetAllChildren(UITestControl uiTestControl)
{
var child = new HtmlControl(uiTestControl);
child.SearchProperties.Add("InnerText", "", PropertyExpressionOperator.Contains);
var items = child.FindMatchingControls().ToList();
var trueChildren = items.Where(i => i.GetParent().Equals(uiTestControl)).ToList();
return trueChildren;
}
I want to be able to have one image that loads into static html pages based on a conditional argument; so if X="something" then src="something.jpg", if X="another" then src="another.jpg" and so on.
I can't use a database.
So I am looking for some other technique or method that can use some kind of array and load one image from that array depending on something unique within the page.
I'm guessing that jQuery might do the job or maybe using XML/XSLT but I'm no programmer so any suggestions/guidelines/pointers will be gratefully received :)
If you are willing to use jQuery, you can add the image once the DOM finishes loading.
Add a div tag in your html
<div id="test"></div>
and add the image with your logic using JavaScript
$(document).ready(){
yourLogic = true;
if (yourLogic){
('#test').prepend('<img id="imgId" src="path.png" />')
}else{
('#test').prepend('<img id="imgId" src="someOtherPath.png" />')
}
}
I have a block of HTML that I would like to use as the basis of a GWT widget, but am not quite sure the best way to do so. As an example, my HTML block looks something like this:
<div class="my-widget">
<div class="header">
<span class="title">Title Text</span>
</div>
<div class="body">
<span class="content">Content Text</span>
</div>
</div>
Now, I can of course paste this as a static string into an HTML widget, but in this case I need the ability to set the text of the "title" and "content" elements on the fly. This kills (or at least makes significantly more difficult) the static text option.
The first thing that comes to mind in that case is to build out the elements in GWT manually and hold references to the ones I need to alter, like so:
DivElement container = document.createDivElement();
setStyleName(container, "my-widget");
setElement(container);
DivElement header = document.createDivElement();
setStyleName(header, "header");
container.appendChild(header);
// Hold onto this element for later manipulation
DivElement title = document.createDivElement();
setStyleName(title, "title");
header.appendChild(title);
But this quickly get unmanageable for all but the simplest of layouts (which mine is not.)
What I would like is the ability to send the HTML in as static text and then do some sort of selector, like jQuery, to query the elements I want to manipulate. I'm aware of GWT-Query but I haven't been able to get it to run without error, and it seems to me to be a bit too early in it's lifespan for me to be comfortable integrating it into a professional product just yet.
I'm also aware of Google's UiBinder, which sounds exactly like what I want. The problem there is, as far as I can tell, that functionality is only available in GWT 2.0, which is still in a release candidate state and therefore unusable for me.
So, given all that (sorry for the long question!) do you have any suggestions about how best to achieve something like this?
GWT 2.0 will be out before the end of the year. So unless you need to deliver in a few days time, I would start working with the RC2 and try out the new UIBinder approach.
How about using HTML.wrap(). For example, if you added an id of "my-widget" to your outer-most div you could then do something like:
HTML myWidget = HTML.wrap(RootPanel.get("my-widget").getElement());
You can use the InlineHTML widget to produce a span and control its content.
As you probably know, GWT doesn't provide a built in widget that maps directly to a span element. If you can use a div for the title and content, then this bit of code should (no GWT on this machine, going a bit by memory) generate the DOM structure you have.
FlowPanel myWidget = new FlowPanel();
myWidget.setStyleName("my-widget");
SimplePanel header = new SimplePanel();
header.setStyleName("header");
Label title = new Label(titleText);
title.setStyleName("title");
header.add(title);
myWidget.add(header);
SimplePanel body = new SimplePanel();
body.setStyleName("body");
Label content = new Label(contentText);
content.setStyleName("content");
body.add(content);
myWidget.add(body);
From here, you can provide accessors to the content and title labels and update them as needed.
title.setText(newTitle);
content.setText(newContent);
The same as above, but getting a GWT Panel (be able to append childs). This is also useful when you need to wrapp a 3rd party toolkit GUI object as a GWT widget:
Panel gwtPanel = HTMLPanel.wrap(anElement);
The following code suites for me:
HorizontalPanel divContainer = new HorizontalPanel ();
Element div = DOM.createDiv();
div.appendChild(...); // whatever element it could fit inside
divContainer.getElement().appendChild(div);
Edit
The idea behind this is manipulating the DOM with the other widgets you have already programmed.
PS: I'm using GWT 2.4
I want to store some additional data on an html page and on demand by the client use this data to show different things using JS. how should i store this data? in Invisible divs, or something else?
is there some standard way?
I'd argue that if you're using JS to display it, you should store it in some sort of JS data structure (depending on what you want to do). If you just want to swap one element for another though, invisible [insert type of element here] can work well too.
I don't think there is a standard way; I would store them in JavaScript source code.
One of:
Hidden input fields (if you want to submit it back to the server); or
Hidden elements on the page (hidden by CSS).
Each has applications.
If you use (1) to, say, identify something about the form submission you should never rely on it on the server (like anything that comes from the client). (2) is most useful for things like "rich" tool tips, dialog boxes and other content that isn't normally visible on the page. Usually the content is either made visible or cloned as appropriate, possibly being modified in the process.
If I need to put some information in the html that will be used by the javascript then I use
<input id="someuniqueid" type="hidden" value="..." />
Invisible divs is generally the way to go. If you know what needs to be shown first, you can improve user experience by only loading that initially, then using an AJAX call to load the remaining elements on the page.
You need to store any sort of data to be structured as HTML in an HTML structure. I would say to properly build out the data or content you intend to display as proper HTML showing on the page. Ensure that everything is complete, semantic, and accessible. Then ensure that the CSS presents the data properly. When you are finished add an inline style of "display:none;" to the top container you wish to have dynamically appear. That inline style can be read by text readers so they will not read it until the display style proper upon the element changes.
Then use JavaScript to change the style of the container when you are ready:
var blockit = function () {
var container = document.getElementById("containerid");
container.style.display = "block";
};
For small amounts of additional data you can use HTML5 "data-*" attribute
<div id="mydiv" data-rowindex="45">
then access theese fields with jQuery data methods
$("#mydiv").data("rowindex")
or select item by attribute value
$('div[data-rowindex="45"]')
attach additional data to element
$( "body" ).data( "bar", { myType: "test", count: 40 } );