How do I insert line breaks in an HtmlDocument? - asp.net

I'm using the Html Agility Pack to copy html content from several files that only contain body elements and their inner HTML, into a single, new html file. The essential code that does this is as follows. The _pageDoc is the HtmlDocument for the new file, and contentNode is a child of that doc, while for each file I build a div and append it to contentNode.
var contents = GetContentDescs(courseId);
foreach (var content in contents)
{
var html = File.ReadAllText(Path.Combine(HtmlDir, content.ContentId + ".html"));
var contentDoc = new HtmlDocument();
contentDoc.LoadHtml(html);
var bodyNode = contentDoc.DocumentNode.Descendants("body").Single();
var contentDiv = _pageDoc.CreateElement("div");
contentDiv.InnerHtml = bodyNode.InnerHtml;
contentNode.AppendChild(contentDiv);
}
This works as expected and the rendered html is perfect, but every contentDiv is on one line, and not very readable. How can I insert a line break in the html file (vs in the rendered html) between each contentDiv?

Something like
HtmlNode linebreak = doc.CreateElement("br");
var contentDivs= doc.DocumentNode.SelectNodes("contentDiv");
for (int i = 0; i < contentDivs.Count; i++)
{
if (i > 0)
{
doc.DocumentNode.InsertBefore(linebreak1, contentDivs[i]);
}
}
I've put up some dirty code by reading documentation but I've never used Agility pack

Related

copy a div to a window popup with css

I'm trying to take a div and basically put it in a child window. The domains are going to be the same so I figure I could do the flowing ( where parm win is the div ).
popOut = function ( win )
{
var newWindow = window.open( "about:blank", "", "toolbar=yes, scrollbars=yes, resizable=yes, top=500, left=500, width=400, height=400", false );
newWindow.onload = function ()
{
this.focus
this.document.body.appendChild( win );
};
}
This seems to do the job but the css is clobbered. In thinking about this, the new window certainly knows nothing of the includes and css files. Can I copy or inject this info over somehow?
Would I be correct in assuming the new window knows nothing of its parent, thus no function can be ran from child to parent?
New window is definitely aware of its opener as well as opener aware of the popup. If the problem is new window not seeing opener styles, the following code should copy styles from opener to popup.
Place this after var newWindow = window.open(...)
var linkrels = document.getElementsByTagName('link');
for (var i = 0, max = linkrels.length; i < max; i++) {
if (linkrels[i].rel && linkrels[i].rel == 'stylesheet') {
var thestyle = document.createElement('link');
var attrib = linkrels[i].attributes;
for (var j = 0, attribmax = attrib.length; j < attribmax; j++) {
thestyle.setAttribute(attrib[j].nodeName, attrib[j].nodeValue);
}
newWindow.document.documentElement.appendChild(thestyle);
}
}
I haven't got a chance to test it, but something like this should work.

adding tooltip to datagrid headers in dojo

