Generate PDF from HTML without buttons - html

I use to generate pdf from my web page wkhtmltopdf.
My project is on ASP.Net and on Bootstrap. So buttons on page has common classes btn btn-primary.
As i know if i set to some element .Visible = false; this element will be invisible on pdf. As there are many buttons on page it isn't too nice to set visibility to each button by Id.
So how can i get all buttons from page just by className?
What i found :
In some post on Stack user advice to add event OnPreRender and in this event set visibility to false. Example:
<asp:LinkButton ID="lnkContinue" runat="server" OnClick="lnkContinue_Click" CssClass="btn btn-primary" Text="Continue" OnPreRender="Button_PreRender"></asp:LinkButton>
protected void Button_PreRender(object sender, EventArgs e)
{
var button = (HtmlGenericControl)sender;
button.Visible = !button.Attributes.CssStyle.Value.Contains("btn btn-primary");
}

You can supply your own javascript function to wkhtmltopdf to iterate over each element and make them invisible:
http://wkhtmltopdf.org/usage/wkhtmltopdf.txt
--run-script js
var eles = document.getElementsByClassName('btn btn-primary');
for (var x = 0; x < eles.length; x++) {
eles[x].style.visibility = false;
}

You should not directly use the HTML generated for your webpage as the HTML for the PDF. Your webpage will likely have navigation and other UI elements (like the mentioned buttons) that aren't appropriate for display in the PDF.
A better solution is to separately generate the HTML. This allows you to retain control over the exact markup used to create the PDF. You can manually build the HTML with StringBuilder or use other libraries to create it.
My favorite way of doing this is using the Razor PDF for MVC library. You use Razor syntax (which is very intuitive) to generate a PDF.

Related

Edit CSS Using Razor/Sitecore

