I am trying to convert large HTML file to PDF. but just want to set first page and following page number.
I have used following code
converter = New HtmlToPdf()
Dim file As String = "C:\TEMP\Document5.pdf"
converter.Options.PdfPageSize = PdfPageSize.A4
converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait
converter.Options.MarginTop = 20
converter.Options.MarginBottom = 20
converter.Options.MarginLeft = 10
converter.Options.MarginRight = 10
converter.Options.DisplayFooter = True
Dim doc As PdfDocument = converter.ConvertHtmlString(htmlString)
converter.Footer.TotalPagesOffset =2
converter.Footer.FirstPageNumber = 2
doc.Save(file)
' close pdf document
doc.Close()
but this part not working,
converter.Footer.TotalPagesOffset =2
converter.Footer.FirstPageNumber = 2
and Is there any what to know total pages?
Here's how I handle my page numbering using SelectPDF and ASP.NET MVC Razor.
for (int x = 0; x < PDF.Pages.Count; x++) {
if (x > 0 && x != PDF.Pages.Count - 1) { // will not number first/last page
PdfPage page = PDF.Pages[x];
PdfTemplate customFooter = PDF.AddTemplate(page.PageSize.Width, 33f);
page.DisplayFooter = true;
PdfHtmlElement customHtml = new PdfHtmlElement(domain + "/template/_pagenumber?pageNum=" + x.ToString() + "&totalPages=" + PDF.Pages.Count.ToString());
customFooter.Add(customHtml);
page.CustomFooter = customFooter;
}
}
And here's what my _pagenumber.cshtml file looks like...
<div style="margin-right:48px;margin-left:48px;height:46px;position:relative;top:-4px;z-index:999;">
<div class="row">
<div class="col-xs-6">
<small>Company info goes here</small>
</div>
<div class="col-xs-6 text-right">
<small><strong>Page #(Request.QueryString["pageNum"]) of #(Request.QueryString["totalPages"])</strong></small>
</div>
</div>
</div>
Related
I wander if in foundation 6 sliders, it is possible to allow negative values e.g. swinging from -50 to 50.
Currently I have a slider in [0 100]:
<div class="row">
<div class="small-4 large-4 columns">
<label>Audio Volume</label>
</div>
<div class="small-6 large-6 columns">
<div class="slider" id="slidervol" data-slider data-end="100" display_selector: "#slidervol">
<span class="slider-handle" data-slider-handle role="slider" tabindex="1" aria-controls="sliderVolOutput"></span>
<span class="slider-fill" data-slider-fill></span>
</div>
</div>
<div class="small-2 large-2 columns">
<input name="AudioVolTxtbox" type="number" style="width: 4em;" tabindex="2" id="sliderVolOutput">
</div>
</div>
You can set a negative start value, but the behaviour is unpredictable when you do so. If you want to make use of negative values, you'll need logic to update the value in #sliderVolOutput after the handle has been moved.
The moved.zf.slider event is triggered every time the handle is moved and you can use that fact to update the textbox value. This event is fired quite a few times, so you'll need to add additional code to get rid of the flickering (if it's bothersome).
I've provided some basic code that should get you started. If you have any questions, please let me know.
var target = document.getElementById("slidervol");
var options = {
"start": 0,
"end": 100,
"decimal": 0
};
var elem = new Foundation.Slider($(target), options);
var offset = 50;
$(target).on('moved.zf.slider', function() {
$('#sliderVolOutput').val(Number($('.slider-handle').attr('aria-valuenow')) - offset);
});
Another approach would be to use the mousemove.zf.slider event. This gets rid of the flicker, but the textbox value is only updated once you've stopped manipulating the slider:
$(target).on('mousemove.zf.slider', function() {
$('#sliderVolOutput').val(Number($('.slider-handle').attr('aria-valuenow')) - offset);
});
UPDATE:
In response to your additional query, I've had time to implement the required functionality (editing the value in the text box causing the slider to update) using a hidden control.
The slider-handle now targets the hidden control (aria-controls), which will always contain a positive value. The text box will contain the negative (computed) value. This is what the updated html looks like for the slider-handle:
<span class="slider-handle" data-slider-handle role="slider" tabindex="1" aria-controls="sliderVolOutputHidden"></span>
And this is the additional hidden input I've used:
<input type="hidden" id="sliderVolOutputHidden" value="0">
I've also added an input event for #sliderVolOutput that updates the value of the hidden input and triggers the change event. The change event is important, as without it, the handle will not update:
$('#sliderVolOutput').on('input', function() {
$('#sliderVolOutputHidden').val(Number($('#sliderVolOutput').val()) + offset);
$('#sliderVolOutputHidden').trigger('change');
});
Fiddle Demo
I get quite a result patching as follows foundation.js.
I can change values smoothly with the slider (with no flickering) but I can not decrement the textbox (aria-controls) below 0 since he event handler does not fire.
## -6953,13 +6953,14 ##
'id': id,
'max': this.options.end,
'min': this.options.start,
+ 'offset': this.options.offset,
'step': this.options.step
});
this.handles.eq(idx).attr({
'role': 'slider',
'aria-controls': id,
- 'aria-valuemax': this.options.end,
- 'aria-valuemin': this.options.start,
+ 'aria-valuemax': this.options.end + this.options.offset,
+ 'aria-valuemin': this.options.start + this.options.offset,
'aria-valuenow': idx === 0 ? this.options.initialStart : this.options.initialEnd,
'aria-orientation': this.options.vertical ? 'vertical' : 'horizontal',
'tabindex': 0
## -6978,8 +6979,8 ##
key: '_setValues',
value: function _setValues($handle, val) {
var idx = this.options.doubleSided ? this.handles.index($handle) : 0;
- this.inputs.eq(idx).val(val);
- $handle.attr('aria-valuenow', val);
+ this.inputs.eq(idx).val(val+this.options.offset);
+ $handle.attr('aria-valuenow', val+this.options.offset);
}
/**
## -7033,7 +7034,8 ##
} else {
//change event on input
value = this._adjustValue(null, val);
- hasVal = true;
+ value = value - this.options.offset;
+ hasVal = true;
}
this._setHandlePos($handle, value, hasVal);
## -7286,7 +7288,13 ##
* #option
* #example false
*/
- invertVertical: false
+ invertVertical: false,
+ /**
+ *
+ * #option
+ * #example 0
+ */
+ offset: 0
};
function percent(frac, num) {
Then, for instance I want to change my parameter "Audio Volume" from -24 to 24 so in js:
// Audio Volume
vartxt = GetParameter("AudioVolume") // get the value in some way
tval = parseFloat(vartxt);
document.DeviceConfig.AudioVolTxtbox.value = tval - 24; //change the textbox
var target = document.getElementById("slidervol");
var options = {
"start": 0,
"end": 48,
"decimal": 0,
"step": 1,
"offset": -24,
"initialStart": tval
};
var elem = new Foundation.Slider($(target), options);
At the moment the only problem I get is that I have to configure the input box as 'text', since if I set it as 'number' the spinner does not allow to go below the 0.
I create a PDF report with header generated automatically by phantomjs. In the report I have a long div which contains text, blank lines, simple data tables etc.
Since I believe phantomjs might have problem with the page break, I calculate the page break manually, break up the long div into multiple divs with page break at the end of each div.
Here is my calculation in the jQuery(document).ready()
//pagination the Notes pages
if (encData.pnotes && encData.pnotes.length > 0) {
pageCnt++;
var $notes = jQuery('<div id="pageNotes" class="notes" style="width:100%;margin-top:100px;border:1px solid red">' +
pNotesString + '</div>');
$body.append($notes);
var height = 0;
var children = $notes.children();
var p = children.slice(0);
var pages = [];
var counter = 0;
for (var i = 0; i < children.length; i++) {
if (height + children[i].offsetHeight < 1350)
height += children[i].offsetHeight;
else {
pages.push([counter, i]);
height = 0;
counter = i;
}
}
pages.push([counter, children.length]);
for (var i = 0; i < pages.length; i++) {
//first notes page
if (i == 0) {
$notes.children().slice(pages[i][1]).remove();
$notes.after('<div style="border:1px solid black;height:1px"></div><div id="pageNotesBreak" style="page-break-after:always"> </div>');
}
else {
pageCnt++;
var $new = jQuery('<div id="page' + pageCnt + '" class="notes" style="width:100%;margin-top:100px;border:1px solid blue"></div>');
$new.append(p.slice(pages[i][0], pages[i][1]));
$body.append($new);
$body.append('<div style="border:1px solid black;height:1px"></div><div id="pageBreak' + pageCnt + '" style="page-break-after:always"> </div>');
}
}
The "<div style='border:1px solid black;height:1px'>" is just a silly marker to find where my page breaks are on the PDF.
1350px in the estimated height of objects where the page break should be created when I traverse all the children of the long div.
In Chrome, I see that I have a total of 5 pages.
But when it is rendered in PDF, the number of pages goes up to 6 or 7 depending the size of the font, the line height, etc.
Here is the image of the pages
Does anyone know the cause of the problem? And how to solve it in general.
I have a quite long html menu list (circa 30 menu positions) where I am trying to dynamically populate with labels according to a .csv file. I’d like to change the each menu label i.e. “the Slots”. Each time the page is loaded, I’ll need to look up position1, and return the right label and Title tag in the page I'm pointing to. There are many fixed positions, but when the .csv file is updated, the menu label needs to change accordingly. To add fuel to my fire, I need to hide a menu if the position in the first column of the .csv cannot be found. This absolute amateur would appreciate any insight you might have.
CSV file saved into directory
position1,Slot1
position2,Slot2
position3,Slot3
position4,Slot4
HTML
<a href='link'>
<span class='hidden-minibar'>Slot 1 </span>
</a>
</li>
<a href='gohere'>
<span class='hidden-minibar'>Slot 2 </span>
</a>
</li>
<a href='link'>
<span class='hidden-minibar'>Slot 3 </span>
</a>
</li>
<a href='link'>
<span class='hidden-minibar'>Slot 4 </span>
</a>
</li>
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function(filedata) {
var list = filedata.target.result;
csvParser(list);
};
reader.readAsText(this.selectedfile.target.files.item(0));
}
var csvParser = function(list) {
var quoteRegexp = new RegExp("^\"(.*)\"$");
var data = [];
var lines = list.split(new RegExp("\r?[\r\n]"));
for (var iCtr = 0; iCtr < lines.length; iCtr += 1) {
var fields = lines[iCtr].split(",");
for (var jCtr = 0; jCtr < fields.length; jCtr += 1) {
fields[jCtr] = fields[jCtr].replace(quoteRegexp, "$1");
}
data.push(fields);
}
return data;
}
use FileReader object and read csv file on client site
use csvParser function to parse row csv data
create dynamic html and appropriate logic on csvParser function result data.
Basic csv read Example
http://jsfiddle.net/techrevolt/W8fME/
I need to create a screen which automates Google search.
I know JavaScript and I'm trying to get GSE works.
I have a search engine and an API key.
The problem is Google's documentation is cyclic i.e. pages point to each other.
There is no working sample from where I can start my research.
Please help if you know of a working sample.
The documents I have read are:
cselement-devguide
introduction
I know this is an old question, but here is what I did to make the API results formatted like the Google Site Search used to give since they are ending the paid accounts and will have ads now. The API way has an option to pay still for over 100 searches per day, so going with that but had to format the results still, and used the existing one to build the css to do similar styling also.
Search form going to this page is just a simple:
<form action="search-results.htm" id="cse-search-box">
<div>
<input class="" name="q" type="text">
<input class="" type="submit">
</div>
</form>
and then the search results page:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>JSON/Atom Custom Search API Example</title>
<!--<link href="default.css" rel="stylesheet" type="text/css">-->
<link href="google.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="gsc-result-info" id="resInfo-0"></div>
<hr/>
<div id="googleContent"></div>
<script>
//Handler for response from google.
function hndlr(response) {
if (response.items == null) {
//Sometimes there is a strange thing with the results where it says there are 34 results/4 pages, but when you click through to 3 then there is only 30, so page 4 is invalid now.
//So if we get to the invalid one, send them back a page.
window.location.replace("searchresults.htm?start=" + (start - 10) + "&q=" + query);
return;
}
//Search results load time
document.getElementById("resInfo-0").innerHTML = "About " + response.searchInformation.formattedTotalResults + " results (" + response.searchInformation.formattedSearchTime + " seconds)";
//Clear the div first, CMS is inserting a space for some reason.
document.getElementById("googleContent").innerHTML = "";
//Loop through each item in search results
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var content = "";
content += "<div class='gs-webResult gs-result'>" +
"<table class='gsc-table-result'><tbody><tr>";
//Thumbnail image
if (item.pagemap.cse_thumbnail != null)
content += "<td class='gsc-table-cell-thumbnail gsc-thumbnail'><div class='gs-image-box gs-web-image-box gs-web-image-box-portrait'><a class='gs-image' href='" + item.link + "'>" +
"<img class='gs-image' class = 'gs-image-box gs-web-image-box gs-web-image-box-portrait' src='" + item.pagemap.cse_thumbnail[0].src + "'></a></td>";
//Link
content += "<td><a class='gs-title' href='" + item.link + "'>" + item.htmlTitle + "</a><br/>";
//File format for PDF, etc.
if (item.fileFormat != null)
content += "<div class='gs-fileFormat'><span class='gs-fileFormat'>File Format: </span><span class='gs-fileFormatType'>" + item.fileFormat + "</span></div>";
//description text and URL text.
content += item.htmlSnippet.replace('<br>','') + "<br/><div class='gs-bidi-start-align gs-visibleUrl gs-visibleUrl-long' dir='ltr' style='word-break:break-all;'>" + item.htmlFormattedUrl +"</div>" +
"<br/></td></tr></tbody></table></div>";
document.getElementById("googleContent").innerHTML += content;
}
//Page Controls
var totalPages = Math.ceil(response.searchInformation.totalResults / 10);
console.log(totalPages);
var currentPage = Math.floor(start / 10 + 1);
console.log(currentPage);
var pageControls = "<div class='gsc-results'><div class='gsc-cursor-box gs-bidi-start-align' dir='ltr'><div class='gsc-cursor'>";
//Page change controls, 10 max.
for (var x = 1; x <= totalPages && x<=10; x++) {
pageControls += "<div class='gsc-cursor-page";
if (x === currentPage)
pageControls += " gsc-cursor-current-page";
var pageLinkStart = x * 10 - 9;
pageControls+="'><a href='search-results.htm?start="+pageLinkStart+"&q="+query+"'>"+x+"</a></div>";
}
pageControls += "</div></div></div>";
document.getElementById("googleContent").innerHTML += pageControls;
}
//Get search text from query string.
var query = document.URL.substr(document.URL.indexOf("q=") + 2);
var start = document.URL.substr(document.URL.indexOf("start=") + 6, 2);
if (start === "1&" || document.URL.indexOf("start=") === -1)
start = 1;
//Load the script src dynamically to load script with query to call.
// DOM: Create the script element
var jsElm = document.createElement("script");
// set the type attribute
jsElm.type = "application/javascript";
// make the script element load file
jsElm.src = "https://www.googleapis.com/customsearch/v1?key=yourApikeyhere&cx=yoursearchengineidhere&start="+start+"&q=" +query +"&callback=hndlr";
// finally insert the element to the body element in order to load the script
document.body.appendChild(jsElm);
</script>
</body>
</html>
I am using Dojo v1.8 with Worklight; I would like create a SwapView dynamically in View, but I'm encountering problems...
HTML code:
<div data-dojo-type="dojox.mobile.View" id="listeInscriptionView"
data-dojo-props="selected:false,scrollDir:'vh'"
style="background-image: url('images/bg-texture.jpg');"
data-dojo-id="id">
</div>
JavaScript code:
var view = registry.byId(listeInscriptionView);
alert(view);
for(var i = 1; i < 3; i++ ){
var swap = new dojox.mobile.SwapView({
id: i,
selected:false
});
var head = new dojox.mobile.Heading({
label:'Swap' + i,
});
swap.addChield(head);
view.addChield(swap);
alert("test" + i);
}
The above does not work. How I can create the widget SwapView dynamically?
Is that a copy of your actual code? I have not actually tested it but there are syntax errors and typos:
registry.byId(listeInscriptionView);
should be
registry.byId("listeInscriptionView");
(missing quotes), and
swap.addChield(head);
view.addChield(swap);
should be
swap.addChild(head);
view.addChild(swap);
Maybe it works better with these errors fixed?