How to get table row image in PDF using jsPDF? - jspdf

i have a html table with images.When i was trying to convert as PDF Only data are coming.Image not displaying in PDF.
How to get table td images in pdf ?
Contract Title Contains a Checkbox image.But is not coming in pdf ?
my pdf code :
function fnExportDIVToPDF() {
var pdf = new jsPDF('l', 'pt', 'a2');
pdf.setFontSize(8);
source = $('#divReport')[0];
specialElementHandlers = {
'#bypassme': function (element, renderer) {
return true
}
};
margins = {
top: 30, bottom: 40, left: 10, width: 1300};
pdf.fromHTML(
source, margins.left, margins.top, {
'elementHandlers': specialElementHandlers},
function (dispose) {
pdf.save('Report.pdf');
}
, margins);
}
Div:
<div id="divReport">
<div width="100%">
<p><span id="oHeadingSummary" class="rptheader"></span></p>
</div>
<table class="table table-striped rpttable" border="1" cellspacing="0" id="oReportContractDetailsByCA" width="100%">
<colgroup>... <col width="10%">
</colgroup></table>
Autogenerate table i added a image :
function GenerateTable(data) {
document.getElementById('divExport').style.display = "";
if (i == 0) {
$('#oReportContractDetailsByCA').append("<tr style='background-color:" + bkColor + ";'><td><img src='../../../_layouts/15/1033/IMAGES/eContracts/checked-checkbox-512.jpg'></img></td></tr>")
}

You can use the didDrawCell hook to add any content to a cell.
https://codepen.io/someatoms/pen/vLYXWB
function generate() {
var doc = new jsPDF();
doc.autoTable({
html: '#mytable',
bodyStyles: {minCellHeight: 15},
didDrawCell: function(data) {
if (data.column.index === 5 && data.cell.section === 'body') {
var td = data.cell.raw;
// Assuming the td cells have an img element with a data url set (<td><img src="data:image/jpeg;base64,/9j/4AAQ..."></td>)
var img = td.getElementsByTagName('img')[0];
var dim = data.cell.height - data.cell.padding('vertical');
var textPos = data.cell.textPos;
doc.addImage(img.src, textPos.x, textPos.y, dim, dim);
}
}
});
doc.save("table.pdf");
}

Related

Trouble with jspdf script

I have added this jspdf script on my website to download pdf. However I get this error.
Uncaught TypeError: Cannot read property '1' of undefined
at f.renderParagraph (jspdf.min.js:202)
at f.setBlockBoundary (jspdf.min.js:202)
at k (jspdf.min.js:202)
at k (jspdf.min.js:202)
at k (jspdf.min.js:202)
at jspdf.min.js:202
at l (jspdf.min.js:202)
at Image.i.onerror.i.onload (jspdf.min.js:202)
This happens on certain pages while others work fine.I have added the code I am using below. I am not sure if it is anything to do with my code or the jspdf.
//Code I am using:
<script type="text/javascript">
function HTMLtoPDF(){
var pdf = new jsPDF('p', 'pt', 'letter');
source = $('#HTMLtoPDF')[0];
specialElementHandlers = {
'#bypassme': function(element, renderer){
return true
}
}
margins = {
top: 50,
left: 60,
right:60,
width: 545
};
pdf.fromHTML(
source // HTML string or DOM elem ref.
, margins.left // x coord
, margins.top // y coord
, {
'width': margins.width // max width of content on PDF
, 'elementHandlers': specialElementHandlers
},
function (dispose) {
// dispose: object with X, Y of the last line add to the PDF
// this allow the insertion of new lines after html
pdf.save('Download.pdf');
}
)
}
</script>
<button type="button" onclick="HTMLtoPDF()" style=" height: 40px; width: 154px; background-color: #008800; color: #ffffff; font-size: 150%;">Download PDF </button>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"> </script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var str_pdf = $("#HTMLtoPDF").html();
var regex = /<br\s*[\/]?>/gi;
$("#HTMLtoPDF").html(str_pdf.replace(regex, '<p data-empty="true"><br></p>'));
});
function HTMLtoPDF(){
var pdf = new jsPDF('p', 'pt', 'a4');
source = $('#HTMLtoPDF')[0];
specialElementHandlers = {
'#bypassme': function (element, renderer) {
return true
}
};
margins = {
top: 30,
bottom: 30,
left: 40,
width: 522
};
pdf.fromHTML(
source,
margins.left,
margins.top, {
'width': margins.width,
'elementHandlers': specialElementHandlers
},
function (dispose) {
pdf.save('Download.pdf');
}, margins);
}
</script>
<!-- these js files are used for making PDF -->

