Why my drop down list items are invisible? - c#

I am trying to make 2 cascading drop down lists.
First one works fine, you pick an item but when you go to the second drop down list, you can actually see correct number of spaces generating according to the items in the database but not the items themselves!
Its like they are invisible!
Can you please advise?
My View :
#using (Html.BeginForm("Browse", "Bookings", new { id = "TypeItemFormID", data_itemsListAction = #Url.Action("ItemsList") }))
{
<fieldset>
<legend> Type/Item</legend>
#Html.DropDownList("department", ViewBag.ItemTypesList as SelectList, "Select a Type", new {id="ItemTypeID"})
<div id="ItemsDivId">
<label for="Items">Items </label>
<select id="ItemsID" name="Items"></select>
</div>
<p>
<input type ="submit" value="Submit" id="SubmitID" />
</p>
</fieldset>
}
<script type="text/javascript">
$('#ItemTypeID').on('change', function () {
$.ajax({
type: 'POST',
url: '#Url.Action("GetItemTypeForm")',
data: { itemTypeId: $('#ItemTypeID').val() },
success: function (results) {
var options = $('#ItemsID');
options.empty();
options.append($('<option />').val(null).text("- Select an Item -"));
$.each(results, function () {
options.append($('<option />').val(this.ItemsID).text(this.Value));
});
}
});
});
</script>
My Controller :
[HttpPost]
public JsonResult GetItemTypeForm(string itemTypeId)
{
//pseudo code
var data = from s in db.Items
where s.ItemType.ItemTypeName == itemTypeId
select s.ItemName;
return Json(data);
}

You have the initial problem I mentioned in my comment, but it appears from your comments that your member names probably do not match either.
This may not be exact, as we do not know all your data/member names, but you may want something like this (using an anonymous type to return the shape of data you expect):
[HttpPost]
public JsonResult GetItemTypeForm(string itemTypeId)
{
//pseudo code
var data = from s in db.Items
where s.ItemType.ItemTypeName == itemTypeId
select new { Value = s.ItemName, ItemsID = s.ItemId };
return Json(data);
}

Related

Display incremented count from database table ID using Ajax

I want to get the last ID from a database table and increment by 1, to be displayed in an Input or Label parameter of HTML.
Most tutorials display it in tables. Here is my code:
index.cshtml
<td>Trans Id</td>
<td><input id="tbTransID" type="text" /></td>
<script>
$(document).ready(function () {
$.ajax({
type: "GET",
url: "/CashAdvance/GetTransID",
data: "{}",
success: function (data) {
var s = data.TransID;
}$("#tbTransId").html(s);
}
});
});
</script>
CashAdvanceController
public ActionResult GetTransID()
{
AcctgContext db = new AcctgContext();
return Json(db.CATransactions.Select(x => new
{
TransID= x.TransID + 1
}).ToList(), JsonRequestBehavior.AllowGet);
}
You need to change your linq query in the controller as below:
public ActionResult GetTransID()
{
AcctgContext db = new AcctgContext();
return Json(db.CATransactions.OrderByDescending(i => i.TransID).Select(i=>new
{
TransID= x.TransID + 1
}).FirstOrDefault(), JsonRequestBehavior.AllowGet);
}
In your query, you are selecting list of values whereas you need only the max id to increment it.

Join two fields with Linq query

I am trying to show Name and Surname in a textbox with an autocomplete function, the problem is that I have these two fields in different columns in my Database (attached image)
I want to know if there is a way to concatenate these two variables so that the user can see in the Texbox the full name (v_Nombre + v_Apellido), since at present I only show the name
Any help for me?
View:
<script>
$(document).ready(function () {
$("#usuario").autocomplete({
source: '#Url.Action("BuscarUsuario")'
});
});
</script>
<div class="form-group">
<label>Usuario que retiro</label>
<input type="checkbox" name="checkusuario" id="idcheckusuario" checked="checked" value="true" />
#Html.TextBox("searchTerm", null, new { #class = "form-control", id = "usuario" })
</div>
My Controller:
public JsonResult BuscarUsuario(string term)
{
using (DataContext db = new DataContext())
{
List<string> resultado;
resultado = db.Usuarios.Where(x => x.v_Nombre.Contains(term)).Select(n => n.v_Nombre).Take(10).ToList();
return Json(resultado, JsonRequestBehavior.AllowGet);
}
}
You should be able to concatenate in your Select:
.Select(n => n.v_Nombre + " " + n.v_Apellido)

Returning Data with Jquery and Ajax

