MVC multiple forms on single view not working - asp.net-mvc

I have 2 forms on a single razor view that open in seperate dialog boxes. The forms are submitted using jquery post..
First form works perfectly but the second form isnt recognised at all and when I try to serializr the data it returns an empty string.
Code below:
#using (Html.BeginForm("SaveElectricReading", "Store", FormMethod.Post, new { id = "frmSaveElectricReading" }))
{
<div id="electricDialog" style="display: none;" title="Electric Readings">
<p>
Please ensure the electric readings have been entered!
</p>
<table width="100%">
<tr>
<th>
Serial:
</th>
</tr>
<tr>
<td>
<input type="text" name="Serial" />
</td>
</tr>
<tr>
<th>
Reading:
</th>
</tr>
<tr>
<td>
<input type="text" name="Reading" />
</td>
</tr>
<tr>
<th>
Comment:
</th>
</tr>
<tr>
<td>
<div class="textwrapper">
<textarea rows="5" cols="10" name="Comment"></textarea>
</div>
</td>
</tr>
</table>
</div>
}
#using (Html.BeginForm("SaveWaterReading", "Store", FormMethod.Post, new { id = "myform" }))
{
<div id="waterDialog" style="display: none;" title="Water Readings">
<p>
Please ensure the water readings have been entered!
</p>
<table width="100%">
<tr>
<th>
Serial:
</th>
</tr>
<tr>
<td>
<input type="text" name="WaterSerial" />
</td>
</tr>
<tr>
<th>
Reading:
</th>
</tr>
<tr>
<td>
<input type="text" name="WaterReadingsdfsdf" />
</td>
</tr>
<tr>
<th>
Comment:
</th>
</tr>
<tr>
<td>
<div class="textwrapper">
<textarea rows="5" cols="10" name="WaterComment"></textarea>
</div>
</td>
</tr>
</table>
</div>
}
function showWaterDialog() {
var $dialog = $('#waterDialog').dialog({
autoOpen: false,
modal: true,
width: 400,
height: 400,
buttons: {
Submit: function () {
// $('#frmCreateStore').submit();
var data = $('#frmSaveWaterReading');
$.post("/Store/SaveWaterReading",
$("#frmSaveWaterReading").serialize(),
function () {
$("#waterDialog").dialog("close");
});
//$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
$dialog.dialog('open');
}

In the jquery function for showing the dialog with the form in it, I needed to add that dialog content to the second form on the page as follows:
$("#waterDialog").parent().appendTo($("form").eq(1)[0]);

Related

I have a problem when I try to render a partial view in may main view

I have the following partial view:
#model IDECOHealthInsurance.Models.Pharmacy
#using (Ajax.BeginForm("pharmacyDetials", "Pharmacy", new AjaxOptions { HttpMethod = "Get", UpdateTargetId = "pDetail", InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace, LoadingElementId = "Loading", OnBegin = "" }))
{
<h4>تفاصيل الصيدلية</h4>
<div id="pDetail" class="MainGridContainer pb-5">
#if (Model.dtItemsDetails != null)
{
<table dir="rtl" id="Paitents" class="MainGrid">
<thead>
<tr style="text-size-adjust:auto">
<th>
رقم الموظف
</th>
<th>
التاريخ
</th>
<th>
الوقت
</th>
<th>
المستفيدون
</th>
<th>
ملاحظات
</th>
<th>
الباركورد
</th>
<th>
أسم العينة
</th>
<th>
الكمية
</th>
<th>
السعر
</th>
</tr>
</thead>
<tbody>
#foreach (System.Data.DataRow row in Model.dtItemsDetails.Rows)
{
<tr style="width:100%">
<td>
#row["EMPLOYEE_NUMBER"]
</td>
<td>
#row["ENTRY_DATE"]
</td>
<td>
#row["ENTRY_TIME"]
</td>
<td>
#row["BENEFICIARIES"]
</td>
<td>
#row["NOTE"]
</td>
<td>
#row["ITEM_CODE"]
</td>
<td>
#row["ITEM_NAME"]
</td>
<td>
#row["QTY"]
</td>
<td>
#row["PRICE"]
</td>
</tr>
}
</tbody>
</table>
}
</div>
}
And the follwing controller:
[HttpGet]
public ActionResult pharmacyDetials(Pharmacy model)
{
var masterID = Convert.ToInt32(Session["login"]);
if (masterID == 0)
{
return RedirectToAction("Login");
}
else
{
Models.Pharmacy objPharamcyMode = new Pharmacy();
IDECOServiceReference.IdecoAPIServiceClient idecoAPI = new IDECOServiceReference.IdecoAPIServiceClient();
DataTable dataTable = idecoAPI.GETPHARMACYEMPLOYEEMASTER("", 1);
model.dtItemsDetails = dataTable;
return PartialView("_PharmacyDetails", model);
}
}
And the following main view:
#model IDECOHealthInsurance.Models.Pharmacy
#{
ViewBag.Title = "PharmacyApplication";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table style="height:680px; width:1280px; border:hidden">
<tr>
<td>
<div id="pDetail">
#Html.Partial("_PharmacyDetails", Model)
</div>
</td>
<td>
#using (Ajax.BeginForm("PharmacyApplication", "Pharmacy", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "updatePnl", InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace, LoadingElementId = "Loading", OnBegin = "" }))
{
<div class="form-horizontal">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="panel" value="أضافة" class="btn btn-default" />
</div>
<input class="btn btn-default" type="button" value="خروج" onclick="#("window.location.href='" + #Url.Action("LogOut", "Pharmacy") + "'");" />
</div>
</div>
}
</td>
</tr>
</table>
<div id="updatePnl">
#Html.Partial("_PartialPharmacyDetails", Model)
</div>
<br />
<br />
<br />
<div id="pnlItemsDetails">
#Html.Partial("_PartialItemsDetails", Model)
</div>
When I try to render _PharmacyDetails in my main view it won't return any records. What is the problem? and how I can fix it? Please provide me with an explanation of how this problem occurs. What did I do wrong?
Instead of using Partial method to render the partial view I used Action method:
<tr>
<td>
<div id="pDetail" style="background-color:aliceblue" method="Get">
#Html.Action("pharmacyDetials", Model)
</div>
</td>
<td>

keep the checkbox checked browsing through the paging (Using PagedList asp.net mvc)

I have a list of orders in a gridview with customer html which has paging using PagedList asp.net mvc. I have a checkbox for each order in the list. When I use "Check all" to check all orders it should keep the checkbox checked when I go to page 2-3-4. But I lose the checked status when I move to next page. Can anyone help please?
JavaScript code :
$(document).ready(
function () {
$('#selectAll').click(
function () {
$('#TabOrdre td input:checkbox').prop('checked', $(this).is(':checked'));
if ($(this).is(':checked')) {
$('#TabOrdre td input:checkbox').each(function () {
if ($.inArray($(this).val(), list) === -1)
list.push($(this).val());
});
getAll = true;
}
else {
list = [];
getAll = false;
}
}
);
View code :
<section class="panel panel-default">
<header class="panel-heading m-b-none">Liste des ordres</header>
<div class="row wrapper">
<div class="col-md-12 space20">
<div class="doc-buttons">
<a class="btn btn-s-md btn-warning ajout-container"> <i class="fa fa-plus"></i> Ajouter un ordre </a>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped b-t b-light">
<thead>
<tr>
<th width="20">
<input type="checkbox" id="selectAll" value="-1">
</th>
<th style="white-space:nowrap">
EDA
</th>
<th style="white-space:nowrap">
<span class="th-sort">
Immediat
</span>
</th>
<th style="white-space:nowrap">
JNA
</th>
<th style="white-space:nowrap">
Date
</th>
<th style="white-space:nowrap">
Heure début
</th>
<th style="white-space:nowrap">
Heure fin
</th>
<th style="white-space:nowrap">
Puissance
</th>
<th style="white-space:nowrap">
RP
</th>
<th style="white-space:nowrap">
RS
</th>
<th style="white-space:nowrap">
Caractérisation
</th>
<th style="white-space:nowrap">
Commentaire
</th>
<th style="white-space:nowrap">
Source
</th>
<th style="white-space:nowrap">
Date de création
</th>
<th style="white-space:nowrap">
Refus
</th>
<th style="white-space:nowrap" class="th-sortable" data-toggle="class">
</th>
</tr>
</thead>
<tbody>
#if (Model.Count > 0)
{
foreach (var item in Model)
{
#Html.HiddenFor(model => item.ORD_ID)
<tr>
<td>
<input type="checkbox" value="#item.ORD_ID" id="chk_#item.ORD_ID" />
</td>
<td>
#Html.DisplayFor(model => item.EDA_NOM)
</td>
<td>
#(Convert.ToBoolean(item.EDA_IMMEDIAT) ? "Oui" : "Non")
</td>
<td>
#(Convert.ToBoolean(item.EDA_JNA) ? "Oui" : "Non")
</td>
<td>
#if (item.EDA_ORDRE_DATE_DEBUT != null)
{#Html.DisplayFor(model => item.EDA_ORDRE_DATE_DEBUT, "ShortDateTime")}
</td>
<td style="white-space:nowrap">
#if (item.EDA_ORDRE_DATE_DEBUT != null)
{#Html.DisplayFor(model => item.EDA_ORDRE_DATE_DEBUT, "ShortTimeString")}
</td>
<td>
#if (item.EDA_ORDRE_DATE_FIN != null)
{ #Html.DisplayFor(model => item.EDA_ORDRE_DATE_FIN, "ShortTimeString")}
</td>
<td>
#Html.DisplayFor(model => item.EDA_PUISSANCE)
</td>
<td>
#Html.DisplayFor(model => item.EDA_PUISSANCE_RP)
</td>
<td>
#Html.DisplayFor(model => item.EDA_PUISSANCE_RS)
</td>
<td>
#Html.DisplayFor(model => item.Eda_Caracterisation)
</td>
<td>
#Html.DisplayFor(model => item.COMMENTAIRE)
</td>
<td>
#Html.DisplayFor(model => item.SOURCE_NOM)
</td>
<td>
#if (item.EDA_DATE_RECUPEREE != null)
{ #Html.DisplayFor(model => item.EDA_DATE_RECUPEREE, "ShortDateTime")}
</td>
<td>
#Html.DisplayFor(model => item.VAL_REFUS)
</td>
<td >
#if (item.MODIFIABLE == 0)
{
<a class="btn btn-warning editor-container" data-id="#item.ORD_ID" data-toggle="modal"
><i class="fa fa-edit"></i></a>
}
</td>
</tr>
}
}
else
{
<tr>
<td class="text-center " colspan="16">
#VideResult
</td>
</tr>
}
</tbody>
</table>
</div>
<footer class="panel-footer">
<div class="row">
<div class="col-sm-4 ">
<button type="submit" class="btn btn-s-md btn-warning" id="Accepter">Accepter</button>
<button class="btn btn-s-md btn-default" id="Refuser">Refuser</button>
</div>
<div class="col-sm-4 text-center">
</div>
<div class="col-sm-4 text-right text-center-xs">
#Html.PagedListPager(Model, Page_No => Url.Action("Liste",
new
{
eda = ViewBag.eda,
Source = ViewBag.Source
,
datedeb = ViewBag.datedeb
,
datefin = ViewBag.datefin
,
refus = ViewBag.refus
,
page = Page_No
}),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(PagedListRenderOptions.ClassicPlusFirstAndLast
, new AjaxOptions()
{
HttpMethod = "GET",
UpdateTargetId = "TabOrdre",
LoadingElementId = "loader"
}))
</div>
</div>
</footer>
</section>

Disable bootstrap sorting for certain columns

I'm new to bootstrap so I hope that you will be able to help me out. I did some searching on the internet but I can't find a solution that works for me. I want to disable sorting for all of the columns except for the last two which i want to sort in descending order:
#model CCQAS.WebApp.Areas.Credentialing.Models.CredCustodyViewModel
#using CCQAS.API.Model
#{Layout = "~/Areas/Credentialing/Views/Shared/_CredLayout.cshtml";
ViewBag.Title = "Custody History";}
<div class="row">
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">
#ViewBag.Title
</h3>
</div>
#{if (Model.CredCustodyList.Count > 0)
{
<table class="table table-striped table-bordered" id="myTable">
<thead>
<tr>
<th class="text-center">
UIC
</th>
<th class="text-center">
POC
</th>
<th class="text-center">
#Html.DisplayNameFor(model => model.CredCustodyList[0].DescriptionTxt)
</th>
<th class="text-center">
#Html.DisplayNameFor(model => model.CredCustodyList[0].EffectiveDate)
</th>
<th class="text-center">
#Html.DisplayNameFor(model => model.CredCustodyList[0].EndDateString)
</th>
</tr>
</thead>
#foreach (CredCustody credCustody in Model.CredCustodyList)
{
<tr>
<td>
#credCustody.MTFNameTxt<br />
#credCustody.MTFCity <span> </span>#credCustody.UIC
</td>
<td>
#credCustody.PublicAffairsCoorTxt <br />
<span>Phone: </span> #credCustody.MTFCommPhoneTxt <br />
<span>DSN: </span> #credCustody.MTFDSNPhoneTxt <br />
<span>Fax: </span> #credCustody.MTFFaxPhoneTxt <br />
<span>Email: </span> #credCustody.MTFEmailTxt
</td>
<td>
#credCustody.DescriptionTxt
</td>
<td>
#credCustody.EffectiveDateString
</td>
<td>
#credCustody.EndDateString
</td>
</tr>
}
</table>
}
else
{
<p>
<h3 class="text-center">No Records Found</h3>
</p>
}
}
</div>
</div>
</div>
#section scripts{
<script>
$(document).ready(function () {
initializeDataTableNoPaging();
#*Disables all columns from sorting except for the last two: Effective Date and End Date*#
$('#myTable').tablesorter({
"aoColumns": [
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false },
null,
null
]
});
});
</script>
}
As explained in the documentation from here you need to mark which columns you don't want to be sortable using the headers option.
In your code use:
$('#myTable').tablesorter({
headers: {
0: {
sorter: false
},
1: {
sorter: false
},
2: {
sorter: false
}
}
});
I found a solution. The first thing that I had to do was give a name to my headers:
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="text-center">
UIC
</th>
<th class="text-center" id="POC_header">
POC
</th>
<th class="text-center" id="Desc_header">
#Html.DisplayNameFor(model => model.CredCustodyList[0].DescriptionTxt)
</th>
<th class="text-center" id="Effective_header">
#Html.DisplayNameFor(model => model.CredCustodyList[0].EffectiveDate)
</th>
<th class="text-center">
#Html.DisplayNameFor(model => model.CredCustodyList[0].EndDateString)
</th>
</tr>
</thead>
Second, I added this code to disable the sorting:
#section scripts{
<script>
$(document).ready(function () {
initializeDataTableNoPaging();
#*Disables all columns from sorting except for the last two: Effective Date and End Date*#
$("#POC_header").off('click'); //disables click event
$("#POC_header").addClass("sorting_disabled");
$("#POC_header").removeClass("sorting_asc");
$("#Desc_header").off('click'); //disables click event
$("#Desc_header").addClass("sorting_disabled");
$("#Desc_header").removeClass("sorting"); //needed to remove the sorting class to get rid of the sorting arrows on header
$("#Desc_header").removeClass("sorting_asc");
$("#Effective_header").addClass("sorting_desc");
$("#Effective_header").removeClass("sorting_asc"); //Sorts effective date in descending order
});
</script>
}

Knockout with class scoped properties

I am using Knockout and have the ViewModel bound to my data object in my ASP.Net MVC 4 project quite nicely like so:
$(document).ready(function() {
properties = #Html.Raw(Json.Encode(Model));
selectedProperty = properties[0];
viewModel = { properties: ko.mapping.fromJS(#Html.Raw(Json.Encode(Model))), selectedProperty: ko.observable()};
viewModel.setItem = function(item) {
viewModel.selectedProperty(item);
}
ko.applyBindings(viewModel);
Now I want to refactor my JavaScript so that the logic is encapsulated inside a class:
RealEstate.Search = function (properties) {
this.properties = properties;
this.selectedProperty = this.properties[0];
this.viewModel = { properties: ko.mapping.fromJS(this.properties), selectedProperty: ko.observable()};
this.viewModel.setItem = function(item) {
viewModel.selectedProperty(item);
}
ko.applyBindings(this.viewModel);
}
And I am instantiating that object in my HTML page like so:
$(document).ready(function() {
search = new RealEstate.Search(#Html.Raw(Json.Encode(Model)));
}
Now, I am getting the following error:
Error: Unable to parse bindings.
Message: ReferenceError: 'properties' is undefined;
Bindings value: foreach: properties
Here is the snipped HTML for the table bound to the ViewModel:
<div id="divDataTable" data-bind="with: properties">
<table id="dataTable" class="tablesorter">
<thead>
<tr>
<th>Address
</th>
<th>
Suburb
</th>
<th>Price
</th>
<th>Beds
</th>
<th>Baths
</th>
<th>Days Listed
</th>
</tr>
</thead>
<tbody data-bind="foreach: properties">
<tr data-bind="click: $root.setItem">
<td>
<label data-bind="text: $data.Street"></label>
<input data-bind="attr: { value : $index(), id : $index(), name : $index() }" type="hidden" />
</td>
<td data-bind="text: $data.Suburb"></td>
<td data-bind="text: $data.PriceFormatted"></td>
<td data-bind="text: $data.NumOfBedrooms"></td>
<td data-bind="text: $data.NumOfBathrooms"></td>
<td data-bind="text: $data.DaysListed"></td>
</tr>
</tbody>
</table>
</div>
</section>
<div id="divProperty">
<aside class="float-right" data-bind="with: selectedProperty">
<table>
<tr>
<td>
<label data-bind="text: $data.Street"></label>
</td>
<td>
<label data-bind="text: $data.PriceFormatted"></label>
</td>
</tr>
<tr>
<td colspan="2">
<img src="#" /></td>
</tr>
<tr>
<td>Beds:
<label data-bind="text: $data.NumOfBedrooms"></label>
</td>
<td>On OZMite:
<label data-bind="text: $data.DaysListed"></label>
</td>
</tr>
<tr>
<td>Baths:
<label data-bind="text: $data.NumOfBathrooms"></label>
</td>
<td>Year built:</td>
</tr>
</table>
</aside>
I would appreciate it if someone could shed some light on what I am doing wrong.
With the data-bind="with: properties" you are already "in the context" of the properties property inside your div.
So when you write <tbody data-bind="foreach: properties"> KO tries to find the properties property inside your properties array.
What you need is to use to reference the current binding context with the $data.
So your foreach should look like this:
<tbody data-bind="foreach: $data">
...
</todby>

All model and Formcollection values are null, blank or don't exist in Firefox or Chrome

During debugging, my MVC model and Formcollection are blank with no values in FireFox (15) or Chrome (latest version).
During debugging using IE (9), I can see these values just fine.
Do you know what the solution is for this? This is very serious for public facing web sites not being able to do any programming angainst these browsers.
Here is my View...
#model PDFConverterModel.ViewModels.ViewModelTemplate_Guarantors
#{
ViewBag.Title = "BHG :: PDF Generator";
}
<h2>#ViewBag.Message</h2>
<div>
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</tr>
<tr>
<td>#Html.LabelFor(model => model.LoanType)
#Html.DisplayFor(model => model.LoanType)
</td>
<td>
<label for="ddlDept">Department:</label>
#(Html.Kendo().DropDownList()
.Name("ddlDept")
.DataTextField("DepartmentName")
.DataValueField("DepartmentID")
.Events(e => e.Change("Refresh"))
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetDepartments", "Home");
});
})
)
</td>
</tr>
if (Model.ShowGeneratePDFBtn == true)
{
if (Model.ErrorT == string.Empty)
{
<tr>
<td colspan="5">
<u><b>#Html.Label("Templates:")</b></u>
</td>
</tr>
<tr>
#for (int i = 0; i < Model.Templates.Count; i++)
{
<td>
#Html.CheckBoxFor(model => Model.Templates[i].IsChecked)
#Html.DisplayFor(model => Model.Templates[i].TemplateId)
</td>
}
</tr>
}
else
{
<tr>
<td>
<b>#Html.DisplayFor(model => Model.ErrorT)</b>
</td>
</tr>
}
if (Model.ErrorG == string.Empty)
{
<tr>
<td colspan="5">
<u><b>#Html.Label("Guarantors:")</b></u>
</td>
</tr>
<tr>
#for (int i = 0; i < Model.Guarantors.Count; i++)
{
<td>
#Html.CheckBoxFor(model => Model.Guarantors[i].isChecked)
#Html.DisplayFor(model => Model.Guarantors[i].GuarantorFirstName) #Html.DisplayFor(model => Model.Guarantors[i].GuarantorLastName)
</td>
}
</tr>
}
else
{
<tr>
<td>
<b>#Html.DisplayFor(model => Model.ErrorG)</b>
</td>
</tr>
}
}
<tr>
<td colspan="3">
<input type="submit" name="submitbutton" id="btnRefresh" value='Refresh' />
</td>
#if (Model.ShowGeneratePDFBtn == true)
{
<td>
<input type="submit" name="submitbutton" id="btnGeneratePDF" value='Generate PDF' />
</td>
}
</tr>
<tr>
<td colspan="5">
#Model.Error
</td>
</tr>
}
</table>
</div>
<script type="text/javascript">
$('btnRefresh').on('click', '#btnRefresh', function () {
Refresh();
});
function Refresh() {
var LoanID = $("#LoanID").val();
if (LoanID != "") {
document.forms[0].submit();
}
else {
alert("Please enter a LoanId");
}
}
</script>
I know this is a very old question, but answering this might help people like who are struggling with this issue.
I had a similar issue. The problem lies here:
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</td>
</tr>
}
</table>
After begin form there are <tr> tags directly! Browsers like chrome and mozilla get confused in such cases. The <table> tag should be inside the form. If we look at your code, which was exactly what I had done, <table> tag was before #using Html.BeginForm.
Internet Explorer somehow understands this, but the other browsers don't.
When I did an inspect element I found that there was a form tag within each <tr> tag and it always returned FormCollection as null. Simply defining <table> within form solved my problem.
So here's how it should be:
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
<tr><td>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<table>
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</td>
</tr>
</table>
}
</td></tr>
</table>
I just found out what the issue is by experimneting.
The Telerik MVC widgets don't emit any FormCollection data!!!!
Only EditorFor and TextBoxFor emit these values, plus the input buttons.
What good are these widgets if I can't use the FormCollection values from them???? Especially the DropDownList where I can retrireve data and need the selected value to pass onto other methods.
(This would be better suited as comment, but I can't comment yet)
For future reference, here's a spec (W3C might have something different) for what gets submitted when a form is submitted:
http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#category-submit
You can look at whatever HTML was generated to make sure it gets submitted. You could also use something like Fiddler to look at the Http request

Resources