Submit form over a select element in ASP.Net MVC - c#

So in my file i have this working example of submitting a form and initiating a controller action. And in this form there is a functioning select element and it works as expected, the controller is able to retrieve the value in the select element.
#using (Html.BeginForm("InsertEntry", "Modeliai"))
{
<div class="row">
<div class="col-7">
<input type="text" class="form-control" placeholder="Pavadinimas" name="Pavadinimas">
</div>
<div class="col-3">
<select class="selectpicker" data-live-search="true" name="fk_MARKEid">
#foreach (var item in Model.Markes)
{
<option data-tokens="#item.pavadinimas" data-content="#item.pavadinimas">#item.id</option>
}
</select>
</div>
<button type="submit" class="btn btn-success">Add</button>
</div>
}
But when i try to add select element in the table row, controller somehow doesn't catch the value of the select element.
#using (Html.BeginForm("UpdateEntry", "Modeliai"))
{
<td>
<input type="hidden" name="id" value="#item.id" />
<input type="text" name="pavadinimas" class="form-control" value="#item.pavadinimas" />
</td>
<td>
<select class="selectpicker" data-live-search="true" name="fk_MARKEid">
#{
var ignore = Model.Markes.FirstOrDefault(x => x.id == item.fk_MARKEid);
}
#foreach (var x in Model.Markes)
{
if (ignore?.id == x.id)
{
<option data-tokens="#ignore?.pavadinimas" data-content="#ignore?.pavadinimas" selected="selected">#ignore?.id</option>
}
<option data-tokens="#x.pavadinimas" data-content="#x.pavadinimas">#x.id</option>
}
</select>
</td>
<td style="width: 100px">
<button class="close" type="submit">
<i class="fas fa-pencil-alt" style="font-size: smaller"></i>
</button>
</td>
}
Yes i tried checking if select element names and model names match.
Any help regarding making the second form work or explanation why does this happen would be appreciated

The better way to use select in ASP.Net MVC is to use #Html.DropDownListFor with SelectList.
Example: View
#Html.DropDownListFor(x => x.YourModel, new SelectList(ViewBag.customValue, "Text", "Value"), new { htmlAttributes = new { #class = "form-control" } })
Example: Controller
List<SelectListItem> listForSelect = new List<SelectListItem>();
listForSelect.Add(new SelectListItem { Text = "Your text", Value = "Your value" });
ViewBag.customValue = listForSelect;

Related

Multiple forms on one MVC form, model data does not pass to Action

