validate required jquery doesnt work when i try to change rules - c#

I have 2 fields. I'm trying to insert a number into the first. The second value should be less or equal to the first field.
I'm using jquery validation to warn user, but when i do it it doesn't change the messages and layout.
I've tried to follow the documentation but doesn't understand what's wrong.
<div class="form-group">
<label class="control-label" for="inputDefault-4">Quantidade permitida por pedido<span class="text-danger">*</span></label>
#Html.TextBoxFor(t => t.Produto.QuantidadeVenda, new { maxlength = "10", #class = "form-control", #id = "quantidade_pedido", placeholder = "0", validate = "required",#name = "quantidade_pedido" , #type = "number" })
</div>
<div class="form-group">
<label class="control-label" for="inputDefault-4">Possui regime de comodato<span class="text-danger">*</span></label>
<div>
#Html.CheckBoxFor(t => t.Produto.FlagComodato, new { #class = "chk-inativar switcher-example-default", #id = "comodato", #onclick = "checkComodato(this)" })
</div>
</div>
<div id="limitEmprestimo" style="display: none" class="form-group">
<label class="control-label" for="quantidade_comodato">Quantidade limite de empréstimo <span class="text-danger">*</span></label>
#Html.TextBoxFor(t => t.Produto.QuantidadeComodato, new { maxlength = "10", #class = "form-control", #id = "quantidade_comodato", placeholder = "0", validate = "required", #name = "quantidade_comodato", #type = "number"})
function checkComodato(check) {
if (check.checked) {
$("#limitEmprestimo").show();
}
else {
$("#limitEmprestimo").hide();
}
}
$("#quantidade_comodato").focusout(function () {
var quantc = $("#quantidade_comodato").val() === "" ? 0 : parseInt($("#quantidade_comodato").val());
var quantp = $("#quantidade_pedido").val() === "" ? 0 : parseInt($("#quantidade_pedido").val());
if (quantc > quantp) {
var validator = $("#frmCadastro").validate();
$("#quantidade_comodato").rules("remove", "required");
$("#quantidade_comodato").rules("add", {
max: quantp,
messages: {
quantp: "Invalid !"
}
});
validator.element($(this));
}
});

The problem is most likely that the jquery script is not within a <script> tag. Therefore the browser won't understand that your code should be run as javascript, instead the browser just thinks that your code is plain text.
Try this:
<div class="form-group">
<label class="control-label" for="inputDefault-4">Quantidade permitida por pedido<span class="text-danger">*</span></label>
#Html.TextBoxFor(t => t.Produto.QuantidadeVenda, new { maxlength = "10", #class = "form-control", #id = "quantidade_pedido", placeholder = "0", validate = "required",#name = "quantidade_pedido" , #type = "number" })
</div>
<div class="form-group">
<label class="control-label" for="inputDefault-4">Possui regime de comodato<span class="text-danger">*</span></label>
<div>
#Html.CheckBoxFor(t => t.Produto.FlagComodato, new { #class = "chk-inativar switcher-example-default", #id = "comodato", #onclick = "checkComodato(this)" })
</div>
</div>
<div id="limitEmprestimo" style="display: none" class="form-group">
<label class="control-label" for="quantidade_comodato">Quantidade limite de empréstimo <span class="text-danger">*</span></label>
#Html.TextBoxFor(t => t.Produto.QuantidadeComodato, new { maxlength = "10", #class = "form-control", #id = "quantidade_comodato", placeholder = "0", validate = "required", #name = "quantidade_comodato", #type = "number"})
</div>
<script>
function checkComodato(check) {
if (check.checked) {
$("#limitEmprestimo").show();
}
else {
$("#limitEmprestimo").hide();
}
}
$("#quantidade_comodato").focusout(function () {
var quantc = $("#quantidade_comodato").val() === "" ? 0 : parseInt($("#quantidade_comodato").val());
var quantp = $("#quantidade_pedido").val() === "" ? 0 : parseInt($("#quantidade_pedido").val());
if (quantc > quantp) {
var validator = $("#frmCadastro").validate();
$("#quantidade_comodato").rules("remove", "required");
$("#quantidade_comodato").rules("add", {
max: quantp,
messages: {
quantp: "Invalid !"
}
});
validator.element($(this));
}
});
</script>
If that isn't the problem another typical one is that the jquery script is loaded in the end of the _layout.cshtml. So when you call jquery it haven't been defined yet. In that case you should get a script error in the developer console (hit F12 in your browser to show it).
That's easy corrected by wrapping the script in a Razor section.
#section Scripts
{
<script>
// your code here
</script>
}
"Scripts" is declared in _Layout.cshtml as #RenderSection("Scripts", required: false).

