collecting info from view to controller - asp.net-mvc

I have a table in my view containing 2 columns.
My program looks for the number of files in a folder and populates the 2nd column with the names, one in each row.
The first column contains a check box if the right column is populated.
How can I access these checkboxes and filenames in my controller after HttpPost?
(The number of files is not fixed, so the number of checkboxes is also not fixed)
I need to run a stored procedure afterwards if a particular file is present.
Model
public class ImportFiles
{
public string FileName;
public bool FileSelected { get; set; }
}
Controller
[HttpGet]
public ActionResult ImportFiles()
{
string folderpath = #"C:\Users\uvaish\Documents\Visual Studio 2010\Projects\MVCDemo\MVCDemo\Models"; //path
string filename = "*";
string[] fileList = System.IO.Directory.GetFiles(folderpath,filename);//getting the file names from the folder as an array
List<ImportFiles> inputFiles = new List<ImportFiles>(fileList.Length);//making a list of same number of elements as the number of files
foreach (string str in fileList)
{
ImportFiles inputFile = new ImportFiles();
inputFile.FileName = Path.GetFileName(str);
inputFile.FileSelected = false;
inputFiles.Add(inputFile);//creating a list of files and passing to the view
}
return View (inputFiles);
}
View
<table width="550px" class="mGrid table">
<tr>
<th>
Select
</th>
<th>
File Name
</th>
</tr>
#foreach (ImportFiles importFiles in #Model)
{
<tr>
<td>
#Html.EditorFor(importFile => #importFiles.FileSelected)
</td>
<td>
#importFiles.FileName
</td>
</tr>
}
</table>
</div>
<table>
<tr>
<td>
<div>
<input type="submit" value="Load Selected Files" />
</div>
</td>
<td>
</td>
<td>
<div>
<input type="submit" onclick="importCancel()" value="Cancel" />
</div>
</td>
</tr>
</table>
So , from the view I want to access the files corresponding to the checked checkboxes.
after clicking on the submit button , I should be able to manipulate the files that are selected.
I am not sure how to use the HttpPost method after this , could you please help?
I have enclosed the table in view in :
#using (Html.BeginForm("LoadSelectedFiles", "Admin", FormMethod.Post))
But I don't know how to write the LoadSelectedFiles controller method next, I want to access each of the ticked files now.

Related

.NET MVC: Removing items from List in model

