I am new to MVC and stuck with a problem. I have a view that allows users to select an item and then click on a button to view a report on that item. The report is a also an MVC View that expects it's model to be initialized. There is a controller action method to initialize the Model and call the report view.
So my view needs to call the report controller that initialized the model and calls the report view. The call to the report controller has to be made from a JavaScript function.
Finally, I want the report to come up in a new window while leaving the original view up.
I can call the report View directly using window.open, but that skips the report initializer and the report view crashes when it tries to access the model.
Is there a way to call a controller using window.open? Can I call the report controller from the report view if the model is null? can I call the report controller from my JavaScript function in the first view?
Or how do you suggest I handle this? Thanks for your help!
URW
Pseudo code follows:
Below is the code for the View I am working on. It's a search form. The user can enter some values (or not) and click search, on the top part of the form. the form re-displays to show search results below the search form. below the list of items found, are 2 buttons: One to call the ShowReport function and one to call a Wizard. The 2 buttons are on seperate forms, because both need to submit. At least that's how I see it right now. I can change that, if having 2 forms is a problem.
// This is the function that should call the controller to show the report
function ShowReport()
{
if (ReportID != null && ReportID > 0)
{
// I need to call report controller passing ReportID
}
else
{
alert("The Report ID is not valid. Please select a different itemand try again.");
return;
}
}
This function stores the reportID whenever the user selects an item in the list by clicking the radio button at the beginning of the row. It also enables or disables the ShowReport and Run Wizard buttons, depending on the selected item. The report is not available for all items in the list, so this function checks to see if a report is available for the current selection and enables the SHOW Report button if a report is available.
function activateStart(annualWaterReportId) {
// store the ReportID for this ID in a global
// in case the user wants to see the Full report
ReportID = reportId;
document.getElementById("startButton").disabled = false;
if (ReportId > 0) {
document.getElementById("viewReport").disabled = false;
} else {
document.getElementById("viewReport").disabled = true;
}
}
THis function starts the report wizard when the user selects and item and clicks the RunWizard button.
function startAction() {
var elements = document.getElementsByName("Select");
var id = null;
for (var i = 0; i < elements.length; i++) {
if (elements[i].checked) {
id = elements[i].value;
break;
}
}
if (id != null) {
document.getElementById("IDList").value = id;
document.forms["runWizard"].submit();
}
else {
alert("You must first select an item before pressing the Start Wizard button. " );
}
}
THe following form displays 3 fields that will become search parameters when the user enters/selects something and clicks Search below the search fields.
@using ((Html.BeginForm("Index", "Search", FormMethod.Post, new { onsubmit = "showLoadMask('Searching...')" })))
{
<table class="searchTable">
<tr>
<td>
<div>
Name:</div>
<input name="searchName" type="text" value="@ViewBag.searchName" />
</td>
<td>
<div>
ID Number:</div>
<input name="searchID" type="text" value="@ViewBag.searchID"/>
</td>
<td>
<div>
Year:</div>
<input name="searchYear" type="text" value="@ViewBag.searchYear"/>
</td>
</tr>
<tr>
<td colspan="4">
<input type="submit" class="smallButton" value="search" />
</td>
</tr>
</table>
}
next comes the list of items found when the user clicked Search above. Each row is preceded by a radio button, used by the user to select a row before clicking one of the two buttons below the list.
<table style="width: 100%" id="searchResults">
<thead>
<tr>
<th>
Select Person
</th>
<th>
Name
</th>
<th>
City
</th>
<th>
State
</th>
<th>
Zip Code
</th>
</tr>
</thead>
<tbody>
@foreach (var searchVM in Model)
{
<tr>
<td>
<input type="radio" name="Select" value="@searchVM.Number" onclick="activateStart(@searchVM.YearID) " />
</td>
<td>@searchVM.Number
</td>
<td>@searchVM.Name
<td>@searchVM.City
</td>
<td>@searchVM.StateID
</td>
<td>@searchVM.PostalCode
</td>
</tr>
}
</tbody>
Below the search results are 2 buttons that are critical: One to show the Wizard and one to show the report. This form exists only to allow the user to access a Wizard after selecting an item in the list above.
<form id="runWizard" method="post" action="@ViewBag.wizardAction">
<input type="button" value="Start Wizard disabled id="startButton" onclick="startAction()" />
<input type="hidden" name="pageAction" id="pageAction" value="NEXT_ACTION" />
<input type="hidden" name="currentPage" value="3" />
I added this form to use for the "View Report" button so I can better control what happens when the button is clicked.
@using (Html.BeginForm("CallFullReport", "Search", FormMethod.Post, new Dictionary<string, object>{"ReportID", }))
{
// Clicking this button should bring up the report in a new window, while leaving the current window as is.
<input type="submit" value="View Full Report" disabled id="viewReport" onclick="showReport()" />
<input type="hidden" id="ReportID" name="ReportID" value="-1"/>
}
The Controller I want to call is in a seperate dll, The source code is in a file called HomeController.cs the Controller looks like this:
public ActionResult FullReport(int reportID) {
ReportModel reportModel = null;
try {
reportModel = _db.Reports.Find(reportID);
}
catch (Exception) {
// gen up an error message
}
return View(reportModel);
}
Finally, there is the view the controller calls. It displays a report, using the data in reportModel loaded by the controller I've reduced the code to the bare minimum just so I can show you something that makes sense.
<table style="width: 100%">
foreach (Var item in ReportModel)
{
<tr>
<td class="tableLabel base">Name: </td>
<td class="tableData base">@Item.Name</td>
</tr>
<tr>
<td class="lineSpacer"> </td></tr>
<tr>
<td class="tableLabel base">Address: </td>
<td class="tableData base">@Item.Street1</td>
</tr>
@if (Item.Street2 != null && Item.Street2 != "")
{
<tr>
<td> </td>
<td>@Item.Street2</td>
</tr>
}
<tr>
td> </td>
<td>@Item.City, @Item.StateID @Item.PostalCode</td>
</tr>
<tr><td> </td></tr>
<tr><td class="tableLabel base">Phones:</td><td class="tableData base">@(new HtmlString(phones))</td></tr>
<tr><td class="tableLabel base">Email:</td><td class="tableData base"><a href="mailto:@Item.Email">@Item.Email</a></td></tr>
}
</table>
That's all the pseudo code I have. I've inherited all this code and I am new to MVC and everything that goes with it. Let me know if I can provide additional info.
Thanks bunches