I am creating a loop of objects/forms that will enable a user to update data for each object in a partial view. The unique data properly displays in the loop of forms but when I try to submit to the action, the model data that passes to the action is blank and doesn't pull the data from the form I'm submitting from.
In debugging, object data is successfully passed to each var item in the loop.
#foreach (var item in ViewData["CtaList"] as
IEnumerable)
Ex. There are 5 individual forms that are created by the loop each with their own Save and Delete button. If I click Save on the 3rd form in the loop, it goes to the action but the MedInfoModel model for that individual object is blank.
View
#{
ViewData["Title"] = "Edit";
ViewData["hidePluginCSS"] = "yes";
#model POR.Common.MedInfoModel;
}
#foreach (var item in ViewData["CtaList"] as IEnumerable<POR.Common.CtaListModel>)
{
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Edit CTA</h3>
</div>
<div id="partialPlaceHolder">
#using (Html.BeginForm("SaveCtaInfo/" + item.CtaId, "Med", FormMethod.Post, new { #Id = item.CtaId, #class = "content-form form-horizontal" }))
{
<div class="panel-body">
<form class="content-form form-horizontal">
<div class="form-group justify-content-end">
<label for="inputEmail" autocomplete="false" class="col-md-9 control-label">Select Type</label>
#Html.DropDownListFor(m => item.CtaType, Model.CTATypeDropdown, new { #class = "form-control"})
</div>
<div class="form-group justify-content-end">
<label for="inputEmail" autocomplete="false" class="col-md-9 control-label">Select Priority</label>
#Html.DropDownListFor(m => item.CtaOrder, Model.CTAOrderDropdown, new { #class = "form-control" })
</div>
<div class="row mt-2">
<div class="col-md-12 r">
<button class="btn btn-raised btn-danger r" name="ctaSave" value="ctaDelete">Delete</button>
<button class="btn btn-raised btn-success r" name="ctaSave" value="ctaSave">Save</button>
</div>
</div>
</form>
</div>
}
</div>
</div>
}
Controller:
[HttpPost]
public ActionResult SaveCtaInfo(MedInfoModel model, int id)
{
string _sSubmit = Request.Form["ctaSave"].ToString();
if (_sSubmit == "ctaSave")
{
// Code for cta save
model.CtaActionType = "UPDATE";
Helper.SQLSPCrudModel(ConnectionString, "storedProcedure", model);
}
else if (_sSubmit == "ctaDelete")
{
// code for cta delete
model.CtaActionType = "DELETE";
Helper.SQLSPCrudModel(ConnectionString, "storedProcedure", model);
}
return RedirectToAction("Edit/" + id);
}
Rendered Form HTML:
<form action="/Med/SaveCtaInfo%2F1000" class="content-form form-horizontal" id="1000" method="post"> <div class="panel-body">
<div class="form-group justify-content-end">
<label for="inputEmail" autocomplete="false" class="col-md-9 control-label">Select Type</label>
<select class="form-control" id="item_0__CtaType" name="item[0].CtaType"><option value="PDF">PDF</option>
<option selected="selected" value="Call">Call</option>
<option value="Menu">Menu</option>
<option value="Video">Video</option>
</select>
</div>
<div class="form-group justify-content-end">
<label for="inputEmail" autocomplete="false" class="col-md-9 control-label">Select Priority</label>
<select class="form-control" data-val="true" data-val-required="The CtaOrder field is required." id="item_0__CtaOrder" name="item[0].CtaOrder"><option value="0">0</option>
<option selected="selected" value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
<div class="row mt-2">
<div class="col-md-12 r">
<button class="btn btn-raised btn-danger r" name="ctaSave" value="ctaDelete">Delete</button>
<button class="btn btn-raised btn-success r" name="ctaSave" value="ctaSave">Save<div class="ripple-container"></div></button>
</div>
</div>
</div></form>
EDIT:
I just noticed however that the form data is passing through via chrome dev tools as:
item[0].CtaType: Call
item[0].CtaOrder: 1
item[0].CtaLink:
Where in a succesfull passing of the model in another action is passing through as:
CtaType: Call
CtaOrder: 1
CtaLink:
Does the action need to be set up differently since it is no longer the parent model of the page?
The answer was to simply replace the following in the controller in original code I posted:
public ActionResult SaveCtaInfo(MedInfoModel model, int id)
with
public ActionResult SaveCtaInfo(MedInfoModel item, int id)
Thanks for your help mxmissile. Sorry for wasting your time.

Post values by using a table on a view