I have a dojo datagrid which is poulated dynamically. I want to add tooltip to table headers of this datagrid. How can i do that?My datagrid simply has the structure of table and table headers. the fields get populated dynamically.
Thanks,
Sreenivas
Easiest Way
The easiest way, (Without overriding the template) would be to add a domNode to your layout header definition. So for example, when you are setting the "name" for your column in the layout, you can have something like ...
var layout = [
{
cells: [
{
name:"<i id="sometooltip" class='icon-large icon-edit'></i> Col",
field: "_item",
formatter: lang.hitch( this, this.formatter )
}
]
}];
What you then want to do is in your formatter, you want to check to see if "sometooltip" has be initialized as a tooltip, and do your connect.. You can use any tooltip.. not just dijit.Tooltip.
There are a few words of caution though. Because the formatter will run every time there is a redraw on your grid, you might want to think up better ways of creating your tooltip. For instance, you might want to add it to onGridRowHeaderHover, or you might want to just use CSS3 and use [title] attribute to create a CSS3 header.
Also. You can't just create the tooltip once, because the header is constantly rebuilt every redraw/change of data.
The Correct Way
The correct way would be to override the Grid template for the header, and include your tooltip in there. You would then extend the header equivalent of onStyleRow (which I can't remember), but basically the method that places the headers, and create your tooltip then.
I would definitely use the second option by overriding the template. Because otherwise you will find the grid glitchy.
For a pre-AMD Dojo version this is the monkey patch that we included in our globally scoped javascript resource. My other answer was after we switched to an AMD Dojo version.
// HeaderBuilder.generateHtml
// If showTooltips is true, the header contents will be used as the tooltip text.
var old_HeaderBuilder_generateHtml = dojox.grid._HeaderBuilder.prototype.generateHtml;
dojox.grid._HeaderBuilder.prototype.generateHtml = function(inGetValue, inValue){
var html = this.getTableArray(), cells = this.view.structure.cells;
dojox.grid.util.fire(this.view, "onBeforeRow", [-1, cells]);
for(var j=0, row; (row=cells[j]); j++){
if(row.hidden){
continue;
}
html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
for(var i=0, cell, markup; (cell=row[i]); i++){
cell.customClasses = [];
cell.customStyles = [];
if(this.view.simpleStructure){
if(cell.headerClasses){
if(cell.headerClasses.indexOf('dojoDndItem') == -1){
cell.headerClasses += ' dojoDndItem';
}
}else{
cell.headerClasses = 'dojoDndItem';
}
if(cell.attrs){
if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
}
}else{
cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
}
}
markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
// content
markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
// set the tooltip for this header to the same name as the header itself
try {
markup[5] = markup[5].replace("class","title='"+cell.name+"' class");
} catch(e) {
console.debug(e);
}
// styles
markup[3] = cell.customStyles.join(';');
// classes
markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
html.push(markup.join(''));
}
html.push('</tr>');
}
html.push('</table>');
return html.join('');
};
I had a similar requirement. I wanted each DataGrid column header to use the name given to the column as the tooltip since our DataGrids weren't always showing the full column name due to the columns' widths sometimes being squeezed. I added a monkey patch (below) that is done with an AMD Dojo version:
require(
[
"dojo/dom",
"dojox/grid/DataGrid",
"dijit/_Widget",
"dijit/form/FilteringSelect",
"dijit/form/MultiSelect",
"dijit/layout/ContentPane",
"dijit/layout/TabContainer",
"dojox/grid/_Grid",
"dijit/MenuItem",
"dijit/MenuSeparator",
"dojox/grid/_Builder",
"dojox/grid/cells/_base",
"dojox/grid/util",
"dojo/parser",
"dojo/_base/array",
"dojo/_base/lang",
"dojo/ready",
"dojo/query",
"dijit/registry",
],
function(dom, dojox_grid_DataGrid, dijit__Widget, dijit_form_FilteringSelect,
dijit_form_MultiSelect, dijit_layout_ContentPane, dijit_layout_TabContainer,
dojox_grid__Grid, MenuItem, MenuSeparator, dojox_grid__Builder,
dojox_grid_cells__Base, dojox_grid_util,
parser, array, dojoLang, ready, dojoQuery, registry) {
var old_HeaderBuilder_generateHtml = dojox_grid__Builder._HeaderBuilder.prototype.generateHtml;
dojox_grid__Builder._HeaderBuilder.prototype.generateHtml = function(inGetValue, inValue){
var html = this.getTableArray(), cells = this.view.structure.cells;
dojox_grid_util.fire(this.view, "onBeforeRow", [-1, cells]);
for(var j=0, row; (row=cells[j]); j++){
if(row.hidden){
continue;
}
html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
for(var i=0, cell, markup; (cell=row[i]); i++){
cell.customClasses = [];
cell.customStyles = [];
if(this.view.simpleStructure){
if(cell.headerClasses){
if(cell.headerClasses.indexOf('dojoDndItem') == -1){
cell.headerClasses += ' dojoDndItem';
}
}else{
cell.headerClasses = 'dojoDndItem';
}
if(cell.attrs){
if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
}
}else{
cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
}
}
markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
// content
markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
// set the tooltip for this header to the same name as the header itself
markup[5] = markup[5].replace("class","title='"+cell.name+"' class");
// styles
markup[3] = cell.customStyles.join(';');
// classes
markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
html.push(markup.join(''));
}
html.push('</tr>');
}
html.push('</table>');
return html.join('');
};
}
);
Note that if there's any chance that any markup may be added to the cell.name then you'll need to add a condition that will somehow extract just the text from it to be the tooltip, or somehow generate a tooltip that won't throw a rendering error, or avoid setting a tooltip altogether for that column.

How to add href height and width in code behind in asp.net?

im reading datas from xml.
{
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("~/multipleimage.xml"));
XmlNode root = doc.DocumentElement;
XmlNodeList nodeList = root.SelectNodes("Image");
foreach (XmlNode node in nodeList)
{
HtmlAnchor a1 = new HtmlAnchor();
Image imagesource = new Image();
string path = "Uploads/";
string imageurl = path + node.SelectSingleNode("Imagepath").InnerText;
imagesource.Style.Add(HtmlTextWriterStyle.PaddingLeft, "7px");
imagesource.Style.Add(HtmlTextWriterStyle.PaddingRight, "5px");
imagesource.Style.Add(HtmlTextWriterStyle.PaddingTop, "5px");
imagesource.Style.Add(HtmlTextWriterStyle.PaddingBottom, "5px");
imagesource.ImageUrl = imageurl;
imagesource.Height = 90;
imagesource.Width = 90;
string imagetitle = node.SelectSingleNode("imagetitle").InnerText;
a1.Attributes.Add("href", imageurl);
a1.Attributes.Add("rel", "lightbox[roadtrip]");
a1.Attributes.Add("title", imagetitle);
a1.Controls.Add(imagesource);
Div1.Controls.Add(a1);
}
}
so im binding the controls in codebehind.i'm using lightbox effect also in code behind . everything is working fine.but can i set height and widht for the href from code behind?
Try this
HtmlAnchor a1 = new HtmlAnchor();
a1.Style.Add("height", "120px");
Href is an attribute of an anchor tag (<a />) and refers to the location the hyperlink will direct the browser to.
In general I would try to set classes and/or id's in the code behind and set style through css. This way you can change the style without recompiling:
a1.Attributes.Add("class", "my-class");
And in css:
.my-class
{
width:100px;
height:10px;
}
or for the image:
.my-class img
{
width:100px;
height:10px;
}
However lightbox may be updating these values. I would use a tool such as firebug (or the built in inspection tools - try pressing F12) to see what style is actually being added to the image elements.

