mvc 5 dropdownlist Multiple lookup value - c#

So I have a page where I enter employee details and also select an employee form DropdownList to whom it will report to. My table Employees can have Fields like EmpGuid ,EmpName, EmpParentGuid , Department, Age etc. So basically EmpParentGuid is supervisor to whom EmpGuid reports to.
Below is code for dropdownlist
Controller code
ViewBag.EmpParentGuid = new SelectList(db.Employees.ToList(), "EmpGuid ", "EmpName", Employees.EmpParentGuid );
View Code
#Html.DropDownList("EmpParentGuid", null, htmlAttributes: new { #class = "form-control" })
So based on selected EmpParentGuid I can get its "EmpName" value. Now how can I get other field values and probably display in label next to DropdownList.
Also how can I get the same during post. Because I want to update few hidden fields based on selected EmpParentGuid. Thanks.
Thanks.

HTML PAGE:
#Html.ListBox("EmpParentGuid", null, htmlAttributes: new { id = "ElementID", #class = "form-control" })
Add script for change event:
$(document).ready(function () {
$("#ElementID").change(function () {
var Id = $("#ElementID").val();
$("#IdOfPartialViewHolder").load('#(Url.Action("ActionName", "Controller", null, Request.Url.Scheme))?EmpParentGuid=' + Id);
});
});
HTML FOR Partial VIEW:
<div id="IdOfPartialViewHolder" class="h6 ">
#Html.Partial("_YourPartialView", Model)
</div>
Partial View:
#model YourProject.Models.EmployeesViewModel
<div>
Text1: &nbsp #Html.DisplayFor(model => model.YourModelColumn1) <br />
Text2: &nbsp #Html.DisplayFor(model => model.YourModelColumn2)
... YourModelColumn5
</div>
C# CODE how to update partial view:
public async Task<ActionResult> ActionName(string EmpParentGuid)
{
Guid IDtemp = new Guid(EmpParentGuid);
EmployeesViewModel model = new EmployeesViewModel();
Employees E = new Employees();
E = await db.Employees .FindAsync(IDtemp);
model.YourModelColumn1 = E.YourModelColumn1;
model.YourModelColumn2 = E.YourModelColumn2;
return PartialView("_YourPartialView", model);
}
Maybe exist better solution, but this working for me...
If you will submit HTML FORM
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
YOUR HTML
}

Related

Choosing item from drop down list then grabbing the Item's ID C#

Hello I have a view page that looks like this
#model PIC_Program_1._0.Models.Shipping
#using PIC_Program_1._0.Models;
#{
PIC_Program_1_0Context db = new PIC_Program_1_0Context();
Model.preparedBy = Model.preparedBy != null ? Model.preparedBy : IGT.user;
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<table>
<tr>
<th rowspan="3">Items</th>
<td>
#Html.DropDownList("ItemID", null, null, htmlAttributes: new { #class = "form-control chosen-select", })
#{
Item i = db.Items.Find(int.Parse(Request["ItemID"]));
var packedItems = Model.packed(i);
var orderedItems = Model.SalesOrder.totalItems(i);
var itemMax = orderedItems - packedItems;
}
</td>
<td>
<input type="number" value="#ViewBag.ItemQ" name="item_qty" class="form-control" max="#itemMax" />
</td>
</tr>
I want the user to be able to choose the item from the dropdown, then I want to grab the item that the user selected and I want it to put it into the method parameter
On the backend
string strDDLValue = Request.Form["ddlVendor"].ToString();
you can view this in debug to help
#Html.DropDownList("ItemsXY", new SelectList(ViewBag.ItemsXY), "Choose Category", new { #class = "form-control" })
$("#ItemsXY").on("change", function () {
var q = $("#Category").val();
console.log("val = " + q);
});
In your form collection
[HttpPost]
public ActionResult PIC_Program_1(SomeViewModel someMV,FormCollection form)
{
string strDDLValue = form["ItemsXY"].ToString();
return View(MV);
}
or
string strDDLValue = Request.Form["ItemsXY"].ToString();
If you need the text of selected item as well, add a hidden field and on drop down selection change set selected item text in the hidden field:
Update your model to hold hidden values
// Add this to your VM
public string SelectItemsXY {get;set;}
public string SelectedItemsXYText { get; set; }
<script type="text/javascript">
$(function(){
$("#ItemsXY").on("change", function {
$("#SelectedvendorText").val($(this).text());
});
});
</script>
#Html.DropDownListFor(m=>m.SelectedItemsXY , Model.ItemsXY, "Select ItemsXY")
#Html.HiddenFor(m=>m.SelectedItemsXYText)

