Why is the property DEPARTMENTID not inserting into the database on create, I am using Dropdownlist
see the code below, this all my code i need your idea to correct my code.
Controller
// GET: /Budget/Create
public ActionResult Create()
{
var name = User.Identity.GetUserName();
var userroles = _roleDataContext.USERROLEs.Where(u => u.USERNAME.ToLower().Trim() == name.ToLower().Trim() && u.ROLE.Trim() == "6");
var rolegroup = from u in userroles.ToList()
join rg in _roleDataContext.ROLEGROUPs.ToList()
on u.ROLEID equals rg.ROLEID
select rg;
var usergroup = (from rg in rolegroup.ToList()
join ug in _roleDataContext.USERGROUPs.ToList()
on rg.GROUPID equals ug.GROUPID
select ug).OrderBy(i => i.DEPTCODE);
var listSelectitem = usergroup.Select(#group => new SelectListItem
{
Selected = true,
Text = #group.DEPTCODE.Length > 20 ? #group.DEPTCODE.Substring(0, 20) : #group.DEPTCODE,
Value = #group.DEPTCODE
}).ToList();
var firstOrDefault = usergroup.FirstOrDefault();
if (firstOrDefault != null)
{
ViewBag.DeptList = new SelectList(listSelectitem, "Value", "Text", firstOrDefault.DEPTCODE);
}
return View();
}
// POST: /Budget/Create
[HttpPost]
public ActionResult Create(BudgetViewModel model , int month = 1, int year = 2017)
{
// TODO: Add insert logic here
model.DATETIME = DateTime.Now;
BudgetDb.insert(model);
return RedirectToAction("Index");
}
View
#model WarehouseRtoRSystem.Models.BudgetViewModel
#{
ViewBag.Title = "Create";
}
<style>
.col-md-10 {
clear: both;
padding-left: 0px !important;
}
.col-md-2 {
text-align: left !important;
}
</style>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h2>Budget</h2>
<hr />
#Html.ValidationSummary(true)
<label>Month </label>
<select id="month" name="month">
#{ string[] Months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; }
#for (var i = 0; i < 12; i++)
{
var m = i + 1;
if (Convert.ToInt32(ViewBag.month) == m)
{
<option value=#m selected>#Months[i]</option>
}
else
{
<option value=#m>#Months[i]</option>
}
}
</select>
<label>YEAR</label>
<select id="year" name="year">
#for (var c = 0; c < 1000; c++)
{
var yr = c + 2017;
if (Convert.ToInt32(ViewBag.year) == yr)
{
<option value=#yr selected>
#yr
</option>
}
else
{
<option value=#yr> #yr</option>
}
}
</select>
<br />
<br />
<div class="form-group">
<label> LIST OF YOUR DEPARTMENT</label>
<span class="">#Html.DropDownList("DEPARTMENTID", (SelectList)ViewBag.DeptList, new { #class = "form-control" })</span>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BUDGET, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBox("ShowBudget", null, new { #class = "form-control" })
#Html.HiddenFor(model => model.BUDGET, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BUDGET)
</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>
<br />
<br />
<br />
</div>
}
<div>
#Html.ActionLink("Back to List", "Index", null, new { #class ="btn btn-primary"})
</div>
<script>
$(document).ready(function () {
$("#ShowBudget").change(function () {
var value = parseFloat($(this).val());
$("#BUDGET").val(value); //assign the current value to BUDGET field
if (!isNaN(value)) {
var result = value.toLocaleString(
"en-US", // use a string like 'en-US' to override browser locale
{ minimumFractionDigits: 2 }
);
$(this).val(result);
}
})
})
</script>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Model
namespace WarehouseRtoRSystem.Models
{
public class BudgetModel
{
public int MONTH { get; set; }
public int YEAR { get; set; }
public string DEPARTMENTID { get; set; }
public DateTime DATETIME { get; set; }
//[DisplayFormat(DataFormatString = "{0:N}", ApplyFormatInEditMode = true)]
public double BUDGET { get; set; }
public string GROUPID { get; set; }
}
public class BudgetViewModel : BudgetModel
{
public string DEPARTMENTNAME { get; set; }
public double EXPENCES { get; set; }
public double BALANCE { get; set; }
}
public class BudgetContext
{
private readonly OracleCommand cmd = new OracleCommand();
private OracleConnection Conn = new OracleConnection();
private readonly OracleConnModel ORCONN = new OracleConnModel();
public List<BudgetViewModel> List()
{
var Departments = new List<BudgetViewModel>();
///SQL QUERY
Conn = ORCONN.con;
if (Conn.State != ConnectionState.Open)
{
Conn.Open();
}
try
{
cmd.Connection = Conn;
cmd.CommandText = "SELECT * From PH.SYSTEMBUDGET";
cmd.CommandType = CommandType.Text;
var dr = cmd.ExecuteReader();
while (dr.Read())
{
var Dept = new BudgetViewModel();
Dept.MONTH = dr.GetInt32(0);
Dept.YEAR = dr.GetInt32(1);
Dept.DEPARTMENTID = dr.GetString(2);
Dept.DATETIME = dr.GetDateTime(3);
Dept.BUDGET = dr.GetDouble(4);
Dept.GROUPID = dr.IsDBNull(5) ? "" : dr.GetString(5);
Departments.Add(Dept);
}
}
finally
{
Conn.Close();
}
return Departments;
}
public string insert(BudgetModel model)
{
Conn = ORCONN.con;
if (Conn.State != ConnectionState.Open)
{
Conn.Open();
}
try
{
cmd.Connection = Conn;
//var date = new DateTime();
// date = DateTime.Now;
var query = "INSERT into PH.SYSTEMBUDGET(";
query += "MONTH,";
query += "YEAR,";
query += "DEPARTMENTID,";
query += "DATETIME,";
query += "BUDGET,";
query += "GROUPID";
query += ")";
query += "VALUES(";
query += "'" + model.MONTH + "',";
query += "'" + model.YEAR + "',";
query += "'" + model.DEPARTMENTID + "',";
query += "TO_DATE('" + DateTime.Now + "','MM/DD/YYYY HH:MI:SS AM'),";
query += "'"+ model.BUDGET + "'," ;
query += "'" + model.GROUPID + "'";
query += ")";
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
catch(Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
finally
{
Conn.Close();
}
return "Seccessfully inserted";
}
}
}
The error resides in the following code in your controller, whereby you are setting the Value of the SelectListItem to be the DEPTCODE description instead of the ID of the DEPTCODE record
Here is your code:
var listSelectitem = usergroup.Select(#group => new SelectListItem
{
Selected = true,
Text = #group.DEPTCODE.Length > 20 ? #group.DEPTCODE.Substring(0, 20) : #group.DEPTCODE,
Value = #group.DEPTCODE
}).ToList();
The issue is here:
Value = #group.DEPTCODE
Now apologies for not re-creating the code exactly in the controller but the DEPTCODE models were not available, so I improvised slightly.
Here is my Create Controller:
[HttpGet]
public ActionResult Create()
{
List<DeptCode> _depts = new List<DeptCode>();
_depts.Add(new DeptCode { Id = 0, Description = "IT"});
_depts.Add(new DeptCode { Id = 1, Description = "Customer Services" });
_depts.Add(new DeptCode { Id = 2, Description = "Warehouse" });
var _listSelectItem = _depts.Select(#group => new SelectListItem
{
Selected = true,
Text = #group.Description,
Value = #group.Id.ToString()
}).ToList();
var firstOrDefault = _listSelectItem.FirstOrDefault();
if(firstOrDefault != null)
{
ViewBag.DeptList = new SelectList(_listSelectItem, "Value", "Text", firstOrDefault.Text);
}
return View();
}
I have created my SelectListItem with the Value of the Id of the record, because in your code, you were binding ViewBag.DeptList with a SelectList whereby the dataValueField (Source) property was "Value".:
ViewBag.DeptList = new SelectList(_listSelectItem, "Value", "Text", firstOrDefault.Text);
So in my example I have selected a Warehouse department (again I made this value up for the sake of my model), and pressed Create.:
As you can see, this is now bound to model.DEPARTMENTID:
I have added my code here if you want to see how it works:
https://github.com/garfbradaz/StackOverFlowAnswers/tree/master/ASP.NET%20MVC/DropDownListNotWorking/SOAnswer-44879268
Related
I am kind of lost when it comes to jQuery sometimes, though I know there is a way! How do you update or move three cells data to another row based on the rows id to where the row is green (empty cells)? The row column ID name is "LocationID". MVC application using a web grid. What I am trying to do is when I check the row, use the drop-down that has the id, send the data to that row where the id exists populating the three empty cells in green with the current columnar data row that is checked. Any help would be greatly appreciated!
WebGrid below:
enter
<div id="content">
#webGrid.GetHtml(tableStyle: "webgrid-table",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
//alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style",
mode: WebGridPagerModes.All,
htmlAttributes: new { #id = "webGrid" },
columns: webGrid.Columns(
webGrid.Column(header: "Actions", format:#<span class="link">
<!--Add Checkbox here-->
<!-- Note: We can add clickable rows as an option for user using a checkbox, one
selects the data move and the other move to selection. -->
#Html.CheckBoxFor(model => model.SelectedMoveIsChecked, new { #Class =
"SelectedMoveIsChecked", #id = "SelectedMoveIsChecked", #checked = false })
#Html.CheckBoxFor(model => model.SelectedMoveToChecked, new { #Class =
"SelectedMoveToChecked", #id = "SelectedMoveToChecked", #checked = false })
<!-- Html.CheckBox("isActive", false, item.isSelectdRow, true, new { id =
"CheckBoxSelectedBeginMove", Class = "CheckBoxIsSelected" })
Html.CheckBoxFor(Model.Input_Location, item.isSelectdRow, new { = "'SelectedRows'",
data_val = item.Location })
-->
<a class="Edit" href="javascript:;">Edit</a>
<a class="Clear" href="javascript:;">Clear</a>
<a class="Update" href="javascript:;" style="display:none">Update</a>
<a class="Cancel" href="javascript:;" style="display:none">Cancel</a>
</span>),
webGrid.Column(header: "Location", format: #<div>
<label id="LocationLbl" class="label">#item.Location</label>
<input id="Location" class="text" type="text" value="#item.Location" style="display:none"
/><br />
#Html.DropDownListFor(model => model.LocationAppended, Model.LocationAppended,
"Section/Location", new { IReadOnlyDictionary = "document.forms[0].submit();", #id =
"RowLocationDropDownList", #class = "RowLocationDropDownList", #visibility = "hidden",
#placeholder = "Location" })
</div>, style: "Location"),
webGrid.Column(header: "Section", format: #<div>
<label id="SectionLbl" class="label">#item.Section</label>
<input id="Section" class="text" type="text" value="#item.Section" style="display:none" />
</div>, style: "Section"),
webGrid.Column(header: "TrailerNumber", format: #<div>
<label id="TrailerNumberLbl" class="label">#item.TrailerNumber</label>
<input id="TrailerNumber" class="text" type="text" value="#item.TrailerNumber"
style="display:none" />
</div>, style: "TrailerNumber"),
webGrid.Column(header: "CarrierName", format: #<div>
<label id="CarrierNameLbl" class="label">#item.CarrierName</label>
<input id="CarrierName" class="text" type="text" value="#item.CarrierName"
style="display:none" />
</div>, style: "CarrierName"),
webGrid.Column(header: "LoadCommodityStatus", format: #<div>
<label id="LoadCommodityStatusLbl" class="label">#item.LoadCommodityStatus</label>
<input id="LoadCommodityStatus" class="text" type="text" value="#item.LoadCommodityStatus"
style="display:none" />
</div>, style: "LoadCommodityStatus"),
webGrid.Column(header: "DateLoaded", format: #<div>
<label id="DateLoadedLbl" class="label">#item.DateLoaded</label>
<input id="DateLoaded" class="text" type="text" value="#item.DateLoaded" style="display:none"
/>
</div>, style: "DateLoaded"),
webGrid.Column(header: "UserName", format: #<div>
<label id="UserNameLbl" class="label">#item.UserName</label>
<input id="UserName" class="text" type="text" value="#item.UserName" style="display:none" />
</div>, style: "UserName"),
webGrid.Column(header: "PlantLocation", format: #<div>
<label id="PlantLocationLbl" class="label">#item.PlantLocation</label>
<input id="PlantLocation" class="text" type="text" value="#item.PlantLocation"
style="display:none" />
</div>, style: "PlantLocation"),
webGrid.Column(header: "RowPageID", format: #<div>
<label id="LocationIDLbl" class="label">#item.LocationID</label>
</div>, style: "LocationID"))),
<div id="RowCountBpttom"><b>Records: #firstRecord - #lastRecord of
#webGrid.TotalRowCount</b></div>
</div>
<br />
<div class="WebGridTable">
</div>
</div>
</form>
</div>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js">
</script>
<script src="~/Scripts/YardDogAdmin.js"></script>
</body>
jQuery Below:
code here
enter
$('select.RowLocationDropDownList').attr('disabled', true);
$(".SelectedMoveIsChecked").change(function (i, row) {
$actualRowColorRed = $(row);
//When a value is selected in the dropdownlist box.
if ($(this).children("option:selected").val() != '') {
$("select.RowLocationDropDownList").change(function (i, row) {
$actualRowColorRed = $(row);
//Checks to see if the checkbox is checked, display the alert showing data and color the row red again.
/////// if ($('.SelectedMoveIsChecked').is(':checked') == true) {
$('select.RowLocationDropDownList').children("option:selected").val();
var str = $(this).children("option:selected").val();
var ret = str.split(" ");
var RowLocationID = ret[0];
var RowLocationIDNum = parseInt(RowLocationID); //convert string to int.
var RowSection = ret[1];
var RowLocation = ret[2];
var CurrentRowID = $(this).closest("tr").find('#LocationIDLbl').text();
var CurrentRowLocation = $(this).closest("tr").find('#LocationLbl').text();
var CurrentRowSection = $(this).closest("tr").find('#SectionLbl').text();
var CurrentRowTrailerNumber = $(this).closest("tr").find('#TrailerNumberLbl').text();
var CurrentRowCarrierName = $(this).closest("tr").find('#CarrierNameLbl').text();
var CurrentRowLoadCommodityStatus = $(this).closest("tr").find('#LoadCommodityStatusLbl').text();
var CurrentRowDateLoaded = $(this).closest("tr").find('#DateLoadedLbl').text();
var CurrentRowUserName = $(this).closest("tr").find('#UserNameLbl').text();
var CurrentRowPlantLocation = $(this).closest("tr").find('#PlantLocationLbl').text();
// var ConfirmStr = " <b>Are you sure, you want to move this row From: </b>" + CurrentRowID + " Section: " + CurrentRowSection + " Location:" + CurrentRowLocation + " TrailerNumber:" + CurrentRowTrailerNumber + " \n\n\n To \n Section: ";
// alert("Alert " + ConfirmStr + "Original: " + str + " RowPageID: " + RowLocationIDNum + " Section: " + RowSection + " Location: " + RowLocation + "?"
// );
function Confirm() {
var confirm_value = document.createElement("INPUT");
confirm_value.type = "hidden";
confirm_value.name = "confirm_value";
var ConfirmStr = "Are you sure, you want to move this row From: " + CurrentRowID + " Section: " + CurrentRowSection + " Location:" + CurrentRowLocation + " TrailerNumber:" + CurrentRowTrailerNumber + " \n\n\n To \n Section: ";
if (confirm("Confirm! " + ConfirmStr + "Original: " + str + " RowPageID: " + RowLocationIDNum + " Section: " + RowSection + " Location: " + RowLocation + "?")) {
confirm_value.value = "Yes";
//Add new values to (TrailerNumber, CarrierName, LoadCommodityStatus, DateLoaded, UserName).
//Note: Get the UserName currently using the Yard Dog Application.
/// $('#webGrid').closest('tr').find('#TrailerNumber').val();
/// $("#webGrid tbody tr").each(function (i, row) {
// $('#webGrid tbody tr').find('#LocationID'.val(RowLocationIDNum); //= RowLocationIDNum).append('#TrailerNumber'.val(CurrentRowTrailerNumber));
$("body").on("change", "select.RowLocationDropDownList", function () {
// $("body").on("click", "#webGrid TBODY .Update", function () {
// $("#content").on("click", "#webGrid INPUT", function () {
var row = $(this).closest("tr");
$("webGrid td", row).each(function () {
if ($(this).find(".text").length > 0) {
var span = $(this).find(".label");
var input = $(this).find(".text");
span.html(input.val());
}
});
//// $('#webGrid tbody tr').find('#LocationID').val(RowLocationIDNum) = customer;
var RowExchange = $(RowLocationID).closest("tr");
var ToRow = {};
ToRow.LocationID = row.find(".LocationID").find(".label").html();
ToRow.UserName = row.find(".UserName").find(".label").html();
ToRow.Location = row.find(".Location").find(".label").html();
ToRow.Section = row.find(".Section").find(".label").html();
ToRow.TrailerNumber = row.find(".TrailerNumber").find(".label").html();
ToRow.CarrierName = row.find(".CarrierName").find(".label").html();
ToRow.LoadCommodityStatus = row.find(".LoadCommodityStatus").find(".label").html();
ToRow.DateLoaded = row.find(".DateLoaded").find(".label").html();
ToRow.PlantLocation = row.find(".PlantLocation").find(".label").html();
/*
ToRow.LocationID = RowExchange.find('#LocationID').append(RowLocationID) ;
ToRow.UserName = RowExchange.find('.UserName').append(row.find(".UserName").find(".label").html());
ToRow.Location = RowExchange.find('.Location').append(row.find(".Location").find(".label").html());
ToRow.Section = RowExchange.find('.Section').append(row.find(".Section").find(".label").html());
ToRow.TrailerNumber = RowExchange.find('.TrailerNumber').append(ToRow.TrailerNumber);
ToRow.CarrierName = RowExchange.find('.CarrierName').val().append(ToRow.CarrierName);
ToRow.LoadCommodityStatus = RowExchange.find('.LoadCommodityStatus').append(ToRow.LoadCommodityStatus);
ToRow.DateLoaded = RowExchange.find('.DateLoaded').append(row.find(".DateLoaded").find(".label").html());
ToRow.PlantLocation = RowExchange.find('.PlantLocation').append(row.find(".PlantLocation").find(".label").html());
*/
$.ajax({
type: "POST",
url: "/Home/UpdateRowExchange",
data: '{ToRow:' + JSON.stringify(ToRow) +'}',
contentType: "application/json; charset=utf-8",
dataType: "json"
}); setInterval('location.reload()', 777);
});
}
else {
confirm_value.value = "Cancel";
}
document.forms[0].appendChild(confirm_value);
}
Confirm();
code here
Controller:
enter [HttpPost]
public ActionResult UpdateRowExchange(LocationData ToRow)
{
using (PW_YardDogDataEntitiesModel3 entities = new PW_YardDogDataEntitiesModel3())
{
LocationData updatedCustomer = (from c in entities.LocationDatas
where c.LocationID == ToRow.LocationID
select c).FirstOrDefault();
//Check for Duplicates.
///FindDuplicates(customer);
//HighlightDuplicate(webGrid);
//x => customer.TrailerNumber == x.TrailerNumber && x.TrailerNumber == customer.TrailerNumber //errases all data except the first cell TrailerNumber.
if (ToRow.UserName != null) updatedCustomer.UserName = ToRow.UserName.ToUpper();
else updatedCustomer.UserName = ToRow.UserName = null;
/*
if (customer.Location != null) updatedCustomer.Location = customer.Location.ToUpper();
else updatedCustomer.Location = customer.Location = null;
if (customer.Section != null) updatedCustomer.Section = customer.Section.ToUpper();
else updatedCustomer.Section = customer.Section = null;
*/
if (ToRow.TrailerNumber != null) updatedCustomer.TrailerNumber = ToRow.TrailerNumber.ToUpper();
else updatedCustomer.TrailerNumber = ToRow.TrailerNumber = null;
if (ToRow.CarrierName != null) updatedCustomer.CarrierName = ToRow.CarrierName.ToUpper();
else updatedCustomer.CarrierName = ToRow.CarrierName = null;
if (ToRow.LoadCommodityStatus != null) updatedCustomer.LoadCommodityStatus = ToRow.LoadCommodityStatus.ToUpper();
else updatedCustomer.LoadCommodityStatus = ToRow.LoadCommodityStatus = null;
if (ToRow.DateLoaded != null) updatedCustomer.DateLoaded = ToRow.DateLoaded.ToUpper();
else updatedCustomer.DateLoaded = ToRow.DateLoaded = null;
/*
if (customer.PlantLocation != null) updatedCustomer.PlantLocation = customer.PlantLocation.ToUpper();
else updatedCustomer.PlantLocation = customer.PlantLocation = null;
*/
//Create today's Date for a timestamp of inputs.
DateTime now = DateTime.Today;
ToRow.DateLoaded = DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss tt");
updatedCustomer.DateLoaded = ToRow.DateLoaded;
entities.SaveChanges();
//Refresh(out, customer.ToString());
}
return new EmptyResult();
}
code here
Model below:
enter code here
namespace YardDog.Model
{
public class YardDogModel
{
ContYardDogAdmin ContYardDogData = new ContYardDogAdmin();
//Two Properties for DropDownList.
public List<LocationData> LocationDatas { get; set; }
//public List<LocationData> Location { get; set; }
public List<LocationData> TrailerNumber { get; set; }
public List<SelectListItem> PlantLocation { get; set; }
public List<SelectListItem> Location { get; set; }
public List<SelectListItem> LocationList { get; set; }
public List<SelectListItem> SectionList { get; set; }
public List<SelectListItem> LocationAppended { get; set; }
[Display(Name = "Name")]
public List<SelectListItem> Section { get; set; }
public List<SelectListItem> ListDuplicates { get; set; }
public List<SelectListItem> UserName { get; set; }
//Allow the data to be transfered (Backend into SQL Server).
[Required]
public string Input_Location { get; set; }
[Required]
public string Input_Section { get; set; }
public string Input_TrailerNumber { get; set; }
public string Input_CarrierName { get; set; }
public string Input_CommodityLoadStatus { get; set; }
[Required]
public string Input_PlantLocation { get; set; }
//YardDogModel YardDogDatas = new YardDogModel();
//string TrailerNumber = Input_TrailerNumber;
public bool SelectedMoveIsChecked { get; set; } = false;
public bool SelectedMoveToChecked { get; set; } = false;
public string LocationAppendedLbl { get; internal set; }
//public string LocationAppended { get; internal set; }
public string RowLocationDropDownList { get; set; }
public int RowLocationIDNum { get; set; }
}
}
JavaScript:
$('select.RowLocationDropDownList').children("option:selected").val();
var str = $(this).children("option:selected").val();
var ret = str.split(" ");
var RowLocationID = ret[2];
var RowLocationIDNum = parseInt(RowLocationID); //convert string to int.
var RowSection = ret[0];
var RowLocation = ret[1];
var CurrentRowID = $(this).closest("tr").find('#LocationIDLbl').text();
var CurrentRowLocation = $(this).closest("tr").find('#LocationLbl').text();
var CurrentRowSection = $(this).closest("tr").find('#SectionLbl').text();
var CurrentRowTrailerNumber = $(this).closest("tr").find('#TrailerNumberLbl').text();
var CurrentRowCarrierName = $(this).closest("tr").find('#CarrierNameLbl').text();
var CurrentRowLoadCommodityStatus = $(this).closest("tr").find('#LoadCommodityStatusLbl').text();
var CurrentRowDateLoaded = $(this).closest("tr").find('#DateLoadedLbl').text();
var CurrentRowUserName = $(this).closest("tr").find('#UserNameLbl').text();
var CurrentRowPlantLocation = $(this).closest("tr").find('#PlantLocationLbl').text();
function Confirm() {
var confirm_value = document.createElement("INPUT");
confirm_value.type = "hidden";
confirm_value.name = "confirm_value";
var ConfirmStr = "Are you sure, you want to move this row From: " + CurrentRowID + " Section: " + CurrentRowSection + " Location:" + CurrentRowLocation + " TrailerNumber:" + CurrentRowTrailerNumber + " \n\n\n To \n Section: ";
if (confirm("Confirm! " + ConfirmStr + "Original: " + str + " RowPageID: " + RowLocationIDNum + " Section: " + RowSection + " Location: " + RowLocation + "?")) {
confirm_value.value = "Yes";
$("body").on("change", "select.RowLocationDropDownList", function () {
var row = $(this).closest("tr");
$("webGrid td", row).each(function () {
if ($(this).find(".text").length > 0) {
span.html(input.val());
}
});
//Tell the row change to be where ID exists by ID Number (RowLocationIDNum).
var ToRow = {};
ToRow.LocationID = RowLocationIDNum; //row.find(".LocationID").find(".label").html();
ToRow.UserName = row.find(".UserName").find(".label").html();
ToRow.Location = row.find(".Location").find(".label").html();
ToRow.Section = row.find(".Section").find(".label").html();
ToRow.TrailerNumber = row.find(".TrailerNumber").find(".label").html();
ToRow.CarrierName = row.find(".CarrierName").find(".label").html();
ToRow.LoadCommodityStatus = row.find(".LoadCommodityStatus").find(".label").html();
ToRow.DateLoaded = row.find(".DateLoaded").find(".label").html();
ToRow.PlantLocation = row.find(".PlantLocation").find(".label").html();
$.ajax({
type: "POST",
url: "/Home/UpdateRowExchange",
data: '{ToRow:' + JSON.stringify(ToRow) + '}',
contentType: "application/json; charset=utf-8",
dataType: "json"
});
// setInterval('location.reload()', 777);
//Set the Clear Event to clear the initial rows.
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find(".text").length > 0) {
var span = $(this).find(".label");
var input = $(this).find(".text");
$(this).find(".text").show();
$(this).find(".label").hide();
span.html(input.val(null));
span.show();
input.hide();
}
});
row.find(".Cancel").show();
row.find(".Clear").show();
row.find(".Edit").show();
$(this).hide();
var clear = {};
clear.LocationID = row.find(".LocationID").find(".label").html();
clear.UserName = row.find(".UserName").find(".label").html();
clear.Location = row.find(".Location").find(".label").html();
clear.Section = row.find(".Section").find(".label").html();
clear.TrailerNumber = row.find(".TrailerNumber").find(".label").html();
clear.CarrierName = row.find(".CarrierName").find(".label").html();
clear.LoadCommodityStatus = row.find(".LoadCommodityStatus").find(".label").html();
clear.DateLoaded = row.find(".DateLoaded").find(".label").html();
clear.PlantLocation = row.find(".PlantLocation").find(".label").html();
$.ajax({
type: "POST",
url: "/Home/ClearCustomer",
data: '{clear:' + JSON.stringify(clear) + '}',
contentType: "application/json; charset=utf-8",
dataType: "json"
}); setInterval('location.reload()', 500);
});
}
else {
confirm_value.value = "Cancel";
setInterval('location.reload()', 500);
}
document.forms[0].appendChild(confirm_value);
}
Confirm();
});
}
});
I am trying to create a system where it is possible to add/ change device configurations. The user should be able to add / delete rows at the same time.
Everytime a config is saved, a new config_id is created and VersionNr is increased.
I am 100% sure I am doing something wrong, and what is going wrong. But I dont know how to fix it or improve it.
Here is my code:
public ActionResult Edit(int? Id)
{
//create new list
var Device_Pricelist = new List<Device_Pricelist>(db.Device_Pricelist.Where(r => r.DeviceConfig.Device_config_id == Id));
//create new SelectList in Device_Pricelist
var SelectedCMI = (from d in db.pricelist
select new { d.Price_id, Value = d.bas_art_nr }).Distinct();
//call viewbag based on SelectedCMI query
ViewBag.SelectedCMI = new SelectList(SelectedCMI.Distinct(), "Price_id", "Value");
return View(Device_Pricelist);
}
public ActionResult Edit([Bind(Include = "id,Device_config_id,Price_id,amount,assembly_order")]DeviceConfig deviceConfig, List<Device_Pricelist> device_Pricelists)
{
if (ModelState.IsValid)
{
try
{
try
{
db.DeviceConfig.Add(deviceConfig).Device_config_id = deviceConfig.Device_config_id++;
db.DeviceConfig.Add(deviceConfig).device_type_id = deviceConfig.device_type_id = 13;
db.DeviceConfig.Add(deviceConfig).Active = true;
//Needs to be based on current VersionNr in deviceConfig
db.DeviceConfig.Add(deviceConfig).VersionNr = deviceConfig.VersionNr + 1;
db.DeviceConfig.Add(deviceConfig).Date = deviceConfig.Date = DateTime.Now;
}
finally
{
foreach (var item in device_Pricelists)
{
db.Entry(item).State = EntityState.Added;
}
}
db.SaveChanges();
TempData["SuccesMessage"] = "Data is Succesfully saved";
return RedirectToAction("Index");
}
catch
{
TempData["AlertMessage"] = "Saving Data Failed, " + "Try Again";
}
}
return View(device_Pricelists);
}
view:
#model List<ConcremoteDeviceManagment.Models.Device_Pricelist>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("Edit", "Home", FormMethod.Post))
{
<h1>
#Html.DisplayName("Edit Configuration")
</h1>
<h2>
#* #Html.DisplayFor(model => model.DeviceType.name)<br />*#dammit
</h2>
if (TempData["AlertMessage"] != null)
{
<p class="alert alert-danger" id="FailMessage">#TempData["AlertMessage"]</p>
}
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
<div>
#* Add New*#
</div>
<table class="table table-hover" id="dataTable">
<tr>
<th class="table-row">
#Html.DisplayName("BAS artikelnummer")
</th>
<th class="table-row">
#Html.DisplayName("Beschrijving")
</th>
<th class="table-row">
#Html.DisplayName("Aantal")
</th>
<th class="table-row">
#Html.DisplayName("Bouw Volgorde")
</th>
<th class="table-row">
Add New Row
</th>
</tr>
#if (Model != null && Model.Count > 0)
{
int j = 0;
foreach (var item in Model)
{
<tr>
#Html.HiddenFor(a => a[j].id)
#Html.HiddenFor(a => a[j].Device_config_id)
#* #Html.HiddenFor(a => a[j].Price_id)*#
<td class="table-row">
#Html.DropDownListFor(a => a[j].Price_id, (IEnumerable<SelectListItem>)ViewBag.SelectedCMI, null, new { #class = "form-control" })
</td>
<td class="table-row">
#Html.DisplayFor(a => a[j].Pricelist.description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].Pricelist.description, "", new { #class = "text-danger" })
</td>
<td class="table-row">
#Html.EditorFor(a => a[j].amount, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].amount, "", new { #class = "text-danger" })
</td>
<td class="table-row">
#Html.EditorFor(a => a[j].assembly_order, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(a => a[j].assembly_order, "", new { #class = "text-danger" })
</td>
#*<td class="table-row">
#Html.DisplayFor(a => a[j].DeviceConfig.Date, new { htmlAttributes = new { #class = "form-control" } })
</td>*#
<td>
#if (j > 0)
{
Remove
}
</td>
</tr>
j++;
}
}
</table>
<input type="submit" value="Save Device Data" class="btn btn-primary" />
<button onclick="location.href='#Url.Action("Index", "Home")';return false; " class="btn btn-primary">Back to list</button>
}
#section Scripts{
#*#Scripts.Render("~/bundles/jqueryval")*#
<script language="javascript">
$(document).ready(function () {
//1. Add new row
$("#addNew").click(function (e) {
e.preventDefault();
var $tableBody = $("#dataTable");
var $trLast = $tableBody.find("tr:last");
var $trNew = $trLast.clone();
var suffix = $trNew.find(':input:first').attr('name').match(/\j+/);
$trNew.find("td:last").html('Remove');
$.each($trNew.find(':input'), function (i, val) {
// Replaced Name
var oldN = $(this).attr('name');
var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']', '[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']', '[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']');
$(this).attr('name', newN);
//Replaced value
var type = $(this).attr('type');
//if (type.toLowerCase() == "text") {
// $(this).attr('value', '');
//}
// If you have another Type then replace with default value
$(this).removeClass("input-validation-error");
});
$trLast.after($trNew);
// Re-assign Validation
//var form = $("form")
// .removeData("validator")
// .removeData("unobtrusiveValidation");
//$.validator.unobtrusive.parse(form);
});
// 2. Remove
//$('a.remove').live("click", function (e) { --> this is for old jquery library
$('body').on("click", '#remove', function (e) {
e.preventDefault();
$(this).parent().parent().remove();
});
});
</script>
<script type="text/javascript">
function SelectedIndexChanged() {
//Form post
document.demoForm.submit();
}
</script>
I hope somebody is able to help me.
More information will be given when needed.
Your method accepts 2 parameters but you are only posting 1 object - List<Device_PriceList>. Let's assume you want to construct a new DeviceConfig based on the existing one, you should change your Action method to the following:
public ActionResult Edit(List<Device_Pricelist> device_Pricelists)
{
if (ModelState.IsValid)
{
try
{
var deviceConfig = db.DeviceConfig.Find(device_Pricelists.First().Device_config_id);
deviceConfig.device_type_id = 13;
deviceConfig.Active = true;
deviceConfig.VersionNr++;
deviceConfig.Date = DateTime.Now;
db.DeviceConfig.Add(deviceConfig);
foreach(var item in device_Pricelists)
{
item.Device_config_id = deviceConfig.Device_config_id;
}
db.Device_Pricelists.AddRange(device_Pricelists);
db.SaveChanges();
TempData["SuccesMessage"] = "Data is Succesfully saved";
return RedirectToAction("Index");
}
catch
{
TempData["AlertMessage"] = "Saving Data Failed, Try Again";
}
}
return View(device_Pricelists);
}
Remember when posting a list, you need to post complete sets of the object you're trying to map to. That is for example [0].Id, [0].Device_config_id (etc), [1].Id, [1].Device_config_id (etc).
Your JS doesn't seem correct, particularly the .replace(..) call with 6 parameters, so you're probably seeing lots of [0]s when you clone the rows. Some simpler JS that will get you the same result is:
var oldN = $(this).attr('name');
var idx = parseInt(oldN.substr(1, oldN.indexOf(']')));
var newN = oldN.replace('[' + idx + ']', '[' + (idx + 1) + ']');
I'm building a fairly standard razor/c# page for an internal website. Its basically a wrapper around a query that provides valid arguments for a db query.
The page is generating an error in Asp_Web_?????.cshtml when built. For the life of me I cannot find the error. Included below is the source of the page
#{
Layout = "~/_SiteLayout.cshtml";
Page.Title = "ABC Floor Limits";
}
<hgroup class="title">
<h1>#Page.Title.</h1>
<h2>Adjust.</h2>
</hgroup>
#{
var DbCustom = Database.Open("Online_Ctrack6_Custom");
var DbCustLogs = Database.Open("Online_CustLogs");
int vehicleId = -1;
string currentAction;
if(IsPost)
{
vehicleId = Request.Form["vehicleId"].AsInt();
string applianceName = Request.Form["applianceName"];
int floorHours = Request.Form["hours"].AsInt();
DateTime? dateToParse;
DateTime dateTaken;
string result = "";
if (string.IsNullOrEmpty(Request.Form["dateTaken"]) == false)
{
var dtValue = new DateTime();
if (DateTime.TryParse(Request.Form["dateTaken"], out dtValue))
{
dateToParse = dtValue;
}
else
{
dateToParse = null;
}
}
else
{
dateToParse = null;
}
currentAction = Request.Form["action"];
if (currentAction == "updateHours")
{
try
{
dateTaken = (DateTime)dateToParse;
result = doProcessHoursForm(DbCustLogs, vehicleId, applianceName, dateTaken, floorHours);
}
catch (InvalidDataException ex)
{
#:<div class="error">#ex.Message</div>
}
catch (ArgumentNullException ex)
{
#:<div class="error">#ex.ParamName cannot be null.<br />#ex.Message #ex.ParamName</div>
}
finally
{
#:<div class="result">#result</div>
}
}
}
List<SelectListItem> listVehicles = null;
try
{
listVehicles = doCreateVehicleList(DbCustom, vehicleId);
}
catch (Exception ex)
{
#:<div class="error">#ex.Message<br />#ex.InnerException.Message</div>
}
string floorSql = "SELECT [NodeId],[PrimaryPropertyValue],[ID],[PumpADurationSec],[PumpAFloorSec],[PumpAFloorDate],[PumpATotalSec],[PumpBDurationSec],[PumpBFloorSec],[PumpBFloorDate],[PumpBTotalSec],[VacuumDurationSec],[VacuumFloorSec],[VacuumFloorDate],[VacuumTotalSec] FROM [Ctrack6_Custom].[dbo].[vwVeoliaRunningTotals] ORDER BY [Id]";
var floorGrid = new WebGrid(source: DbCustom.Query(floorSql), canPage: false, ajaxUpdateContainerId: "floorGrid");
}
<div class="section">
<h3>Current Floor Values</h3>
<p>This table lists the current floor values for ABC . The values are saved internally as a number of seconds.</p>
#floorGrid.GetHtml(
tableStyle: "VeoliaFloorTable",
headerStyle: "columnHead",
alternatingRowStyle: "altRow",
columns: floorGrid.Columns(
floorGrid.Column(columnName: "NodeId", header: #Functions.Sorter("NodeId", "Node Id", floorGrid)),
floorGrid.Column(columnName: "Id", header: #Functions.Sorter("Id", "Vehicle", floorGrid)),
floorGrid.Column(columnName: "PumpAFloorSec", header: #Functions.Sorter("PumpAFloorSec", "Pump A Floor Sec", floorGrid), style: "alignRight"),
floorGrid.Column(columnName: "PumpAFloorDate", header: #Functions.Sorter("PumpAFloorDate", "Pump A Floor Date", floorGrid), style: "nowrap"),
floorGrid.Column(columnName: "PumpBFloorSec", header: #Functions.Sorter("PumpBFloorSec", "Pump B Floor Sec", floorGrid), style: "alignRight"),
floorGrid.Column(columnName: "PumpBFloorDate", header: #Functions.Sorter("PumpBFloorDate", "Pump B Floor Date", floorGrid), style: "nowrap"),
floorGrid.Column(columnName: "VacuumFloorSec", header: #Functions.Sorter("VacuumFloorSec", "Vacuum Floor Sec", floorGrid), style: "alignRight"),
floorGrid.Column(columnName: "VacuumFloorDate", header: #Functions.Sorter("VacuumFloorDate", "Vacuum Floor Date", floorGrid), style: "nowrap")
)
);
</div>
<div class="section">
<h3>Update Floor Limits</h3>
<p>This form allows you to update the floor limit specified for an appliance mounted on a vehicle.</p>
<form method="post">
<input type="hidden" name="username" value="#WebSecurity.CurrentUserName" />
<input type="hidden" name="action" value="updateHours" />
<label for="selectVehicleControl">Choose Geozone:</label>
#Html.DropDownList("vehicleId", listVehicles)
<label for="selectApplianceControl">Choose Appliance:</label>
<select name="applianceName" id="selectApplianceControl">
<option value="-1">Choose an Appliance</option>
<option value="Pump A">Pump A</option>
<option value="Pump B">Pump B</option>
<option value="Vacuum">Vacuum</option>
</select>
<label for="inputHoursText">Hour Reading:</label>
<input name="hours" type="number" id="inputHoursText" min="0" max="9999999" size="7" required="required" />
<span style="font-size:small">This will be converted into seconds</span>
<br />
<label for="dateTakenControl">Date Taken:</label>
<input name="dateTaken" class="datetimefield" type="datetime" id="dateTakenControl" maxlength="19" required="required" />
<br />
<input type="submit" value="Update Hour Reading" />
</form>
</div>
#{
public string doProcessHoursForm(Database DbCustLogs, int vehicleId, string applianceName, DateTime dateTaken, int floorHours)
{
int floorSeconds = floorHours * 3600;
string sqlHoursUpdate = "exec sp_Veolia_update_floor_limit #0, #1, #2, #3";
if(vehicleId != null && applianceName != null && dateTaken != null && floorSeconds != null)
{
var result = DbCustLogs.Execute(sqlHoursUpdate, vehicleId, applianceName, dateTaken.ToString("yyyy-MM-dd HH:mm:ss"), floorSeconds);
if ( result != 1)
{
throw new InvalidDataException("Operation should only affect one record");
}
else
{
return result + " row(s) changed";
}
}
else
{
string nullArg = "";
if (vehicleId == null) { nullArg += "vehicleId,";}
if (applianceName == null) { nullArg += "applianceName,"; }
if (dateTaken == null) { nullArg += "dateTaken,"; }
if (floorSeconds == null) { nullArg += "floorSeconds,"; }
if (nullArg.Length > 1) { nullArg = nullArg.TrimEnd(','); }
throw new ArgumentNullException(nullArg, "Argument cannot be null");
}
return "An error ocured";
}
public List<SelectListItem> doCreateVehicleList(Database db, int vehicleId)
{
var sqlVehicles = "SELECT NodeId, Id as VehicleName FROM vwVeoliaNodes ORDER BY Id";
List<SelectListItem> listTemp = new List<SelectListItem>();
listTemp.Add(new SelectListItem
{
Text = "Select a Vehicle",
Value = "-1",
Selected = false
});
try
{
foreach (var item in db.Query(sqlVehicles))
{
if (item.NodeId == vehicleId)
{
listTemp.Add(new SelectListItem
{
Text = item.VehicleName,
Value = item.NodeId.ToString(),
Selected = true
});
}
else
{
listTemp.Add(new SelectListItem
{
Text = item.VehicleName,
Value = item.NodeId.ToString(),
Selected = false
});
}
}
}
catch (Exception ex)
{
throw new Exception("Exception occurred building Vehicle List", ex);
}
return listTemp;
}
}
The error details follow:
Error No: 1
Error Message: } expected
File: c:\Users\Lukem\AppData\Local\Temp\Temporary ASP.NET Files\root\53d555f7\b262e6b6\App_Web_abcfloor.cshtml.cdcab7d2.abupdzvs.0.cs
Line: 760
The error in the tempfile is the EndContext reference:
BeginContext("~/VeoliaFloor.cshtml", 5970, 36, true);
WriteLiteral(" />\r\n </form>\r\n </div>\r\n\r\n");
EndContext("~/VeoliaFloor.cshtml", 5970, 36, true);
I've installed a colour matching {} tool to help. There seem to be no problems in the page, only when compiled to the temp file. This is driving me mad.
It is because you are missing the #functions keyword in the section where you are declaring the methods.
This is how i am loading on page load state and city dropdown:
My Controller method:
This is the first method which is calling when page is loaded.
public ActionResult Index()
{
var states = GetStates();
var cities = Enumerable.Empty<SelectListItem>();
ViewBag.States = states;
ViewBag.Cities = cities;
}
private IEnumerable<SelectListItem> GetStates()
{
using (var db = new DataEntities())
{
return db.States.Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() });
}
}
[HttpGet]
public ActionResult GetCities(int id)
{
using (var db = new DataEntities())
{
var data = db.Cities.Where(d=>d.StateId==id).Select(d => new { Text = d.CityName, Value = d.Id }).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
}
My View:
IEnumerable<SelectListItem> States = ViewBag.States;
IEnumerable<SelectListItem> Cities = ViewBag.Cities;
#Html.DropDownList("State", States, "Select State", new { onchange="loadCities(this)"})
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity"})
function loadCities(obj) {
$.ajax({
url: "/Home/GetCities",
data: { id: $(obj).val() },
contentType:"application/json",
success:function(responce){
var html = '<option value="0">Select City</option>';
$(responce).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
}
});
}
Any better way then this to load state and city dropdown?
public class HomeController : Controller
{
public ActionResult Index(int id=0)
{
Person model = null;
var states = GetStates().ToList();
var cities = Enumerable.Empty<SelectListItem>();
if (id > 0)
{
using (var db = new DataEntities())
{
model = db.People.Include("City").FirstOrDefault(d => d.Id == id);
if (model == null)
model = new Person();
else
{
states.First(d => d.Value == model.City.StateId.ToString()).Selected = true;
cities = db.Cities.Where(d => d.StateId == model.City.StateId).ToList().Select(d => new SelectListItem { Text = d.CityName,Value=d.Id.ToString(),Selected=d.Id==model.CityId });
}
}
}
else
{
model = new Person();
}
ViewBag.States = states;
ViewBag.Cities = cities;
ViewBag.Persons = GetPersons();
return View(model);
}
[HttpGet]
public ActionResult GetCities(int id)
{
using (var db = new DataEntities())
{
var data = db.Cities.Where(d=>d.StateId==id).Select(d => new { Text = d.CityName, Value = d.Id }).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
}
public ActionResult SavePersonDetail([Bind(Exclude = "Id")] Person model)
{
// var employeeDal= new Emploee();
//employee.firstname=model.
if (ModelState.IsValid)
{
var Id = model.Id;
int.TryParse(Request["Id"], out Id);
using (var db = new DataEntities())
{
if (Id > 0)
{
var person = db.People.FirstOrDefault(d => d.Id == Id);
if (person != null)
{
model.Id = Id;
db.People.ApplyCurrentValues(model);
}
}
else
{
db.People.AddObject(model);
}
db.SaveChanges();
}
}
if (!Request.IsAjaxRequest())
{
ViewBag.States = GetStates();
ViewBag.Persons = GetPersons();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
return View("Index");
}
else
{
return PartialView("_personDetail",GetPersons());
}
}
public ActionResult Delete(int id)
{
using (var db = new DataEntities())
{
var model = db.People.FirstOrDefault(d => d.Id == id);
if (model != null)
{
db.People.DeleteObject(model);
db.SaveChanges();
}
}
if (Request.IsAjaxRequest())
{
return Content(id.ToString());
}
else
{
ViewBag.States = GetStates();
ViewBag.Persons = GetPersons();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
return View("Index");
}
}
private IEnumerable<SelectListItem> GetStates()
{
using (var db = new DataEntities())
{
return db.States.ToList().Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() });
}
}
private IEnumerable<Person> GetPersons()
{
using (var db = new DataEntities())
{
return db.People.Include("City").Include("City.State").ToList();
}
}
public ActionResult HomeAjax()
{
ViewBag.States = GetStates();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
using (var db = new DataEntities())
{
var data = db.States.Include("Cities").Select(d => new { Id = d.Id, Name = d.StateName, Cities = d.Cities.Select(x => new { Id=x.Id,Name=x.CityName}) }).ToList();
ViewBag.CityStateJson = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(data);
}
ViewBag.Persons = GetPersons();
return View();
}
}
#model IEnumerable<Person>
<div>
<table>
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Email
</th>
<th>
City
</th>
<th>
State
</th>
<th>
Edit
</th>
</tr>
#if (Model.Count() == 0)
{
<tr>
<td colspan="6">
<h3>No data available</h3>
</td>
</tr>
}
else {
foreach (var item in Model) {
<tr data-id="#item.Id">
<td data-id="fn">#item.FirstName</td>
<td data-id="ln">#item.LastName</td>
<td data-id="email">#item.Email</td>
<td data-id="cn">#item.CityName<input type="hidden" value="#item.CityId" /></td>
<td>#item.StateName</td>
<td>
#if (ViewBag.Title == "Home Ajax" || Request.IsAjaxRequest())
{
Update
<span>#Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {OnSuccess="deleteSuccess",OnBegin="showLoader",OnComplete="hideLoader" })</span>
}
else {
<span>#Html.ActionLink("Update", "Index", new { id = item.Id })</span>
<span>#Html.ActionLink("Delete", "Delete", new { id = item.Id })</span>
}
</td>
</tr>
}
}
</table>
</div>
#model Person
#{
ViewBag.Title = "Home Ajax";
IEnumerable<Person> persons = ViewBag.Persons;
IEnumerable<SelectListItem> States = ViewBag.States;
IEnumerable<SelectListItem> Cities = ViewBag.Cities;
IEnumerable<State> fullStates=ViewBag.CityStates;
}
#section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
</hgroup>
</div>
</section>
}
#section styles{
<style type="text/css">
td,th {
border:1px solid;
padding:5px 10px;
}
select {
padding:5px 2px;
width:310px;
font-size:16px;
}
</style>
}
#section scripts{
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
var jsonArray = #Html.Raw(ViewBag.CityStateJson)
function clearValues() {
$("input[type='text'],select").val('');
$("input[type='hidden'][name='Id']").val(0);
}
function loadCities(obj) {
for (var i = 0; i < jsonArray.length; i++) {
if (jsonArray[i].Id == parseInt($(obj).val())) {
fillCity(jsonArray[i].Cities);
break;
}
}
}
function Edit(obj, Id) {
// alert("hi")
$("input[type='hidden'][name='Id']").val(Id);
var tr = $(obj).closest("tr");
$("#txtfirstName").val($("td[data-id='fn']", tr).text().trim());
$("#txtlastName").val($("td[data-id='ln']", tr).text().trim());
$("#txtemail").val($("td[data-id='email']", tr).text().trim());
var city = $("td[data-id='cn'] input[type='hidden']", tr).val();
var state;
for (var i = 0; i < jsonArray.length; i++) {
for (var j = 0; j < jsonArray[i].Cities.length; j++) {
if (jsonArray[i].Cities[j].Id == parseInt(city)) {
state = jsonArray[i].Id;
break;
}
}
if (state) {
fillCity(jsonArray[i].Cities);
break;
}
}
$("#ddlState").val(state);
$("#ddlCity").val(city);
}
function fillCity(obj) {
var html = '<option value="0">Select City</option>';
$(obj).each(function () {
html += '<option value="' + this.Id + '">' + this.Name + '</option>'
});
$("#ddlCity").html(html);
}
function deleteSuccess(responce) {
alert("record deleted successfully");
$("tr[data-id='" + responce + "']").remove();
}
function insertSuccess() {
alert("Record saved successfully");
clearValues();
}
function showLoader() {
$("#overlay").show();
}
function hideLoader() {
$("#overlay").hide();
}
</script>
}
<h3>Add Personal Detail</h3>
#using (Ajax.BeginForm("SavePersonDetail", "Home", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "personList" ,OnSuccess="insertSuccess",OnBegin="showLoader",OnComplete="hideLoader"}))
{
#Html.HiddenFor(m => m.Id);
<ol class="round">
<li>
#Html.LabelFor(m => m.FirstName)
#Html.TextBoxFor(m => m.FirstName, new { id = "txtfirstName" })
#Html.ValidationMessageFor(m => m.FirstName)
</li>
<li>
#Html.LabelFor(m => m.LastName)
#Html.TextBoxFor(m => m.LastName, new { id = "txtlastName" })
#Html.ValidationMessageFor(m => m.LastName)
</li>
<li>
#Html.LabelFor(m => m.Email)
#Html.TextBoxFor(m => m.Email, new { id = "txtemail" })
#Html.ValidationMessageFor(m => m.Email)
</li>
<li>
#Html.Label("State")
#Html.DropDownList("State", States, "Select State", new { onchange = "loadCities(this)", id = "ddlState" })
</li>
<li>
#Html.LabelFor(m => m.CityId)
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id = "ddlCity" })
#Html.ValidationMessageFor(m => m.CityId)
</li>
</ol>
<input type="submit" value="Save" />
<input type="button" value="Cancel" onclick="clearValues();"/>
}
<h2>
Person List
</h2>
<div style="position:fixed;text-align:center;top:0;bottom:0;left:0;right:0;z-index:10;background-color:black;opacity:0.6;display:none;" id="overlay">
<img style="position:relative;top:370px" src="~/Images/ajax-loader.gif" />
</div>
<div id="personList">
#Html.Partial("_personDetail", persons)
</div>
You approach using ajax is fine although I would recommend a few better practices including using a view model with properties for StateID, CityID StateList and CityList, and using Unobtrusive JavaScript rather than polluting you markup with behavior, and generating the first ("please select") option with a null value rather than 0 so it can be used with the [Required] attribute
HTML
#Html.DropDownList(m => m.StateID, States, "Select State") // remove the onchange
#Html.DropDownListFor(m => m.CityID, Cities, "Select City") // why change the default ID?
SCRIPT
var url = '#Url.Action("GetCities", "Home")'; // use the helper (dont hard code)
var cities = $('#CityID'); // cache the element
$('#StateID').change(function() {
$.getJSON(url, { id: $(this).val() }, function(response) {
// clear and add default (null) option
cities.empty().append($('<option></option>').val('').text('Please select'));
$.each(response, function(index, item) {
cities.append($('<option></option>').val(item.Value).text(item.Text));
});
});
});
If you were rendering multiple items (say you were asking the user to select their last 10 cities they visited), you can cache the result of the first call to avoid repeated calls where their selections may include cities from the same state.
var cache = {};
$('#StateID').change(function() {
var selectedState = $(this).val();
if (cache[selectedState]) {
// render the options from the cache
} else {
$.getJSON(url, { id: selectedState }, function(response) {
// add to cache
cache[selectedState] = response;
.....
});
}
});
Finally, in response to your comments regarding doing it without ajax, you can pass all the cities to the view and assign them to a javascript array. I would only recommend this if you have a few countries, each with a few cities. Its a matter of balancing the slight extra initial load time vs the slight delay in making the ajax call.
In the controller
model.CityList = db.Cities.Select(d => new { City = d.CountryID, Text = d.CityName, Value = d.Id }).ToList();
In the view (script)
// assign all cities to javascript array
var allCities= JSON.parse('#Html.Raw(Json.Encode(Model.CityList))');
$('#StateID').change(function() {
var selectedState = $(this).val();
var cities = $.grep(allCities, function(item, index) {
return item.CountryID == selectedState;
});
// build options based on value of cities
});
This is a correct approach, but you can simplify your javascript:
function loadCities(obj) {
$.getJSON("/Home/GetCities", function (data) {
var html = '<option value="0">Select City</option>';
$(data).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
});
}
Further possible simplification:
Add the default item (Select City) server-side, so your javascript will be smaller.
Here's how I'd do it without the page refresh, assuming the list of cities isn't too long.
I'm assuming you can create a GetStatesAndCities method to return a Dictionary.
public ActionResult Index()
{
Dictionary<string, List<String>> statesAndCities = GetStatesAndCities();
ViewBag.StatesAndCities = Json(statesAndCities);
}
Then in the view:
var states = JSON.parse(#ViewBag.StatesAndCities);
function loadCities(obj) {
var cities = states[$(obj).val()];
var html = '<option value="0">Select City</option>';
$(cities).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
}
This way when the state is changed the cities field with update immediately with no need for callback.
disclaimer: This is not a code answer, there are plenty other answers.
I think best way to keep yourself happy to seperate UI pages from data => turn them into API calls:
/GetCities
/GetStates
Now you can simply leave the select's empty on Razor rendering the page. And use a Jquery/Bootstrap plugin to create an AJAX select box.
This way when the user stops typing his search, this search string can than be send with the AJAX call (eg: /GetStates?search=test) and then a small result set can be send back to the website.
This gives:
Better separation in serveside code
Better User eXperience.
Smaller page loads (since you no longer send all the options to user when he requests the page, only when he opens the select box).
How about using Knockout?
Knockout is a JavaScript library that helps you to create rich, responsive display and editor user interfaces with a clean underlying data model
You have to use ajax for your cities. But with knockout you dont need to write
var html = '<option value="0">Select City</option>';
$(responce).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'});
$("#ddlCity").html(html);
in your javascript.Knockout makes it simple.
You can simply write:
function CityModel() {
var self = this; // that means this CityModel
self.cities = ko.observableArray([]);
self.getCities = function () {
$.ajax({
url: "/Home/GetCities",
data: { id: $(obj).val() },
contentType: "application/json",
success: self.cities
});
}
}
ko.applyBindings(new CityModel());
thats all. But you have to bind your data into html elements.
Instead of using :
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity"})
You can use:
<select data-bind="options:cities,optionsValue:"Id",optionsText:"CityName",optionsCaption:"Select City""></select>
or you can mix razor and knockout:
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity",data_bind:"options:cities,optionsValue:\"Id\",optionsText:\"CityName\""})
One more thing you have to call GetCities when State changes, you can :
#Html.DropDownList("State", States, "Select State", new {data_bind:"event:\"change\":\"$root.GetCities\""})
Dont be scare with \"\" things this because " is an escape character and we have to say to razor i want to use " by using \ before it.
You can find more info about knockout :Knockout
And mixing with razor: Razor and Knockout
Ps: yes using knockout is suspend us from Razor and Mvc. You have to write another ViewModel . But like this situations ko is helpful. Mixing razor and knockout is another option for you.
I am trying to return a multi dimension list from controller to view.
I have a
Model
ViewModel
View
Controller
ViewModel:
public class HomeViewModel
{
public DateTime Date { get; set; }
public List<Snapshot> SnapshotItems { get; set; }
}
View:
#model IEnumerable<myproject.ViewModels.HomeViewModel>
<div class="pi-section pi-padding-top-20 pi-padding-bottom-10">
#foreach (var items in Model)
{
<div class="pi-container">
<div class="pi-col-lg-12">
#items.Date.ToString("MMM, dd, 2014")
</div>
</div>
<div class="pi-container">
#foreach (var item in items.SnapshotItems)
{
<div class="item pi-col-lg-4">
<div class="">#Html.ActionLink(item.BrandName, "Index", "Brand", new { guid = item.BrandGuid, brandName = FriendlyUrl.Convert((item.BrandName).ToString()) }, null)</div>
<div class="snapshot-photo-home">
<a class="image_rollover_bottom con_borderImage" data-description="ZOOM IN" href="#Url.Action("html", "snapshot" , new { guid = item.Guid })" target="_blank">
<img class="lazyload" src="#item.Thumbnail" width="300" />
</a>
</div>
<span class="home-subject">#item.Subject</span>
<div class="snapshot-action">
</div>
</div>
}
</div>
}
</div>
Controller:
public PartialViewResult RecentEmails()
{
int days = 2;
HomeViewModel viewModel = new HomeViewModel();
List<Snapshot> snapshots = new List<Snapshot>();
List<HomeViewModel> viewModelList = new List<HomeViewModel>();
for (int count = 0; count < days; count++)
{
viewModel.Date = DateTime.Now.AddDays(count * (-1));
snapshots = GetEmailSnapshot(9, viewModel.Date);
viewModel.SnapshotItems = snapshots;
}
viewModelList.Add(viewModel);
return PartialView(viewModelList.AsEnumerable());
}
private List<Snapshot> GetEmailSnapshot(int numSnapshots, DateTime dateReceived)
{
List<Snapshot> snapshots = new List<Snapshot>();
string dbConnString = WebConfigurationManager.ConnectionStrings["dbConn"].ConnectionString;
MySqlConnection dbConn = new MySqlConnection(dbConnString);
dbConn.Open();
MySqlCommand dbCmd = new MySqlCommand();
string date = dateReceived.ToString("yyyy/MM/dd");
dbCmd.CommandText = "SELECT a.snapshot_id, a.subject, a.snapshot_guid, a.date_sent, a.image, a.thumbnail, a.status, b.name, b.brand_guid FROM snapshots a INNER JOIN brands b ON a.brand_id = b.brand_id WHERE status = 1 AND a.archive = 0 AND (thumbnail IS NOT NULL OR thumbnail = '') AND DATE(date_sent) = '" + date + "' GROUP BY a.brand_id ORDER BY date_sent DESC LIMIT " + numSnapshots;
dbCmd.Connection = dbConn;
MySqlDataReader dbResult = dbCmd.ExecuteReader();
while (dbResult.Read())
{
snapshots.Add(new Snapshot
{
SnapshotId = Convert.ToInt32(dbResult["snapshot_id"]),
Guid = dbResult["snapshot_guid"].ToString().Replace("-", String.Empty),
BrandGuid = dbResult["brand_guid"].ToString(),
BrandName = HttpUtility.HtmlDecode(dbResult["name"].ToString()),
Subject = MyHelpers.Ellipsis(HttpUtility.HtmlDecode(dbResult["subject"].ToString()), 100),
DateTimeSent = Convert.ToDateTime(dbResult["date_sent"]),
Image = dbResult["image"].ToString(),
Status = Convert.ToInt32(dbResult["status"]),
Thumbnail = dbResult["thumbnail"].ToString()
});
}
dbResult.Close();
dbCmd.Dispose();
dbConn.Close();
return snapshots;
}
The problem I am having is that on the VIEW. It is returning the same dataset from GetEmailSnapshot. SO I am seeing the SAME 9 records from 8/10/2014 as an example.
Is there a reason why 8/10/2014 isn't being added to the list and then 8/9/2014 added in addition to the list?
I think I may have overcomplicated it. Here is the simplified version: FIXED
public PartialViewResult RecentEmails()
{
int days = 2;
List<HomeViewModel> viewModelList = new List<HomeViewModel>();
for (int count = 0; count < days; count++)
{
DateTime date = DateTime.Now.AddDays(count * (-1));
viewModelList.Add(new HomeViewModel
{
Date = date,
SnapshotItems = GetEmailSnapshot(9, date)
});
}
return PartialView(viewModelList.AsEnumerable());
}