So here's my problem. I've been trying to solve this for weeks and nothing, so I'm biting the bullet and asking for help.
Basically, I'm trying to write a computer encyclopedia-cum-inventory management-cum-auditing program. Seeing that MVC is all the rage these days I decided to step out of my comfort zone of classic .NET and try MVC.
I have a model with partially the following fields:
public class SoundCard
{
public Guid Id { get; set; }
...
public virtual List<SoundChipset>? SoundChipsets { get; set; }
...
public virtual List<MidiSynthChipset>? MidiSynthChipsets { get; set; }
...
}
The model is scaffolded into creating a controller and then a set of view pages. The add view works brilliantly and I could add sound and midi chipsets as needed. The edit view is where my problem lies: I could add new sound chipsets and midi chipsets, but could not remove the added ones.
The partial code for the controller for edit is as follows:
public async Task<IActionResult> Edit(Guid id, [Bind("Id,ModelSeries,ModelName,ModelNumber,ReleaseDate,HasCDROMInterface,HasSCSIPort,HasIDEPort,HasNECCDPort,HasMatsushitaCDPort,HasWaveBlasterPort,HasRAMForWaveTable,RAMSizeKB,HasGamePort,HasMPU401Port,numAudioOutPorts,numAudioInPorts,numAudioBiDirectionalPorts,numCoaxInPorts,numCoaxOutPorts,numOpticalInPorts,numOpticalOutPorts,numMidiInPorts,numMidiOutPorts")] SoundCard soundCard)
{
...
string[] selectedSndChipsets = Request.Form["lbSoundChipsetsSelected"].ToArray();
List<SoundChipset> sndChipset = new List<SoundChipset>();
foreach (string uuid in selectedSndChipsets)
{
sndChipset.Add(Factories.SoundChipsetDDLFactory.getSoundChipsetByUUID(_context, uuid));
}
soundCard.SoundChipsets = sndChipset;
string[] selectedMidChipsets = Request.Form["lbMidiChipsetsSelected"].ToArray();
List<MidiSynthChipset> MidChipsets = new List<MidiSynthChipset>();
foreach (string uuid in selectedMidChipsets)
{
MidChipsets.Add(Factories.MidiSynthChipsetDDLFactory.getMidiSynthChipsetByUUID(_context, uuid));
}
soundCard.MidiSynthChipsets = MidChipsets;
_context.Update(soundCard);
await _context.SaveChangesAsync();
...
So, practically recreating the Sound Chipsets and Midi Chipsets lists from scratch every single time. Problem is, the program treats the list as new objects to add to the existing list, it does not erase the current list despite the list being a new one!
I've tried to apply a Clear() command to the list but instead the program tossed an NullReferenceException which is puzzling because the list is supposed to be populated.
For completeness sake, here's part of the code for the edit frontend. It's partially JS to handle moving items between two boxes:
<label asp-for="SoundChipsets" class="control-label"></label>
<table>
<tr>
<th>Available</th>
<th>↔</th>
<th>Selected</th>
</tr>
<tr>
<td>
#Html.ListBox("lbAllSoundChipsets",(IEnumerable<SelectListItem>)ViewBag.SoundChipsets, new {#id="lbAllSoundChipsets", #style="min-width: 250px;"})
</td>
<td>
<input onclick="Javascript:SwitchListBoxItems('lbAllSoundChipsets', 'lbSoundChipsetsSelected');" type="button" value="→" /><br />
<input onclick="Javascript:SwitchListBoxItems('lbSoundChipsetsSelected', 'lbAllSoundChipsets');" type="button" value="←" />
</td>
<td>
#Html.ListBox("lbSoundChipsetsSelected",(IEnumerable<SelectListItem>)ViewBag.SelectedSoundChipsets, new {#id="lbSoundChipsetsSelected", #style="min-width: 250px;"})
</td>
</tr>
</table>
</div>
<div class="form-group">
<label asp-for="MidiSynthChipsets" class="control-label"></label>
<table>
<tr>
<th>Available</th>
<th>↔</th>
<th>Selected</th>
</tr>
<tr>
<td>
#Html.ListBox("lbAllMidiChipsets",(IEnumerable<SelectListItem>)ViewBag.MidiSynthChipsets, new {#id="lbAllMidiChipsets", #style="min-width: 250px;"})
</td>
<td>
<input onclick="Javascript:SwitchListBoxItems('lbAllMidiChipsets', 'lbMidiChipsetsSelected');" type="button" value="→" /><br />
<input onclick="Javascript:SwitchListBoxItems('lbMidiChipsetsSelected', 'lbAllMidiChipsets');" type="button" value="←" />
</td>
<td>
#Html.ListBox("lbMidiChipsetsSelected",(IEnumerable<SelectListItem>)ViewBag.SelectedMidiSynthChipsets, new {#id="lbMidiChipsetsSelected", #style="min-width: 250px;"})
</td>
</tr>
</table>
And the JS code:
function SwitchListBoxItems(sourceListItem, targetListItem) {
var src = document.getElementById(sourceListItem);
var dest = document.getElementById(targetListItem);
if (dest != null && src != null) {
while (src.options.selectedIndex >= 0) {
var lstItemNew = new Option(); // Create a new instance of ListItem
lstItemNew.text = src.options[src.options.selectedIndex].text;
lstItemNew.value = src.options[src.options.selectedIndex].value;
dest.options[dest.length] = lstItemNew;
src.remove(src.options.selectedIndex);
}
}
So yeah, if someone can point me in the right direction to get the system to delete items.
Thanks in advance.

Search view : MVC

I need to make a "Search and filter view"
My problem:
I want to create a Search view where the user selects by which attribute he wants to search and than enters something in textbox and submits it. The view than goes to controller finds what it needs to find and displays it
My view goes into the part that is written for when the HttpPost function in controller is done. But it goes in early. I have trouble displaying my results here's controller code part:
public ActionResult Filter()
{
return View();
}
[HttpPost]
public ActionResult Filter(string option, string search, FormCollection fc)
{
var bll = new STUDIJSKIPROGRAMBLLProvider();
StudijskiProgramViewModel model = new StudijskiProgramViewModel();
if (option == "skracenicaSmjer")
{
// For now I just putted some random number to get some data displayed
var program = bll.Fetch(2004);
model.StudijskiProgram = program;
return View(model);
}
else if (option == "skracenicaProfil")
{
return View();
}
else
{
return View();
}
}
And View Code:
#model SolutionC.Models.StudijskiProgramViewModel
#{
ViewBag.Title = "Pretraga studijskih programa";
}
#using (Html.BeginForm("Filter", "StudijskiProgram", FormMethod.Get))
{
<h2>Pretraga studijskih programa</h2>
<b> Kriteriji pretrage: </b>
<input type="radio" name="prvi" value="prvi1"/> <text>Skraćenica profil</text>
#Html.RadioButton("option", "skracenicaSmjer") <text>Skraćenica smjer</text>
#Html.RadioButton("option", "skracenicaProfil") <text> Skraćenica profil </text>
#Html.RadioButton("option", "ECTSOpterecenje")<text>ECTS</text>
#Html.TextBox("search")
<input type = "submit" name = "submit" value = "Traži" />
}
#using (Html.BeginForm("Filter", "StudijskiProgram", FormMethod.Post))
//Don't want my view to display this until i click Submit and my controller sets up data for display
{
<table class="table table-striped">
<thead class="alert alert-info">
<tr>
<th>
Naziv smjera:
</th>
<th>
Naziv profila:
</th>
<th>
Šifra:
</th>
</tr>
</thead>
<tr>
<td> #Model.StudijskiProgram.smjer </td> //Compilation fails here
<td> #Model.StudijskiProgram.profil</td>
<td> #Model.StudijskiProgram.IDStudProg </td>
</tr>
</table>
}
You got it all wrong.
#using (Html.BeginForm("Filter", "StudijskiProgram", FormMethod.Post))
Only means "Make me a form tag wrapper with the following attributes` not only show this when button is posted.
You should instead wrap it with a condition, that will only be met when the model property is set.
if (Model.SomeProperty)
{
<table class="table table-striped">
...
}
The bool SomePropery should be declared on your Model and be set to true when you want the post section to appear.
Note: You should return View(model) when wanting the View to know your model.

bind a table on click event of button

I am working with ASP.NET MVC 3 Razor. I have a list method in controller, so want to bind this list to table on click event of a button. How will I achieve this functionality.
Here is my controller method:
public ActionResult getItnList(string scanCode)
{
List<List<String>> getitnDetails_List = getitnDetails(date, name);
ViewBag.getitnDetails = getitnDetails_List;
return Json(new { getitnDetails_List = getitnDetails_List }, JsonRequestBehavior. AllowGet);
}
Here is my view code:
#{
List<List<String>> str = (List<List<String>>)ViewBag.getitnDetails;
}
<table id="list" width="100%">
<td><b>Harvest Date</b></td>
<td><b>Product</b></td>
#for (int i = 0; i <= str.Count - 1; i++)
<td>#str[i][0].ToString()</td>
<td>#str[i][1].ToString()</td>
</table>
How will I bind this table to list on click event of button?
I'm not exactly sure what you are asking. But if you want to get the list on the click of a button you can use jQuery .getJSON (http://api.jquery.com/jQuery.getJSON/) to retrieve the list data and then insert it with javascript. Or you could render the list in the action and simply use json .get and insert the result.
Try this
View
<table>
<tr>
<th>
Name
</th>
<th>
PhoneNo
</th>
<th>
Address
</th>
<th>
Action
</th>
</tr>
#{var list = ViewBag.RegisterItems; }
#if (list != null)
{
foreach (var m in list)
{
<tr>
<td>
<input id="txtName-#m.ID.ToString()" type="text" class="hide" value="#m.Name.ToString()"/>
</td>
<td>
<input id="txtPhoneNo-#m.ID.ToString()" type="text" class="hide" value="#m.PhoneNo.ToString()"/>
</td>
<td>
<input id="txtAddress-#m.ID.ToString()" type="text" class="hide" value="#m.Address.ToString()"/>
</td>
</tr>
}
}
</table>
Controller
public ActionResult CustomerInfo()
{
ViewBag.RegisterItems = GetAllRegisterData();
return View();
}

