Related
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.
I am getting this error when passing parameter to the datatable jQuery.
If I changed my controller to this
public ActionResult GetUsers(int divisionId)
with out parameter it work fine but I need to pass the parameter.
DataTables warning: table id=users - Ajax error. For more information about this error, please see http://datatables.net/tn/7
here is my view
<div>
<div class="row row-xs align-items-center mg-b-20">
<div class="col-md-4">
<label class="form-label mg-b-0">Division</label>
</div>
<div class="col-md-8 mg-t-5 mg-md-t-0">
<select id="selection" class="form-control select-group">
<option value="0">-- Select User --</option>
#foreach (var user in Model.divisions)
{
<option value="#user.DivisionID">#(user.DivisionName)</option>
}
</select>
</div>
</div>
<div class="table-responsive">
<table id="users" class="table table-striped text-md-nowrap">
<thead>
<tr>
<th>User ID</th>
<th>Employee ID</th>
<th>Username</th>
<th>Email</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
</div>
Controller
public ActionResult GetUsers(int divisionId)
{
int pageSize = 0, skip = 0;
string orderBy = "", draw = "", search = "";
Utility.SetDataTableValues(Request, out draw, out orderBy, out search, out pageSize, out skip);
int recordsTotal = 0;
List<UserPartial> usersList = new List<UserPartial>();
usersList = UserBL.GetUsersByDivision(pageSize, skip, out recordsTotal,2, search);
return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = usersList }, JsonRequestBehavior.AllowGet);
}
and the script:
$(function () {
$("#selection").on('change', function () {
var table = $('#users').DataTable();
table.destroy();
$("#users").show();
var divisionId = $("#selection option:selected").val();
var url = '/AssignHod/GetUsers/';
table = $('#users').DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"orderMulti": false,
"destroy": true,
"ordering": true,
"ajax": {
"url": '#Url.Action("GetUsers", "AssignHod")',
"type": "POST",
"datatype": "json"
},
"columns":
[
{
"data": "UserID"
},
{
"data": "EmployeeId"
},
{
"data": "Username"
},
{
"data": "Email"
},
{
"render": function (data, type, row, meta) {
var html = "";
//if (row.canEdit) {
if (row.isHOD) {
html += '<a title="Mark as User" href="/AssignHoD/deactivate/' + row.UserID + '" class="btn btn-sm waves-effect waves-light btn-outline-info"><i class="fa fa-toggle-off"></i></a>';
}
else if (!row.isHOD) {
html += '<a title="Mark as H.O.D" href="/AssignHoD/activate/' + row.UserID + '" class="btn btn-sm waves-effect waves-light btn-outline-info"><i class="fa fa-toggle-on"></i></a>';
}
return html;
}
}
]
,
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
if (aData[0]) {
}
}
});
});
});
I add attribute route before ActionResult and its now working.
[Route("AssignHoD/GetUsers/{Id}")]
public ActionResult GetUsers(int Id)
{
}
There is a button on the page.
I do not see this button in the page code.
Question: how to determine the origin of a button in a view?
The project is used - ImportExportExcelASPNetCore // talkingdotnet // github.com
After starting the application, a page will appear.
Where in the page code is the Выберите файл button?
Code
#page
#model ImportExportExcelASPNetCore.Pages.ImportExportModel
#{
ViewData["Title"] = "ImportExport";
}
<h2>Import Export using NPOI</h2>
<form method="post" enctype="multipart/form-data">
<br/>
<div class="row">
<div class="col-md-4">
<input type="file" id="fUpload" name="files" class="form-control" />
</div>
<div class="col-md-8">
<input type="button" id="btnUpload" value="Upload" />
</div>
</div>
<div class="row">
<div class="col-md-8" style="padding-top:10px;">
<button asp-page-handler="Export">Export</button>
</div>
</div>
<br/>
<div id="dvData"></div>
</form>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript" language="JavaScript">
$(document).ready(function ()
{
$('#btnUpload').on('click', function ()
{
var fileExtension = ['xls', 'xlsx']; // Расширение файла
var filename = $('#fUpload').val(); // Имя файла
if (filename.length == 0)
{
alert("Please select a file.");
return false;
}
else
{
var extension = filename.replace(/^.*\./, '');
if ($.inArray(extension, fileExtension) == -1)
{
alert("Please select only excel files.");
return false;
}
}
var fdata = new FormData();
var fileUpload = $("#fUpload").get(0);
var files = fileUpload.files;
fdata.append(files[0].name, files[0]);
$.ajax(
{
type: "POST",
url: "/ImportExport?handler=Import",
beforeSend: function (xhr)
{
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: fdata,
contentType: false,
processData: false,
success: function (response)
{
if (response.length == 0)
alert('Some error occured while uploading');
else
{
$('#dvData').html(response);
}
},
error: function (e)
{
$('#dvData').html(e.responseText);
}
});
})
});
</script>
}
I get the following exception in my system.This system worked properly. But suddenly got and exception. I tried doing debugging. But I couldn't find the anything. This is about a profile picture upload. I did some removing of code and I got the error. But then I again add those codes but nothing happen. I tried some solutions in the internet but didn't work. I'm new to this work so please help me if you can. I tried removing some of the codes then I got an error saying invalid operation.
How can I fix this?
I tried to debug and find where the problem occurs, unfortunately I couldn't find where it is.But I guess the problem should be in these codes. These two codes created the exception
Code part 1
#{
var imgUrl = #Url.Content("~/Content/profile/" + Model.SID + ".png") + "?time=" + DateTime.Now.ToString();
}
<img id="user_img" src="#imgUrl" height="50" width="50" style="margin-top:2px" />
</li>
Code part 2
#if (Model.SID != null)
{
var imgUrl = #Url.Content("Content/profile/" + Model.SID + ".png") + "?time=" + DateTime.Now.ToString();
<div class="input-field col s12">
<div class="input-field col s12">
<img id="user_img" src="#imgUrl" height="1" width="1" />
</div>
<div class="mngimg">
#using (Html.BeginForm("UploadPhoto", "Profile", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="input-field col s12">
<input type="file" name="file" id="files" onchange="this.form.submit()" />
</div>
}
</div>
</div>
}
#section Scripts
{
<script>
$(document).ready(function () {
$.validator.setDefaults({
errorClass: 'invalid',
validClass: "valid",
errorPlacement: function (error, element) {
$(element)
.closest("form")
.find("label[for='" + element.attr("id") + "']")
.attr('data-error', error.text());
},
submitHandler: function () {
event.preventDefault();
var SID = $("[name='SID']").val();
var fName = $("[name='fname']").val();
var lName = $("[name='lname']").val();
var dob = $("[name='dob']").val();
var email = $("[name='email']").val();
var pw = $("[name='password']").val();
var confirmPw = $("[name='confirmPassword']").val();
var phone = $("[name='phone']").val();
var address = $("[name='address']").val();
var user = {
SID: SID,
FirstName: fName,
LastName: lName,
DOB: dob,
email: email,
Password: password,
Phone: phone,
Address: address
}
//console.log(SID + " " + email + " " + password);
$.ajax({
type: 'POST',
url: 'saveChanges',
contentType: 'application/json',
data: JSON.stringify(user),
dataType: 'Json',
async: true,
success: function (data) {
if (data == true) {
Materialize.toast('Details Updated Successfully !!!', 4000, 'blue')
}
}
});
}
});
$.validator.addMethod("regx", function (value, element, regexpr) {
return regexpr.test(value);
}, "must contain more than 8 characters & at least 1 Alphabet and 1 Number");
$("#form").validate({
rules: {
SID: {
required: true,
minlength: 10,
maxlength: 10
},
fName: {
required: true,
minlength: 4,
maxlength: 20
},
lName: {
required: true,
minlength: 4,
maxlength: 20
},
dob: {
required: true,
},
email: {
required: true,
email: true
},
Phone: {
required: true,
regx: /^\d{10}$/,
minlength: 10,
maxlength: 10
},
},
messages: {
fName: {
required: true,
minlength: "Should be minimum 4 characters",
maxlength: "Should be maximum 20 characters",
},
lName: {
required: true,
minlength: "Should be minimum 4 characters",
maxlength: "Should be maximum 20 characters"
},
Phone: {
minlength: "Enter valid phone number",
maxlength: "Enter valid phone number"
}
}
});
});
</script>
}
<form id="form" style="width:100%; height:auto; margin-left:1%; margin-top:1%" method="post">
#*<div class="input-field col s12 ">
<i class="material-icons prefix">account_circle</i>
<input id="img" name="img" type="image" value="" readonly="readonly" style="margin-top:5%; margin-bottom:1%">
<label for="img">Profile Picture</label>
</div>*#
<div class="input-field col s12 ">
<i class="material-icons prefix">subtitles</i>
<input id="SID" name="SID" type="text" value="#Model.SID" readonly="readonly">
<label for="SID">Student ID</label>
</div>
<div class="input-field col s12">
<i class="material-icons prefix">account_circle</i>
<input id="fname" name="fname" type="text" class="validate" value="#Model.FirstName">
<label for="fname">First Name</label>
</div>
<div class="input-field col s12">
<i class="material-icons prefix">account_circle</i>
<input id="lname" name="lname" type="text" class="validate" value="#Model.LastName">
<label for="lname">Last Name</label>
</div>
<div class="input-field col s12">
<i class="material-icons prefix">Address</i>
<input id="address" name="address" type="text" class="validate" value="#Model.Address">
<label for="lname">Address</label>
</div>
<div class="input-field col s12">
<i class="material-icons prefix">phone</i>
<input id="phone" name="phone" type="text" class="validate" value="#Model.Phone">
<label for="lname">Phone</label>
</div>
<label for="dob" style="margin-left:10%">Date of Birth</label>
<div class="input-field col s12">
<i class="material-icons prefix">D</i>
<input id="dob" name="dob" type="date" class="validate" value="#Model.DOB.Value.ToString("dd/ MM/ yyyy")"> #*#Model.DOB.Value.ToString("mm/dd/yyyy")*#
</div>
<div class="input-field col s12">
<i class="material-icons prefix">email</i>
<input id="email" name="email" type="email" class="validate" value="#Model.email">
<label for="email">Email</label>
</div>
<div class="input-field col s12">
<i class="material-icons prefix">lock_outline</i>
<input id="password" name="password" type="password" class="validate">
<label for="password">Password</label>
</div>
<div class="input-field col s12">
<i class="material-icons prefix">lock_outline</i>
<input id="confirmPassword" name="confirmPassword" type="password" class="validate" onkeyup="check()">
<label for="confirmPassword">Confirm Password</label>
<lable name="checkpassword"></lable>
</div>
<div class="input-field col s12">
<input class="btn waves-effect waves-light" id="submit" type="submit" name="action" style="width:33%; margin-left:20%; margin-bottom:4%">
</div>
#*</div>*#
</form>
Controller
public ActionResult Index()
{
Session["userID"] = "IT14111884";
string sessionValue = Session["userID"].ToString();
if (Session["userID"].ToString() == null) return View("Login");
person1 = repo.GetPeronById(sessionValue);
var model = person1;
//DateTime da = (DateTime)person1.DOB;
//DateTime date2 = ;
//DateTime.ToString("dd MMM yyyy")
return View(model);
}
[HttpPost]
public JsonResult saveChanges(person person1)
{
person _person = new person();
_person.SID = person1.SID;
_person.FirstName = person1.FirstName;
_person.LastName = person1.LastName;
_person.Address = person1.Address;
_person.Phone = person1.Phone;
_person.DOB = person1.DOB;
_person.password = person1.password;
_person.email = person1.email;
//Session["_person"] = _person;
string sessionValue = Session["userID"].ToString();
bool status;
if (!ModelState.IsValid) return Json(false, JsonRequestBehavior.AllowGet);
status = repo.updatePerson(sessionValue,_person);
return Json(status, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult UploadPhoto(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var user = Session["userID"].ToString();
var fileExt = Path.GetExtension(file.FileName);
if (fileExt.ToLower().EndsWith(".png") || fileExt.ToLower().EndsWith(".jpg"))
{
var fileName = user + ".png";
var filePath = HostingEnvironment.MapPath("~/Content/profile/") + fileName;
var directory = new DirectoryInfo(HostingEnvironment.MapPath("~/Content/profile/"));
if (directory.Exists == false)
{
directory.Create();
}
ViewBag.FilePath = filePath.ToString();
file.SaveAs(filePath);
return RedirectToAction("Index", new { Message = ManageMessageId.PhotoUploadSuccess });
}
else
{
return RedirectToAction("Index", new { Message = ManageMessageId.FileExtensionError });
}
}
return RedirectToAction("Index", new { Message = ManageMessageId.Error });
}
public enum ManageMessageId
{
Error,
PhotoUploadSuccess,
FileExtensionError
}
Reporsitory class
public bool updatePerson(string ID,person _objPerson)
{
//_dbContext.people.Add(_objPerson);
person temp = null;
try
{
temp = (from p in _dbContext.people
where p.SID == ID
select p).SingleOrDefault();
temp.FirstName = _objPerson.FirstName;
temp.LastName = _objPerson.LastName;
temp.Address = _objPerson.Address;
temp.Phone = _objPerson.Phone;
temp.DOB = _objPerson.DOB;
temp.password = _objPerson.password;
temp.email = _objPerson.email;
//_dbContext.SaveChanges();
//Guid id = _objPerson.Person_ID;
if (_dbContext.SaveChanges() > 0)
{
return true;
}
}
catch (DbUpdateException e)
{
string msg = (e.InnerException.Message);
//Console.ReadLine();
}
return false;
}
I have an existing form which relies on a category being selected, if a category does not exist for the user the company belongs too, the user must be able to create one.
I believe jQuery and JSON is the route forward, but I cannot generate a true popup above the current Bootstrap form, nor can I get the popup form to post without posting the main form.
If possible I'd like the jQuery function getCategories to open a popup form only if no data is returned, then the popup form using validation, once a record has been successfully added to the database, the popup form close and then recall the jQuery function getCategories and select the newly added record.
HomeController.cs
public JsonResult GetCategories(int companyId)
{
var categories = _repository.GetCategories(companyId);
return Json(categories, JsonRequestBehavior.AllowGet);
}
_Layout.cshtml
#using Documents
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="" />
<meta name="author" content="#ViewBag.LenderName" />
<title>#ViewBag.Title - #ViewBag.LenderName</title>
#Styles.Render("~/Content/css")
#Styles.Render("~/Content/dataTablesCss")
#Styles.Render("~/Content/blue")
<!--[if lt IE 9]>
#Scripts.Render("~/bundles/ie8")
<![endif]-->
</head>
<body class="has-navbar-fixed-top page-index">
#Scripts.Render("~/bundles/jquery")
<!--[if lt IE 9]>
#Scripts.Render("~/bundles/jqueryvalidate")
<![endif]-->
#RenderSection("featusearch", required: false)
#RenderBody()
<footer id="footer" class="text-center">
<div class="container">
<div class="row">
<div class="col-lg-12">
<p> </p>
<p>
Copyright © 2015 - #ViewBag.CompanyName
</p>
</div>
</div>
</div>
</footer>
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/dataTables")
#Scripts.Render("~/bundles/money")
#Scripts.Render("~/bundles/tooltip")
#Scripts.Render("~/bundles/jquery-ui")
<script type="text/javascript" language="javascript">
$("#menu-close").click(function (e) {
e.preventDefault();
$("#sidebar-wrapper").toggleClass("active");
});
$("#menu-toggle").click(function (e) {
e.preventDefault();
$("#sidebar-wrapper").toggleClass("active");
});
$(function () {
$('a[href*=#]:not([href=#])').click(function () {
if (location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '') || location.hostname === this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
</script>
<script type="text/javascript" charset="utf-8">
$(function () {
$('.validation-summary-errors').each(function () {
$(this).addClass('alert');
$(this).addClass('alert-danger');
});
$('form').each(function () {
$(this).find('div.form-group-individual').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('has-error');
$(this).find('span.field-validation-error').removeClass('field-validation-error');
}
});
});
});
</script>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
var oTable = $('#orders').dataTable({
responsive: true,
"pagingType": "full",
"iDisplayLength": 5,
"aLengthMenu": [[5, 10, 25, -1], [5, 10, 25, "All"]],
columnDefs: [{ type: 'date-euro', targets: 4 }],
"aoColumns": [
{ "visible": false },
{ "bSortable": true, "bSearchable": true },
{ "bSortable": true, "bSearchable": true },
{ "bSortable": true, "bSearchable": true },
{ "bSortable": true, "bSearchable": true },
null,
null,
null
],
"order": [[0, "desc"]]
});
$('#Form').find('select').each(function () {
$(this).tooltip({
placement: "top",
trigger: "focus"
});
});
$('#Form').find('input').each(function () {
$(this).tooltip({
placement: "top",
trigger: "focus"
});
});
$('#Form').find('button').each(function () {
$(this).tooltip({
placement: "top",
trigger: "hover",
container: "body"
});
});
});
</script>
#RenderSection("scripts", false)
</body>
</html>
$(document).ready(function () {
var companyId = parseInt($('#CompanyId').val(), 0);
function getCategories() {
$.getJSON('/Home/GetCategories', { companyId: companyId }, function (data) {
$('#Categories option').remove();
$('#Categories').append('<option value="0">Please select a Category</option>');
for (var i = 0; i < data.length; i++) {
if (data[i].Id != categoryId) {
$('#Categories').append('<option value="' + data[i].Id + '">' + data[i].CategoryName + '</option>');
} else {
$('#Categories').append('<option value="' + data[i].Id + '" selected>' + data[i].CategoryName + '</option>');
}
}
if (data.length > 0) {
// We Have Date
} else {
// No Data
// Create Dialog Popup
alert('Error getting Categories, please add a Category');
}
}).fail(function () {
debugger;
alert('Error getting Categories, please add a Category');
});
}
$('#Categories').change(function () {
var selected = $(this).find('option:selected');
categoryId = selected.val();
$('#CategoryId').val(categoryId);
});
});
Index.cshtml
#using WebApplication1
#using WebApplication1.Helpers
#model WebApplication1.Models.Order
#{
ViewBag.Title = "Test";
}
<div id="navigation" class="wrapper">
<div class="navbar navbar-fixed-top" id="top">
<div class="navbar-inner">
<div class="inner">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle btn btn-navbar" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/" title="Home"><h1>Test</h1><span>#ViewBag.CompanyName</span></a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-right" id="main-menu">
#Html.MenuLink("Logout", "Login", "Logout", "", "Logout")
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="highlighted">
<div class="container">
<div class="header">
<h2 class="page-title">
<span>Test</span> <small>This is a test page.</small>
</h2>
<p></p>
</div>
</div>
</div>
<div id="content">
<div class="container">
<div class="row">
<div class="col-sm-12">
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { #class = "form-horizontal", role = "form", #Id = "Form" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.CategoryId, new { #Value = #ViewBag.CategoryId, #Id = "CategoryId" })
<fieldset>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Title</span>
#Html.DropDownListExt("SalutationId", ViewBag.SalutationList as SelectList, "Title")
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.SalutationId)</p>
</div>
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Forename</span>
#Html.TextBoxForExt(m => m.Forename, new Dictionary<string, object> { { "Value", #ViewBag.Forename } })
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.Forename)</p>
</div>
</div>
</div>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Middle Name</span>
#Html.TextBoxForExt(m => m.MiddleName, new Dictionary<string, object> { { "Value", #ViewBag.MiddleName } })
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.MiddleName)</p>
</div>
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Surname</span>
#Html.TextBoxForExt(m => m.Surname, new Dictionary<string, object> { { "Value", #ViewBag.Surname } })
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.Surname)</p>
</div>
</div>
</div>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Categories</span>
<select id="Categories" name="Categories" class="form-control" data-toggle="tooltip" title="Categories">
<option></option>
</select>
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.CategoryId)</p>
</div>
<div class="col-sm-1">
<button type="submit" class="btn btn-primary" name="Submit" value="Submit" title="Click to Submit">Submit</button>
</div>
</div>
</div>
</fieldset>
}
</div>
</div>
</div>
</div>
<script type="text/javascript" src="/Scripts/form.js"></script>
form.js
$(document).ready(function () {
var companyId = parseInt($('#CompanyId').val(), 0);
var categoryId = parseInt($('#CategoryId').val(), 0);
getCategories();
function getCategories() {
$.getJSON('/Home/GetCategories', { companyId: companyId }, function (data) {
$('#Categories option').remove();
$('#Categories').append('<option value="0">Please select a Category</option>');
for (var i = 0; i < data.length; i++) {
if (data[i].Id != categoryId) {
$('#Categories').append('<option value="' + data[i].Id + '">' + data[i].Category + '</option>');
} else {
$('#Categories').append('<option value="' + data[i].Id + '" selected>' + data[i].Category + '</option>');
}
}
if (data.length > 0) {
// We Have Data
} else {
// No Data
// Create Dialog Popup
alert('Error getting Categories, please add a Category');
}
}).fail(function () {
debugger;
alert('Error getting Categories, please add a Category');
});
}
$('#Categories').change(function () {
var selected = $(this).find('option:selected');
categoryId = selected.val();
$('#CategoryId').val(categoryId);
});
});
Add.cshtml
#using WebApplication1.Helpers
#model WebApplication1.Models.Category
<div id="content">
<div class="container">
<div class="row">
<div class="col-sm-4">
#using (Html.BeginForm("Add", "Home", FormMethod.Post, new { #class = "form-horizontal", role = "form", #Id = "AddForm" }))
{
#Html.HiddenFor(m => m.CompanyId, new { #Value = #ViewBag.CompanyId, #Id = "CompanyId" })
<fieldset>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-4">
<div class="input-group">
<span class="input-group-addon">Category Name</span>
#Html.TextBoxForExt(m => m.CategoryName)
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.CategoryName)</p>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-1">
<button type="submit" class="btn btn-primary" name="Add" value="Add" title="Click to Add a Category">Add</button>
</div>
</div>
</fieldset>
}
</div>
</div>
</div>
</div>
BundleConfig.cs
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.IgnoreList.Clear();
bundles.UseCdn = true;
BundleTable.EnableOptimizations = false;
bundles.Add(new ScriptBundle("~/bundles/ie8").Include(
"~/Scripts/html5shiv.js",
"~/Scripts/respond.js"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js"));
var jquery = new ScriptBundle("~/bundles/jquery", "~/Scripts/jquery-2.1.4.js").Include(
"~/Scripts/Compatibility/jquery-1.11.3.js");
jquery.CdnFallbackExpression = "window.jQuery";
bundles.Add(jquery);
bundles.Add(new ScriptBundle("~/bundles/jqueryvalidate").Include(
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js",
"~/Scripts/_extensions.js"));
bundles.Add(new ScriptBundle("~/bundles/money").Include(
"~/Scripts/jquery.price_format.2.0.js"));
bundles.Add(new ScriptBundle("~/bundles/tooltip").Include(
"~/Scripts/tooltip.js"));
bundles.Add(new ScriptBundle("~/bundles/dataTables").Include(
"~/Scripts/DataTables-1.10.9/jquery.dataTables.js",
"~/Scripts/DataTables-1.10.9/dataTables.bootstrap.js",
"~/Scripts/DataTables-1.10.9/date-euro.js"));
bundles.Add(new ScriptBundle("~/bundles/awesomeMvc").Include(
"~/Scripts/AwesomeMvc.js"));
bundles.Add(new ScriptBundle("~/bundles/jquery-ui").Include(
"~/Scripts/jquery-ui.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/Site.css"));
bundles.Add(new StyleBundle("~/Content/blue").Include(
"~/Content/colour-blue.css"));
bundles.Add(new StyleBundle("~/Content/red").Include(
"~/Content/colour-red.css"));
bundles.Add(new StyleBundle("~/Content/dataTablesCss").Include(
"~/Content/DataTables-1.10.9/dataTables.bootstrap.css",
"~/Content/DataTables-1.10.9/Buttons-1.0.3/buttons.bootstrap.css"));
}
}
Any help would be much appreciated :-)
It sounds like you might be looking for a Modal popup. Bootstrap already has this built in. You can learn about it here: http://www.w3schools.com/bootstrap/bootstrap_modal.asp
You can also pull what to show in the modal from another view using the Html.RenderPartial(view)
Following on from Drew Rochon's suggestion, I have researched and resolved my issue.
The following code is either replacement or addition where specified.
_Add.cshtml (Replacement for Add.cshtml)
#using WebApplication1.Helpers
#model WebApplication1.Models.Category
<div class="modal fade" id="AddCategoryModal" tabindex="-1" role="dialog" aria-labelledby="Add" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h5 class="modal-title">Add Category</h5>
</div>
<div class="modal-body">
#using (Html.BeginForm(null, null, FormMethod.Post, new { #Id = "AddCategoryForm" }))
{
#Html.HiddenFor(m => m.CompanyId, new { #Id = "CompanyId" })
<fieldset>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-12">
<div class="input-group">
<span class="input-group-addon">Category Name</span>
#Html.TextBoxForExt(m => m.CategoryName)
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.CategoryName)</p>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<button type="submit" class="btn btn-primary">Add</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
</fieldset>
}
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
var path = $("#Path").val();
var companyId = parseInt($('#CompanyId').val(), 0);
var categoryId = parseInt($('#CategoryId').val(), 0);
var abort = false;
$("#AddCategoryModal").modal('show');
$('#AddCategoryModal').off("hidden.bs.modal").on('hidden.bs.modal', modalClose);
function modalClose() {
$("#AddAdvisoryModal").remove();
$('.modal-backdrop').remove();
}
$('#AddCategoryForm').formValidation({
framework: 'bootstrap',
excluded: ':disabled',
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
CategoryName: {
validators: {
notEmpty: {
message: 'Category Name is required'
}
}
}
}
}).on('success.form.fv', function (e) {
e.preventDefault();
var companyId = $("#CompanyId").val();
var categoryName = $("#CategoryName").val();
var model = {
CompanyId: companyId,
CategoryName: categoryName
};
$.ajax({
url: "/Home/_Add/",
type: "POST",
contentType: "application/json;charset=utf-8;",
dataType: "html",
data: JSON.stringify(model),
success: function (markup) {
categoryId = parseInt(markup, 0);
if (categoryId > 0) {
$('#Categories').val(categoryId);
getCategories();
alert("Category added successfully.");
modalClose();
}
},
error: function () {
alert('Ajax request not recieved!');
}
});
});
function getCategories() {
$.getJSON(path + 'GetCategories', { companyId: companyId }, function (data) {
$('#Categories option').remove();
$('#Categories').append('<option value="0">Please select a Category</option>');
$('#Categories').append('<option value="9999999">Add a Category</option>');
for (var i = 0; i < data.length; i++) {
if (data[i].Id != categoryId) {
$('#Categories').append('<option value="' + data[i].Id + '">' + data[i].CategoryName + '</option>');
} else {
$('#Categories').append('<option value="' + data[i].Id + '" selected>' + data[i].CategoryName + '</option>');
}
}
if (data.length > 0) {
if (categoryId > 0) {
$('#Categories').val(categoryId);
}
} else {
alert('Error getting Categories, please add a Category');
}
}).fail(function () {
debugger;
alert('Error getting Categories, please add a Category');
});
}
$('#AddCategoryForm').find('select').each(function () {
$(this).tooltip({
placement: "top",
trigger: "focus"
});
});
$('#AddCategoryForm').find('input').each(function () {
$(this).tooltip({
placement: "top",
trigger: "focus"
});
});
});
</script>
form.js (Replacement)
$(document).ready(function () {
var companyId = parseInt($('#CompanyId').val(), 0);
var categoryId = parseInt($('#CategoryId').val(), 0);
getCategories();
$('#Categories').change(function () {
var selected = $(this).find('option:selected');
categoryId = selected.val();
if (categoryId == 9999999) {
openModal();
}
$('#CategoryId').val(categoryId);
});
function getCategories() {
$.getJSON(path + 'GetCategories', { companyId: companyId }, function (data) {
$('#Categories option').remove();
$('#Categories').append('<option value="0">Please select a Category</option>');
$('#Categories').append('<option value="9999999">Add a Category</option>');
for (var i = 0; i < data.length; i++) {
if (data[i].Id != categoryId) {
$('#Categories').append('<option value="' + data[i].Id + '">' + data[i].CategoryName + '</option>');
} else {
$('#Categories').append('<option value="' + data[i].Id + '" selected>' + data[i].CategoryName + '</option>');
}
}
if (data.length > 0) {
if (categoryId > 0) {
$('#Categories').val(categoryId);
}
} else {
alert('Error getting Categories, please add a Category');
openModal();
}
}).fail(function () {
debugger;
alert('Error getting Categories, please add a Category');
});
}
function openModal() {
var companyId = $("#CompanyId").val();
var model = { CompanyId: companyId };
$.ajax({
url: "/Home/_Add/",
type: "POST",
contentType: "application/json;charset=utf-8;",
dataType: "html",
data: JSON.stringify(model),
success: function (markup) {
if (isNaN(markup) || markup == "0") {
$(document.body).append(markup);
}
}
});
}
});
BundleConfig.cs (Addition)
bundles.Add(new StyleBundle("~/Content/formValidationCss").Include(
"~/Content/formValidation.css"));
bundles.Add(new ScriptBundle("~/bundles/formValidation").Include(
"~/Scripts/formValidation.min.js",
"~/Scripts/foundationBootstrap.min.js",
"~/Scripts/foundation.min.js"));
_Layout.cshtml (Addition)
#Styles.Render("~/Content/formValidationCss")
#Scripts.Render("~/bundles/formValidation")
HomeController.cs (Addition)
public ActionResult _Add(WebApplication1.Models.Category model)
{
int id;
if (ModelState.IsValid)
{
id = _documentsRepository.SetCategory(model);
}
else
{
ModelState.Clear();
return PartialView(model);
}
return Content(id.ToString());
}
Hope this proves useful to others.