I am writing a function on a webpage where when you type in a serial number, it will look up what model of part goes with that serial number in a SQL database. Right now, the JsonResult is working and finding the correct information, but something is wrong with the jquery and ajax because it is not showing up after you click off of the serial number box (set with a blur, which does trigger as well).
Here is the controller code.
public JsonResult SerialNumberSearch(string serialnum)
{
var result = db.IASerialNoMasters.Where(x => x.SerialNo == serialnum).Select(x => x.Model).Single().ToString();
return Json(result, JsonRequestBehavior.AllowGet);
}
Here is the script that I currently have on my View.
<script type="text/javascript">
var serialnum;
var url = '#Url.Action("SerialNumberSearch", "WarrantyRegistration")'
$("#SerialNum").blur(function () {
GetLiftModel();
});
function GetLiftModel() {
serialnum = $("#SerialNum").val();
$.ajax({
type: "GET",
url: url,
data: { serialnum: serialnum },
success: function(data) {
$('#ModelName').val(data.Model);
}
})
}
</script>
And this is the code for the textboxes on the View.
<div class="row">
#Html.TextBoxFor(model => model.SerialNum, new { placeholder = "Serial #" })
#Html.ValidationMessageFor(model => model.SerialNum, null, new { #class = "text-danger" })
</div>
<br />
<div class="column-1">
#Html.TextBoxFor(model => model.ModelName, new { placeholder = "Model" })
#Html.ValidationMessageFor(model => model.ModelName, null, new { #class = "text-danger" })
</div>
Can anyone tell what I am missing from the function GetLiftModel area of the code?
Are you sure you want to show data.Model? In case you return JsonResult then data variable is in fact representation of your serial numbers and so it's probably that data.Model is in fact undefined.
Try change it to
$.ajax({
type: "GET",
url: url,
data: { serialnum: serialnum },
success: function(data) {
$('#ModelName').val(data);
}
})
on the other hand based on fact you are returning just string there is no reason to return JsonResult. You could change signature of your controller method to
public JsonResult SerialNumberSearch(string serialnum)
{
var result = db.IASerialNoMasters
.Where(x => x.SerialNo == serialnum)
.Select(x => x.Model).Single().ToString();
return result;
}
This ultimately depends on what you want to access and if you need to access multiple properties :
Need a single property? If you only need a single property, then you should be able to isolate that property out similar to your current code and only pass that back.
Need multiple properties? Then you'll likely need to return the entire object or at least part of it from your SerialNumberSearch() method.
Returning a Single Property
Your current code has a final ToString() call that seems to indicate that you'll be returning just a single property, in this case the Model property :
var result = db.IASerialNoMasters
.Where(x => x.SerialNo == serialnum)
.Select(x => x.Model)
.Single()
.ToString(); // This returns a string
Since that is the case, your data object that is being returned will already contain that specific property, and thus you'll just need to use data as seen below :
success: function(data) {
// data will already contain your result, so just use it
$('#ModelName').val(data);
}
Returning Multiple Properties or an Object Graph
If you expect to be able to access multiple properties from your object in JSON, you'll want to actually return the object itself and let the serializer handle passing it to Javascript so that it can be used as expected :
public JsonResult SerialNumberSearch(string serialnum)
{
var result = db.IASerialNoMasters
.SingleOrDefault(x => x.SerialNo == serialnum);;
if(result == null)
{
// Do something if it doesn't exist
return HttpNotFound();
}
return Json(result, JsonRequestBehavior.AllowGet);
}
And then simply access the property you need from your data object within your Javascript code :
success: function(data) {
// data will already contain your result, so just use it
$('#ModelName').val(data.Model);
}

How can i create a SelectListItem() with Int Value

I have the folloiwng code inside my asp.net mvc action method:-
var CustomerData = customerlist.Select(m => new SelectListItem()
{
Text = m.SDOrganization.NAME,
Value = m.SDOrganization.ORG_ID.ToString(),
});
currently if i remove the ToString() from the ORG_ID , i will get an error that "can not explicitly convert long to string". so it seems that i have to define both the value and the text for the SelectListItem as strings. but since the SelectListItem should hold long , so is there a way to pass the values of the SelectListItem as long instead of strings?
...so is there a way to pass the values of the SelectListItem as long instead of strings?
No. And it doesn't make any sense to do so as when it is rendered, it's just HTML which has no concept of long.
If we have the action
public ActionResult Test()
{
var dictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" }
};
ViewBag.SelectList = new SelectList(dictionary, "Key", "Value");
return this.View();
}
and the following view "Test.cshtml":
#using (Html.BeginForm())
{
#Html.DropDownList("id", ((SelectList)ViewBag.SelectList), "All")
<input type="submit" value="Go" />
}
The generated HTML is
<form action="/home/test" method="post">
<select id="id" name="id">
<option value="">All</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<input type="submit" value="Go">
</form>
and when we post to this action, text of your number is effectively parsed back into your desired type by the Model Binder
[HttpPost]
public ActionResult Test(int? id)
{
var selectedValue = id.HasValue ? id.ToString() : "All";
return Content(String.Format("You selected '{0}'", selectedValue));
}
And the above works as you might expect.

