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);
});
});
})
Related
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");
}
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.
I have #Html.PagedListPager(Model, page => Url.Action("GetTabData", new { page })
and inside my js file I have ready to use myTab variable which I need to send together with page in above example.
How can I do that?
Update:
I'm using js variable to determine which tab is user click and based on that value I'm quering data. Now I have implemeted pagination which uses above generated link. With this in place my ajax call for sending activeTab is broken, I need to send this value together with page inside above Url.Action.
This is js variable which I use to send over ajax to determine which tab is user click
$(function () {
var activeTab = null;
$('#tabs .tabLink').click(function (event) {
var activeTab = $(this).attr('href').split('-')[1];
GetTabData(activeTab);
});
GetTabData(ommitted on purpse)
});
I don't get the question clearly, but I am taking a guess here. Don't know if this is what you are looking for.
Note - You have GetTabData in both your javascript as well as cshtml code, I am hoping this is just coincidence, because the js function cannot be invoked via #Url.Action in this manner.
If you need to send two values as part of your URL, you could do it either in a RESTful way or have querystrings.
Option 1 -
Url.Action("GetTabData", new { page=2, tab="blah" })
Your corresponding controller action would look like
public ActionResult GetTabData(int page, string tab)
{
...
}
Option 2 -
create a querystring and append it to the URL
/GetTabData?page=2&tab=blah
In this case the controller action would look like this
public ActionResult GetTabData()
{
var params = Request.QueryString;
...
}
In a user control I have an unordered list that contains items showing editable file data.
I create these items in my javascript using a JSON string set in a hidden field when the page is loaded or when the controlling element (AJAX async file upload) performs it's OnClient_UploadComplete function.
Everything I have is solid so far: the items are created on the client side, and I can get any values changed using an existing hidden field and transfer the data back to a BL object when I need it.
My problem is that during the server-side On_UploadComplete function, my server code cannot find any of the dinamically created items created by my javascript to add essential data to the new item.
I have to be missing something. The value I get from the control is "/r/n"..
My best guess is that my c# code is set up wrong. On the page, to find the ul I have:
Control m_ulFileItems = m_fuPhotoUpload.FindControl("m_ulFileItems");
I'll do some more loking, but this is an important aspect of getting this control to work.
I do not have any idea how you could be able to access these controls on server side. However, what I would suggest is that you pass their values from client to server, perhaps like this:
$.ajax({
url: ...,
type: ...,
data: ids and values from your controls in json format
});
Here are some more details:
if this is the HTML:
<div>
<div id="placeHolder"></div>
<input type="button" value="Submit" onclick="submit();" />
</div>
And I have added some text boxes the following way:
$(document).ready(function () {
for (var idx = 0; idx < 10; idx++) {
$('<input class="myInput" type="text" />').appendTo($('#placeHolder'));
}
});
Then this should work:
function submit() {
var jsonInput = '{';
var inputList = $(".myInput");
for (var idx = 0; idx < inputList.length; idx++) {
jsonInput = jsonInput + 'txt_' + idx + ': ' + $(inputList[idx]).val() + ',';
}
jsonInput = jsonInput.substring(0, jsonInput.length - 1);
jsonInput = jsonInput + '}';
alert(jsonInput);
$.ajax({
url: "WebForm1.aspx/HandleSubmitClick",
data: jsonInput
});
}
Hope it helps.
If you do not like the Ajax call to the server I can suggest to use a hidden control, and put that string into the hidden control before you go to the server. Then you will be able to take the value of that hidden control on the server side.
Anyway, this is the basic idea - collect and prepare the data on the client side, then send it to the server side somehow.
Add a hidden field to the page and before posting back to the server, scan all the items in the list, maybe create a JSON object which contains all the needed info from the created items, and set the hidden field value to this JSON. Now you should be able to grab that value and parse the JSON in C# and handle it from there.
I am quite new to this net mvc thing. to understand what I am trying to do I will put an example.
Example
I have a list of clients that contains data and in my view I used a <select> with a foreach that goes through all the clients to show the data. What I am trying to do is, when a user selects a client name he would be redirected to another page where that page would get the client name as a parameter & do stuff with that.
I tried this but I am stuck in a part
<select>
#foreach (var item in Model.clients)
{
<option>
#Html.Encode(item.name)
</option>
}
</select>
I know how to redirect from page A to page B like this RedirectToAction(...) what I want to do is handle that select action to call the method in my controller & use that method to send a parameter to page B
UPDATE
<script type="text/javascript">
function Fct() {
var v = arguments[0]; //get The ID in the parameter
window.location.href = "#Url.Action("Index", "PageB")?client_id=" + v;
}
</script>
I tried both lists and the one proposed by #Shyui is easier but i wanted to try something with this one
<select id="clients_list" onchange="Fct(this.value)">
<option class="placeholder" selected disabled value="-1">Select Name</option> <!-- Can't be selected -->
#foreach (var item in Model.clients)
{
<option value="#item.ID">
#Html.Encode(item.name)
</option>
}
<option value="0">New Client</option>
</select>
Listen to the change event of the dropdown, get the selected option and redirect the user to the next action.
<select id="Clients">
#foreach (var item in Model.clients)
{
<option value="#item.name">#Html.Encode(item.name)</option>
}
</select>
Here is the javascript(using jQuery) to handle the change event
$(function(){
$("#Clients").change(function(){
var v=$(this).val();
window.location.href="#Url.Action("Details","Clients")?clientName="+v;
});
});
I am using the Url.Action helper method to generate the correct relative path to the action method. This will work if your code is inside a razor view. But if it is inside an external js file, try the solution explained in this answer.
Assuming your Details action method in ClientsController accepts a client name
public ActionResult Details(string clientName)
{
// to do : Return something
}
You might also consider using the html helper methods like Html.DropdownList to generate the dropdown element instead of doing a foreach.
#Html.DropDownList("Clients",new SelectList(Model.clients, "name", "name"))
Also you might consider passing the unique client Id(numeric) instead of the client name. There are limitations of query string value length in some browsers.