Accepting A IENUMERABLE model post in a controller in mvc 3 vb.net?

I have a view in my app that uses a #modeltype ienumerable of (xxxxxxx.abc), and uses a for each loop to populate the view. This view has select boxes that show up next to each item in the view. When I post the form to the controller accepting it as a formcollection does not work, and if I accept it like: ByVal abc as abc it says that its an invalid model.. The code is as follows:
<AcceptVerbs(HttpVerbs.Post)>
Function ClassAttendance(ByVal Attendance As Attendance) As ActionResult
If ModelState.IsValid Then
UpdateModel(Attendance)
db.SaveChanges()
Return RedirectToAction("Index")
End If
Return View()
End Function
Any ideas?? Can I somehow use a for each loop in the view without making it ienumerable? If so when It posts to the controller my below code would just about work.. The only value that really matters is the selectlist choice and the id of the record that it was changed for...
The view is:
#ModelTYPE List(Of xxxxx.attendance)
#Code
ViewData("Title") = "Class Attendance Record"
End Code
#Using Html.BeginForm
#<fieldset>
<table>
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Registrant ID
</th>
<th>
Course Status
</th>
<th>
Comments
</th>
</tr>
#For r As Integer = 0 To ViewBag.count
Dim i As Integer = r
#Html.HiddenFor(Function(m) m(i).id)
#<tr>
<td>
#Html.DisplayFor(Function(m) m(i).firstName)
</td>
<td>
#Html.DisplayFor(Function(m) m(i).lastName)
</td>
<td>
#Html.DisplayFor(Function(m) m(i).reg_id)
</td>
<td>
#Html.DisplayFor(Function(m) m(i).Completed_Class)
</td>
<td>
#Html.DropDownList("Completed_Class", New SelectList(ViewBag.courseStatus, "Status", "Status"))
</td>
<td>
#Html.TextBoxFor(Function(m) m(i).Comments, New With {.class = "AttenComment"})
</td>
</tr>
Next
</table>
<p>
<input type="submit" name="submit" />
</p>
</fieldset>
End Using
I have been over countless tut's and posts with no luck at all... I only want to update the model record for each record to the corresponding selected value from the selectlist... Thanks greatly for any and all help..
In brief, this can be done. There are many ways to accomplish this, the easiest by far I found was to have a custom view model which contains an array of the model you want to bulk insert.
public class MultipleAttendance
{
public Attendance[] attendances {get;set;}
}
Then in your View you can loop as such:
#for(int i=0,i<10;i++)
{
#Html.TextBox(attendances[i].firstName)
}
In the controller
[HttpPost]
public ActionResult Create(MultipleAttendance model)
{
// Get a value
model.attendances[0].firstName;
}
Hope it helps :)