Related

jqGrid is not reloading or refreshing properly on keyup event

I needed to create a search page where various types of text, dropdown, date field will be there. i added onkeyup function to every text field so that whenever i put any text or number a grid will appear with subgrid. The issue i am facing is if i give input for the first time then the grid appear with correct data. if i clear that field then the grid is reloading also but if i input again in that field or any other text field then the js is not sending request to the action method with updated post value.
Here is my View Part:
<section class="content">
<div class="container-fluid">
<!-- SELECT2 EXAMPLE -->
<!-- SELECT2 EXAMPLE -->
<div class="card card-info">
<div class="card-header">
<h3 class="card-title">Search Criteria</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse">
<i class="fas fa-minus"></i>
</button>
</div>
</div>
<!-- /.card-header -->
#using (Html.BeginForm("SearchReport", "LRLiveSearch", FormMethod.Post))
{
<div class="card-body">
<div class="row">
<div class="col-md-12" style="line-height:1.50px;">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Deed No</label>
#Html.TextBoxFor(model => model.DeedNo, new { #class = "form-control", onkeyup = "LiveSearch('DN', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Deed Identity</label>
#Html.TextBoxFor(model => model.DeedId, new { #class = "form-control", onkeyup = "LiveSearch('DI', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Client Name</label>
#Html.TextBoxFor(model => model.ClientName, new { #class = "form-control", onkeyup = "LiveSearch('CN', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Client Contact Number</label>
#Html.TextBoxFor(model => model.ClientPhoneNumber, new { #class = "form-control", onkeyup = "LiveSearch('CP', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>MR No</label>
#Html.TextBoxFor(model => model.MRNo, new { #class = "form-control", onkeyup = "LiveSearch('MR', this.value)" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>Cheque No</label>
#Html.TextBoxFor(model => model.ChequeNo, new { #class = "form-control", onkeyup = "LiveSearch('CQN', this.value)" })
</div>
</div>
</div>
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>Collection Type</label>
#Html.DropDownListFor(model => model.CollectionType, Model.CollectionTypeList, new { #class = "form-control" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>From Date</label>
<div class="input-group date" id="FirstDate" data-target-input="nearest">
#Html.TextBoxFor(model => model.FromDate, new { #class = "form-control datetimepicker-input", #data_target = "#FirstDate" })
<div class="input-group-append" data-target="#FirstDate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>To Date</label>
<div class="input-group date" id="SecondDate" data-target-input="nearest">
#Html.TextBoxFor(model => model.ToDate, new { #class = "form-control datetimepicker-input", #data_target = "#SecondDate" })
<div class="input-group-append" data-target="#SecondDate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
#*<div class="col-md-1">
<div class="form-group">
<center>
<button id="btnLRSearch" formaction="SearchList" class="btn btn-md btn-primary" style="margin-top:.80rem" type="button">Search</button>
</center>
</div>
</div>
<div class="col-md-1">
<div class="form-group">
<center>
<button id="btnPrint" formaction="SearchReport" class="btn btn-md btn-warning" style="margin-top:.80rem" type="submit">Report</button>
</center>
</div>
</div>*#
</div>
</div>
</div>
</div>
}
</div>
</div>
<!-- /.container-fluid -->
<table class="table table-bordered table-striped table-hover text-nowrap text-sm" id="Demogrid"></table>
<div class="container-fluid" id="pager"></div>
</section>
here is my JS part where i handled onkeyup event:
function LiveSearch(type, value) {
var searchType = type;
var searchValue = value;
if (value == "" || value == null) {
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
else {
$("#Demogrid").jqGrid({
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
colNames: ['ProjectName', 'PlotName', 'TotalLandArea', 'DeedId', 'DeedDate', 'RentFeeType', 'RentFee', 'ClientName', 'ClientAddress', 'ClientContactNo', 'EffectiveDate'],
//colModel takes the data from controller and binds to grid
colModel: [
{ name: "ProjectName" },
{ name: "PlotName" },
{ name: "TotalLandArea" },
{ name: "DeedId" },
{ name: "DeedDate" },
{ name: "RentFeeType" },
{ name: "RentFee" },
{ name: "ClientName" },
{ name: "ClientAddress" },
{ name: "ClientContactNo" },
{ name: "EffectiveDate" }
],
height: '100%',
viewrecords: true,
caption: 'Deed Info',
emptyrecords: 'No records',
rowNum: 10,
pager: jQuery('#pager'),
rowList: [10, 20, 30, 40],
jsonReader:
{
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
},
postData: {
Type: searchType,
SearchValue: searchValue
},
autowidth: true,
subGrid: true,
subGridRowExpanded: function (subgridId, rowId) {
// create the subgrid HTML here
var subgridTableId = subgridId + "_t";
$("#" + subgridId).html("<table id='" + subgridTableId + "'></table>");
// get the data for the parent row
var parentRowData = $("#Demogrid").jqGrid("getRowData", rowId);
// retrieve the primary key value of the parent row
var parentId = parentRowData.DeedId;
$("#" + subgridTableId).jqGrid({
// configure the subgrid
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
colNames: ['CollectionId', 'CollectionDate', 'MRIdentity', 'MRNo', 'MRDate', 'MRType', 'CollectionType', 'ChequeNo', 'BankName'],
//colModel takes the data from controller and binds to grid
colModel: [
{ name: "CollectionId", hidden: true },
{ name: "CollectionDate" },
{ name: "MRIdentity" },
{ name: "MRNo" },
{ name: "MRDate" },
{ name: "MRType" },
{ name: "CollectionType" },
{ name: "ChequeNo" },
{ name: "BankName" }
],
height: '100%',
viewrecords: true,
caption: 'Collection Details',
emptyrecords: 'No records',
rowNum: 10,
jsonReader: {
repeatitems: false
},
postData: {
Type: searchType,
SearchValue: searchValue,
DeedId: parentId
},
autowidth: true
});
},
}).navGrid('#pager',
{
edit: true,
add: true,
del: true,
search: true,
refresh: true,
closeAfterSearch: true
});
}
}
and it is my action method:
public JsonResult LiveSearch(string sord, int page, int rows, string searchString, string Type, string SearchValue, string DeedId)
{
if(SearchValue == "")
{
SearchValue = "$";
}
var query = iLRSearchRepository.LiveSearchFilter(Type, SearchValue);
if (DeedId == null)
{
//#2 Setting Paging
int pageIndex = Convert.ToInt32(page) - 1;
int pageSize = rows;
//#3 Linq Query to Get Data
var Results = query.Select(
x => new
{
ProjectName = x.ProjectName,
PlotName = x.PlotName,
TotalLandArea = x.TotalLandArea,
DeedId = x.DeedId,
DeedDate = x.DeedDate.ToString("dd/MM/yyyy"),
RentFeeType = x.RentFeeType,
RentFee = x.RentFee,
ClientName = x.ClientName,
ClientAddress = x.ClientsAddress,
ClientContactNo = x.ClientsContactNo,
EffectiveDate = x.ActivateDate.ToString("dd/MM/yyyy")
}).Distinct();
//#4 Get Total Row Count
int totalRecords = Results.Count();
var totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
//#5 Setting Sorting
if (sord.ToUpper() == "DESC")
{
Results = Results.OrderByDescending(s => s.DeedId);
Results = Results.Skip(pageIndex * pageSize).Take(pageSize);
}
else
{
Results = Results.OrderBy(s => s.DeedId);
Results = Results.Skip(pageIndex * pageSize).Take(pageSize);
}
//#6 Setting Search
if (!string.IsNullOrEmpty(searchString))
{
Results = Results.Where(m => m.DeedId == searchString);
}
//#7 Sending Json Object to View.
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = Results
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
else
{
var Results = query.Where(x => x.DeedId == DeedId).Select(
x => new
{
CollectionId = x.CollectionId,
CollectionDate = x.CollectionDate?.ToString("dd/MM/yyyy"),
MRIdentity = x.MRIdentity,
MRNo = x.MRNo,
MRDate = x.MRDate?.ToString("dd/MM/yyyy"),
MRType = x.MRType,
CollectionType = x.CollectionType,
ChequeNo = x.ChequeNo,
BankName = x.BankName,
});
var jsonData = new
{
rows = Results
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
//model.landRent_View_SearchInfos = query;
//return View("_LandRentInfoList", model);
}
With your code you every time try create jqGrid when you do a search, which of course is not allowed since the grid is already created.
if (value == "" || value == null) {
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
else {
$("#Demogrid").jqGrid({}...)
}
To solve the problem first create the grid and the do a reload when the value changes
$("#Demogrid").jqGrid({
url: '/HRM/LRLiveSearch/LiveSearch',
datatype: "json",
mtype: 'Get',
//table header name
...
});
function LiveSearch(type, value) {
var searchType = type;
var searchValue = value;
$("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
return true;
}
Hope this helps.
Initially you can set values (postData) so that the grid return empty data or create the grid with empty local data (datatype : local) and then change the datatype to json.

html helper don't get values back from controller after ajax.beginform

I have a ajax.beginform that I have to upload a file and then in the view I have hidden for the path of the file that have been
saved in the server.
The problem is that the value of the path doesn't return to the view after the the post call.
I am returning new partial view with the errors and the value don't
coming
please help me
post method from controller that return partial view
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveSocioDetails(SpSocio socio) // ajax for 1 step in socio
{
bool sociook = false;
socio.StudentId = sStudentId; // bind student id to socio model
socio = SocioDetValid(ref sociook,socio);
// add validation
if (ModelState.IsValid && sociook)
{
socio = SaveSocioModel(socio);
Response.StatusCode = 200;
}
else
Response.StatusCode = 300; // return error to client the model is not valid
return PartialView("~/Views/Student/Socio/SocioDetails.cshtml", socio); // return the partial view of the forn with validation messages
}
Sociodetvalid function that saves the file and add the path to path field:
// bank account validation and save
if (socio.FileBankAccount == null) // if there is no file
{
if (socio.PathBankAccount == null) // check if he upload file already - if not add error message
{
ModelState.AddModelError("FileBankAccount", "חובה לצרף קובץ");
ok = false;
}
}
else // upload new the file
socio.PathBankAccount = Files.SaveFileInServer(socio.FileBankAccount, "BankAccount", sStudentId, socio.PathBankAccount);
the section in view for upload and the hidden for the path string:
<div class="row">
<div class="col-xl-3 col-lg-3 col-md-4 col-12 ">
#Html.LabelFor(model => model.BankStatus, htmlAttributes: new { #class = "control-label col-12" })
#Html.EditorFor(model => model.BankStatus, new { htmlAttributes = new { #class = "form-control must m-1 mt-0" } })
#Html.ValidationMessageFor(model => model.BankStatus, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.PathBankAccount)
</div>
<div class="col-xl-3 col-lg-3 col-md-4 col-12">
#Html.LabelFor(model => model.FileBankAccount, htmlAttributes: new { #class = "control-label col-12 must-sign", #for = "" })
<div class="chose-file m-1 mt-0">
#Html.TextBoxFor(model => model.FileBankAccount, new { #class = "form-control must", #type = "file", #accept = "image/jpeg,image/jpg,image/png,application/pdf", #style = "display:none;" })
<label for="FileBankAccount">
<i class="ml-1 material-icons">add_photo_alternate</i>
בחר קובץ
</label>
</div>
#Html.ValidationMessageFor(model => model.FileBankAccount, "", new { #class = "text-danger" })
</div>
#*
<div class="col-xl-3 col-lg-3 col-md-4 col-12" style="display:#(Model.PathBankAccount != null ? "" : "none")">
<label class="control-label col-12" for="">קובץ שמור</label>
<a name="#Model.PathBankAccount" class="btn btn-light btn-file m-1 mt-0">צפייה בקובץ שמור</a>
</div>*#
Thanks for help
Update:
Ajax form code : this is the part of the ajax that in a big view
<fieldset>
#using (Ajax.BeginForm("SaveSocioDetails", "Student", new AjaxOptions { HttpMethod = "POST", OnSuccess = "firstsuccess",OnFailure = "sociodetailsfail", UpdateTargetId="partialsocio" ,LoadingElementId = "div_loading" }, new { #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div id="partialsocio">
#Html.Action("PartialSocioDetails", "Student", new { SpId = ViewBag.SpId })
</div>
<div id="div_loading" style="display:none;">
<img src="#Url.Content("~/Content/Pic/Spinner.gif")" alt="" />
</div>
<button class="btn btn-primary" type="submit">המשך</button>
}
<input type="button" name="next" class="next action-button bg-primary" hidden value="Next" id="sociodetnext" />
</fieldset>
this is the function of fail and success ajax:
<script>
$(document).ready(function ()
{
});
function firstsuccess() {
console.log('this is ajaxSuccess');
$("#sociodetnext").click();
}
function sociodetailsfail(bdata) {
console.log('this is ajaxfail');
console.log(bdata.responseText);
$('#partialsocio').html(bdata.responseText);
}
</script>
In the script that Have returned to the client the value of the string doesn't appear..
Thanks for help

How to reload avatar image and replace for default picture after users push file ? - ASP.NET MVC

I'm having a Sign up form for the user to input : avatar, name, mail, etc...
The default image for the avatar is an user image, how can I update this image to be the new avatar that user pushes to the web?
Here's the SignUp view :
#model TimShop.Models.USERS
using (Html.BeginForm("SignUp", "Account", FormMethod.Post, new { #class = "login100-form validate-form signUpForm" }))
{
#Html.AntiForgeryToken()
<div class="container-login100">
<div class="wrap-login100 signUpPageFlex">
<div class="login100-pic js-tilt" data-tilt="" style="will-change: transform; transform: perspective(300px) rotateX(0deg) rotateY(0deg);">
<img src="~/Content/images/img-01.png" alt="avatar" class="signUpImg">
<input type="file" name="file" id="uploadAvatar" class="fileImgUpload">
<label for="uploadAvatar">
<i class="fa fa-upload"></i> Upload your avatar
</label>
</div>
<span class="login100-form-title signUpFormTitle">
Member resgiteration
</span>
<div class="wrap-input100 validate-input">
#Html.EditorFor(model=>model.FULLNAME, new { htmlAttributes = new { #class= "input100 SignUpInput", #required = "true", placeholder = "Full name", name= "fullname" } } )
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input">
#Html.EditorFor(model => model.EMAIL, new { htmlAttributes = new { #class = "input100 SignUpInput", #required = "true", placeholder = "Email", name = "email" } })
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input">
#*<input class="input100 SignUpInput" type="password" name="pass" placeholder="Password">*#
#Html.PasswordFor(model => model.PASS, new { htmlAttributes = new { #class = "input100 SignUpInput", #required = "true", placeholder = "Password", name = "pass" } } )
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input">
#Html.Password("confirmPass", new { htmlAttributes = new { #class = "input100 SignUpInput", #required = "true", placeholder = "Confirm password", name = "passConfirm" } })
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input">
#Html.EditorFor(model => model.DATEOFBIRTH, new { htmlAttributes = new { #class = "input100 SignUpInput", #required = "true", placeholder = "Date of birth", #type="date", name = "dob" } })
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input">
#Html.EditorFor(model=>model.PHONE, new { htmlAttributes = new { #class = "input100 SignUpInput", #required = "true", placeholder = "PHONE", #type = "number", name = "phone" } } )
<span class="focus-input100"></span>
</div>
<div class="container-login100-form-btn container-signUp-form">
<input class="login100-form-btn signUpbutton" type="submit" value="COMPLETE"/>
</div>
</div>
</div>
<!-- Body signUp end -->
}
And my controller that handles the sign up process:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SignUp([Bind(Include = "FULLNAME,PASS,EMAIL,DATEOFBIRTH,PHONE,AVATAR")] USERS user, string confirmPass, HttpPostedFileBase file)
{
bool error = false;
try
{
// TODO: Add insert logic here
if (db.USERS .Where(m => m.EMAIL == user.EMAIL).Any())
{
ViewData["insertResult"] = "This email is already taken.";
}
else
{
if(file != null)
{
file.SaveAs(HttpContext.Server.MapPath("~/Content/images/users/") + file.FileName);
user.AVATAR= file.FileName;
}else
{
user.AVATAR = "";
}
db.USERS.Add(user);
db.SaveChanges();
Session["account"] = user.FULLNAME;
return RedirectToAction("Success", "Home", new { displayText = "Successful registeration" });
}
}
catch
{
ViewData["insertResult"] = "Cannot register your account. Please check again";
}
return View();
}
Or you can see the image that describes my idea to be clear :My idea
you have to write some javascript in your view code as below:
<script type="text/javascript">
function onChange(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#signUpImg').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#uploadAvatar").change(function(){
onChange(this);
});
Now change your view part image code as below:
<img src="~/Content/images/img-01.png" alt="avatar" id = "signUpImg" class="signUpImg">
Hope this will help you!

Multiple posts on a single page asp.net MVC with partial views

We've got a page which currently contains a four or five partial views, but is something that could grow. At the moment, there's two POST actions, for two entirely different database functions.
If we try doing the create function on another, the redirect then results in an "Object reference not set to an instance of an object." error, which is then relating to the other POST partial view.
Is there a way to stop this? Essentially, it seems to me that the post for one partial view is trying to interact with the other. Any ideas?
Thanks
Bulletins Controller for Creating:
[HttpPost]
public ActionResult CreateMain(BulletinsViewModel viewModel)
{
if (ModelState.IsValid)
{
BulletinsContext.tblBulletins.Add(new tblBulletin
{
ID = viewModel.BulletinID,
BulletinDisplayDate = viewModel.BulletinDisplayDate,
BulletinFilename = viewModel.MainBulletinName,
IsSixthForm = viewModel.IsSixthForm
});
//For loop to delete bulletins
//If bulletin folder has more than 10 files in
//Delete the oldest file, itererate till only 10 remain
{
DirectoryInfo dir = new DirectoryInfo(#"D:\Inetpub\WWWroot\intranet\Dashboard\Dashboard\Files\Bulletins");
List<FileInfo> filePaths = dir.GetFiles().OrderByDescending(p => p.CreationTime).ToList();
for (int index = filePaths.Count() - 1; index > 9; index--)
{
var fileNames = filePaths[index].Name;
//Delete from directory
filePaths[index].Delete();
//Remove from collection to restart the loop
filePaths.RemoveAt(index);
}
}
//Save changes to database
BulletinsContext.SaveChanges();
//Return to main bulletins index page
return RedirectToAction("~/Home/Index");
}
return View(viewModel);
}
Bulletins Create View:
#model Dashboard.Viewmodels.BulletinsViewModel
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.BulletinDisplayDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BulletinDisplayDate, new { htmlAttributes = new { #class = "form-control", #id = "datepicker-basic", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.BulletinDisplayDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MainBulletinName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
#Html.EditorFor(model => model.MainBulletinName, new { htmlAttributes = new { #class = "form-control", #Value = "Select File...", #readonly="readonly" } })
<span class="input-group-addon" href="javascript:;" onclick="moxman.browse({ fields: 'MainBulletinName', extensions: 'pdf', path: 'D:/Inetpub/WWWroot/intranet/Dashboard/Dashboard/Files/Bulletins' });" style="cursor: pointer;"><i class="fa fa-upload"></i></span>
#Html.ValidationMessageFor(model => model.MainBulletinName, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
}
<script type="text/javascript" src="~/Scripts/tinymce/plugins/moxiemanager/js/moxman.loader.min.js"></script>
Printer Credits Create Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PrinterCredits(PrinterCreditsViewModel viewModel)
{
if (ModelState.IsValid)
{
//Send the email if credits are added..
//Create a bunch of variables for the email
//Create the email body etc
var fromAddress = "";
string toName = Request.Form["Username"].ToUpper();
string AmountOfCredits = Request.Form["AmountAdded"];
string Plural = "";
string Title = "";
string AddedByWho = User.Identity.Name.Split('\\')[1];
System.DateTime AddedWhen = DateTime.Now;
if (AmountOfCredits == "1")
{
Plural = " printer credit has ";
Title = "Printer Credit Added!";
}
else
{
Plural = " printer credits have ";
Title = "Printer Credits Added!";
}
var toEmail = toName + "";
var subject = AmountOfCredits + Plural + "been added to your account, " + toName;
string body = "";
//Create an SMTP client for sending an email
var smtp = new SmtpClient
{
Host = "",
Port = 25,
EnableSsl = false,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = true,
};
//Populate the SMTP client and encode the body for the HTML
using (var message = new MailMessage(fromAddress, toEmail)
{
Subject = subject,
Body = body,
IsBodyHtml = true,
BodyEncoding = System.Text.Encoding.UTF8
})
//Try to send the email. If sent, insert data.
//Redirect back to original page
//Take current printer credit from and update with fund + cost
try
{
//Link the viewmodel and the database together
PartialViewContext.tblPrinterCredits.Add(new tblPrinterCredit
{
Username = viewModel.Username,
AmountAdded = viewModel.AmountAdded,
AddedBy = AddedByWho,
AddedWhen = viewModel.AddedWhen,
Money = viewModel.AmountAdded * 0.02
});
Nullable<double> cost = viewModel.AmountAdded * 0.02;
//Update the printer credit fund and insert into tblOption
tblOption fund = (
from n in PartialViewContext.tblOptions
where n.ID == 1
select n).First();
fund.PrinterCreditFund = fund.PrinterCreditFund + cost;
PartialViewContext.SaveChanges();
message.CC.Add("");
smtp.Send(message);
Response.Redirect("~/Home/Index");
}
//If it fails, go chicken oriental (only a redirect, will eventually become a crazy message)
catch
{
smtp.Send(message);
Response.Redirect("~/Home/Index");
}
}
return View(viewModel);
Printer Credits View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="panel">
<div class="panel-heading">
<span class="panel-icon">
<i class="fa fa-print"></i>
</span>
Add Printer Credits - #Costings
</div>
<div class="panel-body">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<label class="control-label col-md-3">User:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.Username, new { htmlAttributes = new { #class = "form-control", #id = "Username", #name = "Username", #maxlength = "6" } })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">Amount:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.AmountAdded, new { htmlAttributes = new { #class = "form-control", #id = "AmountAdded", #onkeyup = "Update()", #Value = 0 } })
#Html.ValidationMessageFor(model => model.AmountAdded, "", new { #class = "text-danger", #type="number" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">Cost:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.TotalCost, new { htmlAttributes = new { #class = "form-control", #id = "TotalCost", #readonly = "readonly", #Value = "0" } })
#Html.ValidationMessageFor(model => model.TotalCost, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-1 col-md-10">
<input type="submit" value="Add Printer Credits" class="btn btn-primary btn-gradient dark btn-block" />
#Html.EditorFor(model => model.AddedBy, new { htmlAttributes = new { #class = "form-control", #Value = User.Identity.Name.Split('\\')[1], #Style = "display: none;" } })
#Html.ValidationMessageFor(model => model.AddedBy, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
}
<script type="text/javascript">
$(document).ready(
function () {
Update();
$('#AmountAdded, #TotalCost')
.keyup(function () {
Update();
})
}
);
function Update() {
var cost = 2
var one = $('#AmountAdded'),
two = $('#TotalCost');
two.val(parseInt(one.val()) * cost / 100);
}
</script>
<script type="text/javascript">
document.getElementById('Username').focus()
</script>
Just figured out that I need to tell the form which action and controller to use, despite the fact two different controllers are running the views. But anyway, an example is:
#using (Html.BeginForm("CreateMain", "Bulletins", FormMethod.Post, new { }))

Retrieving ViewModel data collection is null

I am passing model from view to controller. in my viewmodel List<TradeLaneDetailsDTO> is null always, and i am passing my data through ajax. what is the problem in my code.
please help me...
here is my viewmodel
public class SLAViewModel
{
public List<TradeLaneDetailsDTO> Items { get; set; }
}
here is my view
#using (Html.BeginForm("SaveSLA", "SLAMgmt", FormMethod.Post, htmlAttributes: new { #class = "form-horizontal", #role = "form", id = "frmEstDays" }))
{
for (int i = 0; i < Model.Items.Count; i++)
{
<div class="form-group">
#Html.LabelFor(model => model.Items.ElementAt(i).legname, Model.Items.ElementAt(i).legname, new { #class = "col-md-4" })
<div class="col-md-3">
#Html.TextBoxFor(model => model.Items.ElementAt(i).estddays, new { #class = "form-control", type = "text", MaxLength = "10" })
</div>
</div>
}
<div class="form-group">
<div class="offset-3 col-md-8">
<button id="btnSave" type="button" title="Save" class="btn btn-success" onclick="getPage1('#Url.Action("SaveSLA", "SLAMgmt")')">
<span class="glyphicon glyphicon-floppy-disk"></span>Save
</button>
</div>
</div>
}
and here is my ajax function
function getPage1(page)
{
alert("get page1");
$.ajax({
type: "POST",
url: page,
data: $("#frmEstDays").serialize(),
xhrFields: {
withCredentials: true
},
success: function (html) {
alert(html.responseText);
},
error: function (data) {
var error = "Error ";
}
});
}
here is my controller functions
public ActionResult SaveSLA(SLAViewModel slavModel)
{
string[] ErrorMessageArray = new string[4];
int errorIndex = 0;
return anything;
}
Simply use model=>model.Items[i].PROPERTYNAME as below
#Html.TextBoxFor(model => model.Items[i].estddays, new { #class = "form-control", type = "text", MaxLength = "10" })
hope this will help
Please remove type = "text" from TextBoxFor html helper.
#Html.TextBoxFor(model => model.Items.ElementAt(i).estddays, new { #class = "form-control", MaxLength = "10" })
The HtmlTextboxFor always creates a textbox <input type="text" />. So you don't have to specify explicitly.

Categories