I am passing viewdata into my aspx page like so:
//Controller
List<user> userList = Data.GetAllUsersForCompany(companyId);
List<SelectListItem> dropDownList = FormatUserList(userList);
ViewData["UserList"] = userList;
ViewData["FormattedUserList"] = dropDownList;
return View();
I am populating a drop down with the name of a user, which I want to bind with Jquery so that when the user changes the drop down this in turn updates the input fields with the current selected user.
The ASPX page:
<p>
<%= Html.DropDownList("userSelected", (List<SelectListItem>)ViewData["FormattedUserList"] )%><br /><br />
<%= Html.TextBox("userFName")%><br />
<%= Html.TextBox("userLName")%><br />
<%= Html.TextBox("userEmail")%>
</p>
I hook up Jquery to detect the drop-down changes which work, but how do I manipulate the input boxes with data?
<script type="text/javascript">
$(document).ready(function() {
$("#userSelected").change(function() {
var pkUser = $("#userSelected").val();
alert("Current UserID is " + pkUser); //works up to here just fine
$("#userFName).val() = ViewData["UserList"].Select(x => x.pkUser == valueOfDropDown).fName; ???
.
.
.
});
});
</script>
Am I doing things completely wrong? Can you point out what the best practice is for this scenario. If I can get away from having postbacks that would be ideal.
Soul (MVC newbie)
It looks like you are mixing your javascript and c#, remember that the javascript only executes client side, and the c# only executes server side. That being said, if you want to have some of your viewdata hanging around for your javascript to use on the client side, you need to encode it in the page somewhere the javascript can get at it. The easiest way I can think of is to use a JavaScriptSerializer and embed the values into your javascript, kind of like:
<%
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
%>
<script type="text/javascript">
var users = <%= serializer.Serialize(ViewData["UserList"]) %>;
//Use the users variable now with a copy of the view data.
</script>
In most cases, it is better to have static javascript files. It's not universally the case, but its often very hard to manage code that's parsed together at runtime. So rather than trying to write serverside code in your script tags (like the line that seems to be breaking), you should try writing the data to a hidden part of the page, perhaps, and then getting that data with jQuery.
You should be able to output a hidden form element with the value of any data that you want to use later on.
Say your output was:
<input type="hidden" id="fname_store" name="fname" value="soul" />
This could also be a single variable that is set in an inline script if you find this method messy:
<script type="text/javascript">
var data = <% serialized_data_from_the_server_side %>;
</script>
Then your line that breaks would be something like this:
$('#userFName').val($('#fname_store').val());
Notice that you are missing a quote in your code at the end of the selector, and also notice that the jQuery val() function is set by passing it a value, not setting it equal to a value.
Best of Luck!
You can always update your Action.
List<user> userList = Data.GetAllUsersForCompany(companyId);
List<SelectListItem> dropDownList = FormatUserList(userList);
return Json(new { UserList = userList, FomattedUserList = dropDownList} );
Related
What would be the best method to transfer data from one view to another view? or is this bad practice?
The reason is that i want to display #model.count() from one view to the homepage, basically a summary of all the views on the homepage. There is tempdata, html.helper etc but id like to know the best and most reliable method. Thus avoiding problems further on down the line
here is the code in question
product.cshtml
<p>Total amount of Products = #Model.Count()</p>
i basically want that same value to display on the homepage
You'd have to refresh the homepage for the value to actually 'update.' At that point you may as well pass the value back in as a parameter, but I think that's not what you're hoping for.
It probably isn't the cleanest solution, but I would think you'd want your text on the main page to be settable via some javascript/jquery.
Main Page has this snippet:
<form id="PassBackVals"
<input type="hidden" name="ProductCount" value="0">
</form>
<script>$( ".ProductCount" ).change(function() {
$("$CurrentProductCount").text = $(".ProductCount").val;
});
</script>
and the Area displaying the text itself on the main would have something along the lines of
<p> I'm currently showing <div id="CurrentProductCount">0</div> Products </p>
Then in your product.cshtml, you'd have
<script>$(".ProductCount").val = #Model.Count()
$( ".ProductCount" ).change();
</script>
Ok i looked into other methods and resolved the issue by moving the code behind the viewbag into a public method below
[OutputCache(NoStore = true, Location = OutputCacheLocation.Client, Duration = 10)]
public ActionResult UpdateTotals()
{
JobController j = new JobController();
ViewBag.JobCount = j.JobCount();
ProductController p = new ProductController();
ViewBag.ProductCount = p.ProductCount();
return PartialView("UpdateTotals");
}
then i added the viewbags into a partial view and using setinterval() javascript,
<div id ="UpdateTotals">
#{ Html.RenderAction("UpdateTotals");}
</div>
<script>
setInterval("$('#UpdateTotals').load('/home/UpdateTotals')", 10000);
</script>
i was able to refresh the data constantly to my desire without the mess of pulling data through views via javascript.
hopefully this will help anyone in future :)
There's sometimes that you need to add another textbox or other input type for additional information. Ok, say, A Customer can have many Address. As the user completes the form and as he reach the address he can hit the plus sign to add another textbox for another address. So what I did is something like this: (don't know if it's recommended or not)
Html:
Additional Address
<div class="address-container"></div>
JS:
<script>
$(function() {
var i = 0;
var addAddress = function() {
var strBuilder = '<input type="text" name="Addresses[i].Location" />';
$('.address-container').append(strBuilder);
i++;
return false;
};
$('.add-address').click(addAddress);
});
</script>
So my question is:
It is possible to add the textbox as this #Html.EditorFor()?
It would really be great if I can also add in the #Html.ValidationMessageFor(), is it possible?
I'm using ASP.NET MVC 4; EF Code first approach.
Any help would be much appreciated. Thanks.
Just use i for name attribute.
name="Addresses[' + i + '].Location"
This shoud bind with your model.
var i = 0;
var addAddress = function() {
var strBuilder = '<input type="text" value="" name="Addresses[' + i + '].Location">';
$('.address-container').append(strBuilder);
i++;
return false;
};
See this post which was much useful for me.
Updated
for validation just add this attributes too along with input element.
data-val-email="The Email field is not a valid e-mail address."
data-val="true"
An idea behind this is that, appending correct element with name attribute and validation(data-val="true").
You can see rendered html for already working page where you have used validation.
No, razor works on he server side. Once you're on the client, you don't have access to #Html. This post shows how to model bind with lists, though it looks like you already have a grasp on that with your i iterator.
Generally, I'll have razor produce a mocked Address[0], then copy that generated html into the javascript to generate. It should retain all client-side validation attributes that jQuery looks for.
It is possible to use Razor generated tags on the client side. Create an EditorFor template file that uses {...} syntax for dynamic properties. Then use it like this.
<script type="text/javascript">
var editorFor = '#Html.EditorFor(...)';
var i = 0;
$().ready(function(){
$('.address-container').append(editorFor.replace("{id}", i));
i++;
}
});
</script>
You are not able to add HTML helpers on the client side. You can, however, add simple HTML controls using jquery in a number of ways. You can use the append function as you have above or the html function.
Your validation will also have to be handled client side.
But for best practices, you should create a partial view template of address text fields and then use Knockout to add a new template each time the user clicks add new address. You can then handle validation easily because your viewmodel will be bound to your MVC model.
I am trying to pass parameter to one function in the code behind in C# from javascript
<script type="text/javascript">
$(document).ready(function () {
$("#some_id").click(function () {
var id = document.getElementById('HiddenField2');
var a = <%=btn_Click(id)%>;
});
});
</script>
<asp:HiddenField ID="HiddenField2" runat="server" Value='<%# DataBinder.Eval(Container.DataItem, "item_id")%>' />
code behind
public string btn_Click(String item_id)
{
/*do some thing*/
return null;
}
But this piece of code always giving me error of context. That id is not defined in this context.
Can some please let me know what wrong i am doing?
First, var id is javascript and the code within <%= %> is C#. You can't pass a variable between the languages like that.
Second, the value of id in this case is going to be a DOM element which C# can't use anyways. If you want to get the value of HiddenField2 within the code behind you can use HiddenField2.Value.
Third, since you're using ASP.net, instead of using jQuery's .click handler you should use the onServerClick attribute to wire up the button click behavior to btn_Click.
The button click event in C# will be triggered by Postback when your browser post data back to asp.net
I do not understand why you use HiddenField here,so my suggestion do not consider about it
Solution 1:
first you can extract your code in btn_Click to a HttpHandler(*.ashx in asp.net),then use Ajax by using js framework like jQuery to send data to your HttpHandler,data returned by HttpHandler can be processed by js
sample code is here
Solution 2:
if your code in btn_Click is relevent to your page, just use ajax Get method, the data will send to your page,the data returned by your data will be processed by js too
In the end, if you are new to web, I recommend you to learn or implement asp.net MVC, in my opinion, it is more flexible than asp.net webform
I have <asp:TextBox runat="server" ID="lastName" /> on a page and I want to set focus it with jQuery but it is not returning it. My code is like this:
$.ready() {
var tb = $('lastName').focus(); // don't work, why?
}
You have two different problems here that you need to resolve: a malformed selector and the fact that in ASP.NET client IDs don't match server IDs.
What you want is:
$.ready() {
$('#<%= lastName.ClientID %>').focus();
}
Let's break it down...
First, in jQuery a selector that accesses an element by it's id attribute needs to begin with a '#' symbol. So the accessor should look more like: $('#lastName'). Selectors in jQuery are similar, but more robust than in CSS. You can familiarize yourself with the selector syntax at the jQuery API site.
Second, with ASP.NET, the id's assigned to the HTML elements are often different than those that identify an asp control on the server. This is because ASP.NET needs to make sure that all elements are uniquely identified - and don't collide with names that may be defined in master pages, user controls, or repeated sections of content. These ids tend to get long and are often impossible to predict - fortunately, we can use the <%= %> code expansion together with the ClientID property of the control to insert the appropriate id for the HTML element without having to know the details of how ASP.NET assigns unique ids.
In ASP.NET 4.0, the client ID can now be specified directly, which can help avoid the technique shown above.
Here is a function I use for selecting server controls in pages that have a masterpage. It doesnt work in all cases such as nested controls but for simpler stuff its real handy.
This goes on the masterpage somewhere
<script type="text/javascript">
baseName = "<%= Content.ClientID %>_";
</script>
Using this function you can go GetServerElementById("lastname")
function GetServerElementById(id) {
return $("#" + baseName + id);
}
You can do a partial attribute query:
<script type="text/javascript">
$(function() {
$('#btnExtract').click(
function() {
alert($("input[id$='txtMessage").val());
}
);
});
Selecting ASP.NET Web Controls in jQuery
I'm trying to read the value of a C# property from my code behind file into some JQuery script (see below). The JQuery selector I've written accesses an ASP.Net GridView and then a CheckBox field within the gridview. Whenever a checkbox is checked or un-checked the code is hit, but I need to access the C# property from the code behind to take the appropriate action based on the value of the property.
$(".AspNet-GridView-Normal > td > input").click(function() {
//Need to access the C# property here
//Take action here based on the value of the C# property
});
This may be stating the obvious, but the code behind doesn't exist on the client side where your jQuery code is executing. What you could do is assign the value of the property to a hidden field on the server side so that when you need to check it with jQuery on the client side it will be available. So you might do the following on the client side.
Markup:
<asp:HiddenField ID="hfValueINeedToKnow" runat="server"/>
Code Behind:
hfValueINeedToKnow.Value = <some value>;
jQuery:
$("#<%= hfValueINeedToKnow.ClientID %>").val();
You might need to make some minor changes to support a value for each row of the grid, but hopefully this explains the general idea.
You mentioned in a comment that the value is an int. And I see it's also a public property in your codebehind. This is trivial now - you don't need to escape the value, nor access it in some round-about way, and you get type safety for free:
<script>
$(".AspNet-GridView-Normal > td > input").click(function() {
var AvailableInstalls = <%= AvailableInstalls %>;
});
</script>
Well you can't.
You need to render the C# property in some element (perhaps a hidden field) and then look at it that way.
But explain further: What property are you trying to check?
What I've done for this scenario in the past is to print out my code value into the markup and store whatever it is in a javascript variable, thus making a copy of it available to client-side code. This is a silly example, but hopefully it makes sense:
<%
var messsge = "Hello World!"
%>
<html>
<head>
<script type="text/javascript">
function ShowMessage()
{
var msg = '<%= message %>';
if(msg)
alert(msg);
}
</script>
</head>
</html>
There isn't a really clean way to do this. Your best bet would probably be to use the ClientScript.RegisterClientScriptBlock functionality built into ASP.NET. Here's a good primer.
private int myValue;
protected void Page_Load(object sender, EventArgs e) {
ClientScript.RegisterClientScriptBlock(typeof(Page),
"vars", "<script>var myParams = { p1: " + myValue + ", p2: 'My Name' };</script>");
}
This will put the supplied script on your page towards the top of the form. You can change that too. Obviously, it isn't the prettiest; you are essentially string concatenating a different language, but it will work, and for simple variable declaration isn't too rough on the eyes.
ASP Embedded in JavaScript always makes me nervous from the perspective of script injection attacks and the inability to unit-test your JavaScript.
This build upon an ealier answer:
<script type="text/javascript">
$(".AspNet-GridView-Normal > td > input").click(function() {
var AvailableInstalls = $("#MyHidden").val();
});
</script>
You could move it to a hidden variable:
<input type="hidden" id="#MyHidden" value="<%= AvailableInstalls %>" />
However this doesn't get around the problem of injection. So you could you could add a server-side hidden variable and set it from the Page_Load event function in ASP.NET.
(P.s. you also need the attribute type="text/javascript" in your script tag to make it valid HTML).
If you will put your value into an asp:HiddenField with id hfValueINeedToKnow, the simplest way to retrieve this value client side is
var jsvar = $("[id$=hfValueINeedToKnow]").val();
So you can also place this code in a separate .js file.