I have a table on my view and I pass a model to this view on tbody I get values from the model and a select where I get values from a viewbag. I want to relate the values that are on each row something like Metadisciplina.Nome with the selected value on ViewBag.Docente.... Per each row I will get something like a list I don't know. Right now I have a method where I get two different types of lists where in one I get the model and in the other the values from the select option... But using this two cycles and a lot of if's I just can have one of my ideas... Or I can get for the same Docente value each Metadisciplina.Nome or for each Metadisciplina.Nome get different Docente values... I want to have the possibilty to have both Metadisciplina.Nome with different Docente values and Metadisciplina.Nome with the same Docente values.. The user will decide that...
View
#model IList<ModelsLibrary.Turno>
#{
ViewData["Title"] = "Index";
}
<div class="row">
<div class="col-md-4">
<form asp-action="Index" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger">
</div>
<div class="form-group">
<label>Ano Letivo</label>
<select name="anoLetivo" class="form-control" asp-items="ViewBag.Ano"></select>
</div>
<div class="form-group">
<label>Ano Curricular</label>
<select name="ano" class="form-control">
<option>-Select-</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</div>
<div class="form-group">
<label>Semestre</label>
<select name="semestre" class="form-control">
<option>-Select-</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
<div class="form-group">
<input type="submit" value="Escolhido" class="btn btn-default" />
</div>
</form>
</div>
</div>
<form asp-action="Create" method="post">
<table class="table">
<thead>
<tr>
<th>
<label>Disciplina</label>
</th>
<th>
<label>Turno</label>
</th>
<th>
<label>Tipologia</label>
</th>
<th>
<label>Docente</label>
</th>
</tr>
</thead>
<tbody>
#for (var i = 0; i < Model.Count; i++)
{
#Html.HiddenFor(x => x[i].TurnoId)
#Html.HiddenFor(x => x[i].MetaDisciplina.Nome)
<tr>
<td>
#Html.DisplayFor(modelItem => modelItem[i].MetaDisciplina.Nome)
</td>
<td>
#Html.DisplayFor(modelItem => modelItem[i].LetraTurno)
</td>
<td>
#Html.DisplayFor(modelItem => modelItem[i].Tipologia.Tipo)
</td>
<td>
<select name="DocenteId" asp-items="ViewBag.Docente"></select>
</td>
</tr>
}
</tbody>
</table>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Controller Method
[HttpPost]
public async Task<IActionResult> Create(IList<Turno> Turno, IList<int> DocenteId)
{
var turnodocente = new List<TurnoDocente>();
foreach (var item in Turno)
{
foreach (var ite in DocenteId)
{
if(!turnodocente.Any(x=>x.DocenteId == ite && x.TurnoId == item.TurnoId))
{
turnodocente.Add(new TurnoDocente
{
TurnoId = item.TurnoId,
DocenteId = ite
});
}
}
}
HttpResponseMessage responsemeta = await HttpRequestBuilder.WebApiClient.PostAsJsonAsync("api/TurnoDocente", turnodocente);
responsemeta.EnsureSuccessStatusCode();
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
Expected Result
I expect to get the values without the red cross not all.... This is one of the options.. In here I just have an example but I try another way to do the if clause but the result is not what I want... And and didn't really know how I can get the values that are related per each table row...

Bootstrap multi select buttons

In previously I use standard check-boxes, but now I want to use the bootstrap Multiple select boxes.
At this moment I can't see any rows in my drop down.
My new code:
<li>
<select href="#" class="selectpicker" data-value="option1" tabIndex="-1" multiple data-selected-text-format="count">
<option checked> #Html.DisplayTextFor(model => Model.AvailableCompanies[i].NAME)</option>
<option name="selection[#i]" value="true"></option>
<option name="ids[#i]" value="#Model.AvailableCompanies[i].ID"></option>
</select></li>
My previously code:
<li>
<a href="#" class="small" data-value="option1" tabIndex="-1">
<input type="checkbox" checked /> #Html.DisplayTextFor(model => Model.AvailableCompanies[i].NAME)
<input type="hidden" name="selection[#i]" value="true"/>
<input type="hidden" name="ids[#i]" value="#Model.AvailableCompanies[i].ID" />
</a>
In C# we have cool helper and Multi select buttons
#Html.ListBoxFor(model => model.Companies,
new MultiSelectList(Model.AvailableCompanies, "ID", "NAME", null),
new
{
data_dropdown_align_right = "auto",
id = "",
data_selected_text_format = "count",
data_actions_box = "true",
#class = "selectpicker form-control",
multiple = "multiple",
data_live_search = "true"
})

Ajax query refreshing whole page instead of part

