Andra Andra - 2 months ago 5
ASP.NET (C#) Question

Validation on one of two Submit button only

I have 2 submit buttons in my MVC C# project. First one is to Save and the second one is to Save and Post. When Save is clicked I don't want to do any validation. But when Save and Post is clicked I want to validate and make sure all fields are filled in. At the Save and Post click all fields are mandatory. So being new to MVC C# I'm wondering what is the easiest way to do this and does anyone have any examples of how to do this? Thank you!

Here is my view with the Save button and then the Save and Post button

@using Budget.Models
@model Budget.Models.Budget_Mod.Budget_GrpObj

@{
ViewBag.Title = "Index";
}

<h2>Prepare Budget</h2>

@using (Html.BeginForm("SaveData", "PrepareBudget", FormMethod.Post))
{

<table id="budgettable">
<thead>
<tr>
<th style="width: 100px; background-color:#7ac0da">Fund</th>
<th style="width: 400px; background-color: #7ac0da; ">Function</th>
<th style="width: 2500px; background-color: #7ac0da; ">Object</th>
<th style="width: 600px; background-color: #7ac0da; ">Department</th>
<th style="width: 600px; background-color: #7ac0da; ">Location</th>
<th style="width: 400px; background-color: #7ac0da; ">Project</th>
<th style="width: 800px; background-color: #7ac0da; " align="center">@ViewData["prev_yr2_yr"]<br /> Budget</th>
<th style="width: 800px; background-color: #7ac0da; " align="center">@ViewData["prev_yr1_yr"]<br /> Budget</th>
<th style="width: 800px; background-color: #7ac0da; " align="center">@ViewData["Curr_yr_yr"]<br /> Actuals</th>
<th style="width: 800px; background-color: #7ac0da; " align="center">@ViewData["next_yr_yr"]<br /> Proposed Budget</th>
<th style="width: 1000px; background-color: #7ac0da; ">Nature</th>
<th style="width: 1000px; background-color: #7ac0da; ">The Need</th>
<th style="width: 1000px; background-color: #7ac0da; ">Impact If Not Funded</th>
<th style="width: 1000px; background-color: #7ac0da; ">Aligns to District<br />Strategic Goal</th>
<th style="width: 1000px; background-color: #7ac0da; ">Aligns to District<br />Priority</th>
<th style="width: 1000px; background-color: #7ac0da; ">Rationale or <br />Computation</th>
<th style="width: 500px; background-color: #7ac0da; ">Is this an<br />Investment<br />Request?</th>
<th style="width: 1000px; background-color: #7ac0da; ">If this is an<br />Investment request,<br />please justify.</th>
<th style="width: 800px; background-color: #7ac0da; ">Major Object Total</th>
</tr>
</thead>
<tbody>
<tr>
<th style="width:100px"></th>
<th style="width:400px"></th>
<th style="width:2500px"></th>
<th style="width:600px"></th>
<th style="width:600px"></th>
<th style="width:400px"></th>
<th style="width:800px"></th>
<th style="width:800px"></th>
<th style="width:800px"></th>
<th style="width:800px"></th>
<th style="width:1000px"></th>
<th style="width:1000px"></th>
<th style="width:1000px"></th>
<th style="width:1000px"></th>
<th style="width:1000px"></th>
<th style="width:1000px"></th>
<th style="width:500px"></th>
<th style="width:1000px"></th>
<th style="width:800px"></th>
<th style="width:1000px">Total Budget<br />Requested</th>
</tr>


@{
string prevObject = "0";
string prevDept = "0";
}


@for (var i = 0; i < @Model.budgetList.Count; i++)
{

if (@Model.budgetList[i].acct_object_type != prevObject)
{
<tr>
<td colspan="3" style="font-weight:bold">@Model.budgetList[i].acct_object_type</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td style="font-weight:bold">@String.Format("{0,14:c}", Model.budgetList[i].major_object_total)</td>
@if (@Model.budgetList[i].department != prevDept)
{
<td style="font-weight:bold">@String.Format("{0,14:c}", Model.budgetList[i].total_budget_requested)</td>
}
</tr>
}
prevObject = Model.budgetList[i].acct_object_type;
prevDept = Model.budgetList[i].department;
@Html.HiddenFor(model => model.budgetList[i].version)
@Html.HiddenFor(model => model.budgetList[i].fy)
@Html.HiddenFor(model => model.budgetList[i].acct_object_type)
@Html.HiddenFor(model => model.budgetList[i].created_by)
@Html.HiddenFor(model => model.budgetList[i].date_created)
@Html.HiddenFor(model => model.budgetList[i].modified_by)
@Html.HiddenFor(model => model.budgetList[i].date_modified)
@Html.HiddenFor(model => model.budgetList[i].major_object_total)
@Html.HiddenFor(model => model.budgetList[i].total_budget_requested)

<tr>
<td align="left">
@Model.budgetList[i].fund
@Html.HiddenFor(model => model.budgetList[i].fund)
</td>
<td align="left">
@Model.budgetList[i].acct_function
@Html.HiddenFor(model => model.budgetList[i].acct_function)
</td>
<td style="width:2500px" align="left">
@Model.budgetList[i].acct_object
@Html.HiddenFor(model => model.budgetList[i].acct_object)
</td>
<td align="left">
@Model.budgetList[i].department
@Html.HiddenFor(model => model.budgetList[i].department)
</td>
<td align="left">
@Model.budgetList[i].location
@Html.HiddenFor(model => model.budgetList[i].location)
</td>
<td align="left">
@Model.budgetList[i].program
@Html.HiddenFor(model => model.budgetList[i].program)
</td>
<td align="right">
@String.Format("{0,14:c}", Model.budgetList[i].prev_yr2_budget)
@Html.HiddenFor(model => model.budgetList[i].prev_yr2_budget)
</td>
<td align="right">
@String.Format("{0,14:c}", Model.budgetList[i].prev_yr1_budget)
@Html.HiddenFor(model => model.budgetList[i].prev_yr1_budget)
</td>
<td align="right">
@String.Format("{0,14:c}", Model.budgetList[i].curr_yr_actuals)
@Html.HiddenFor(model => model.budgetList[i].curr_yr_actuals)
</td>

@if (Model.budgetList[i].acct_object_type == "10000 Salaries" || Model.budgetList[i].acct_object_type == "20000 Employee Benefits")
{
<td align="right" style="text-align: right">
@String.Format("{0,14:c}", Model.budgetList[i].next_yr_proposed_budget)
@Html.HiddenFor(model => model.budgetList[i].next_yr_proposed_budget)
</td>
<td align="left">
@Model.budgetList[i].nature
@Html.HiddenFor(model => model.budgetList[i].nature)
</td>
<td align="left">
@Model.budgetList[i].need
@Html.HiddenFor(model => model.budgetList[i].need)
</td>
<td align="left">
@Model.budgetList[i].impact_if_not_funded
@Html.HiddenFor(model => model.budgetList[i].impact_if_not_funded)
</td>
<td align="left">
@Model.budgetList[i].align_to_district_goal
@Html.HiddenFor(model => model.budgetList[i].align_to_district_goal)
</td>
<td align="left">
@Model.budgetList[i].align_to_district_priority
@Html.HiddenFor(model => model.budgetList[i].align_to_district_priority)
</td>
<td align="left">
@Model.budgetList[i].rationale
@Html.HiddenFor(model => model.budgetList[i].rationale)
</td>
<td align="left">
@Model.budgetList[i].investment_request
@Html.HiddenFor(model => model.budgetList[i].investment_request)
</td>
<td align="left">
@Model.budgetList[i].investment_request_justification
@Html.HiddenFor(model => model.budgetList[i].investment_request_justification)
</td>
}
else
{
<td align="right" style="text-align: right">
@Html.TextBoxFor(model => model.budgetList[i].next_yr_proposed_budget, "{0:0.00}")
</td>
<td align="left">
@Html.TextAreaFor(model => model.budgetList[i].nature, new { cols = 50, rows = 3 })
</td>
<td align="left">
@Html.TextAreaFor(model => model.budgetList[i].need, new { cols = 50, rows = 3 })
</td>
<td align="left">
@Html.TextAreaFor(model => model.budgetList[i].impact_if_not_funded, new { cols = 50, rows = 3 })
</td>
<td align="left">
@Html.DropDownListFor(model => model.budgetList[i].align_to_district_goal, ViewData["goals"] as SelectList, new { @class = "dropdownSource" })
@Html.HiddenFor(model => model.budgetList[i].align_to_district_goal)
</td>
<td align="left">
@Html.DropDownListFor(model => model.budgetList[i].align_to_district_priority, new SelectList(string.Empty, "Value", "Text"), new { @class = "clsColumnNames" })
@Html.HiddenFor(model => model.budgetList[i].align_to_district_priority)
</td>
<td align="left">
@Html.TextAreaFor(model => model.budgetList[i].rationale, new { cols = 50, rows = 3 })
</td>
<td align="left">
@Html.EditorFor(model => model.budgetList[i].investment_request)
</td>
<td align="left">
@Html.TextAreaFor(model => model.budgetList[i].investment_request_justification, new { cols = 50, rows = 3 })
</td>
}
</tr>
}
</tbody>
</table>

<p>
<input type="submit" formnovalidate="formnovalidate" value="Save Data" name="SaveData" id="SaveData" />
</p>
<br /><br />

if (Model.role == "Budget_Role" || Model.role == "Chiefs_Role")
{
<p>
<input type="submit" value="Save and Post Data" name="SavePost" id="SavePost"/>
</p>
}

@Html.AntiForgeryToken()
<p>
<h3><a href="https://apecsreports.scsk12.org/Secure/">Back to Main Menu</a></h3>
</p>
}

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="../Scripts/jquery.freezeheader.js"></script>

<script>
$(document).ready(function () {
$("#budgettable").freezeHeader();
})

</script>

<script>
$("select.dropdownSource").on("change", (function () {

var columnSelectBox = $(this).parent("td").next("td").find("select.clsColumnNames");

$.ajax({
type: 'POST',
url: '/PrepareBudget/GetPriorities',
dataType: 'json',
data: { goals: $(this).find("option:selected").text() },
success: function (str) {

$.each(str, function (Value, Text) {
columnSelectBox.append('<option value ="' + Text + '">' + Text + '</option>');

});
},
error: function (ex) {
alert('Failed to retrieve columns.' + ex);
}
});
return false;
}));
</script>


And here is my controller

[HttpPost]
public ActionResult SaveData(Budget.Models.Budget_Mod.Budget_GrpObj list, string SaveData, string SavePost)
{
string verClosed = null;

if (ModelState.IsValid)
{
var session_user = User.Identity.Name;
if (String.IsNullOrEmpty(session_user))
{
session_user = HttpContext.Request.Cookies["username"].Value;
}
AuditTrailManager.Add(session_user, "Saving Budget ALL Data","All Data");

list.user_id = session_user;
PCN mod = new PCN();

int month = DateTime.Now.Month;
if (month > 7)
{
list.curryr = DateTime.Now.AddYears(+1).Year.ToString();
}
else
{
list.curryr = DateTime.Now.Year.ToString();
}

if (!string.IsNullOrWhiteSpace(SavePost))
{
var BPosted = BudgetListManager.PostData(list);
list.deptSelect = BudgetListManager.GetByID(list.user_id).ToList();
mod.fteList = PCNListManager.PostFTEData(list.deptSelect, list.user_id, list.curryr);
mod.ptList = PCNListManager.PostPTData(list.deptSelect, list.user_id, list.curryr);
mod.stipendList = PCNListManager.PostSTData(list.deptSelect, list.user_id, list.curryr);
verClosed = "Y";
}
else
{
verClosed = "N";
}

using (REPORTS_DBEntities context = new REPORTS_DBEntities())
{
for (var i = 0; i < list.budgetList.Count; i++)
{
var version = list.budgetList[i].version;
var fy = list.budgetList[i].fy;
var fund = list.budgetList[i].fund;
var acct_function = list.budgetList[i].acct_function;
var acct_object_type = list.budgetList[i].acct_object_type;
var acct_object = list.budgetList[i].acct_object;
var department = list.budgetList[i].department;
var location = list.budgetList[i].location;
var program = list.budgetList[i].program;

var c = context.SCS_BUDGET.Where(a => a.VERSION.Equals(version)).Where(a => a.FY.Equals(fy)).Where(a => a.FUND.Equals(fund)).Where(a => a.ACCT_FUNCTION.Equals(acct_function))
.Where(a => a.ACCT_OBJECT_TYPE.Equals(acct_object_type)).Where(a => a.ACCT_OBJECT.Equals(acct_object)).Where(a => a.DEPARTMENT.Equals(department))
.Where(a => a.LOCATION.Equals(location)).Where(a => a.PROGRAM.Equals(program)).FirstOrDefault();

if (c != null)
{
c.NEXT_YR_PROPOSED_BUDGET = decimal.Parse(list.budgetList[i].next_yr_proposed_budget.ToString());
c.NATURE = list.budgetList[i].nature;
c.NEED = list.budgetList[i].need;
c.IMPACT_IF_NOT_FUNDED = list.budgetList[i].impact_if_not_funded;
c.ALIGN_TO_DISTRICT_GOAL = list.budgetList[i].align_to_district_goal;
c.ALIGN_TO_DISTRICT_PRIORITY = list.budgetList[i].align_to_district_priority;
c.RATIONALE = list.budgetList[i].rationale;
c.INVESTMENT_REQUEST = list.budgetList[i].investment_request;
c.INVESTMENT_REQUEST_JUSTIFICATION = list.budgetList[i].investment_request_justification;
c.DATE_MODIFIED = DateTime.Now;
c.MODIFIED_BY = session_user;
c.VERSION_CLOSED = verClosed;
}
}
context.SaveChanges();
}


System.Data.DataTable dtBudget = new System.Data.DataTable();

Response.ClearContent();
Response.Buffer = true;
string strFName = "BudgetData_" + list.user_id + "_" + DateTime.Now.ToString("MMddyyyyhhmmss") + ".csv";
Response.AddHeader("content-disposition", "attachment; filename=" + strFName);
Response.ContentType = "text/csv";
Response.Charset = "";

if (!string.IsNullOrWhiteSpace(SavePost))
{

System.Data.DataTable dtPCNfte = new System.Data.DataTable();
System.Data.DataTable dtPCNpt = new System.Data.DataTable();
System.Data.DataTable dtPCNstipend = new System.Data.DataTable();

dtBudget = BudgetListManager.ToDataTable<Budget_Mod.Budgets>(list.budgetList);
dtPCNfte = PCNListManager.ToDataTable<PCN.PCN_FTE>(mod.fteList);
dtPCNpt = PCNListManager.ToDataTable<PCN.PCN_PT>(mod.ptList);
dtPCNstipend = PCNListManager.ToDataTable<PCN.PCN_STIPEND>(mod.stipendList);

Response.WriteFile(BudgetListManager.CreateAllCSV(dtBudget, dtPCNfte, dtPCNpt, dtPCNstipend, strFName));
}
else
{
dtBudget = BudgetListManager.ToDataTable<Budget_Mod.Budgets>(list.budgetList);
Response.WriteFile(BudgetListManager.CreateCSV(dtBudget, strFName));
}

Response.Flush();
Response.End();
}
return RedirectToAction("Index");
}

Answer

You should POST in both cases to the server because you are saving data... just in "Save and Post" scenario you want to do validation.

Basically on the server you can differentiate which button was clicked. Here is the code that does that:

[HttpPost]
public ActionResult About(AboutModel model, string save)
{
    // your button id/name is save - this value will be initialized only if that button is clicked
    if (!String.IsNullOrEmpty(save))
    {
        // just save
    }
    else
    {
        // save and post... you can check for ModelState.IsValid like:
        if (ModelState.IsValid)
        {

        }
        else
        {
            // invalid model
        }
    }

    return View();
}

And here is how cshtml form will look like so you can get idea on what is being done:

@model AboutModel

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Test Form</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.Label("Name", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input id="save" name="save"
                       type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input @* no id/name *@
                       type="submit" value="Save and Post" class="btn btn-default" />
            </div>
        </div>
    </div>
}