Here are my model classes:
public class SensorTest
{
public int SerialNo { get; set; }
public string SensorName { get; set; }
public string TestName { get; set; }
public List<string> ImpactSide { get; set; }
}
public class SensorTestsViewModel
{
public List<SensorTest> SensorTestList { get; set; }
}
Controller action methods:
GET:
[HttpGet]
public ActionResult SensorTests()
{
SensorTestsViewModel obj = new SensorTestsViewModel();
obj.SensorTestList = new List<SensorTest>();
SensorTest sensortest;
sensortest = new SensorTest();
sensortest.SerialNo = 1;
sensortest.SensorName = "FLAT 13 KMH";
sensortest.TestName = "";
obj.SensorTestList.Add(sensortest);
sensortest = new SensorTest();
sensortest.SerialNo = 1;
sensortest.SensorName = "CURB IMPACT 40KMH";
sensortest.TestName = "";
obj.SensorTestList.Add(sensortest);
return View(obj);
}
POST:
[HttpPost]
[ActionName("SensorTests")]
public ActionResult SensorTests_Post(SensorTestsViewModel sensortests)
{
//SensorTestsViewModel model = new SensorTestsViewModel();
//UpdateModel(model);
return View(sensortests);
}
View code:
#model Safety.Models.SensorTestsViewModel
#using (Html.BeginForm("SensorTests", "Safety"))
{
var grid = new WebGrid(Model.SensorTestList, canSort: false, canPage: false);
int rowNum = 0;
<div>
#grid.GetHtml(columns:
grid.Columns
(
grid.Column("SerialNo", format: item => rowNum = rowNum + 1),
grid.Column("SensorName"),
grid.Column("TestName", format: (item) => Html.TextBox("TestName[" + (rowNum - 1).ToString() + "].TestName", (object)item.TestName))
), mode: WebGridPagerModes.Numeric)
</div>
<input type="submit" value="Submit" />
}
See the Viewmodel is null during POST. I have tried UpdateModel as well. My requirement is I need to post whole viewmodel data to controller and do the necessary actions from there. Not sure what I am missing? Can someone Please suggest?
First, take a look at this example: post items of webgrid asp.net mvc3
Try making the textbox name like this: "SensorTestList[someIndexHere].SensorName"
Related
Sorry if I am missing something obvious as I am new to ASP.NET MVC.
As shown in the code sample below, I have Kendo Textbox and Multiselect controls inside a partial view. When "change" event of Textbox is fired I am posting the form and trying to Rebind Kendo Multiselect control to Model.
Multiselect control binds to the Model on the intial load but after the ajax call it does not rebind/refresh to reflect the changes in the model.
Can anybody help with where I might be going wrong?
Please see code sample below:
Index.cshtml:
#model MVCTest20.Models.Config
#{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript">
jQuery(function ($) {
$('#SalesOrder').on("change", function () {
$.ajax({
url: '/Home/Index',
data: $('#form').serialize(),
type: 'POST'
});
});
});
</script>
<form>
#{Html.RenderPartial("_SOLookup", Model);}
</form>
_SOLookup.cshtml
<p><strong>Sales Order / Project</strong></p>
#(Html.Kendo().TextBox()
.Name("SalesOrder")) <div id="sales-order-arrow" class="help_arrow"></div>
<p><strong>Line Item</strong></p>
#(Html.Kendo().MultiSelect()
.Name("LineItems")
.Placeholder("Select Line(s)")
.HtmlAttributes(new {#class= "cb-create-control" })
.DataTextField("Name")
.DataValueField("Id")
.AutoBind(true)
.BindTo(Model.LineItemCollection))
HomeController:
public class HomeController : Controller
{
private static Config config;
public ActionResult Index()
{
if (config == null)
{
config = new Config();
}
config.LineItemCollection = new LineItem[]
{
new LineItem {Name = "500.1 - FAS8060AE - 001 - R6", Id = "700"}
}.ToList();
return View(config);
}
[HttpPost]
public ActionResult Index(Config data)
{
data.LineItemCollection = new LineItem[]
{
new LineItem {Name = "1.1 - FAS8060AE - 001 - R6", Id = "100"},
new LineItem {Name = "3.1 - FAS8060AE - 001 - R6", Id = "200"},
new LineItem {Name = "6.1 - FAS8060AE - 001 - R6", Id = "300"}
}.ToList();
return View(data);
}
Model:
public class Config
{
public Config()
{
LineItemCollection = new List<LineItem>();
}
private string _salesorder;
public string SalesOrder
{
get
{
return _salesorder;
}
set
{
_salesorder = value;
}
}
public string LineItems { get; set; }
public List<LineItem> LineItemCollection { get; set; }
}
public class LineItem
{
public string Id { get; set; }
public string Name { get; set; }
}
I am trying to implement a search panel with several checkbox to filter a table data, but i have a problem. I cant retain value of input checked after submit.
How can I solve?
My model :
public class OrdineView
{
public int anno { get; set; }
public Int32 nrOrdine { get; set; }
public string centro { get; set; }
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:d}")]
public DateTime? data { get; set; }
public String codice { get; set; }
public String ragsoc { get; set; }
[DisplayFormat(DataFormatString = "{0:C}")]
public Nullable<double> importo;
}
I have a Search model:
public class OrdiniSearchModel
{
public int? anno {get;set;}
public String[] Distinzione {get;set;}
}
public class OrdiniBusinessLogic
{
private NORTHWNDEntities1 db;
public OrdiniBusinessLogic()
{
db = new NORTHWNDEntities1();
}
public IQueryable<OrdineView> GetOrdini(OrdiniSearchModel ordiniSearch)
{
var queryOrdineView = (from ordine in db.ORDINI
join cliente in db.CLIENTI on ordine.Codcli equals cliente.Codana
select new OrdineView
{
anno = ordine.Anno,
nrOrdine = ordine.Numord,
centro = ordine.Codcen,
data = ordine.Datord,
codice = ordine.Codcli,
ragsoc = cliente.Ragso1,
importo = ordine.Totord
}).ToList().AsQueryable();
var model = queryOrdineView;
if (ordiniSearch.anno != null)
{
model = model.Where(o => o.anno == ordiniSearch.anno);
}
if (ordiniSearch.Distinzione != null && ordiniSearch.distinzione.Count() > 0)
{
List<string> distinzioniSelezionate = new List<string>();
foreach (var item in ordiniSearch.Distinzione)
{
distinzioniSelezionate.Add(item);
}
model = model.Where(o => distinzioniSelezionate.Contains(o.distinzione));
}
return model;
}
}
My Controller:
public ActionResult Index(OrdiniSearchModel searchModel, int? pageNumber )
{
ViewBag.Anno = db.ORDINI.Select(o => new { o.Anno }).Distinct().OrderByDescending(o => o.Anno).Select(o => o.Anno);
var searchLogic = new OrdiniBusinessLogic();
var model = searchLogic.GetOrdini(searchModel);
return View(model.OrderBy(i => i.codice).ToPagedList(pageNumber ?? 1, 10));
}
In my view I have
<input name="Distinzione" type="checkbox" value="001">001
<input name="Distinzione" type="checkbox" value="002">002
...and so on
After submit I get data correctly but lose checked state.
UPDATE: Based on the comments, I updated the view and adde more code.
If you mean that the checkboxes don't stay checked after the page is refreshed. It's because you don't tell them which should be checked. There is one possible solution for you. Create a simple helper method right in the view where you need the checkboxes. This method just checks the array of values and if it finds the value there, it will render a checkbox with checked state.
View.cshtml
#model OrdinePagedList
#MyCheckbox("001")
#MyCheckbox("002")
#helper MyCheckbox(string value)
{
if (Model.Distinzione.Contains(value))
{
<input type="checkbox" name="Distinzione" value="#value" checked="checked"/>
}
else
{
<input type="checkbox" name="Distinzione" value="#value" />
}
#value
}
I suggest to create a new view model class:
public class OrdinePagedList
{
public IEnumerable<OrdiniView> Pages { get; set; }
public IEnumerable<string> Distinzione { get; set;
}
And update either your business logic so that it returns this new class
// from
public IQueryable<OrdineView> GetOrdini(OrdiniSearchModel ordiniSearch)
// to
public OrdinePagedList GetOrdini(OrdiniSearchModel ordiniSearch)
or update the controller:
public ActionResult Index(OrdiniSearchModel searchModel, int? pageNumber )
{
ViewBag.Anno = db.ORDINI.Select(o => new { o.Anno }).Distinct().OrderByDescending(o => o.Anno).Select(o => o.Anno);
var searchLogic = new OrdiniBusinessLogic();
var pages = searchLogic.GetOrdini(searchModel);
OrdinePagedList model = new OrdiniPagedList {
Pages = pages.OrderBy(i => i.codice).ToPagedList(pageNumber ?? 1, 10),
Distinzione = searchModel.Distinzione
}
return View(model);
}
or if you don't want (or can't) create the new view model (but I strongly recommend to do so). You can use ViewBag to pass the additinal collection of checked values:
public ActionResult Index(OrdiniSearchModel searchModel, int? pageNumber)
{
ViewBag.Distinzione = searchModel.Distinzione;
// original code
}
and then you'll just have to update the helper method. For the sake of simplicity I don't check if the ViewBag.Distinzione exists. But you should.
#helper MyCheckbox(string value)
{
if (ViewBag.Distinzione.Contains(value))
{
<input type="checkbox" name="Distinzione" value="#value" checked="checked"/>
}
else
{
<input type="checkbox" name="Distinzione" value="#value" />
}
#value
}
In short. You need to make sure that the data (collection of checked values), you get in controller, are being sent back to the view.
List<string> distinzioniSelezionate = new List<string>();
if (searchModel.distinzione != null && searchModel.distinzione.Count() > 0)
{
foreach (var item in searchModel.distinzione)
{
distinzioniSelezionate.Add(item);
}
}
OrdinePagedList model = new OrdinePagedList
{
Pages = pages.OrderBy(i => i.Codice).ToPagedList(pageNumber ?? 1, 10),
Distinzione = distinzioniSelezionate
};
I had to modify the ActionResult because Distinzione is not empty
i want to develop some opinion poll type mvc application..so far i create my view model
public class SurveyCommonViewModel
{
public List<SurveyQuestionViewModel> Questions { get; set; }
public List<QuestionOption> Options { get; set; }
}
public class SurveyQuestionViewModel
{
public int QuestionId { get; set; }
public String QuestionText{get;set;}
public int QuestionResultId { get; set; }
}
public class QuestionOption
{
public int QuestionOptionId { get; set; }
public string FriendlyName { get; set; }
}
Now am confused how to design view? So that on next, prev question click I get updated models with fetched question and available options. As far I develop but I got model properties null view model on httppost.
My Controller Like :
public ActionResult Poll()
{
SurveyCommonViewModel retVal = GetMockDataForSurvey();
return View(retVal);
}
[HttpPost]
public ActionResult Poll(SurveyCommonViewModel scm)
{
return View(scm);
}
private SurveyCommonViewModel GetMockDataForSurvey()
{
SurveyCommonViewModel retVal = new SurveyCommonViewModel();
retVal.Options = new List<QuestionOption>();
retVal.Options.Add(new QuestionOption()
{
FriendlyName = "A",
QuestionOptionId = 500
});
retVal.Options.Add(new QuestionOption()
{
FriendlyName = "B",
QuestionOptionId = 501
});
retVal.Options.Add(new QuestionOption()
{
FriendlyName = "C",
QuestionOptionId = 502
});
List<SurveyQuestionViewModel> questions = new List<SurveyQuestionViewModel>()
{
new SurveyQuestionViewModel()
{
QuestionId = 1,
QuestionText = "Question 1 ?"
},
new SurveyQuestionViewModel()
{
QuestionId = 2,
QuestionText = "Question 2 ?"
},
new SurveyQuestionViewModel()
{
QuestionId = 3,
QuestionText = "Question 3 ?"
},
new SurveyQuestionViewModel()
{
QuestionId = 4,
QuestionText = "Question 4 ?"
}
};
retVal.Questions = questions;
return retVal;
}
my razor view is like :
#using (Html.BeginForm())
{
<label id="lblQuestion">#Model.Questions.Where(m => m.QuestionId== 1).FirstOrDefault().QuestionText.ToString()</label>
#foreach (var option in Model.Options)
{
#Html.RadioButton("answer", #option.FriendlyName) #option.FriendlyName
}
<input type="submit" name="Next" value="Next"/>
}
I want all these 4 questions one by one basis...on next button click I want to store this selected option to my view model...and display next question to end user..lastly on 4th question save button is there for updates view models.. I hope you understand what I actually want..... I am not clear about how can I create my razor view....that Is what actually want to be help it out by guys like you...please give me some ideas how can I create or design my razor view....mine view model is finalized...but razor view I cant be able to design...I am beginner to MVC Framework
How does this work?
Here's my view code:
#model pedidosOnlineMVC.Models.ViewModel.AdmView
#using pedidosOnlineMVC.Models
#{
Layout = "~/Views/Administrador/_LayoutAdm.cshtml";
List<Usuario> lu = pedidosOnlineMVC.Controllers.UsuarioController.favoreds(Model.adm.estabelecimento.Estabelecimento_Id);
}
#using (var f = Html.Bootstrap().Begin(new Form()))
{
using (var p = Html.Bootstrap().Begin(new Panel()))
{
using (var t = Html.Bootstrap().Begin(new Table()))
{
using (var h = t.BeginHeader())
{
using(var hr = h.BeginHeaderRow())
{
#hr.Cell("Usuário")
#hr.Cell("Status")
}
}
using(var b = t.BeginBody())
{
for(int i=0;i<lu.Count;i++)
{
using(var c = b.BeginRow())
{
#f.FormGroup().CustomControls(Html.HiddenFor(model => model.Usuario_Id[i], lu[i].Usuario_Id))
#c.Cell(lu[i].nome)
#c.Cell(f.FormGroup().CustomControls(Html.Bootstrap().CheckBoxFor(model=>model.checkAuts[i])))
}
}
}
}
using (var pf = p.BeginFooter())
{
#f.FormGroup().CustomControls(#Html.HiddenFor(model => model.adm.Administrador_Id, Model.adm.Administrador_Id))
#f.FormGroup().CustomControls(Html.Bootstrap().SubmitButton().Text("Autorizar"))
}
}
}
And I had a similar problem here: cshtml page not passing date value on post, but what I did then doesn't work here.
I tried looking in the network window in the developer tools and I can see the ID values (Administrador_ID and Usuario_ID) being sent on post, but they never reach my controller.
Here's the code for the controller:
[HttpPost]
public ActionResult autCli(AdmView adm)
{
return null;
}
It has no code in it because I still didn't get it to work, but the parameters should still work when debugging, but I get NULL in every attribute instead.
If anyone can help, I'd appreciate it.
AdmView model, as requested:
public class AdmView
{
public Administrador adm { get; set; }
public Produto prod { get; set; }
public virtual List<bool> checkAuts { get; set; }
public virtual List<int> Usuario_Id { get; set; }
}
Try to use the FormCollection to pass data from view to controller.
Just like this:
[HttpPost]
public ActionResult autCli(FormCollection collection)
{
strint Usuario_Id = collection["Usuario_Id"]; //You can get data with this way...
return View();
}
Check this question for more info.
Add [HttpPost] before your ActionResult method.
I am trying to build a web application having multiple drop downs. I have used enums in my model to populate these drop down and there is a single from submit button in my view. I am trying to figure out how could I get all the selected Index from these drop down with 1 button click.
My Controller looks something like this:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new DropDownModel();
return View(model);
}
[HttpPost]
public ActionResult Index(DropDownModel model)
{
// Get the selected value
int id = model.SelectedId;
return View();
}
public ActionResult About()
{
return View();
}
}
DropDown in my view:
#Html.DropDownListFor(x => x.SelectedId, Enum.GetNames(typeof(BTSWeb.Models.BillTemplate)).Select(e => new SelectListItem { Text = e }),"--BillTemplate--",new { style = "width:108px;font-size:90%;border-radius: 6.5px 6.5px 6.5px 6.5px" })
<span style="margin-left:1px"></span>
#Html.DropDownListFor(x => x.SelectedId, Enum.GetNames(typeof(BTSWeb.Models.ReadType)).Select(e => new SelectListItem { Text = e }),"--Read Type--",new { style = "width:70px;font-size:90%;border-radius: 6.5px 6.5px 6.5px 6.5px" })
<input type="submit" value="Submit" hidden="hidden"/>
and My Model:
namespace BTSWeb.Models
{
public enum States { ANY, FL, TX, GA, NE };
public enum PaymentType { ANY, Email, Paper, No };
public class DropDownModel
{
public int SelectedId { get; set; }
}
}
The problem is you are using DropDownModel as your view model. You will only ever be able to populate on selectedID using this. What you need to do is somehting like
public class ViewModel
{
public int SelectedStateId { get; set; }
public int SelecPaymentTypeId { get; set; }
}
then in your controller you would pass in
var viewModel = new ViewModel()
return View(ViewModel);
and on your view you would have
#Html.DropDownListFor(x => x.SelectedStateId, Enum.GetNames(typeof(BTSWeb.Models.BillTemplate)).Select(e => new SelectListItem { Text = e }),"--BillTemplate--",new { style = "width:108px;font-size:90%;border-radius: 6.5px 6.5px 6.5px 6.5px" })
<span style="margin-left:1px"></span>
#Html.DropDownListFor(x => x.SelecPaymentTypeId , Enum.GetNames(typeof(BTSWeb.Models.ReadType)).Select(e => new SelectListItem { Text = e }),"--Read Type--",new { style = "width:70px;font-size:90%;border-radius: 6.5px 6.5px 6.5px 6.5px" })
and finally on your controller post method you would have
[HttpPost]
public ActionResult Index(ViewModelmodel)
{
// Get the selected value
int id = model.SelectedStateId;
int id2 = model.SelecPaymentTypeId;
return View();
}