How can I show the number of page only from the second page in TCPDF - footer

How can I showing the number of pages only from the second page in tcpdf?
How can I center de number of pages?
I use this class
private $customFooterText = "";
/**
* #param string $customFooterText
*/
public function setCustomFooterText($customFooterText)
{
$this->customFooterText = $customFooterText;
}
public function Footer()
{
// Linha 1
$this->SetY(-16);
$this->SetFont('helvetica', 'I', 8);
$this->Cell(0, 10, $this->customFooterText, 0, false, 'C', 0, '', 0, false, 'T', 'M');
// Números de página
$this->Cell(0, 10, 'Pag '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M');
}
Thanks a lot!

I got it!!!
$pageN = TCPDF::PageNo();
if($pageN == 1){
//if page is 1... don't print anything
return;
}else{
$this->Cell(0, 10, $this->getAliasNumPage(), 0, false, 'C', 0, '', 0, false, 'T', 'M');

Related

How to bind database in Syncfusion Bar Chart on Asp.net mvc

I tried to use the code on its documentation but it's still not running even if it's static data. Here is the code on the link that I've used but it is not connected to the database. Here are the pictures of the codes I've used:
//CS File(I JUST PUT HERE)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Syncfusion.EJ2.Charts;
namespace EJ2MVCSampleBrowser.Controllers.Chart
{
public partial class ChartController : Controller
{
// GET: RoundedColumn
public ActionResult RoundedColumn()
{
List<RoundedColumnChartData> chartData = new List<RoundedColumnChartData>
{
new RoundedColumnChartData { x= "BGD", y= 106, text= "Bangaladesh" },
new RoundedColumnChartData { x= "BTN", y= 103, text= "Bhutn" },
new RoundedColumnChartData { x= "NPL", y= 198, text= "Nepal" },
new RoundedColumnChartData { x= "THA", y= 189, text= "Thiland" },
new RoundedColumnChartData { x= "MYS", y= 250, text= "Malaysia" }
};
ViewBag.dataSource = chartData;
ViewBag.font = new { fontWeight = "600", color = "#ffffff" };
return View();
}
public class RoundedColumnChartData
{
public string x;
public double y;
public string text;
}
}
}
//CSHTML File (I JUST PUT HERE)
<script src="~/Scripts/theme-color.js"></script>
<div class="control-section">
<div style="text-align:center">
#Html.EJS().Chart("container").Series(series =>
{
series.Type(Syncfusion.EJ2.Charts.ChartSeriesType.Column).XName("x").YName("y")
.CornerRadius(cr=>cr.BottomLeft(10).BottomRight(10).TopLeft(10).TopRight(10))
.Marker(mr => mr.DataLabel(dl => dl.Visible(true).Position(Syncfusion.EJ2.Charts.LabelPosition.Top).Font(ff => ff.FontWeight("600").Color("#ffffff"))))
.DataSource(ViewBag.dataSource).Name("Tiger").Add();
}).PrimaryXAxis(px => px.Interval(1).MajorGridLines(mg=>mg.Width(0))
.LabelStyle(ls=>ls.Color("#ffffff")).TickPosition(Syncfusion.EJ2.Charts.AxisPosition.Inside)
.LabelPosition(Syncfusion.EJ2.Charts.AxisPosition.Inside).ValueType(Syncfusion.EJ2.Charts.ValueType.Category)
).PrimaryYAxis(py => py.Minimum(0).Maximum(300).Interval(50)
.MajorGridLines(mg => mg.Width(0)).LabelStyle(ls=>ls.Color("transparent"))
.MajorTickLines(mg => mg.Width(0)).LineStyle(mg => mg.Width(0))
).Title("Trade in Food Groups").ChartArea(area => area.Border(br=>br.Color("transparent"))
).Tooltip(tt => tt.Enable(false)).LegendSettings(lg => lg.Visible(false)
).Load("load").PointRender("pointRender").Loaded("loaded").Render()
</div>
<div style="float: right; margin-right: 10px;">
Source:
blogs.scientificamerican.com
</div>
</div>
<script>
var pointRender = function (args) {
var selectedTheme = location.hash.split('/')[1];
selectedTheme = selectedTheme ? selectedTheme : 'Material';
if (selectedTheme && selectedTheme.indexOf('fabric') > -1) {
args.fill = fabricColors[args.point.index % 10];
}
else if (selectedTheme === 'material') {
args.fill = materialColors[args.point.index % 10];
}
else {
args.fill = bootstrapColors[args.point.index % 10];
}
};
var count = 0;
var loaded = function (args) {
args.chart.loaded = null;
setInterval(
function () {
if (count === 0) {
args.chart.series[0].dataSource = [
{ x: 'Tea', y: 206, text: 'Bangaladesh' },
{ x: 'Misc', y: 123, text: 'Bhutn' },
{ x: 'Fish', y: 48, text: 'Nepal' },
{ x: 'Egg', y: 240, text: 'Thiland' },
{ x: 'Fruits', y: 170, text: 'Malaysia' }
];
args.chart.animate();
count++;
}
else if (count === 1) {
args.chart.series[0].dataSource = [
{ x: 'Tea', y: 86, text: 'Bangaladesh' },
{ x: 'Misc', y: 173, text: 'Bhutn' },
{ x: 'Fish', y: 188, text: 'Nepal' },
{ x: 'Egg', y: 109, text: 'Thiland' },
{ x: 'Fruits', y: 100, text: 'Malaysia' }
];
args.chart.animate();
count++;
}
else if (count === 2) {
args.chart.series[0].dataSource = [
{ x: 'Tea', y: 156, text: 'Bangaladesh' },
{ x: 'Misc', y: 33, text: 'Bhutn' },
{ x: 'Fish', y: 260, text: 'Nepal' },
{ x: 'Egg', y: 200, text: 'Thiland' },
{ x: 'Fruits', y: 30, text: 'Malaysia' }
];
args.chart.animate();
count = 0;
}
}, 2000);
}
</script>
}

