As the title says, I'm trying to use ajax to populate a dropdown list from my ApiController and I'm a bit lost. I basically have an entity table that brings back a bunch of department names. After debugging, I know my table is bringing back data as it shows department names coming through. So I think the issue mainly lies within the ajax. When I view the page, the dropdown just says 'nothing selected' and has an empty list. In my ApiController I have:
[RoutePrefix("Api/Request")]
public class NewUserController : ApiController
{
private readonly ZeusEntities _zeus_Entity;
public NewUserController(ZeusEntities zeus)
{
_zeus_Entity = zeus;
}
[Route("Departments")]
[HttpGet]
[CustomApiAuthorize(Roles = UserRole.HR)]
public async Task<IHttpActionResult> GetDepartments()
{
var departments = await _zeus_Entity.DEPARTMENT.Where(z => z.B_DELETE == 0).Select(z => z.S_NAME).Distinct().ToListAsync();
return Ok(departments);
}
}
And in my view, I have:
<div class="form-group col-xs-12 col-sm-4">
<div class="input-group ">
<span class="input-group-addon white">Department</span>
<select class="form-control gray" id="departmentSelect" type="text" </select>
</div>
</div>
Inline:
$.ajax({
type: "GET",
url: "#Url.Action("Departments", "Api/Request")",
data: "{}",
success: function (data) {
var s = '<option value="-1">Please Select a Department</option>';
for (var i = 0; i < data.length; i++) {
s += '<option value="' + data[i].I_PATTERNID + '">' + data[i].S_NAME + '</option>';
}
$("#departmentSelect").html(s);
}
});
Could you please point me in the right direction?
Thanks
So I change the ajax for function to a $.each and realized that I was calling the table column names instead of the variable names I assigned to the data.
$.each(deptList, function (key, department) {
departmentsHtml += "<option value='" + department.DeptId + "'>" + department.Department + "</option>"
});
I feel very silly that I overlooked that bit. Nonetheless, that solved my issue.
Related
I am new and struggling to find a way to create a searchable dropdownlist (MVC5/C#). I have tried Select2, and could not get it working. I am desperate and out of time.
Looking at a few tutorials on Jquery Autocomplete, it seems pretty straight and forward. My problem is that all of the examples on line seems to use static data. My dropdownlist is populated from my Controller using a List of pre-filtered results.
This is how I populate my doprdownlist
List<SelectListItem> autocomplete = db.ICS_Supplies.Where(s => s.InvType == "F").Select(x => new SelectListItem { Value = x.Supplies_ID.ToString(), Text = x.Old_ItemID + " " + " | " + " " + " Description: " + x.ItemDescription, Selected = false }).DistinctBy(p => p.Text).OrderBy(p => p.Text).ToList();
ViewBag.FormsList = new SelectList(autocomplete, "Value", "Text");
As is, the dropdown populates - but it has a lot of records and is VERY slow.
From most of the examples I have seen online, the searchable items are something like:
var options = [
{ value: 'Adam', data: 'AD' },
// ...
{ value: 'Tim', data: 'TM' }
];
That's great, if I want to type out a thousand possible items - but I need to populate my DropDownList options from a table. .. and I am lost.
I am very new to Jquery and any direction is greatly appreciated.
EDIT1*
I am adding the View Code (from the online Example) for more clarification
<div class="form-group col-sm-5">
<label for="files">Select Supply:</label>
<input type="text" name="supplies" id="autocomplete" />
</div>
<div>
Selected Option : <span class="label label-default" id="selected_option"></span>
</div>
I suggest you need ajax to get a dynamic autocomplete list. Here's some sample code - it's the definition of a basic jQuery implementation that uses ajax.
function close_autocomplete($elemid) {
jQuery($elemid).autocomplete("destroy" );
}
function attach_autocomplete($elemid) {
jQuery($elemid)
.autocomplete({
delay : 250,
minLength : 3,
source : function( request, response ) {
var $thedata = request.term;
jQuery.ajax({
url : myajaxresponder.php,
type : "GET",
data : {
action_id : "autocomplete",
thedata : $thedata
},
error : function (jqXHR, textStatus, errorThrown){
console.log(textStatus + " " + errorThrown);
response("");
},
success : function (result) {
var resultarray = JSON.parse(result);
response(resultarray);
}
});
},
select : function ( event, ui ) {
jQuery($elemid).val(ui.item.value);
return false;
},
})
}
// attach the handlers
jQuery("#myid").focus(function ()
{attach_autocomplete(jQuery(this).prop("id"))});
jQuery("#myid").blur(function ()
{close_autocomplete(jQuery(this).prop("id"))});
I am using ASP.NET Core 3.1 MVC to create a page with a form. The form has a dropdown and a textbox. The dropdown is populated with values from the database. The textbox will populate with a value from the same table and the dropdown, based on the selected dropdown value. My goal is to call a function from my controller inside of my view, is that possible?
My cshtml file:
<form method="post" asp-controller="Index" asp-action="Index" role="form">
<div class="form-group">
<select id="fileName" asp-items="#(new SelectList(ViewBag.message, "ID", "fileName"))" onchange="getUploadedFile()"></select>
<input />
</div>
</form>
My Model
public class myFiles
{
public int ID {get; set;}
public string fileName {get; set;}
public string uploadedFile {get; set;}
}
My controller has a function named GetUploadedFile() which runs a query to the database that returns the file name based on the ID. I originally thought I could reference the GetUploadedFile through my view(cshtml file) by adding the onchange handler and setting it as onchange="GetUploadedFile()". I have also tried to do an ajax call to get the UploadedFile.
My goal is to call a function from my controller inside of my view, is that possible?
Do you mean you want to add the myfiles' uploadfile value according to the dropdownlist selected value in the onchange getUploadedFile jquery method? If this is your requirement, I suggest you could try to use ajax to achieve your requirement.
You could write the ajax to post request to the mvc action, then you could get the value and set the result to the textbox.
Details, you could refer to below codes:
<form method="post" asp-controller="home" asp-action="Index" role="form">
<div class="form-group">
<input id="uploadedFile" type="text" class="form-control" />
<select id="fileName" asp-items="#(new SelectList(ViewBag.message, "ID", "fileName"))" onchange="getUploadedFile(this)"></select>
</div>
</form>
<script>
function getUploadedFile(Sle) {
$.ajax({
url: "/Home/GetUploadfileName",
data: { "FileID": Sle.value} ,
type: "Post",
dataType: "text",
success: function (data) {
console.log(data);
$("#uploadedFile").val(data);
},
error: function (data) {
alert(data);
}
});
}
</script>
Action method:
private List<myFiles> myfiletestdata = new List<myFiles>() {
new myFiles(){ ID=1, fileName="test1", uploadedFile="testuploadfile" },
new myFiles(){ ID=2, fileName="test2", uploadedFile="testuploadfile2" },
new myFiles(){ ID=3, fileName="test3", uploadedFile="testuploadfile3" },
};
[HttpPost]
public IActionResult GetUploadfileName(int FileID) {
//get the filename result accoding to ID
var result = myfiletestdata.Where(x=>x.ID== FileID).First();
return Ok(result.uploadedFile);
}
Result:
If I understand correctly, you just want to get the file name from the database when a value from the dropdown is selected.
What errors did you get when you tried the ajax call??
In your cshtml file, you can have something like this:
<script>
function getUploadedFile() {
var id = $('#fileName option:selected').val();
$.getJSON('/ControllerName/GetUploadedFile', { id: id }, function (result) {
var file = result.fileName;
.... do whatever with the result
to set value of the textbox:
$('#textBoxId').text(file);
});
}
</script>
Instead of getJSON, you could use ajax:
<script>
function getUploadedFile() {
var id = $('#fileName option:selected').val();
$.ajax({
url: 'ControllerName/GetUploadedFile',
type: 'GET',
dataType: 'json',
data: {
'id': id
}
})
.done(function (result) {
if (!result.errored) {
var file = result.fileName;
}
else {
}
});
}
</script>
Then in your controller, if you are not submitting the form and just want to update the value of the textbox, then it can just be:
[HttpGet]
public async Task<IActionResult> GetUploadedFile(int id)
{
Sample code:
var file = await GetFileFromDb(id);
return Json(new { fileName = file });
}
Also, you should consider using ViewModels instead of ViewBag.
I'm in the middle of developing a Skills feature in my project And I'm trying to figure out how to do the next thing, I will first describe how the system is built so far:
There is a selectsize text window that allows you to select several skills together, after you select a link, it inserts it below the selection window and asks you what level of your chosen skill.
It can be added and deleted, but it slightly complicates me because I can not find a way to transfer all the selected skills and also selected their level to the controller.
I just want to know in Controller what only the selected skills and their level, that's my code so far built:
List type:
public class SkillDetails
{
public uint SkillID { get; set; }
public Levels Level { get; set; }
public SkillDetails(uint id, Levels level) =>
(SkillID, Level) = (id, level);
}
List definition:
public IList<Skill.SkillDetails> Skills { get; set; }
Javascript - On select event:
Skills[0].SkillID is just a test and it didn't work and it crashes the website.
$eventSelect.on("select2:select", function (e)
{
console.log("select: ", e);
var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + e.params.data.id + "\"/>");
var fType = $('<div class="input-group mb-2"><span class="input-group-prepend"><span class="input-group-text">' + e.params.data.text + '</span ></span ><input type="hidden" name="Skills[0].SkillID" value="' + e.params.data.id + '"/><select class="form-control" name="TEST"><option value="0">None</option><option value="1">Know</option><option value="2">Understand</option><option value="3">Master</option></select></div>');
fieldWrapper.append(fType);
$("#buildyourform").append(fieldWrapper);
});
Javascript - On un-select event:
Here whats happen when delete skill selected from selectsize.
$eventSelect.on("select2:unselect", function (e)
{
console.log("unselect: ", e);
$( "#field" + e.params.data.id).remove();
});
HTML User interact with skills:
<div class="input-group mb-2">
<span class="input-group-prepend">
<span class="input-group-text">' + e.params.data.text + '</span ></span >
<input type="hidden" name="Skills[0].SkillID" value="' + e.params.data.id + '"/>
<select class="form-control" name="Skills[0].Level">
<option value="0">None</option>
<option value="1">Know</option>
<option value="2">Understand</option>
<option value="3">Master</option>
</select>
</div>
Because it is dynamic and every time a new skill is created / deleted how can an updated SkillDetails type list be transferred to the controller according to the skills I selected and entered their level?
If you give each instance of a skill in Skills an index value then you can submit a collection of items to the controller. I have something similar in a project although not using JS/Ajax.
Add:
<input type="hidden" name="Skills.Index" id="Skills.Index" value="0" />
for each instance of a skill...where 0 changes to be a unique value for each instance.
Each form field per 'skill' should use this index, so...
<input type="text" name="Skills[0].title" id="Skills[0].title" value="[whatever]" />
<input type="text" name="Skills[0].SkillID" id="Skills[0].SkillID" value="[whatever]" />
and so on...
Then, in the controller you can accept IList<Skill.SkillDetails> Skills from your form submission.
Your Javascript code should include a way to notify the controller that the list of skills is changed.
You could achieve that using a simple Ajax call and a controller method endpoint which will update your back-end repository (the database).
You could try something like:
$eventSelect.on("select2:select", function (e)
{
console.log("select: ", e);
var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + e.params.data.id + "\"/>");
var fType = $('<div class="input-group mb-2"><span class="input-group-prepend"><span class="input-group-text">' + e.params.data.text + '</span ></span ><input type="hidden" name="Skills[0].SkillID" value="' + e.params.data.id + '"/><select class="form-control" name="TEST"><option value="0">None</option><option value="1">Know</option><option value="2">Understand</option><option value="3">Master</option></select></div>');
fieldWrapper.append(fType);
$("#buildyourform").append(fieldWrapper);
// This block of code will convert the content of the skill list to json
// and pass it back to a controller.
var jsonSkills = JSON.stringify([js object containing the list of skills]);
$.ajax({
type: 'POST',
url: '/path/to/your/controller',
data: {
'skillList': jsonSkills
},
success: function(msg){
alert('ok: ' + msg);
}
});
});
Also, about your:
Skills[0].SkillID is just a test and it didn't work and it crashes the
website
That's because you are encoutering a Null Reference Exception since you are not initialising the collection in the controller.
In an attempt of doing a cascading dropdown, I followed this good tutorial. But I made a few changes through out the process.
Summing up, I have two dropdowns where one should control the other. The first one is working well, it returns the data that I expect.
The second one, it returns the correct amount that I expect, however, all the different items come as "unknown".
For example, I choose a name on the 1st dropdown the 2nd dropwdown changes to the correct amountt of items related to the 1st dropdown but the information/items comes as unknown.
On my .cshtml, I have
<div class="editor-label">
#Html.LabelFor(model => model.VId, "vendor")
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.VId, ViewBag.VendorName as SelectList, "--Select Vendor--", new { #class = "form-control" })
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IFID, "family")
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.IFID, ViewBag.FamilyName as SelectList, "--Select Family--", new { #class = "form-control" })
</div>
Also, on my .cshtml, I have the part where I am creating the jquery script:
#section scripts {
<script src="https://ajax.microsoft.com/ajax/jquery/jquery-1.10.2.js" type="text/javascript"></script>
<script src="https://ajax.microsoft.com/ajax/jquery/jquery-1.10.2.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.12.0/jquery.validate.min.js" type="text/javascript"></script>
<script>
$(document).ready(function ()
{
//Dropdownlist Selectedchange event
$("#VId").change(function ()
{
$("#IFID").empty();
$.ajax({
type:'POST',
url: '#Url.Action("SelectFamilies")',
dataType: 'json',
data: { id: $("#VId").val() },
success: function (families)
{
alert($("#VId").val());
alert(families.dataType);
$.each(families, function (i, family)
{
$("#IFID").append('<option value="'
+ family.IFID + '">'
+ family.IndexFamilyName + '</option>');
});
},
error: function (ex)
{
alert('Failed to retrieve states.' + ex.responseText);
}
});
return false;
})
});
</script>
}
On this .cshtml, I am pointing to a #model that defines the variables this way:
public virtual ICollection<IFDto> families { get; set; }
public virtual ICollection<VDto> vendors { get; set; }
public virtual VDto vendor { get; set; }
public virtual IFDto family { get; set; }
"#Url.Action("SelectFamilies")" comes from (this is in a controller):
public JsonResult SelectFamilies(int id)
{
//IEnumerable<IFDto> families = db.states.Where(stat => stat.country_id == id);
IEnumerable<IFDto> families = _indexfamilyDataGateway.GetFamiliesByVendor(id);
return Json(families);
}
Also, on this same controller I have:
public ActionResult Create()
{
//ViewBag.VendorName = GetVendorSelectItems();
//ViewBag.FamilyName = GetFamilySelectItems();
ViewBag.VendorName = new SelectList(_vendorDataGateway.GetAll(), "VId", "AbbrevAndName");
ViewBag.FamilyName = new SelectList(_indexfamilyDataGateway.GetAll(), "IFID", "IFName");
return View();
}
This is a similar problem mentioned here and here.
In one of the comments, it was requested (and also a good idea) for me to do a "console.log(families)" inside the .ajax success. It is returning the information that I need:
Please, noticed that it is printing 4 times because I put the "console." before and after the .ajax success "each" statement. If I just put after success and before the $.each it returns an array.
With a good idea, provided by #Ammar, of using "console.log(families)" I was able to figure it out that inside the .ajax $.each I was wrongly using:
+ family.IFID + '">'
+ family.IndexFamilyName +
When I should be using:
+ family.iFID + '">'
+ family.indexFamilyName +
The problem was the wrong use of an uppercase letter after the ".".
I am new to both AngularJs and MVC. I am trying to get related records for a company when the company is selected in a dropdown list using AngularJS and MVC. I am populating the dropdown list, but when a company is selected, the event to get related records never fires. Here is my Angular Controller:
myApp.controller("CompanyController",
function($scope, $timeout, companyService)
{
getCompanies();
function getCompanies() {
companyService.getCompanies()
.success(function (data) {
$scope.companies = data;
})
.error(function (error) {
$scope.status = 'Unable to load customer data: ' + error.message;
});
};
$scope.getCurrentModules = function(){
companyId = $scope.company;
companyService.getCurrentModules(companyId)
.success(function (data){
$scope.data =data;
});
}
});
Here is my Angular Service:
angular.module('dashboardManagement')
.service('companyService', [
'$http', function ($http) {
this.getCompanies = function () {
return $http.get('/Home/GetAllCompanies');
};
this.getCurrentModules = function (id) {
return $http.get('/Home/GetCurrentModules?id=' + id);
};
}
]);
Here is my MVC View:
<td>
Please Select an Operator:<br />
<br />
<div id="companyContainer">
<div ng-controller="CompanyController">
<select id="CompanySelector" data-ng-model="company" data-ng-change="getCurrentModules()">
<option ng-repeat="company in companies" value="{{company.CompanyID}}">{{company.vchCompanyName}}</option>
</select>
<br />
You selected: {{company}}
</div>
</div>
</td>
Here is my MVC Controller:
[System.Web.Http.HttpPost]
public JsonResult GetCurrentModules(int companyId)
{
// throw new NotImplementedException();
var modules = this._operatorDashboardRepository.GetWithStoredProcedure("scGetDashboardModulesByWidgetID #WidgetID", "companyId");
var moduleList = modules.OrderBy(module => module.vchRankingWidgetModuleHeaderText);
return Json(moduleList, JsonRequestBehavior.AllowGet);
}
Can anyone tell me what I am doing wrong? I placed a break in the MVC Controller to see if the "GetCurrentModules" ever fires, but it does not. Any assistance is greatly appreciated.
Option 1
Change your getCurrentModules method to use $http.post instead of $http.get. Also make sure your parameter names match
return $http.post('/Home/GetCurrentModules?companyId=' + id);
public JsonResult GetCurrentModules(int companyId)
Option 2
Change your JsonResult to allow HttpGet
[System.Web.Http.HttpGet]
public JsonResult GetCurrentModules(int companyId)
again make sure parameter names match