Send data from loop created input fields in view to mvc controller

i have a view with different fields in a loop. Depending on the model it should create as much fields as counts for the loop. Here a example for the page:
_________ ___________ _________
|CONNECTOR| |SEARCHINPUT| |Selection|
|_________| |___________| |_________|
________________ ________________
|Add Search Field| |Sub Search Field|
|_B_U_T_T_O_N____| |_B_U_T_T_O_N____|
The View class looks like:
#model Modelle.Models.SearchModel
<table>
#for (int i = 0; i < (int)Model.SearchCount; i++)
{ <tr>
<th>#if (i > 0)
{<select name="ConnectorList" id="ConnectorList">
<option value="AND" #(Model.ConnectorList.ElementAt(i - 1).Equals("AND") ? "selected" : "")>AND</option>
<option value="OR" #(Model.ConnectorList.ElementAt(i - 1).Equals("OR") ? "selected" : "") >OR</option>
<option value="NAND" #(Model.ConnectorList.ElementAt(i - 1).Equals("NAND") ? "selected" : "") >NAND</option>
<option value="NOR" #(Model.ConnectorList.ElementAt(i - 1).Equals("NOR") ? "selected" : "") >NOR</option>
</select>}
</th>
<th>
<input name="SearchInput" id="SearchInput" type="text" value="#(Model.SearchList.ElementAt(i) as String)" /></th>
<th>
<select name="SelectionList" id="SelectionList">
#for (int j = 0; j < Model.SelectedList.Count(); j++)
{<option value="#j" #(Model.Selection.ElementAt(i).Equals(j) ? "selected" : "")>#(Model.SelectedList.ElementAt(j).Name as String)</option>
}
</select>
</th>
</tr>}
</table>
<p>
<button name="button" type="button" onclick="AddSearchField()">Add one more search field</button>
<button name="button" type="button" onclick="SubSearchField()">Remove one search field</button>
Here the jquery code for the buttons:
function AddSearchField() {
var value1 = $('#SearchInput').val();
var value2 = $('#SelectionList').val();
var value3 = $('#ConnectorList').val();
$.ajax({
url: "#Url.Action("AddSearchField", "Search")",
type: 'POST',
chache:false,
data: 'searchInput=' + value1 + '&selectionList=' + value2 + '&connectorList=' + value3,
success: function (response) {
$('#OpenSearchInput').html(response);
},
});
}
function SubSearchField() {
var value1 = $('#SearchInput').val();
var value2 = $('#SelectionList').val();
var value3 = $('#ConnectorList').val();
$.ajax({
url: "#Url.Action("SubSearchField", "Search")",
type: 'POST',
chache: false,
data: 'searchInput=' + value1 + '&selectionList=' + value2 + '&connectorList=' + value3,
success: function (response) {
$('#OpenSearchInput').html(response);
},
});
}
And the controller code:
public PartialViewResult AddSearchField(List<String> searchInput, List<int> selectionList, List<String> connectorList)
{
SearchModel searchModel = new SearchModel();
if (connectorList == null)
{
connectorList = new List<String>();
}
searchModel.ConnectorList = connectorList;
searchModel.Selection = selectionList.ToList();
searchModel.SelectedList = setSearchFields();
List<String> searchList = new List<String>();
int row = searchInput.Count();
searchModel.SearchList = searchInput.ToList();
searchModel.SearchList.Add("search");
searchModel.SearchCount = row + 1;
searchModel.ConnectorList.Add("AND");
searchModel.Selection.Add(0);
return PartialView("SearchInput", searchModel);
}
public PartialViewResult SubSearchField(List<String> searchInput, List<int> selectionList, List<String> connectorList)
{
SearchModel searchModel = new SearchModel();
if (connectorList == null)
{
connectorList = new List<String>();
}
searchModel.ConnectorList = connectorList;
searchModel.Selection = selectionList.ToList();
searchModel.SelectedList = setSearchFields();
List<String> searchList = new List<String>();
int row = searchInput.Count();
searchModel.SearchList = searchInput.ToList();
if (searchInput.Count() > 1)
{
searchModel.SearchList.RemoveAt(searchInput.Count() - 1);
searchModel.SearchCount = row - 1;
searchModel.ConnectorList.RemoveAt(connectorList.Count() - 1);
searchModel.Selection.RemoveAt(selectionList.Count() - 1);
}
else
{
searchModel.SearchCount = row;
}
return PartialView("SearchInput", searchModel);
}
If i load the page normally it has one search line. If i press the button "add one more search field" it added one line. If i click it a second time nothing happens. If i click the "Remove one search field button (anytime) the second fields disappear. In the debug mode, i can see that in the controller everytime the lists just count 1.
Did someone know where i´m mistaken?
Know anybody a easier way to add the lines? I have to send all the inputs later to the controler to search in a database with different rules depending on the inputs.
You are using
<input name="SearchInput" id="SearchInput" type="text" value="#(Model.SearchList.ElementAt(i) as String)" />
and all other form elements as well in a for loop.
therefore in DOM, you are rendering multiple fields with same ids('SearchInput','ConnectorList','SelectionList')
var value1 = $('#SearchInput').val(); assigns only one string value to value1,
data: 'searchInput=' + value1
here value1 will have only one stirng.
remove Ids for form elements
change your ajax call as
$.ajax({
url: "#Url.Action("SubSearchField", "Search")",
type: 'POST',
cache: false,
data: $('#the form tag id').serialize(),
success: function (response) {
$('#OpenSearchInput').html(response);
},
});
i got already a form around for the search request but i don´t mentioned i could use it for this problem to, cause it would need different buttons to call different methods. A litte workaround from Andrey Shchekin safed my day (http://blog.ashmind.com/2010/03/15/multiple-submit-buttons-with-asp-net-mvc-final-solution/ ) so i could use this form to solve my problem.
The view class now looks like:
#model Modelle.Models.SearchModel
<table>
#for (int i = 0; i < (int)Model.SearchCount; i++)
{ <tr>
<th>#if (i > 0)
{<select name="ConnectorList" id="ConnectorList">
<option value="AND" #(Model.ConnectorList.ElementAt(i - 1).Equals("AND") ? "selected" : "")>AND</option>
<option value="OR" #(Model.ConnectorList.ElementAt(i - 1).Equals("OR") ? "selected" : "") >OR</option>
<option value="NAND" #(Model.ConnectorList.ElementAt(i - 1).Equals("NAND") ? "selected" : "") >NAND</option>
<option value="NOR" #(Model.ConnectorList.ElementAt(i - 1).Equals("NOR") ? "selected" : "") >NOR</option>
</select>}
</th>
<th>
<input name="SearchInput" id="SearchInput" value="#(Model.SearchList.ElementAt(i) as String)" /></th>
<th>
<select name="SelectionList" id="SelectionList">
#for (int j = 0; j < Model.SelectedList.Count(); j++)
{<option value="#j" #(Model.Selection.ElementAt(i).Equals(j) ? "selected" : "")>#(Model.SelectedList.ElementAt(j).Name as String)</option>
}
</select>
</th>
</tr>}
</table>
<p>
<button name="AddSearchField" type="submit">Add one more search field</button>
<button name="SubSearchField" type="submit"">Remove one search field</button>
And the View with the form above:
#model Tumormodelle.Models.SearchModel
<h2>Search Request</h2>
<fieldset>
<legend id="SearchInputHeadline">Here you can Search for all accessible TumorModels</legend>
<b>#ViewBag.Message2 </b>
#using (Ajax.BeginForm("Action", "Search", null, new AjaxOptions { HttpMethod = "post"}, new { id = "SearchForm" }))
{
Html.RenderPartial("SearchFields");
Html.RenderPartial("SearchFilter");
<p>
<button name="SearchForTumorModels" class="submitSearchForm" value="OpenSearchOutput" type="submit">Search for tumor models</button>
<button name="button" type="submit">Clear the search form</button>
</p>}
</fieldset>
In this way i don´t need any jquery but a new class to handle the different buttons and redirect them to the right methods:
public class HttpParamActionAttribute : ActionNameSelectorAttribute
{
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
return true;
if (!actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
return false;
var request = controllerContext.RequestContext.HttpContext.Request;
return request[methodInfo.Name] != null;
}
}
Last but not least i have to put [HttpParamAction] [AcceptVerbs(HttpVerbs.Post)] to the methods in the controller.
The main problem is solved now but it remains a little new problem. Depending on the button it should render the response in different div's.

Categories