Export Highcharts polar chart csv with categories in place of polar coordinates

I've implemented a polar chart in which each series has 4 values corresponding to 4 categories. When I export the chart csv, the category column contains polar coordinates. I would like to replace these with the corresponding category name. How do I do this?
Adding the categories to each series, had no effect. I also tried adding a categories property to the xAxis, but it had not effect. An xAxis.label formatter successfully returns the category name for each data polar coordinate.
const options = {
chart: {
polar: true,
},
title: {
text: '',
},
tooltip: {
valueDecimals: 2,
headerFormat: '<br/>',
},
legend: {},
pane: {
startAngle: 0,
endAngle: 360,
},
xAxis: {
tickInterval: 45,
min: 0,
max: 360,
labels: {
// eslint-disable-next-line
formatter: function() {
switch (this.value) {
case 45:
return '<b>Experience</b>'
case 135:
return '<b>Frictionless</b>'
case 225:
return '<b>Low Price</b>'
case 315:
return '<b>Brand</b>'
default:
return ''
}
},
},
},
yAxis: {
min: 0,
max: 10,
labels: {
format: '{}',
},
},
plotOptions: {
series: {
pointStart: 45,
pointInterval: 90,
},
column: {
pointPadding: 0,
groupPadding: 0,
},
},
series: kahnSeries,
}
You need to use categories property, but without options like: pointInterval, pointStart, min and max:
xAxis: {
categories: ['Experience', 'Frictionless', 'Low Price', 'Brand']
},
Live demo: http://jsfiddle.net/BlackLabel/z8cm1p39/
API Reference: https://api.highcharts.com/highcharts/xAxis.categories
To avoid changing the chart's current display, I wrapped the getCSV function and replaced the CSV category values. If there was a simpler way, please share it.
{
(function (H) {
H.wrap(H.Chart.prototype, 'getCSV', function (
proceed,
useLocalDecimalPoint
) {
// Run the original proceed method
const result = proceed.apply(
this,
Array.prototype.slice.call(arguments, 1)
)
const itemDelimiter = ','
const lineDelimiter = '\n'
const rows = result.split(lineDelimiter)
let newResult = ''
let rowCategories = false
rows.forEach((row, rowIndex) => {
const columns = row.split(itemDelimiter)
if (rowIndex === 0 && columns[0] === '"Category"') {
rowCategories = true
}
if (rowIndex > 0 && rowCategories) {
let newRow = formatter(columns[0])
columns.forEach((column, columnIndex) => {
if (columnIndex > 0) {
newRow += itemDelimiter
newRow += column
}
})
newResult += newRow
} else {
newResult += row
}
if (rowIndex < rows.length - 1) {
newResult += lineDelimiter
}
}
)
return newResult
})
}(Highcharts))
}

Highcharts Export Server: Polar Chart Ignoring Formatters in Callback