ASP.NET MVC C# - Pass dynamic parameter using URL ACTION

How can I pass the value of my textbox "R_endDate" from my VIEW to my controller ExportToExcel function using Url.Action ?
On my View: Index.cshtml
I have this textbox with value of date.
<div class="uk-form-row">
<label class="uk-form-label" for="R_endDate">Ending Date:</label>
<div class="uk-form-controls">
#Html.TextBoxFor(m => m.R_endDate, new { #class = "uk-form-small uk-text-left required", #maxlength = 12, #data_uk_datepicker = "{format: 'MM/DD/YYYY'}" })
</div>
</div>
I have this anchor tag with url action.
Export
On my Controller: MISReportController.cs
public FileContentResult ExportToExcel()
{
byte[] filecontent = ExcelExportHelper.ExportExcel(list, "Technology", true, strAddtional);
return File(filecontent, ExcelExportHelper.ExcelContentType, strTitle);
}
my scripts
error1
You can easily handle this using javascript/jquery.
UI:
<a id="aExportToExcel" href="#" class="uk-button uk-button-small uk-text-center uk-text-small ">Export</a>
Script:
<script type="text/javascript">
$(document).ready(function () {
$("#aExportToExcel").click(function () {
var param = $("input[name='R_endDate']").val();
var _url = '#Url.Action("ExportToExcel", "MISReportController", new { param = "XXX" })'; // Param is the example parameter name. Change as needed.
_url = _url.replace("XXX", param); // _url will contain your url string so you can just play with it as needed for your requirement.
window.open(_url, "_blank");
});
});
</script>
try using html helper beginform()
in index.cshtml
#using (Html.BeginForm("ExportToExcel", "MISReport")) {<div class="uk-form-row">
<label class="uk-form-label" for="R_endDate">Ending Date:</label>
<div class="uk-form-controls">
#Html.TextBoxFor(m => m.R_endDate, new { #class = "uk-form-small uk-text-left required", #maxlength = 12, #data_uk_datepicker = "{format: 'MM/DD/YYYY'},#name="date" })</div></div>}
in the controller
[HttpPost]public FileContentResult ExportToExcel(Datetime date){ .......
}

How to get autocompletet textbox Locations from google API in mvc?

I am using MVC and in View i want to bind a textbox to google API to get auto complete address, How to do this in MVC??
Note: I dont want to display google maps. just textbox show suggestions .. I Did something like this
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAacPaT9YiOu-8leoacd1RDbRfx7an1u74&libraries=places&callback=initMap"
async defer></script>
<script>
google.maps.event.addDomListener(AddNewJob, 'load', function () {
var options = {
types: ['(cities)'],
componentRestrictions: { country: "in" }
};
});
autocomplete = new google.maps.places.Autocomplete(document.getElementById('FromAddress'));
autocomplete.addListener();
</script>
}
And in textBox
<div class="form-group">
#Html.LabelFor(model => model.FromAddress, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="text" id="FromAddress" />
#Html.ValidationMessageFor(model => model.FromAddress, "", new { #class = "text-danger" })
</div>
</div>
var input = document.getElementById('your input tag id');
var autocomplete = new google.maps.places.Autocomplete(input);
Use javascript to do it. Follow api documentation
Check it out on jsfiddle
To do this, you'll need a Maps API Key which you can obtain here : https://developers.google.com/maps/documentation/embed/get-api-key.
Replace YOUR_API_KEY in the scripts url with the api key you obtain from the link above.
Change the id to match the id of the input element you want to attach this to. In the example below, the input element's id is "FromAddress".
And you might want to change options or remove it entirely depending on your needs as the current setting limits the auto-completion to cities in India.
#section Scripts {
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap" async="" defer=""></script>
<script>
function initMap() {
google.maps.event.addDomListener(window, 'load', function () {
var options = {
types: ['(cities)'],
componentRestrictions: { country: "in" }
};
var input = document.getElementById('FromAddress');
var places = new google.maps.places.Autocomplete(input, options);
});
}
</script>
}

Partial within a partial null exception

