This is my first time trying to use jQuery autocomplete and I feel like I am most of the way there, but the autocomplete is not working.
I am using a textarea with a data-autocomplete-url to pass the input to my controller action:
<textarea id="assign-to" rows="1" data-autocomplete-url="#Url.Action("AutoCompleteUsername")"></textarea>
This is what should allow the autocomplete to work?:
$(document).ready(function () {
$("*[data-autocomplete-url]")
.each(function() {
$(this).autocomplete({
source: $(this).data("autocomplete-url")
});
});
});
Controller Action:
public ActionResult AutoCompleteUsername(string term)
{
using (var entity = new TestEntities())
{
var users = entity.uspSearchUserByName(term).ToList();
return Json(users, JsonRequestBehavior.AllowGet);
}
}
The input is getting POSTed to the controller action and is being filtered through my stored procedure. The disconnect for me is how the data for the autocomplete is actually being returned to the textarea. Right now it seems like I am just returning the data to no where.
Within users, there is both a Username and Id being returned. I am unsure how to set the value and label for the autocomplete.
Thanks for your help
According to the documentation, you need to return the JSON data as an array of objects with label and value properties.
[ { label: "Choice1", value: "value1" }, ... ]
In the autocomplete dropdown, the labels will be shown and after you select an option, the corresponding value will be set into your textarea.
Related
I'm trying to create a page for admins to create new users. When these users are created they will also have a role that they are assigned, and each of those roles will have a list of associated rights. The role will be selected from a dropdownlist of roles. After the role has been selected, but before the user has been created I want the list of associated roles to be displayed on the side of the form so they can see if the rights associated with that role are what they want.
I'm not entirely sure how to approach this problem without reloading the entire page after selecting a role. I'm sure how to have a refresh on a div when the information changes
You can use AJAX to achieve this.
Here is a simple solution to start with. First, create an action method in your controller which accepts the roleId value and get's the rights associated with that role and return that as JSON array.
In the below example, I am simply hard coding 2 rights. You can replace this implementation with however you want to get the data(may be from a database) using the roleId param value.
public JsonResult RoleDetails(int roleId)
{
// Hard coded data.
// Replace with data from your db using roleId value
var rightList = new List<string> { "Admin", "Editor" };
return Json(rightList);
}
So when called with a request URL like /Home/RoleDetails?roleId=2, this action method will return data like this(JSON array).
["Admin","Editor"]
Now, Render your select element with the Roles as options. We shall store the path to the action method in a data attribute on the SELECT element. For example, your rendered HTML should be like this.
<select id="selectedRole" data-url="/Home/RoleDetails">
<option>Select one</option>
<option value="1">Role A</option>
<option value="2">Role B</option>
<option value="3">Role C</option>
</select>
<div id="role-details"></div>
We also rendered a div to show the details.
I am assuming you know how to render a SELECT element. If you do not, please refer
Select Tag Helper in ASP.NET Core MVC post
You can use the Url.Action helper to generate the correct path to the RoleDetails action method, for example,
<select id="selectedRole" data-url="#Url.Action("RoleDetails","Home")">
Now you can use JavaScript to listen to the change event of the SELECT element, read the selected option value, make an ajax call to the action method we created above, get the data ,which is a JSON array, and update the UI using that.
Here is a working sample using jQuery for DOM manipulations.
$(function () {
// Listen to "change" event on SELECT
$("#selectedRole").change(function () {
//Get the value of selected option
var roleId = $(this).val();
var url = $(this).data("url") + "?roleId=" + roleId;
//Make the AJAX call
$.getJSON(url).then(function (data) {
var list = "";
// Loop through the JSON array and build HTML for a list of P tags.
$.each(data, function (index, item) {
list += "<p>" + item + "</p>";
});
// Update the Div content
$("#role-details").html(list);
}).fail(function (e) {
$("#role-details").html("Error getting data");
console.warn(e);
});
});
})
I need to get the selected value of a dropdownlist when I click an ActionLink.
Here is the dropdownlist I am binding from controller.
#Html.DropDownList("resource", new SelectList(ViewBag.ResourceList, ViewBag.SelectedResource), "Resource", new { #class = "span6", #style = "width:14%; color:black;"})
And ActionLink with the function without [HttpPost]
#Html.ActionLink("Export Data", "ExportData");
I have tried from Request.Form["resource"] but it gives me null all the time
public ActionResult ExportData()
{
var req = Request.Form["resource"];
}
I just need to get the text value whatever is in the DropDownList inside my ExportData Function.
The action link basically renders an a tag, and the a tag will look something roughly like this;
Export Data
Because links issue a GET request, any parameters need to be passed via:
Export Data
Request.Form will always be empty in a get request because a POST request populates the form collection. But either way, with a GET or POST request, you can pass the data as a parameter of the action method like:
public ActionResult ExportData(string resource)
So either put a <form> around the data you want to post to the server and change the hyperlink to a button to initiate the post, or use javascript to append "?resource=VAL" to the end of the hyperlink HREF attribute, where VAL is the value from the dropdown.
EDIT: in the few scenarios I had to do this before, what I'll normally do is on the link, add a data attribute (in C# API, use data_ for data attributes):
#Html.ActionLink("Export Data", "ExportData", new { data_url = "ExportData" })
The reason why I use a data attribute is to preserve the original URL and that way I don't have to do string manipulation. Using jQuery, on resource value change, you can update the URL easily:
$("#resource").on("change", function(e) {
var val = $(this).val();
var href = $("#linkid").data("url") + "?resource=" + val;
$("#linkid").attr("href", href);
});
Anytime the dropdown changes, it updates the link url.
You should try the GetValues() method:
public ActionResult ExportData()
{
var req = Request.Form.GetValues("resource");
}
I am getting value in a dropdown list and I wanted to get the selected value in controller when user select any value from the dropdown list. My view is -
#using (Html.BeginForm("ApReport", "Sales", FormMethod.Post))
{
#Html.DropDownList("Ddl", null, "All", new { #class = "control-label"})
#Html.Hidden("rddl")
}
controller -
[HttpPost]
public ActionResult ApReport(ApReport Ddl)
{
string Ddlvalue = string.Empty;
if (Request.Form["rddl"] != null)
{
Ddlvalue = Request.Form["rddl"].ToString();
}
}
but I am not getting any value. Also, I donot want to use any submit button.
Thanks in advance
The use of Ajax allows you as the developer to update the main view without reloading the entire page, as well as send data to the server in the background.
This is how I would have accomplished this task.
Firstly, I would have created an action in my controller which returns a JsonResult. This will return a JSON object to your calling jquery code, that you can use to get values back into your views. Here is an example of the action method.
[HttpGet]
public JsonResult YourActionName(string selectedValue) //Assuming key in your dropdown is string
{
var result = DoYourCalculation(selectedValue);
return Json(new { myResult = result }, JsonRequestBehavior.AllowGet);
}
Now, you need to add your jquery code. I would recommend you place this in a seperate javascript file referenced by your view.
Here is the JQuery code, with the ajax call to the Action in your controller. The Ajax call to the server is initiated by the 'change' event of your DropDown, handled in JQuery, as can be seen below.
$(function () {
$(document)
.on('change', '#Ddl', function(){
var valueofDropDown = $(this).val();
var url = '/YourControllerName/YourActionName';
var dataToSend = { selectedValue: valueofDropDown }
$.ajax({
url: url,
data: dataToSend,
type: 'GET',
success: function (dataReceived) {
//update control on View
var receivedValue = dataReceived.myResult ;
$('YourControlIDToUpdate').val(receivedValue);
}
})
});
};
I am trying to do a look up with Ajax and a dropdown list, The user enters a postcode in a text box, then clicks search.
From here I want to populate a dropdown list, with the values coming from the database,
The action is in a separate controller :-
public ActionResult Search(string Pcode)
{
return Json(new[] {
new { value = '1', text = "text 1" },
new { value = '2', text = "text 2" },
new { value = '3', text = "text 3" }
});
}
My HTML:
Pcode:- #Html.TextBox("GPPOST")
GP Practice:
#Html.EditorFor(model => model.Patient.GPSurgery)
<br/>
#Html.DropDownListFor(m =>m.Patient.GPSurgery Enumerable.Empty<SelectListItem>(),"-- Select GP --")
GP : <input type="button" id="SearchPcode" value="Search">
And finally the Ajax:
$(function () {
$('#SearchPcode').click(function () {
// get the new value
var value = $(this).val();
// and send it as AJAX request to the action
$.ajax({
url: '/GP_Practices/Search', //'<%= Url.Action("Search", "GP_Practices") %>',
type: 'POST',
data: { pcode: value },
success: function (result) {
// when the AJAX succeeds refresh the dropdown list with
// The JSON values returned from the controller action
var GPNames = $('#Patient.GPSurgery');
GPNames.empty();
$.each(result, function(index, item) {
alert(item.text);
});
$.each(result, function (index, item) {
GPNames.append(
$('<option/>', {
value: item.value,
text: item.text
}));
});
}
});
});
});
When I run the code I do get the Json results back, (which I can see in the alert box).
My 2 problems are:
1)I cannot seem to pass the value from the text box Html.TextBox("GPPOST")
2)The Dropdown list is not refreshing with the new values.
1)I cannot seem to pass the value from the text box Html.TextBox("GPPOST")
That's because your Javascript passes pcode, yet your controller expects Pcode (casing matters).
Also as Ehsan Sajjad mentions, you're not sending the value of the textbox, but this unearths a bigger problem: You're binding two fields to the same model property, you can't do that. You'll have to use a separate field for your dropdown and your search input.
2)The Dropdown list is not refreshing with the new values.
That's because your jQuery selector is incorrect:
var GPNames = $('#Patient_GPSurgery');
I have a datatable, on that datatable i set a Html.ActionLink. When I click that action link, I want to send an id of the item to a javascript function and have a new datatable appear below with all of its content that belongs to the selected item in the datatable above. So for example if I click a students name in a table, I want all the students Grades and Test to appear below in a separate datatable. I've never worked with javascript much so I'm not sure how I can do this. If someone can please point me in the right direction or give some tips I'd appreciate it.
original first datatable:
#foreach (var item in ((List<Epic>) ViewData["selectedestimate"]))
{
<tr>
<td>
#* #Html.ActionLink(#item.Name, "action", "controller", new {id = item})*#
#item.Name
</td>
Javascript to call:
<script type="text/javascript">
function StoryClick(story) {
$.get("#Url.Action("action", "controller")", function (response) {
$('#stories').accordion({ collapsible: true });
});
}
</script>
ActionController:
public List<EpicDetails> getEpicDetails(int id)
{
return eRepository.getItemsById(id).tolist();
}
Or do I need an ActionResult?
public Actionresult Details(int id)
{
}
I realize that I'm not even close right now, but its just b/c I'm not sure what steps to take to do this.
Eventually I would make a accordion and put the table in the accordion.
In situations like this I like to actually keep the <a> the ActionLink generates, and just add JavaScript to enhance the behavior of the link. So your view wouldn't really change (I did add a class so that we can bind an event handler to it later):
#Html.ActionLink(#item.Name, "action", "controller", new {id = item, #class = "item-link" })
Then write some jQuery (it looks like you already have a dependency on jQuery. If not, I can revise the answer to use vanilla JavaScript) to bind an event handler to links with class item-link:
<script type="text/javascript">
$(document).ready(function () {
$("a.item-link").click(function (event) {
event.preventDefault(); // Stop the browser from redirecting as it normally would
$.get(this.href, function (response) {
// Do whatever you want with the data.
});
});
});
</script>
And, yes, your action method in the controller should return an ActionResult. It's hard for me to say what type of ActionResult you should return without actually knowing what type of data you want to consume on the client, but if you wanted to inject HTML onto the page, you could write something like this:
public ActionResult Details(int id)
{
var itemDetails = /* Get details about the item */;
return PartialView("Details", itemDetails);
}
Then in your JavaScript you would write:
$("a.item-link").click(function (event) {
event.preventDefault(); // Stop the browser from redirecting as it normally would
$.get(this.href, function (response) {
$("element_to_populate").html(response);
});
});
Where element_to_populate would be a selector that points to where you want to inject the HTML.
I would highly recommend using javascript templating (I prefer handlebars.js) on the client side and returning your student data as a JsonResult. This will keep your bandwidth usage to a minimum.
But, because you seem more comfortable with razor, you could use that for all your templates, return plain html from your controller/view, and then use this javascript instead
<script type="text/javascript">
$(function() {
$("a.item-link").click(function (event) {
event.preventDefault(); // Stop the browser from redirecting as it normally would
$("#gradesContainer").load(this.href, function (response) {
//Do whatever you want, but load will already have filled up
//#gradesContainer with the html returned from your grades view
});
});
});
</script>
In your main page, below the student list, you would just need to add
<div id="gradesContainer"></div>
Your other controller would look like this
public ActionResult TestGrades(int id) {
var model = getTestGradesModel(id);
return View(model);
}
If you were returning JSON for client-side javascript templating it would look like
public ActionResult TestGrades(int id) {
var model = getTestGradesModel(id);
return new JsonResult() {Data = model}; //no view here!
}