We're currently generating a polar chart in HighCharts that renders correctly on the client-side (in the browser), and correctly applies formatters to the xAxis, yAxis, and plotOptions. Here is a jsFiddle that shows how it is rendering (correctly) in the browser: https://jsfiddle.net/cmodzelewski/38f03Lse/1/
On the server side, we are constructing a JSON payload and sending it to a node-export-server instance and returning a PNG. Based on our research, it is clear that formatters need to be included in the callback key of our JSON payload and passed to the server as a string, rather than in the infile key.
That's fine, and so we're converting our formatter functions into strings, composing them into the options object in our callback key, and then redrawing the chart at the end of our callback key.
This approach works great for non-polar charts, but if polar == true the export server returns a valid PNG from the export server, however that chart does not apply our formatter functions to the xAxis, yAxis, or plotOptions.series.
Here is the JSON payload that we are sending to a node-export-server instance:
{
"callback": "function (chart) {var options = chart.options;var xAxisFormatter = function () { var extra_hrs = 0; if (this.value == 0) { extra_hrs = 12; }; return ((this.value / 0.5)/60) + extra_hrs + ':00'; };if (\"labels\" in options[\"xAxis\"]) { options[\"xAxis\"][\"labels\"][\"formatter\"] = xAxisFormatter; } else { options[\"xAxis\"][\"labels\"] = { \"formatter\": xAxisFormatter, \"style\": { \"fontSize\": \"8px\" } }; };var yAxisFormatter = function () { return Highcharts.numberFormat(this.value, 2, '.', ',') + \"%\"; };if (\"labels\" in options[\"yAxis\"]) { options[\"yAxis\"][\"labels\"][\"formatter\"] = yAxisFormatter; } else { options[\"yAxis\"][\"labels\"] = { \"formatter\": yAxisFormatter, \"style\": { \"fontSize\": \"8px\" } };};var plotOptionsFormatter = function () { return Highcharts.numberFormat(this.value, 2, '.', ',') + \"%\"; };options[\"plotOptions\"][\"series\"][\"dataLabels\"][\"formatter\"] = plotOptionsFormatter;chart = new Highcharts.chart(chart.container, options);chart.redraw();}",
"infile": "{chart: {backgroundColor: \"white\", borderWidth: 0, height: 300, polar: true, width: 300}, colors: [\"#16C1F3\", \"#3C6E71\", \"#EAC435\", \"#E63946\", \"#33658A\", \"#DFD6A7\", \"#627264\", \"#86CCA5\", \"#6268B0\", \"#E8D33F\", \"#DA2C38\"], credits: {enabled: false, position: {align: \"right\", verticalAlign: \"bottom\"}, text: \"(c) Insight Industry Inc., 2017.\"}, exporting: {enabled: false}, legend: {enabled: false}, plotOptions: {column: {groupPadding: 0, pointPadding: 0}, series: {dataLabels: {}, pointInterval: 30, pointStart: 0}}, series: [{data: [{name: \"12:00am - 4:59am\", x: 0, y: 2.737994945240101}, {name: \"5:00am - 5:29am\", x: 150, y: 1.6287559674248806}, {name: \"5:30am - 5:59am\", x: 165, y: 1.6849199663016006}, {name: \"6:00am - 6:29am\", x: 180, y: 5.9112608817747825}, {name: \"6:30am - 6:59am\", x: 195, y: 11.513619769727605}, {name: \"7:00am - 7:29am\", x: 210, y: 17.98652064026959}, {name: \"7:30am - 7:59am\", x: 225, y: 17.733782645324347}, {name: \"8:00am - 8:29am\", x: 240, y: 20.190957596180848}, {name: \"8:30am - 8:59am\", x: 255, y: 7.848918843021623}, {name: \"9:00am - 9:59am\", x: 270, y: 8.438640831227183}, {name: \"10:00am - 10:59am\", x: 300, y: 3.1592249368155008}, {name: \"11:00am - 11:59am\", x: 330, y: 1.1654029766919405}], name: null, pointPlacement: \"on\", type: \"column\"}], title: {text: null}, tooltip: {style: {fontSize: \"10px\"}, valueDecimals: 1, valueSuffix: \"%\"}, xAxis: {labels: {style: {fontSize: \"10px\"}}, max: 360, min: 0, tickInterval: 30, title: {text: null}}, yAxis: {labels: {style: {fontSize: \"10px\"}}, max: 25.0, min: 0, showLastLabel: false, tickInterval: 5, title: {style: {color: \"#0A3B61\", fontSize: \"9px\", fontWeight: \"bold\"}, text: \"Workers, Aged 25+\"}}}",
"scale": 2,
"type": "png"
}
We have recreated what we (suspect) is the process that the node export server goes through, and have definitely recreated the (weird) behavior that we're seeing in this jsFiddle: https://jsfiddle.net/cmodzelewski/v4gm6t9a/2/
Are we missing something blatantly obvious (which is what we suspect)? Or is there a better way of doing this to get the behavior we're looking for?
Any help would be very much appreciated!
In your fiddle with the suspected process, and in your callback, you are setting the axis labels in the following way:
options["yAxis"]["labels"]
This will set an object labels on the yAxis element, however, since you can have several axis in highcharts, they are indexed, and stored as such. That means you have to edit the first axis like this:
options["yAxis"][0]["labels"]
Here is a picture of the yAxis object in the incorrect configuration:
Here is a picture of the yAxis object in the correct configuration:
Working example using your second fiddle: https://jsfiddle.net/ewolden/v4gm6t9a/4/