I have a MVC form which is more complex than all of my others, utilising three models.
Company -> Base_IP -> RequestedIP which goes ViewModel -> Partial1 -> Partial2
I am using BeginCollectionItem for this has each model has a property list of the the model down from it. IE - Company has a property called baseIps, the BaseIp class has a property called requestedIps, it is requestedIps that is coming back null, the count is there on page render, but is not on submit.
When submitting to the database in the post Create(), I get nulls on the 'requestedIps' property, why is this?
I've added the offending controller and partial code samples below, not the entire thing as it's massive/redundant - any questions, please let me know.
Controller - [HttpGet]Create()
public ActionResult Create()
{
var cmp = new Company
{
contacts = new List<Contact>
{
new Contact { email = "", name = "", telephone = "" }
}, pa_ipv4s = new List<Pa_Ipv4>
{
new Pa_Ipv4
{
ipType = "Pa_IPv4", registedAddress = false, existingNotes = "", numberOfAddresses = 0, returnedAddressSpace = false, additionalInformation = "",
requestedIps = new List<IpAllocation>
{
new IpAllocation { allocationType = "Requested", cidr = "", mask = "", subnet = "" }
}
}
}
};
return View(cmp);
}
Controller - [HttpPost]Create()
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Company cmp) // does not contain properties assigned/added to in view render
{
if (ModelState.IsValid)
{
db.companys.Add(cmp);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(cmp);
}
Create View
#model Company
#using (Html.BeginForm())
{
<div id="editorRowsAsn">
#foreach (var ip in Model.pa_ipv4s)
{
#Html.Partial("Pa_IPv4View", ip)
}
</div>
<br />
<div data-role="main" class="ui-content">
<div data-role="controlgroup" data-type="horizontal">
<input type="submit" class="ui-btn" value="Create" />
</div>
</div>
}
Pa_Ipv4 View
#model Pa_Ipv4
#using (Html.BeginCollectionItem("pa_ipv4s"))
{
#Html.AntiForgeryToken()
<div id="editorRowsRIpM">
#foreach (var item in Model.requestedIps)
{
#Html.Partial("RequestedIpView", item)
}
</div>
#Html.ActionLink("Add", "RequestedManager", null, new { id = "addItemRIpM", #class = "button" }
}
RequestedIpView
#model IpAllocation
<div class="editorRow">
#using (Html.BeginCollectionItem("requestedIps"))
{
<div class="ui-grid-c ui-responsive">
<div class="ui-block-a">
<span>
#Html.TextBoxFor(m => m.subnet, new { #class = "checkFiller" })
</span>
</div>
<div class="ui-block-b">
<span>
#Html.TextBoxFor(m => m.cidr, new { #class = "checkFiller" })
</span>
</div>
<div class="ui-block-c">
<span>
#Html.TextBoxFor(m => m.mask, new { #class = "checkFiller" })
<span class="dltBtn">
<img src="~/Images/DeleteRed.png" style="width: 15px; height: 15px;" />
</span>
</span>
</div>
</div>
}
</div>
You first (outer) partial will be generating correct name attributes that relate to your model (your code does not show any controls in the Pa_Ipv4.cshtml view but I assume you do have some), for example
<input name="pa_ipv4s[xxx-xxx].someProperty ...>
however the inner partial will not because #using (Html.BeginCollectionItem("requestedIps")) will generate
<input name="requestedIps[xxx-xxx].subnet ...>
<input name="requestedIps[xxx-xxx].cidr ...>
where they should be
<input name="pa_ipv4s[xxx-xxx].requestedIps[yyy-yyy].subnet ...>
<input name="pa_ipv4s[xxx-xxx].requestedIps[yyy-yyy].cidr ...>
Normally you can pass the prefix to the partial using additional view data (refer this answer for an example), but unfortunately, you do not have access to the Guid generated by the BeginCollectionItem helper so its not possible to correctly prefix the name attribute.
The articles here and here discuss creating your own helper for handling nested collections.
Other options include using nested for loops and including hidden inputs for the collection indexer which will allow you to delete items from the collection and still be able to bind to your model when you submit the form.
for (int i = 0; i < Model.pa_ipv4s.Count; i++)
{
for(int j = 0; j < Model.pa_ipv4s[i].requestedIps.Count; j++)
{
var name = String.Format("pa_ipv4s[{0}].requestedIps.Index", i);
#Html.TextBoxFor(m => m.pa_ipv4s[i].requestedIps[j].subnet)
#Html.TextBoxFor(m => m.pa_ipv4s[i].requestedIps[j].cidr)
...
<input type="hidden" name="#name" value="#j" />
}
}
However if you also need to dynamically add new items you would need to use javascript to generate the html (refer examples here and here)
If you look at your final markup you will probably have inputs with names like
input name="subnet"
input name="cidr"
input name="mask"
This is how the form collection will appear when the form gets posted. Unfortunately this will not bind to your Company model.
Your fields will need to look like this instead
input name="Company.pa_ipv4s[0].subnet"
input name="Company.pa_ipv4s[0].cidr"
input name="Company.pa_ipv4s[0].mask"
input name="Company.pa_ipv4s[1].subnet"
input name="Company.pa_ipv4s[1].cidr"
input name="Company.pa_ipv4s[1].mask"
There are multiple ways to "fix" this, and each has its own caveats.
One approach is to setup "Editor" views (typically in ~/Views/Shared/EditorTemplates/ClassName.cshtml), and then use #Html.EditorFor(x => x.SomeEnumerable). This will not work well in a scenario in which you need to be able to delete arbitrary items from the middle of a collection; although you can still handle those cases by means of an extra property like ItemIsDeleted that you set (e.g. via javascript).
Setting up a complete example here would be lengthy, but you can also reference this tutorial: http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/
As a start, you would create a simple template like
~/Views/Share/EditorTemplates/Contact.cshtml:
#model yournamespace.Contact
<div>
#Html.LabelFor(c => c.Name)
#Html.TextBoxFor(c => c.Name)
#Html.ValidationMessageFor(c => c.Name)
</div>
<div>
#Html.LabelFor(c => c.Email)
#Html.TextBoxFor(c => c.Email)
#Html.ValidationMessageFor(c => c.Email)
</div>
... other simple non-enumerable properties of `Contact` ...
#Html.EditorFor(c => c.pa_ipv4s) #* uses ~/Views/Shared/EditorTemplates/pa_ipv4s.cshtml *#
In your view to edit/create a Company, you would invoke this as
#Html.EditorFor(company => company.Contacts)
(Just like the EditorTemplate for Company invokes the EditorFor pa_ipv4s.)
When you use EditorFor in this way, MVC will handle the indexing automatically for you. (How you handle adding a new contact/IPv4/etc. here is a little more advanced, but this should get you started.)
MVCContrib also has some helper methods you can use for this, but it's not particularly simple from what I recall, and may tie you down to a particular MVC version.

Dynamically Change Data of Partial View while maintaining code bound to parent View/Model

I'm stuck trying to wrap my head around how to make a page like this work. My model contains a list of objects which have text fields for different languages. There's a spot in the view that needs to be dynamically changed to display the text fields associated to the language selected in a drop-down list. The text fields also need to be editable such that when the parent form is submitted, the text fields need to save correctly in the parent model after being edited in the partial view/model. I was hinted in another page that partial views is what I should try to do, maybe something about programmatically generating partial views for each language in the list, and doing something to update/render the correct partial view based on the selection in the drop down list...?
My initial attempt led me to try using ajax calls to the controller to return the correct partial view based on the value of the drop down menu, but I can't bind it to the model, and hence can't update/save it when the main view form is submitted. Here's what I've been working with so far:
Model:
public class EditModel
{
public List<TextField> TextFieldList;
public List<string> DisplayList
{
get
{
List<string> tempList = new List<string>();
foreach (TextField a in TextFieldList)
{
tempList.Add(a.Language.ToString() + "/" + a.Currency.ToString());
}
return tempList;
}
}
}
Controller:
public ActionResult EditTextFields(int adId, int index)
{
Ad ad = this.Repository.GetById(adId);
return PartialView("EditTextFields", ad.TextFieldsList[index]);
}
Main View:
#model Models.EditModel
<script type="text/javascript">
$(function () {
$(href('DisplayList').change(function () {
var value = $(this).find(':selected').val();
var adId = GetId();
$.get('/Controllers/EditTextFields', "{\"adId\": " + String(adId) + ", \"index\":\"" + value + "\"}", function (data) {
$('#TextFieldDiv').html(data);
});
}));
});
</script>
#using (Html.BeginForm("Edit", "Widget", FormMethod.Post, new { id = "WidgetEditForm", enctype = "multipart/form-data" }))
{
<div>
#Html.DisplayFor(m => m.DisplayList)
</div>
<div id="TextFieldDiv">
#{Html.RenderPartial("EditTextFields", (TextField)#Model.TextFieldList[0]);}
</div>
}
Partial View:
#model Objects.TextField
#using (Html.BeginForm())
{
<table>
<tr>
<td class="fieldName" style="vertical-align: top;">
Headline Text:
</td>
<td>
#Html.EditorFor(m => m.Headline)
#Html.ValidationMessageFor(m => m.Headline)
</td>
</tr>
<tr>
<td class="fieldName">
Sub-Headline Text:
</td>
<td>
#Html.EditorFor(m => m.SubHeadline)
#Html.ValidationMessageFor(m => m.SubHeadline)
</td>
</tr>
</table>
}
Ideas to point me in a good direction?

Categories

Resources