This is sort of a Catch-22 with my ASP.NET (Sharepoint) WebPart/page. I need to respond to a button click, but doing that requires that the code be client-side (jQuery), because server-side/code-behind seems only to be available for the "Submit" process, and I don't want to submit the page in this scenario.
To be more clear, this is what I can do to have a button (an HtmlButton, to be more precise), and respond to clicking it without submitting the form:
Server-side (C#):
HtmlButton btnAddFoapalRow = null;
. . .
btnAddFoapalRow = new HtmlButton();
btnAddFoapalRow.Attributes["type"] = "button";
btnAddFoapalRow.InnerHtml = "+";
btnAddFoapalRow.ID = "btnAddFoapalRow";
this.Controls.Add(btnAddFoapalRow);
Client-side (jQuery):
$(document).on("click", '[id$=btnAddFoapalRow]', function (e) {
... script elided for brevity
});
This works fine.
I can do it all on the server side (in C#) for the "submit" button, like so:
Button btnSave = new Button();
btnSave.Text = "Save";
btnSave.Click += new EventHandler(btnSave_Click);
this.Controls.Add(btnSave);
. . .
private void btnSave_Click(object sender, EventArgs e)
{
. . . code elided for brevity
}
But the crux of the problem is that I need to respond to a button click without submitting the form, but then run some code on the server side. I can fulfill the first requirement in jQuery (as shown above with HtmlButton btnAddFoapalRow), but I need to ultimately call some C# code in response to the click - I need to carry out an action on the server side.
So my question is: How can I, from the client-side code, "poke" the server-side code to "wake up and call this (some) function"?
Maybe I can update a variable (HiddenField) that I create in C# like so:
HiddenField PDFGenBtnClicked = null;
. . .
PDFGenBtnClicked = new HiddenField();
PDFGenBtnClicked.ID = "pdfgenbtnclicked";
PDFGenBtnClicked.Value = "no";
this.Controls.Add(PDFGenBtnClicked);
...from the jQuery, like so:
$(document).on("click", '[id$=btnGeneratePDF]', function () {
$('[id$=pdfgenbtnclicked]').val("yes");
});
..and then have code like this on the server-side to kick off the calling of the method:
if (PDFGenBtnClicked.Value == "yes")
{
GeneratePDF(listOfListItems);
}
...but how can I cause this (last) bit of code to be called? Can I put a timer on the page, and have it check the status of PDFGenBtnClicked.Value every so often? This is probably possible, but almost certainly Goldberg-esque.
Who has a better idea?
Theoretically (I think!) this should work (non-Ajax way to indirectly run server-side code from client-side code):
0) Create the Timer
private Timer tmr = null;
1) Create the "Generate PDF" button and the Timer:
btnGeneratePDF = new HtmlButton();
btnGeneratePDF.Attributes["type"] = "button";
btnGeneratePDF.InnerHtml = "Generate PDF";
btnGeneratePDF.ID = "btnGeneratePDF ";
this.Controls.Add(btnGeneratePDF);
tmr = new Timer();
tmr.Interval = 3000; // three seconds
tmr.Tick += TickHandler;
tmr.Enabled = true;
2) Call the method when the Timer trips:
private void TickHandler(object sender, object e)
{
GeneratePDF(listOfListItems);
}
3) Run the code if the user selected the "Generate PDF" button:
private void GeneratePDF(List<ListColumns> listOfListItems)
{
if (PDFGenBtnClicked.Value != "yes")
{
return;
}
tmr.Enabled = false; // only run this once, after val has changed to "yes" by the user clicking the "btnGeneratePDF" button (set from "no" to "yes" in jQuery's response to the clicking of the button)
. . .
However, I have a breakpoint on the first line of GeneratePDF(), and I'm not reaching it, dod-durn it.
I even added another event handler, for init:
tmr.Tick += TickHandler;
tmr.Init += InitHandler;
tmr.Enabled = true;
message.Text = "Converting the data to a PDF file has been successful";
(I do see the message Text, although it's not true).
With breakpoints in both methods:
private void TickHandler(object sender, object e)
{
GeneratePDF(listOfListItems);
}
private void InitHandler(object sender, object e)
{
GeneratePDF(listOfListItems);
}
...neither is ever reached. Why not? Theoretically, this seems like it should work...(I know, everything works in theory).
The short answer to your question is that you'll have to use ajax, jQuery has some information regarding using it - https://learn.jquery.com/ajax/.
The longer answer is you'll need to do something like this:
$(document).on("click", '[id$=btnGeneratePDF]', function () {
$.get('/some/route/', function(result) {
//do something with the response, or not depending on your needs
}
});
I'm not familiar with Sharepoint so I can't offer any help on that side, but the basics are that you'll need to create a new page that fires off your PDF generation and access it using ajax, then handle the results in whatever way is appropriate.