I have simple View where I have a ajax form I use for filtering records:
#using (Ajax.BeginForm("Index", new AjaxOptions()
{
InsertionMode=InsertionMode.Replace,
UpdateTargetId="dane"
}))
{
#Html.Partial("SearchTab")
}
#Html.Partial("ShowPartial") // <--- id="dane"
Partial SearchTab:
<div class="row">
<div class="col-lg-3">
<div class="input-group">
<div class="input-group-addon name">
User name:
</div>
<input type="text" name="name" class="form-control" />
</div>
</div>
<div class="col-lg-3">
<div class="input-group">
<div class="input-group-addon surname">
User surname:
</div>
<input type="text" name="surname" class="form-control" />
</div>
</div>
<div class="col-lg-3">
<div class="input-group">
<div class="input-group-addon devicename">
Device name:
</div>
<input type="text" name="deviceName" class="form-control" />
</div>
</div>
<div class="col-lg-3">
<div class="input-group">
<div class="input-group-addon devicemanufacturer">
Device Manufactuer:
</div>
<input type="text" name="deviceManufacturer" class="form-control" />
</div>
</div>
</div>
<input type="submit" class="btn btn-default" value="Filter" id="filter"/>
<br />
Controller action:
public ActionResult Index(string name, string surname ,string deviceName, string deviceManufacturer, string Page)
{
bool RoleId = ad.CheckIfAdmin(Request.LogonUserIdentity.Name.Substring(Request.LogonUserIdentity.Name.LastIndexOf(#"\") + 1));
ViewBag.RoleId = RoleId;
var deviceusages = db.DeviceUsages.Include(d => d.DeviceInstance).Include(d => d.Storage).Include(d => d.User).Where(w=>w.UserId!=6).Skip((int.Parse(Page)-1)*30).Take(30);
if(name!="" && name!=null)
{
deviceusages = deviceusages.Where(w => w.User.Name.Contains(name));
}
if (surname != "" && surname != null)
{
deviceusages = deviceusages.Where(w => w.User.Surname.Contains(surname));
}
if (deviceName != "" && deviceName != null)
{
deviceusages = deviceusages.Where(w => w.DeviceInstance.Device.Name.Contains(deviceName));
}
if (deviceManufacturer!= "" && deviceManufacturer != null)
{
deviceusages = deviceusages.Where(w => w.DeviceInstance.Device.Manufacturer.Contains(deviceManufacturer));
}
return View(deviceusages.ToList());
}
After writing something into input field and pressing filter. Ajax should refresh ShowPartial and keep values in the input fields from SerchTab but instead I get filtered records and inputs are getting empty. Can anyone suggest me edits to change this behaviour
If you are intending to
return View()
you should also return the original model so that control values can be populated with your captured values.
Alternatively if you just need to return the list:
deviceusages.ToList()
Then you can return a PartialView() e.g.;
return PartialView(deviceusages.ToList());
Ok I found cause of a problem.
I need to change this code
<div class="input-group">
<div class="input-group-addon name">
User name:
</div>
<input type="text" name="name" class="form-control" />
</div>
into same thing made wit use of .net Html helpers.
After this change everything works!
#Html.Label("User name: ", new { #class = "input-group-addon" })
#Html.TextBox("name", null, new { #type = "text", #class = "form-control" })

#Html.RenderAction with Ajax Form ASP.NET Mvc3 c#

I have a scenario where i need some code setup when a control renders. I have a widget that'll be used on a number of pages called a QuickRate:
I'm trying to call it like so in my cshtml file:
<div class="dragbox" id="quick-rate">
<h2>Retrieve a Quick Rate</h2>
#Html.Action("Create", "QuickRate")
</div>
and then in the create on the QuickRateController.cs I have:
public ActionResult Create()
{
var model = new QuickRateModel();
model.Products = currentUser.GetProducts(dataRepository).ToSelectList(p => p.ProductId, p => p.ProductName);
return View("QuickRateResult", model);
}
i then have a QuickRatePartial.cshtml file that contains the following:
#model Project.Web.Models.QuickRateModel
#{
Layout = "";
AjaxOptions options = new AjaxOptions()
{
HttpMethod = "Post",
UpdateTargetId = "quick-rate-content"
};
}
<div class="clearfix">
#using (Ajax.BeginForm("GetQuickRate", "QuickRate", null, options, new { #id="quick-rate-form" }))
{
<fieldset>
#Html.DropDownListFor(model => model.ProductId, Model.Products)
#Html.ValidationMessageFor(model => model.ProductId)
<select data-val="true" name="DropDown1" data-bind="
options: Items1,
optionsText :'ItemName',
value: SelectedName
">
</select>
<select data-val="true" name="DropDown2" id="DropDown2" data-val-required="Please select an Item." data-bind="
options: SelectedItem().MoreItems,
optionsText: 'Text',
optionsValue: 'Text',
value: MoreItem,
optionsCaption: 'Select One'
"></select>
<div class="clearfix">
#Html.ValidationMessageFor(model => model.MoreItems)
</div>
<div>
<input type="submit" value="Get Quick Rate" />
</div>
<div id="quick-rate-content"></div>
</fieldset>
}
</div>
try as i might I can't get the form to render at all.. just wondering if you had any suggestions?
Cheers!
You've named the file quickratepartial.cshtml but in the action you are looking for a view called quickrateresult. Is this correct?

Categories