Cell text colour refuses to change jsdpdf-autotable

I have followed the steps to some answers on this topic already, but none of them are working. I have the following text which needs to display in a red text:
<table id="heading1">
<tr>
<td class="hrow"><h4>1. DETAILS</h4></td>
</tr>
</table>
Here is the code I have written for the PDF:
<script>
exportGraph = function () {
var pdfsize = 'a4';
var pdf = new jsPDF('l', 'mm', pdfsize);
var totalPagesExp = "{total_pages_count_string}";
var res2 = pdf.autoTableHtmlToJson(document.getElementById("heading1"));
pdf.autoTable(res2.columns, res2.data, {
createdCell: function(cell, data) {
var tdElement = cell.raw;
if (tdElement.classList.contains("hrow")) {
cell.styles.textColor = "[255,72,72]";
}
},
startY: 10,
margin: {left: 5 },
styles: { halign: 'left', fontsize: 12 }
});
pdf.save('Submission-Printout.pdf');
}
</script>
As you can see, what I have done SHOULD in theory work, but the text still appears as not red. Does anyone know why it's not appearing in red text colour?
What about this example ?
function generate() {
var doc = new jsPDF('p', 'pt', 'a4');
var elem = document.getElementById('example');
var data = doc.autoTableHtmlToJson(elem);
doc.autoTable(data.columns, data.rows, {
createdCell: function (cell, data) {
if ($(cell.raw).hasClass("demo1")) {
cell.styles.textColor = [200, 0, 0];
cell.styles.fontStyle = 'bolditalic';
};
if ($(cell.raw).hasClass("demo2")) {
cell.styles.textColor = [0, 0, 205];
cell.styles.fontStyle = 'bold';
};
return false;
}
});
doc.save("table.pdf");
}

GeoXml3 Display Custom Field From KML File In A DIV Tag