We have a component that contains a background image. Our front-end guy needs it to be loaded through CSS (i.e. background: url(/*path here*/)...). The following is a possible solution we came up with:
#string src = // Get image path from Sitecore().Field("Picture");
<div style="background: url(#src) left top no-repeat;"> ... </div>
However, there are two problems with this approach:
It makes it very difficult for the content editor to swap out the image. They will have to manually change it through edit item.
It feels like a hack/workaround.
So the question is as follows: Is there a way to edit the CSS of an element through Razor/Sitecore? Specifically, the background: field.
I had a similar case and I used :
<footer class="layout_footer" style="background-color: #Model.BackgroundColor">
on view rendering (cshtml file)
And on the model we have :
public string BackgroundColor
{
get
{
Sitecore.Data.Fields.ImageField imgField =((Sitecore.Data.Fields.ImageField)item.Fields["BackgroundImage"]);
return Sitecore.Resources.Media.MediaManager.GetMediaUrl(imgField.MediaItem);
}
}
For editing this field in page editor you can use Sitecore Field Editor from a command : http://blog.istern.dk/2012/05/21/running-sitecore-field-editor-from-a-command/
Check for edit mode, and display in edit mode a editable field. Also create a Custom Experience Button from the Field Editor Button Type. You can also display. See User friendly developing with the Sitecore Experience Editor
#string src = // Get image path from Sitecore().Field("Picture");
<div style="background: url(#src) left top no-repeat;">
#if (IsInEditingMode)
{
<h3>Backgroiund Picture: #Editable(m => m.Picture)</h3>
}
</div>
There is no Sitecore extension method which will do this out of the box (i.e. #Html.Sitecore().Field("fieldName") will not work here as it would render the entire image tag (also a load of other non-image markup in page editor mode) as you probably know.
The method that #sitecore climber mentions is useful for controller renderings (or view renderings with a custom RenderingModel). If you want to stick with simple view renderings (i.e. not create a RenderingModel) then you could create a Html extension method which can be re-used on any view rendering. This could be something like the following:
public string ImageFieldSrc(this SitecoreHelper sitecoreHelper, string fieldName, Item item = null)
{
if (item == null) {
item = sitecoreHelper.CurrentItem;
}
var imageField = new ImageField(item.Fields[fieldName]);
var mediaItem = imageField.MediaItem;
var mediaUrl = MediaManager.GetMediaUrl(mediaItem);
mediaUrl = HashingUtils.ProtectAssetUrl(mediaUrl); //if you want to use media request protection (adding the hash onto the end of the URL, use this line
return mediaUrl;
}
It's worth noting that if you are using Sitecore 7.5 or above there is a feature to protect media URLs with a hash to prevent malicious DoS type attacks described in this blog post by Adam Najmanowicz.
In summary; if you are using Sitecore 7.5+ and you use media hashing then you will need to call HashingUtils.ProtectAssetUrl on the media URL if it is to respect size parameters.

How to capture a click event on a link inside a HTML widget in GWT?

I´m evaluating GWT as one of the alternatives to develop AJAX applications for my future projects. Untill now it is as good as it gets, but now I´m stuck looking for a way to capture a click on a tag inside HTML widget. I want to write links inside the HTML but I want to process the clicks in my application, withou reloading the page. Imagine I have the following HTML:
<p>GWT is a great tool and I think it will be my preferred tool to develop web applications. To check out my samples <a id='mylink'>click here</a></p>
I want to capture the click over the "click here" part of the text. What I´ve done so far is to try to attach the id "mylink" to some sort of clickable widget and process the click with a ClickHandler for that widget, but nothing is working.
Is there a way to do that? By the way, I know very little about Javascript.
Thank you in advance.
You can also do it like this:
Anchor.wrap(DOM.getElementById("mylink")).addClickHandler(yourClickHandler);
DOM class is com.google.gwt.user.client.DOM.
Edit after comments.
OK, the method works for elements out of GWT widgets (element comes with HTML file). If you need to generate it in GWT code then you can add link element separately. But it won't work if your content goes for instance from DB.
HTMLPanel html = new HTMLPanel("GWT is a great tool and I think it will be my preferred tool to develop web applications. To check out my samples ");`
Anchor a = new Anchor("click here");
a.addClickHandler(yourClickHandler);
html.add(a);
If it is fully dynamic I don't have an idea at this point. I was trying with HTML() widget, where you can plug your click handler, but I couldn't find a right way to determine whether the click was in A element. Strange.
The final approach (I hope)
This one should work finally. And I think this is the way it should be done, especially that it allows any structure of the HTML. The are two ways:
1. Convert links within HTMLPanel
This one will find all A elements and convert them into Anchors. It ignores href attribute, but you can add it easily :)
HTMLPanel html = new HTMLPanel("<p>Multilink example 2: <a>link1</a> and <a>link2</a></p>");
NodeList<Element> anchors = html.getElement().getElementsByTagName("a");
for ( int i = 0 ; i < anchors.getLength() ; i++ ) {
Element a = anchors.getItem(i);
Anchor link = new Anchor(a.getInnerHTML());
link.addClickHandler(...);
html.addAndReplaceElement(link, a);
}
2. Insert links into prepared spots
Just insert placeholders, where the widgets should be inserted. You could also use the addAndReplaceElement() method but with string ID.
Anchor a1 = new Anchor("a1");
a1.addClickHandler(...);
Anchor a2 = new Anchor("a2");
a2.addClickHandler(...);
HTMLPanel html = new HTMLPanel("<p>Multilink example: <span id='a1'></span> and <span id='a2'></span></p>");
html.add(a1, "a1");
html.add(a2, "a2");
Try something like this.
For your web page, you can use UiBinder:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel ui:field="panel">
<p>
GWT is a great tool and I think it will be my preferred tool to
develop web applications. To check out my samples
<g:Anchor ui:field="myLink" text="click here" />
</p>
</g:HTMLPanel>
</ui:UiBinder>
Notice that I've replaced your tag with an Anchor widget. There is also a Hyperlink widget, which has hooks into the history system.
The Anchor has a id of "myLink", which is used in the GWT companion to the XML file:
public class So extends Composite {
private static SoUiBinder uiBinder = GWT.create(SoUiBinder.class);
interface SoUiBinder extends UiBinder<Widget, So> {
}
#UiField
Anchor myLink;
public So() {
initWidget(uiBinder.createAndBindUi(this));
myLink.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
GWT.log("caught the click");
}
});
}
}
I've added a ClickHandler that captures and acts on the click event.
The main program is simple:
public class SOverflow implements EntryPoint {
public void onModuleLoad() {
RootLayoutPanel.get().add(new So());
}
}
Run this after and a webpage appears with the text and hyperlink. Click on it and "caught the click" appears in the console window (I'm using Eclipse).
I hope this is what you're after. If not exactly, it might at least give you some ideas of how to attack your problem.

html data in a string make clickable html link AS3/Flex

I have a scenario that I get an string with html data, this is not just html data it's an email (outlook) saved as an html file and dropped in the string.
Now this string needs to be formatted to an html document and should be a clickable link in a datagrid. So when I click on the link, the HTML document should pop-up and should gave me a nice HTML page that is readable for the normal users. I hope it's a bit clear what I want o_0.
I don't know where to start.
You can download the example html from here: http://www.mediafire.com/?b2gfwymw70ynxir
Thanks!
---edit
Hopefully I can explain it a little bit better. I need to create an link and when they click on it they get an HTML page.
The string variable has HTML data in it, to be precise, the source data of the HTML example above.
example:
public var html:String = source_code_of_example_file;
The entire source code of the HTML page is in my variable html. Now I need to make this an link and when they click on it, they will get the html page (as pop-up) on the fly.
You can use the htmlText property and then specify a CSS to perform the proper formatting:
<mx:TextArea id="resourceText" height="100%" width="100%"
styleName="resourceText" editable="false"
styleSheet="{resourceStyleSheet}" htmlText="{html}"/>
To read in the style sheet I declare it in the model:
public var resourceStyleSheet : StyleSheet;
It gets read in from an external file:
private function loadCSS():void {
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, cssCompleteHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
try {
urlLoader.load(new URLRequest("folder/base-html.css"));
} catch (error:Error) {
Alert.show("Unable to load requested document.");
}
}
private function cssCompleteHandler(event:Event):void {
// Convert text to style sheet.
var styleSheet:StyleSheet = new StyleSheet();
styleSheet.parseCSS(URLLoader(event.currentTarget).data);
// Set the style sheet.
model.resourceStyleSheet = styleSheet;
}
private function ioErrorHandler(event:IOErrorEvent):void {
trace("ioErrorHandler: " + event);
}
This will get it into the model, but then make sure resourceStyleSheet is bindable when you use it (I actually set a bindable variable on the view that I set to the model value.
It's not really clear what you want to do.
If your problem is you need to show HTML formatted text in flex there is a component which can do this
http://code.google.com/p/flex-iframe/
-- update after edit
If your intention is to open a html popup once the user clicks on the link you could use ExternalInterface to call a javascript function to do this.
Hope it Helps
There is no easy way to display HTML in a flex web application(this is a web application, right?). Like Xavi Colomer said you can use the Flex Iframe but is terribly slow, it requires you to change the display mode for your swf to opaque and this can cause more problems, depending on your application.
You could open a new page in the browser that will be used to display the HTML. Something like:
http://www.yourcooldomain.com/bla/displayTheHtml.php?oneTimeId=jhsfg765437gro734
More info on how to do this from flex here.
On the other side(server) I assume that you keep this html messages on a database(?) so displaying them using php(or whatever you are using :P) should be easy.
If you are gonna choose this path be careful about the security: oneTimeId in
displayTheHtml.php?oneTimeId=jhsfg765437gro734
should really be an one tyme only id.

Render asp.TextBox for html5 input type="date"

I don't know if it has been asked before, couldn't find it either.
Is it possible to control the type of the input text that is rendered by an asp:TextBox? I would like to change it to <input type="date">
any suggestions or comments are welcome, thanks
There is an update for .NET framework 4 which allows you to specify the type attribute
http://support.microsoft.com/kb/2468871.
See feature 3 way down the page
Feature 3
New syntax lets you define a
TextBox control that is HTML5
compatible. For example, the following
code defines a TextBox control that is
HTML5 compatible:
<asp:TextBox runat="server" type="some-HTML5-type" />
If you don't mind subclassing, you can do this by overidding AddAttributesToRender
public class DateTextbox : System.Web.UI.WebControls.TextBox
{
protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
{
writer.AddAttribute("type", "date");
base.AddAttributesToRender(writer);
}
}
Here is how I did it... hope it helps...
Add a new item to your project of the type "JScript File", then paste this code in:
var setNewType;
if (!setNewType) {
setNewType = window.onload = function() {
var a = document.getElementsByTagName('input');
for (var i = 0; i < a.length; i++) {
if (a[i].getAttribute('xtype')) {
a[i].setAttribute('type', a[i].getAttribute('xtype'));
a[i].removeAttribute('xtype');
};
}
}
Now add this line into your aspx page after the body tag (change the file name to whatever you called it above!):
<script type="text/javascript" src="setNewType.js"></script>
Finally, add something like the following to your code behind PageLoad ( I used VB here):
aspTxtBxId.Attributes("xtype") = "tel" ' or whatever you want it to be
The important part above is the Attributes.("xtype"), as it places the attribute XTYPE in the rendered html for the "textbox", which the javascript then finds and uses to replace the original "type" attribute.
Good Luck!
FJF
I know this question is old, but I was having the same issue in a Web Forms application. You need to use TextMode
While the documentation states that
Use the TextMode property to specify how a TextBox control is displayed. Three common options are single-line, multiline, or password text box.
You can also use html5, date, time, number, etc built in Visual Studio 2012/2013.
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.textbox.textmode(v=vs.110).aspx
I went the route of building my own set of html5 inputs by building custom controls. I get the custom keyboards on iPad and iPhone plus the postback coding of true asp.net controls. It worked for my inhouse project, so I decided to license the whole suite to save other people the time and trouble of doing it from scratch.
Hope this helps!
Actually there is no easy way to override the type attribute in standart asp:TextBox.
You can simly use an input element
Here is an example
<input type="date" id="Input1" runat="server" />
Let me know if it helps...

Integrating a GWT Dialog into an existing HTML application

I have a situation where I need to integrate a gwt dialog (which to the best of my understanding is implemented as a div with z-index manipulation) into an existing html page.
There are two scenarios:
1. Which is the preferrable and more complicated is where i give the host html page another page which they embed as an iframe and I work my magic through there (maybe connect somehow to the parent window and plant my dialog I'm not sure).
2. Where I have limited access to the html page and I plant some code there which will load my dialog box.
Any ideas or thoughts on how I can implement these?
I've been working for a few months now with GWT and have found it quite nice although I have stayed far far away from the whole HTML area and until now all my work has been done strictly inside my java classes.
Thanks for any ideas and help handed
Ittai
I'll assume by dialog you mean a popup that is invisible at page load and made visible by, say, a click on something in the existing HTML. A simple strategy to make this happen is wrapping the existing HTML.
I have no experience with option 1. As for 2, all you need to alter in the existing HTML is
adding the JS import, e.g.
<script type="text/javascript" language="javascript" src="/com.your.org.Module/com.your.org.module.client.Module.nocache.js"></script>
then adding an id to some clickable element you want to activate your dialog, e.g.
<button id="launchDialog">Show Dialog</button>
and finally adding an empty div with an id to insert your dialog into the DOM.
<div id="dialog"></div>
Then all you need in your Module is
public class Module implements EntryPoint {
#Override
public void onModuleLoad() {
Button b = Button.wrap(DOM.getElementById("launchDialog"));
b.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
RootPanel panel = RootPanel.get("dialog");
Widget w = ... // your dialog widget here
panel.add(w);
}
});
}
}
Lastly, you can play with the visibility of your popup div with the "display: none" style and the show() and hide() methods on the widget.