Given I have contained within a string an entire HTML document, how can I launch a new browser window, and then inject the html into that instance so that the new window renders the document?
I've found so many examples on the web that simply do not work. I'm a middle tier guy, so I'm weak on the web/javascript stuff.
UPDATE: Here's a snippet of code that shows what I'm trying to do
void Display()
{
string javascript = string.Empty;
javascript += "<script type='text/javascript'>";
javascript += "var win = window.open('', '', '');";
javascript += "win.document.open();";
javascript += "win.document.write('{0}');"; //<------Notice I have a format parameter placed within the call to document.Write
javascript += "win.document.close();";
javascript += "win.focus();";
javascript += "</script" + ">";
// this.DisplayableDocumentation is an IEnumerable of strings. Each string contains an entire
// HTML document. Ultimately, I want to launch a new window for each document.
this.DisplayableDocumentation
.ForEach(document =>
{
HttpContext.Current.Response.Write(string.Format(javascript, document));
});
}
void Display() {
var i = 0;
var javascript = "<script type='text/javascript'>";
DisplayableDocumentation
.ForEach(document =>
{
i++;
Response.Write(String.Format("<input id='txt{1}' type='text' value='{0}' style='display:none;'/>", Server.HtmlEncode(document), i));
javascript += String.Format(#"
var win{1} = window.open('', '', '');
win{1}.document.open();
win{1}.document.write(document.getElementById('txt{1}').value);
win{1}.document.close();
win{1}.focus();
", document, i);
});
javascript += "</" + "script>";
RegisterStartupScript("javascript", javascript);
}
Put the string somewhere so you can reference it from another page... or rather, another handler. Then set the address of your new window to use this handler as it's href.
In my MVC2 application I use CKEditor where I allow the user to create a PDF document.
First the CKEditor content will get converted into HTML file and later as PDF document.
I have provided a button called Arrow on click of it image of an arrow should get inserted. In editor image gets displayed successfully but in HTML and PDF file image is not getting displayed inplace of it alt content gets displayed.
Code for an arrow button:
<input type="button" class="green_button" id="arrow" name="Arrow" value="Arrow" style="width: 110px; height: 30px; background-color: #FFFFFF;" onclick="return arrow_onclick()" />
function arrow_onclick() {
var editor = CKEDITOR.instances.message;
editor.insertHtml(' <input type="image" alt="arrow" src="../../PDFimages/arrow-left-up.jpg" style="height:100px; width:100px" />');
}
Controller code:
public ActionResult CreateFile(FormCollection data)
{
var filename = data["filename"];
var htmlContent = data["content"];
string sFilePath = Server.MapPath(_createdPDF + filename + ".html");
htmlContent = htmlContent.Trim();
if (!System.IO.File.Exists(sFilePath))
{
using (FileStream fs = new FileStream(sFilePath, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.Write(htmlContent);
}
}
string filename1 = Path.GetFileNameWithoutExtension(sFilePath);
string name = Server.MapPath(_createdPDF + filename1 + ".pdf");
HTML2PDF.SetModulePath(#"C:\Documents and Settings\shubham\My Documents\visdatemplatemanger\visdatemplatemanger\bin");
using (PDFDoc doc = new PDFDoc())
{
if (HTML2PDF.Convert(doc, sFilePath))
doc.Save(name, pdftron.SDF.SDFDoc.SaveOptions.e_linearized);
}
System.IO.File.Delete(sFilePath);
UploadURL(name);
}
return View();
}
Before submit your form, you should set textarea value from CkEditor and make your action that accepts the post has this annotation applied [HttpPost, ValidateInput(false)]
$("#content").val(CKEDITOR.instances.message.getData());
And check your src value. Maybe should using:
src="#(Url.Content( "~/PDFimages/arrow-left-up.jpg" ))"
if PDFimages folder included in Project/Content
Consider this editor template (even though it doesn't make sense - I have simplified it for clarity):
#Html.TextBox("", null)
This editor template should retrieve the name and the value for the element which it was called for. The name does get set correctly. The value, however, does not.
The data type differs - sometimes it is a double, sometimes it is a string. So I cannot declare a specific data type as the model.
The only way I can make it behave correctly is if I specify the type as dynamic:
#model dynamic
#Html.TextBox("", (string)Convert.ToString(Model))
This seems like a very clumsy syntax, although it works. Have I got it right?
EDIT:
The full code for my editortemplate is a textfield, that can dynamically be calculated by js ajax calls. It works perfectly, and is meant as a general template for any value that can be calculated from the value of other fields. It is not necessarily a string type. However, I need to provide an object for the argument of the Html.TextBox value.
#model dynamic
#{
var CalcClasses = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcClasses")) ? " " + #ViewData.ModelMetadata.AdditionalValues["CalcClasses"] : "";
var CalcUrl = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcUrl")) ? #ViewData.ModelMetadata.AdditionalValues["CalcUrl"] : "";
var CalcDependsOn = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcDependsOn")) ? #ViewData.ModelMetadata.AdditionalValues["CalcDependsOn"] : "";
var CalcTooltip = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcTooltip")) ? #ViewData.ModelMetadata.AdditionalValues["CalcTooltip"] : "";
}
<div class="calculated-field-container input-append">
#Html.TextBox("", (string)Convert.ToString(Model), new
{ #class="calculated-field" + CalcClasses,
data_calc_url = CalcUrl,
data_calc_dependencies = CalcDependsOn
})
<button class="btn button-calculate" data-toggle="tooltip" title="#CalcTooltip">=</button>
</div>
EDIT 2:
Seems this works as well:
#{
var CalcClasses = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcClasses")) ? " " + #ViewData.ModelMetadata.AdditionalValues["CalcClasses"] : "";
var CalcUrl = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcUrl")) ? #ViewData.ModelMetadata.AdditionalValues["CalcUrl"] : "";
var CalcDependsOn = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcDependsOn")) ? #ViewData.ModelMetadata.AdditionalValues["CalcDependsOn"] : "";
var CalcTooltip = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcTooltip")) ? #ViewData.ModelMetadata.AdditionalValues["CalcTooltip"] : "";
}
<div class="calculated-field-container input-append">
#Html.TextBox("", Model, new
{ #class="calculated-field" + CalcClasses,
data_calc_url = CalcUrl,
data_calc_dependencies = CalcDependsOn
})
<button class="btn button-calculate" data-toggle="tooltip" title="#CalcTooltip">=</button>
</div>
I'm using Twitter Bootstrap, and trying to make my links ASP.Net MVC look nice.
However, the <i class=... in the link below, is html encoded, rather than being sent as html to the browser:
#Html.ActionLink("<i class='icon-user icon-white'></i> Create New", "Create", "", New With {Key .class="btn btn-primary"} )
Is there any way of keeping the <i class=... as html, so that the button displays correctly?
Instead of using #Html.ActionLink(), just write out the <a> tag yourself. You can use #Url.Action() to get the URL of an action for your HREF attribute.
The #Html helpers are nice, but they won't always provide the flexibility you need.
I was dealing with the same issue, but wanted to keep using a helper, because I was making an Ajax button.
I ended up with these two helper methods, one for each helper:
public static MvcHtmlString IconActionLink(this AjaxHelper helper, string icon, string text, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes)
{
var builder = new TagBuilder("i");
builder.MergeAttribute("class", icon);
var link = helper.ActionLink("[replaceme] " + text, actionName, controllerName, routeValues, ajaxOptions, htmlAttributes).ToHtmlString();
return new MvcHtmlString(link.Replace("[replaceme]", builder.ToString()));
}
public static MvcHtmlString IconActionLink(this HtmlHelper helper, string icon, string text, string actionName, string controllerName, object routeValues, object htmlAttributes)
{
var builder = new TagBuilder("i");
builder.MergeAttribute("class", icon);
var link = helper.ActionLink("[replaceme] " + text, actionName, controllerName, routeValues, htmlAttributes).ToHtmlString();
return new MvcHtmlString(link.Replace("[replaceme]", builder.ToString()));
}
Just throw them in a static class in your project, compile and you should see them (You may need to add an using statement on your page).
When using the helper you can use "icon-plus" or even "icon-plus icon-white" for the icon string.
3-Step Solution:
1. Create this HtmlExtensions class:
using System.Web.Mvc;
public static class HtmlExtensions
{
public static MvcHtmlString ActionButton(this HtmlHelper html, string linkText, string action, string controllerName, string iconClass)
{
//<i class="#lLink.IconClass"></i><span class="">#lLink.LinkText</span>
var lURL = new UrlHelper(html.ViewContext.RequestContext);
// build the <span class="">#lLink.LinkText</span> tag
var lSpanBuilder = new TagBuilder("span");
lSpanBuilder.MergeAttribute("class", "");
lSpanBuilder.SetInnerText(linkText);
string lSpanHtml = lSpanBuilder.ToString(TagRenderMode.Normal);
// build the <i class="#lLink.IconClass"></i> tag
var lIconBuilder = new TagBuilder("i");
lIconBuilder.MergeAttribute("class", iconClass);
string lIconHtml = lIconBuilder.ToString(TagRenderMode.Normal);
// build the ... tag
var lAnchorBuilder = new TagBuilder("a");
lAnchorBuilder.MergeAttribute("href", lURL.Action(action, controllerName));
lAnchorBuilder.InnerHtml = lIconHtml + lSpanHtml; // include the <i> and <span> tags inside
string lAnchorHtml = lAnchorBuilder.ToString(TagRenderMode.Normal);
return MvcHtmlString.Create(lAnchorHtml);
}
}
2. Add this using at your View
#using Extensions
3. And simple call when you need
#: <li class="btn btn-mini btn-inverse"> #Html.ActionButton(lLink.LinkText, lLink.ActionName, lLink.ControllerName, lLink.IconClass)</li>
Use TwitterBootstrapMVC.
It works with intellisense, allows for fluent syntax and you can write something like this with it:
#(Html.Bootstrap().ActionLinkButton("Create New", "Create")
.IconPrepend(Icons.user, true)
.Style(ButtonStyle.Primary))
Parameter true in the IconPrepend is for white icon type.
Besides, it's got a lot more very useful helpers.
Disclaimer: I'm the author of TwitterBootstrapMVC
Use of this library for Bootstrap 3 is not free.
#Html.ActionLink(" New", "Create", "", new { #class="icon"} )
In css style:
.icon:before{
font-family: FontAwesome;
content: "\f055";
}
Index
#Html.ActionLink("Link Title", "ActionName", "ControllerName", New With {.id = Model.id }, New With {.class = Html.Raw("btn btn-primary btn-mini")})
This HTML.AcionLink overload allows you to add attributess to the rendered html - remember to pass null/nothing for the needed parameters in this overload.
For any ASP.NET user this is how it worked for me:
<%: Html.ActionLink("Cancel", "Index", "Catalog_Users", new { #class = "btn btn-primary" })%>
The shown text will be: Cancel.
The ActionResult will be Index and Catalog_Users is the controller.
Though this question is old, but I still though of providing a simpler solution. At first, I thought its so difficult to achieve this but its so simple.
<i class="fa fa-fw fa-bar-chart-o"></i> Chart
#Url.Action() give the same power as that of Html.ActionLink. See below image (top button is exactly the way you're using it, while the bottom button is the solution to the problem.
I like G Jeny Remirez's answer. I just want to expand on this a bit. It's important that you use a four argumnent actionlink to include the class. So, if you just want to redirect to the same controller, but a different action, it's:
#Html.ActionLink("cancel", "Index", null, new { #class = "btn" })
Or if you want to redirect to the same controller with some parameters:
#Html.ActionLink("Cancel", "Index", new { param1 = ViewBag.param1, input = "activity" }, new { #class = "btn" })
Greetings,
I can see that when I set htmlText in a textarea control, the text property contains the html free version of the text. So there is a parser somewhere that is ripping of html from the content, which would be very usefull for my purposes.
However, based on the flex source code, the setting of html is done in UITextField.as, which is the type of the textfield member of TextArea. The line that does the work is:
super.htmlText = value;
in function
override public function set htmlText(value:String):void
Trying to follow the class hieararchy, I end up in FlexTextField class, which extends flash player's textfield class.
It appears the functionality I am after is in flash player. So is there any way of accessing this html cleaning function? Am I missing something here?
Best Regards
Seref
In case regex fails you, here is something you might want to check out:
var t:String = "asd <span>This is <font>some</font> text <b> :) </b> </span> \nand more";
function stripTags(x:XML):String {
var t:String = "";
var children:XMLList = x.children();
var child:XML;
for(var i:Number = 0; i < children.length(); i++){
child = children[i];
if(child.nodeKind() == "text")
t += child.toString();
else if(child.nodeKind() == "element")
t += stripTags(child);
}
return t;
}
var x:XML = new XML("<root>" + t + "</root>");
XML.ignoreWhitespace = false;
var s:String = stripTags(x);
trace(s);
PS: I haven't tested this ActionScript code, here is the equivalent JavaScript code that I tested and found working. I assume it would work in ActionScript since both follow ECMAScript.
var t = "asd <span>This is <font>some</font> text <b> :) </b> </span> \nand more";
function stripTags(str){
function strip(x){
var t = "";
var children = x.children();
var child;
for(var i = 0; i < children.length(); i++){
child = children[i];
if(child.nodeKind() == "text")
t += child.toString();
else if(child.nodeKind() == "element")
t += strip(child);
}
return t;
}
var xml = new XML("<root>" + str + "</root>");
XML.ignoreWhitespace = false;
return strip(xml);
}
var s = stripTags(t);
console.log(s);
output:
asd This is some text :)
and more
Nope, there is no way to access code in the Flash Player native classes.
However, you should be able to use a Regex to easily parse out all HTML Tags in your content.
Although, not tested, here is one option that came up in Google. You can just use that in Flex. So, you can probably do something like this:
var regEx : RegExp = new RegExp('<(.|\n)*?>');
var noHTMLText = htmlText.replace(regEx , '');
Of course, this was written in the browser. More info on Regex in Flex.