SVG to PNG with Embedded Style Sheet

I'm interested in creating a PNG from SVG. I followed the code given in:
https://developer.mozilla.org/en-US/docs/HTML/Canvas/Drawing_DOM_objects_into_a_canvas
But the image does not come out right due to styling from CSS. I made a local CSS file and do an import into the SVG, as described in:
How to apply a style to an embedded SVG?
But it does not appear to be using the style sheet. Any ideas why I would have this error?
Thanks.
Have a look at PhantomJS - You need to install it then either write your own script or run something along these lines:
phantomjs rasterize.js http://ariya.github.com/svg/tiger.svg tiger.png
You can also save to PDF, set Zoom setting, etc.
You could use html2canvas to generate a canvas from any dom element (including svg elements).
However, style definitions for svg elements defined in stylesheets are not applied to the generated canvas. This can be patched by adding style definitions to the svg elements before calling html2canvas.
Inspired on this article, I've created this:
function generateStyleDefs(svgDomElement) {
var styleDefs = "";
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
var rules = sheets[i].cssRules;
for (var j = 0; j < rules.length; j++) {
var rule = rules[j];
if (rule.style) {
var selectorText = rule.selectorText;
var elems = svgDomElement.querySelectorAll(selectorText);
if (elems.length) {
styleDefs += selectorText + " { " + rule.style.cssText + " }\n";
}
}
}
}
var s = document.createElement('style');
s.setAttribute('type', 'text/css');
s.innerHTML = "<![CDATA[\n" + styleDefs + "\n]]>";
//somehow cdata section doesn't always work; you could use this instead:
//s.innerHTML = styleDefs;
var defs = document.createElement('defs');
defs.appendChild(s);
svgDomElement.insertBefore(defs, svgDomElement.firstChild);
}
// generate style definitions on the svg element(s)
generateStyleDefs(document.getElementById('svgElementId'));
// after generating the style defintions, call html2canvas
html2canvas(document.getElementById('idOfElement')).then(function(canvas) {
document.body.appendChild(canvas);
});
The example at
"How to apply a style to an embedded SVG?" as you mentioned should work. You need to define youObjectElement in this line of code when you test it.
var svgDoc = yourObjectElement.contentDocument;
try again.

Add css style into textnode dynamically

I'm having a problem of adding a css style into the auto generated textnode. I know that the textnode does not has any parent node. So I cannot just append the css style in it.
Basically, what I need to do is when user clicks on the "+" button which I create it in the page and it will add a new textnode into one of the . When the user clicks one more time, and it will add another new textnode continually. However, I would like to add a css style after the textnode is created.
Here is my code:
function addRowToTable() {
//find the last row in the table and add the new textnode when user clicks on the button
var tbl = document.getElementById('audioTable2');
var lastRow = tbl.rows.length;
var iteration = lastRow;
var row = tbl.insertRow(lastRow);
//after find the last row in the table, and it will add the new cell with the new textnode
var cellLeft = row.insertCell(0);
var el_span = document.createElement('span');
var el_spanClass = el_span.setAttribute('class', 'test');
var textNode = document.createTextNode(iteration);
cellLeft.appendChild(textNode);
}
//this is the css style I would like to apply into the new gerenated textnode
function appendStyle(styles){
var css = document.createElement('style');
css.type='text/css';
if (css.styleSheet) css.styleSheet.cssText = styles;
else css.appendChild(document.createTextNode(styles));
document.getElementsByTagName("head")[0].appendChild(css);
}
Could someone help me on this? Thanks a lot.
You say: "I'm having a problem of adding a css style into the auto generated textnode," but the code you provide shows that you are trying to add a style element to the head for every new textnode. I think what you want is to either 1) apply a style already defined in your style sheet to the textnode, or 2) directly style the textnode inline. Therefore, I think your code should be either:
1) Apply a style in your css stylesheet to the textnode via the span:
//after find the last row in the table, and it will add the new cell with the new textnode
var cellLeft = row.insertCell(0);
var el_span = document.createElement('span');
var el_spanClass = el_span.setAttribute('class', 'test');
var textNode = document.createTextNode(iteration);
cellLeft.appendChild(el_span);
el_span.appendChild(textNode);
}
This puts the span into the cell (which you don't do in your code) which would then wrap the textnode with the span giving it a class of test.
2) Apply a style directly (inline) to the textnode via the span:
//after find the last row in the table, and it will add the new cell with the new textnode
var cellLeft = row.insertCell(0);
var el_span = document.createElement('span');
el_span.setAttribute('style', 'color: red'); /*just an example, your styles set here*/
var textNode = document.createTextNode(iteration);
cellLeft.appendChild(el_span);
el_span.appendChild(textNode);
}
In either case, your appendStyle function could be deleted.

Resources