How to do Sorting/Paging in jqgrid in ASP.net MVC

First of all am new to ASP.NET MVC.
I want to do custom sorting and paging in JqGrid using a stored procedure. Parameters to the stored procedure are StartIndex, PageSize, SortExpression.
How can I get the current page details and sort details and how to call my action method on each navigation in jqgrid?
As far as I know the stored procedure side is fine. But when I load first time 10 records are retrieved. Total number of record is 16. But I cannot see page 2 or control for navigating to the expected next page.
$(function () {
$("#myGrid").jqGrid({
url: '/Request/GetRequests/',
datatype: 'json',
mytype: 'get',
colNames: ['RequestType', 'RequestFrom', 'Summary', 'Status', 'CreatedDate', 'RequestID'],
colModel: [
{ name: 'RequestType', index: 'RequestType', width: 200 },
{ name: 'FromName', index: 'FromName', width: 200 },
{ name: 'Summary', index: 'Summary', width: 350 },
{ name: 'RequestStatus', index: 'RequestStatus', width: 150 },
{ name: 'CreatedDate', index: 'CreatedDate', width: 150 },
{ name: 'RequestID', index: 'RequestID', width: 150 }
],
pager: $('#myPager'),
rowNum: 10,
sortname: 'CreatedDate',
gridview: true,
sortorder: 'desc',
loadonce: true,
rowList: [5, 10, 20, 50],
width: 1100,
height: 900,
viewrecords: true,
caption: 'Request Details',
onSelectRow: function ()
{
}
});
//var j = jQuery.noConflict();
//j('.datepicker').datepicker();
});
<table id="myGrid"></table>
<div id="myPager"></div>
Action method:
[HttpGet]
public JsonResult GetRequests(string sidx, string sord, int page, int rows)
{
RequestRepository edb = new RequestRepository();
int pageIndex = page;
int pageSize = rows;
int startRow = (pageIndex * pageSize) + 1;
RequestNavigation data = edb.RequestGetParam(page, rows, sidx, sord);
int totalRecords = data.totalRecords;
int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = data.RequestDetails.ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
I found the solution.
Its a simple problem in jqgrid property loadonce: true we have to change this to loadonce: false
in the javascript:
...
gridview: true,
sortorder: 'desc',
loadonce: true,
rowList: [5, 10, 20, 50],
...
Becomes
...
gridview: true,
sortorder: 'desc',
loadonce: false,
rowList: [5, 10, 20, 50],
...

How to pass form data and jqGrid (editUrl) data to Controller at same time

I have an asp.net MVC3 app with various bits of form data and a jqGrid.
When I edit a row in the jqGrid I need to post the grid data as well as some of the form pieces to the editUrl controller.
I can post the jqGrid edited data to my controller through the editUrl just fine.
Is there a way to do this?
Im not sure how to send the other form elements and how to receive them in my controller.
Any help will be greatly appreciated.
Below is my jqGrid:
$("#jqTable").jqGrid({
// Ajax related configurations
url: '#Url.Action("_CustomBinding")',
datatype: "json",
mtype: "POST",
postData: {
programID: function () { return $("#ProgramID option:selected").val(); },
buildID: function () { return $('#Builds option:selected').val(); }
},
// Specify the column names
colNames: ["Actions", "Assembly ID", "Assembly Name", "Assembly Type", "Cost", "Order", "Budget Report", "Partner Request", "Display"],
// Configure the columns
colModel: [
{ name: 'myac', width: 80, fixed: true, sortable: false, resize: false, formatter: 'actions', formatoptions: { keys: true} },
{ name: "AssemblyID", key: true, index: "AssemblyID", width: 40, align: "left", editable: false },
{ name: "AssemblyName", index: "AssemblyName", width: 100, align: "left", editable: true, edittype: 'select',
editoptions: {
dataUrl: '#Url.Action("_Assemblies")',
buildSelect: function (data) {
var response = jQuery.parseJSON(data);
var s = '<select>';
if (response && response.length) {
for (var i = 0, l = response.length; i < l; i++) {
var ri = response[i];
s += '<option value="' + ri + '">' + ri + '</option>';
}
}
return s + "</select>";
}
}
},
{ name: "AssemblyTypeName", index: "AssemblyTypeName", width: 100, align: "left", editable: false, edittype: 'select' },
{ name: "AssemblyCost", index: "AssemblyCost", width: 50, align: "left", formatter: "currency", editable: true },
{ name: "AssemblyOrder", index: "AssemblyOrder", width: 50, align: "left", editable: true },
{ name: "AddToBudgetReport", index: "AddToBudgetReport", width: 100, align: "center", formatter: "checkbox", editable: true, edittype: 'checkbox' },
{ name: "AddToPartnerRequest", index: "AddToPartnerRequest", width: 100, align: "center", formatter: "checkbox", editable: true, edittype: 'checkbox' },
{ name: "Show", index: "Show", width: 50, align: "center", formatter: "checkbox", editable: true, edittype: 'checkbox'}],
// Grid total width and height and formatting
//width: 650,
//height: 220,
altrows: true,
// Paging
//toppager: true,
pager: $("#jqTablePager"),
rowNum: 10,
rowList: [10, 20, 30],
viewrecords: true, // Specify if "total number of records" is displayed
emptyrecords: 'No records to display',
// Default sorting
sortname: "AssemblyID",
sortorder: "asc",
// Grid caption
caption: "Build Template",
// grid command functionality
editurl: '#Url.Action("_AjaxUpdate")',
onSelectRow: function (AssemblyID) {
if (AssemblyID && AssemblyID !== lastsel) {
$('#jqTable').jqGrid('restoreRow', lastsel);
$("#jqTable").jqGrid('editRow', AssemblyID, true);
lastsel = AssemblyID;
}
}
}).navGrid("#jqTablePager",
{ refresh: false, add: false, edit: false, del: false },
{}, // settings for edit
{}, // settings for add
{}, // settings for delete
{sopt: ["cn"]} // Search options. Some options can be set on column level
);
You can customize what is being sent to the server using onclickSubmit option:
.navGrid("#jqTablePager",
{ refresh: false, add: false, edit: false, del: false },
{ // settings for edit
onclickSubmit: function(params, postdata)
{
postdata.extraParam = 'value'
}
},
{}, // settings for add
{}, // settings for delete
{sopt: ["cn"]} // Search options. Some options can be set on column level
);
The controller will receive a JSON object containing all edited properties + extraParam. It is up to you how you handle this on the server side.
I see you use already programID and buildID properties defined as functions. The functions will be called during every request to get the data for the grid. In the same way you can use inlineData or extraparam parameter of the editRow which you call explicitly inside of your onSelectRow callback.
Try to call the demo which has the following jqGrid options:
inlineData: {
myParam: function () {
alert("inlineData is calling!!!");
return "OK";
}
},
onSelectRow: function (id) {
if (id && id !== lastSel) {
$(this).jqGrid('restoreRow', lastSel);
$(this).jqGrid('editRow', id, true, null, null, null, {
myNextParam: function () {
alert("extraparam of 'editRow' is calling!!!");
return "Fine";
}
});
lastSel = id;
}
}
You will see two alerts if you would save the data of the editing row. In my demo I used editurl: 'myDummyUrl' which has no code on the server side and you will see an error at the end, but if you examine the HTTP traffic (with respect of Fiddler or Firebug) you will see that the following additional parameters will be send to the editurl:
myParam=OK&myNextParam=Fine
I think it is what you need.
inlineData:{}
is working fine for getting work before goes to controller while editing.
But in case of delete how to get event like before to pass control to controller to make json , after click on delete.

Resources