MVC update list items

Hi I have a view which displays Invoices and InvoiceLines.
#model VectorCheck.ViewModels.InvoiceViewModel
#{
ViewBag.Title = "Invoice Details";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/EditorHookup.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary()
<fieldset>
<legend>Invoice</legend>
<table>
<tr>
<th>
Activity ID
</th>
<th>
Invoice Line Amount
</th>
<th>
Payment Type
</th>
<th>
Note
</th>
<th>
</th>
<th>
</th>
<th>
</th>
</tr>
#foreach (var item in Model.InvoiceLines) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Activity.Descriptor)
</td>
<td>
#Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
#Html.DisplayFor(modelItem => item.PaymentType.Name)
</td>
<td>
<span>Person:</span>
#Html.DropDownListFor(modelItem => item.PersonrId, Model.People as IDictionary<string, IEnumerable<SelectListItem>>, "--- Select ---")
</td>
<td>
<input type="submit" value="Update" />
</td>
</tr>
}
}
</table>
</fieldset>
}
What I'm wanting is for each InvoiceLine without going to another screen to be able to change the value in the dropdown list for Person, click update and get this updated InvoiceLine in the controller where I can save it.
However when I get to the controller the InvoiceLine does not contain the values.
Controller method:
[HttpPost]
public ActionResult EditInvoiceLine(InvoiceLine invoiceLine, int id)
{
return View(invoiceLine);
}
Has anyone achieve anything like this on the same page or knows how to do it?
No, I do not want to use jqgrid. I have other functionality which jqgrid isn't suitable for.
InvoiceLine is empty because the controller doesn't know where it's coming from. Also, where is the 'id' coming from? Shouldn't it be 'Personid'? Easiest technique in my opinion would be just to use ajax on the button click and send values using GET through querystrings.
I would use a form per line approach (with or without AJAX). Note this will be easier if you use a non-table-based layout. At a minimum, your submit button will need to share the same table element with the input that you want to post back. Further, you could probably get by with just the line id and the person id, instead of the whole model. Use the line id to fetch the entity from the db, then update the person id and save it. Remove the surrounding form and put a form inside each table element with the dropdown list (moving the submit button as well). Modify the signature of your action to match.
#foreach (var item in Model.InvoiceLines) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Activity.Descriptor)
</td>
<td>
#Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
#Html.DisplayFor(modelItem => item.PaymentType.Name)
</td>
<td>
#using (Html.BeginForm("EditInvoiceLine", new { id => modelItem.InvoiceId } ))
{
<span>Person:</span>
#Html.DropDownListFor(modelItem => item.PersonrId, Model.People as IDictionary<string, IEnumerable<SelectListItem>>, "--- Select ---")
<input type="submit" value="Update" />
}
</td>
</tr>
}
[HttpPost]
public ActionResult EditInvoiceLine( int id, int personId )
{
var line = db.InvoiceLines.SingleOrDefault( id );
line.PersonId = personId;
db.SaveChanges();
return View( line ); // more more likely a model based on the line...
}

Resources