I am trying to get data from a custom field in the KML file to display in the div id=summary section when that KML file is selected from either the map or the sidebar. I just simply copied the sidebar html to make a summary html section and wanted the content from the KML at (Document/Folder/Placemark/summary.text) to be displayed in that div tag.
<table style="width:100%;">
<tr>
<td>
<div id="loaddiv">Loading.....    please wait!
<br />
</div>
<div id="map_canvas">
</div>
</td>
<td>
<div id="sidebar" style="width:300px;height:600px; overflow:auto"></div>
</td>
<td>
<div id="summary" style="width:300px;height:600px; overflow:auto"></div>
</td>
</tr>
<tr>
<td colspan="2">
<div id="link"></div>
</td>
</tr>
</table>
I feel like this may require some function overrides from the geoxml3.js file. I saw a section that had the below in geoxml3.js and it seemed like there may need to be something added to pull info from the KML file.
placemark = {
name: geoXML3.nodeValue(node.getElementsByTagName('name')[0]),
description: geoXML3.nodeValue(node.getElementsByTagName('description')[0]),
styleUrl: geoXML3.nodeValue(node.getElementsByTagName('styleUrl')[0]),
id: node.getAttribute('id')
};
Website with summary table column next to the sidebar column:
https://s20.postimg.cc/6jjcrnke5/geo1.png
KML files XML view:
https://s20.postimg.cc/4eyzqkqh9/geo2.png
Create the below functions:
function showSummary(pm, doc) {
summaryHtml = geoXmlDoc[doc].placemarks[pm].summary;
document.getElementById("summary").innerHTML = summaryHtml;
}
function clickPoly(poly, polynum, doc) {
google.maps.event.addListener(poly, "click", function() {
showSummary(polynum, doc);
});
}
In the function useTheData(doc) add clickPoly(placemark.polygon, i, j); under the line highlightPoly(placemark.polygon, i, j); and add clickPoly(placemark.polyline, i, j); under the line highlightPoly(placemark.polyline, i, j);.
Lastly add showSummary(pm, doc); to the first line in the function kmlPlClick(pm, doc).
create a custom parse function for the custom tag in your KML (parses that information from the KML and populates a custom field in the object processed by geoxml3
example: http://www.geocodezip.com/geoxml3_test/votemap_address2.html)
// Custom placemark parse function
function parsePlacemark (node, placemark) {
var summaryNodes = node.getElementsByTagName('summary');
var summary = null;
if (summaryNodes && summaryNodes.length && (summaryNodes .length > 0)) {
placemark.summary = geoXML3.nodeValue(summaryNodes[0]);
}
}
add code to put that information in the <div> on a click (from #PieDev's answer):
function showSummary(pm, doc) {
summaryHtml = geoXmlDoc[doc].placemarks[pm].summary;
document.getElementById("summary").innerHTML = summaryHtml;
}
function clickPoly(poly, polynum, doc) {
google.maps.event.addListener(poly, "click", function() {
showSummary(polynum, doc);
});
}
function kmlPlClick(pm,doc) {
showSummary(pm, doc);
if (geoXmlDoc[doc].placemarks[pm].polyline.getMap()) {
google.maps.event.trigger(geoXmlDoc[doc].placemarks[pm].polyline,"click", {vertex: 0});
} else {
geoXmlDoc[doc].placemarks[pm].polyline.setMap(map);
google.maps.event.trigger(geoXmlDoc[doc].placemarks[pm].polyline,"click", {vertex: 0});
}
}
function useTheData(doc){
var currentBounds = map.getBounds();
if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
// Geodata handling goes here, using JSON properties of the doc object
sidebarHtml = '<table><tr><td>Show All</td></tr>';
geoXmlDoc = doc;
for (var j = 0; j<geoXmlDoc.length;j++) {
if (!geoXmlDoc[j] || !geoXmlDoc[j].placemarks || !geoXmlDoc[j].placemarks.length)
continue;
for (var i = 0; i < geoXmlDoc[j].placemarks.length; i++) {
var placemark = geoXmlDoc[j].placemarks[i];
if (placemark.polygon) {
if (currentBounds.intersects(placemark.polygon.bounds)) {
makeSidebarPolygonEntry(i,j);
}
var kmlStrokeColor = kmlColor(placemark.style.color);
var kmlFillColor = kmlColor(placemark.style.fillcolor);
var normalStyle = {
strokeColor: kmlStrokeColor.color,
strokeWeight: placemark.style.width,
strokeOpacity: kmlStrokeColor.opacity,
fillColor: kmlFillColor.color,
fillOpacity: kmlFillColor.opacity
};
placemark.polygon.normalStyle = normalStyle;
highlightPoly(placemark.polygon, i, j);
clickPoly(placemark.polygon, i, j);
}
if (placemark.polyline) {
if (currentBounds.intersects(placemark.polyline.bounds)) {
makeSidebarPolylineEntry(i,j);
}
var kmlStrokeColor = kmlColor(placemark.style.color);
var normalStyle = {
strokeColor: kmlStrokeColor.color,
strokeWeight: placemark.style.width,
strokeOpacity: kmlStrokeColor.opacity
};
placemark.polyline.normalStyle = normalStyle;
highlightPoly(placemark.polyline, i, j);
clickPoly(placemark.polyline, i, j);
}
if (placemark.marker) {
if (currentBounds.contains(placemark.marker.getPosition())) {
makeSidebarEntry(i,j);
}
}
}
}
sidebarHtml += "</table>";
document.getElementById("sidebar").innerHTML = sidebarHtml;
};
working example

jQuery Droppable: Only allow element to drop, if there is no other element in that dropzone

I'm writing a puzzle, where you have to drag an item into the correct dropzone.
Problem: I want that you can only drag an item into a dropzone, if that dropzone does not contain any other items. How can I check, whether there are no other items in that dropzone?
Here is a gif of my current puzzle:
Here is a gif which shows the problem:
As you can see, I can drag multiple items into the same dropzone.
If a dropzone already contains an item, the user should not be able to drop another item into that dropzone. How do I achieve that?
My script so far:
$( ".draggable" ).draggable({ revert: 'invalid', snap: ".dropfield", snapTolerance: 30, snapMode: "inner"});
$( ".dropfield" ).droppable({
accept: ".dropling",
drop: function( event, ui ) {
if(some-condition){ // if correct word got dragged into the correct dropzone
var id = ui.draggable.attr('id');
$("#" + id).draggable( 'disable' );
$(this).droppable( 'disable' );
$("#" + id).css( "background-color", "#7FFF00");
}
});
Html-excerpt:
<div id="liebe" class="dropling draggable text-center">
Liebe
</div>
<span class="dropfield" value="scheitern">
</span>
PS: There are already several topics on Stack-Overflow with the same question. However, I'm not intelligent enough to apply the suggested answers to my case. Please help me.
Edit1
Here is a gif which shows my preferred behavior:
I dragged a wrong word into a dropzone. But as long that dropzone is occupied by a word, no other words should be able to be dropped into that dropzone.
My current code:
if(some-condition){ //correct word
$("#" + id).draggable( 'disable' );
$(this).droppable( 'disable' );
$("#" + id).css( "background-color", "#7FFF00");
}
} else { //wrong word
console.log("wrong word dropped");
$(this).droppable( 'disable' );
}
As soon as I drag the wrong word out of the dropzone, the dropzone should become enabled again. But how can I achieve that?
I would advise breaking this into their own functions. This way you can enable and disable drop repeatedly. Not sure what you want to trigger the item to become draggable and droppable again based on the example you have supplied. Based on what you have supplied, I can offer this the following example.
$(function() {
function enableDrop($target) {
console.log("Enabled Drop");
$target.droppable({
accept: ".dropling",
classes: {
"ui-droppable-hover": "drop-target"
},
drop: function(event, ui) {
var $that = $(this),
dragWord = ui.draggable.text().trim(),
$item = ui.draggable;
if (checkWord(dragWord)) {
console.log("Accepted: " + $item.attr("id"));
$item.
removeClass("draggable")
.draggable('disable')
.attr("style", "")
.appendTo($that);
disableDrop($that);
$that.css("background-color", "#7FFF00");
} else {
return false;
}
}
});
}
function disableDrop($target) {
console.log("Disabling Drop on " + $target.attr("class"));
$target.droppable("destroy");
}
function checkWord(w) {
var result = false;
console.log("Checked Word: " + w);
if (w == "Liebe") {
result = true;
}
return result;
}
$(".draggable").draggable({
revert: 'valid',
snap: ".dropfield",
snapTolerance: 30,
snapMode: "inner"
});
enableDrop($(".dropfield"));
});
p .dropfield {
border: 1px solid #ccc;
border-radius: 3px;
display: inline-block;
width: 4em;
height: 1.5em;
margin-bottom: -.25em
}
p .drop-target {
border: 1px dashed #ccc;
background-color: #ccc;
}
.text-center {
text-align: center;
}
.draggable {
border: 1px solid #ccc;
border-radius: 3px;
display: inline-block;
width: 4em;
height: 1em;
padding: .25em 0;
margin-bottom: -.25em
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<p>Diese Schlussfolgerung ist <span class="dropfield" value="scheitern"></span>: Ee kann doch nicht sein, dass es gut ist, </p>
<div id="liebe" class="dropling draggable text-center">Liebe</div>
<div id="absurd" class="dropling draggable text-center">absurd</div>
The easiest way here is probably to solve the whole thing in a more generic way. For this I would add an attribute to the respective Dom element (data-count) and then check how many characters are contained and how many are still allowed:
See /** ADDED **/ for the things i did:
$(function() {
function textWrapper(str, sp, btn) {
if (sp == undefined) {
sp = [0, 0];
}
var txt = "";
if (btn) {
txt = "<span class='w b'>" + str + "</span>";
} else {
txt = "<span class='w'>" + str + "</span>";
}
if (sp[0]) {
txt = " " + txt;
}
if (sp[1]) {
txt = txt + " ";
}
return txt;
}
function chunkWords(p) {
var words = p.split(" ");
words[0] = textWrapper(words[0], [0, 1]);
var i;
for (i = 1; i < words.length; i++) {
var re = /\[.+\]/;
if (re.test(words[i])) {
var b = makeTextBox(words[i].slice(1, -1));
words[i] = " " + b.prop("outerHTML") + " ";
} else {
if (words[0].indexOf(".")) {
words[i] = textWrapper(words[i], [1, 0]);
} else {
words[i] = textWrapper(words[i], [1, 1]);
}
}
}
return words.join("");
}
function unChunkWords(tObj) {
var words = "";
$(tObj).contents().each(function(i, el) {
if ($(el).hasClass("b")) {
words += "[" + $(el).text() + "]";
} else {
words += $(el).text();
}
});
return words.replace(/\s+/g, " ").trim();
}
function makeBtn(tObj) {
var btn = $("<span>", {
class: "ui-icon ui-icon-close"
}).appendTo(tObj);
}
function makeTextBox(txt) {
var sp = $("<span>", {
class: "w b"
}).html(txt);
makeBtn(sp);
return sp;
}
function makeDropText(obj) {
return obj.droppable({
drop: function(e, ui) {
var txt = ui.draggable.text();
var newSpan = textWrapper(txt, [1, 0], 1);
$(this).after(newSpan);
makeBtn($(this).next("span.w"));
makeDropText($(this).next("span.w"));
$("span.w.ui-state-highlight").removeClass("ui-state-highlight");
update()
},
over: function(e, ui) {
$(this).add($(this).next("span.w")).addClass("ui-state-highlight");
},
out: function() {
$(this).add($(this).next("span.w")).removeClass("ui-state-highlight");
}
});
}
$("p.given").html(chunkWords($("p.given").text()));
$("p.given").on("click", ".b > .ui-icon", function() {
$(this).parent().remove();
});
$("p.given").blur(function() {
var w = unChunkWords($(this));
$(this).html(chunkWords(w));
makeDropText($("p.given span.w"));
});
$("span.given").draggable({
helper: "clone",
revert: "invalid"
});
makeDropText($("p.given span.w"));
/** ADDED **/
// update at beginning
update();
// register update events
$("p.given").on('click keydown keyup drag drop', update);
function update(e) {
var templateText = unChunkWords($("p.given"));
var templateTextWithoutParameters = templateText.replace(/\[(.+?)\]/g, "");
var templateTextWithoutParametersLenght = templateTextWithoutParameters.length;
// calc total length
var totalLength = templateTextWithoutParametersLenght;
// since 'helper: clone' we have to ignore it!
$("[data-count]:not(.ui-draggable-dragging)").each(function(index, item) {
var count = $(item).attr("data-count")
var text = "[" + $(item).text() + "]";
var length = templateText.split(text).length - 1;
totalLength += count * length;
});
// 46,8 keycodes for delete & backspace
var maxLength = 200;
if (totalLength >= maxLength && e && e.keyCode !== 46 && e.keyCode !== 8) {
e.preventDefault();
}
// disable data counts
var remaining = maxLength - totalLength;
$("[data-count]:not(.ui-draggable-dragging)").each(function(index, item) {
var count = $(item).attr("data-count");
if (parseInt(count) > remaining) {
$(item).attr("disabled", true);
$(item).draggable().draggable('disable');
} else {
$(item).attr("disabled", false);
$(item).draggable().draggable('enable');
}
})
$(".output").text(totalLength);
}
});
p.given {
display: flex;
flex-wrap: wrap;
}
p.given span.w span.ui-icon {
cursor: pointer;
}
div.blanks {
display: inline-block;
min-width: 50px;
border-bottom: 2px solid #000000;
color: #000000;
}
div.blanks.ui-droppable-active {
min-height: 20px;
}
span.answers>b {
border-bottom: 2px solid #000000;
}
span.given {
margin: 5px;
}
/** ADDED **/
[disabled] {
color: grey
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="row">
<p class="given" contenteditable="true">Lorem Ipsum is [Test] Ipsum has been the industry's [America] standard dummy text ever since the 1500s, </p>
</div>
<div class="divider"></div>
<div class="section">
<section>
<div class="card blue-grey ">
<div class="card-content white-text">
<div class="row">
<div class="col s12">
<span class="given btn-flat white-text red lighten-1" rel="1" data-count="50">Test</span>
<span class="given btn-flat white-text red lighten-1" rel="2" data-count="30">America</span>
<span class="given btn-flat white-text red lighten-1" rel="3" data-count="20">Qatar</span>
<span class="given btn-flat white-text red lighten-1" rel="4" data-count="10">Philippines</span>
</div>
</div>
</div>
</div>
</section>
</div>
<div class="divider"></div>
Count: <span class="output"></span>

MVC/Razor Passing form variables to a chart image method

I have updated the code, but am still running into problems... I think I'm lost in spaghetti code at the moment.
My financial periods controller:
public ActionResult GetChartImage(bool checkedCash, bool checkedPrepaidExpenses)
{
var sql = String.Format("select * from FinancialPeriods");
var chartData = db.FinancialPeriods.SqlQuery(sql);
var myChart = new Chart(width: 600, height: 400);
myChart.AddSeries(name: "Prepaid Expenses", chartType: "Line", xValue: chartData, xField: "Year", yValues: chartData, yFields: "PrepaidExpenses");
/*
if (checkedCash)
{
myChart.AddSeries(name: "Cash", chartType: "Line", xValue: chartData, xField: "Year", yValues: chartData, yFields: "Cash").AddLegend("Legend");
}
*/
return File(myChart.ToWebImage().GetBytes(), "image/bytes");
}
//bool checkedCash, bool checkedPrepaidExpenses
public ActionResult Chart(bool checkedCash, bool checkedExpenses)
{
ViewBag.CheckedCash = checkedCash;
ViewBag.CheckedExpenses = checkedExpenses;
var sql = String.Format("select * from FinancialPeriods");
var chartData = db.FinancialPeriods.SqlQuery(sql);
var myChart = new Chart(width: 600, height: 400);
if (checkedCash)
{
myChart.AddSeries(name: "Cash", chartType: "Line", xValue: chartData, xField: "Year", yValues: chartData, yFields: "Cash").AddLegend("Legend");
}
return PartialView("_Chart"); // returns a partial view of the chart based on the model
}
My INDEX View:
<tr><td><input type="submit" class="btn btn-default" id="updatechart" value="Update Chart"></td></tr>
</table>
</p>
</div>
}
<div id="graphRight"> #Html.Action("GetChartImage", new { checkedCash = false, checkedPrepaidExpenses = false })</div>
</div>
<script src ="/assets/plugins/jquery-1.8.3.min.js" type="text/javascript">
var url = '#Url.Action("Chart")';
var imgcontainer = $('graphRight');
$('#updatechart').click(function () {
var isCash = $('#checkedCash').is(':checked');
var isExpenses = $('#checkedPrepaidExpenses').is(':checked');
imgcontainer.load(url, { checkedCash: isCash, checkedPrepaidExpenses: isExpenses });
});
</script>
_Chart.cshtml (shared)
#model IEnumerable<FinancialAnalysisSite.Models.FinancialPeriod>
<img src="#Url.Action("Chart", new { checkedCash = ViewBag.CheckedCash, checkedPrepaidExpenses = ViewBag.checkedPrepaidExpenses })" />
I have updated the code, but am still running into problems... I think I'm lost in spaghetti code at the moment.
You can use ajax to call a controller method that returns a partial view of the updated chart. Assuming you have a controller method
public ActionResult Chart(bool checkedCash, bool checkedExpenses)
{
ViewBag.CheckedCash = checkedCash;
ViewBag.CheckedExpenses = checkedExpenses;
return PartialView("_Chart"); // returns a partial view of the chart based on the model
}
and the _Chart.cshtml view
<img src="#Url.Action("GetChartImage", new { checkedCash = ViewBag.CheckedCash, checkedPrepaidExpenses = checkedExpenses })"/>
which in turn calls your GetChartImage() to generate the chart. Note the return type of your method should be
return File(chart, "image/bytes");
Then in the view, include a button to update the chart
<button type="button" id="updatechart">Update chart</button>
and include a script to handle the buttons .click() event and update the DOM using the jquery .load() method.
var url = '#Url.Action("Chart")';
var imgcontainer = $('graphRight');
$('#updatechart').click(function() {
var isCash = $('#checkedCash').is(':checked');
var isExpenses = $('#checkedExpenses').is(':checked');
imgcontainer.load(url, { checkedCash: isCash, checkedExpenses: isExpenses });
});
Note the code for generating the initial image could then use the same method using #Html.Action() (passing in whatever default values are necessary)
<div id="graphRight">#Html.Action("Chart", new { checkedCash = false, checkedExpenses = false })</div>

Resources