My scenerio is a user could click on 12 different items on the page and depending on which item they click, a div will be populated with text. I was thinking a good way to do this is just pass all the different text strings to the client on their first request rather than doing a possible of 12 different AJAX calls. I figured front loading the client with the initial load time would be better since the text strings aren't long anyways.
What I am trying to figure out is the best way to write a javascript dictionary/hastable in my C# code behind and pass it to the page on load. What would be the best way to do this?
You can create 12 hidden divs, populate them with HTML and show the appropriate one depending on what the user clicked.
You can convert the Dictionary object to a JavaScript object literal, something like:
var pageContent = {
button1: "some content",
button2: "some other content"
// ...
};
Have a look at System.Runtime.Serialization.Json Namespace and this answer for code. You can then populate a div with the content depending on button clicked.
protected void btnHey_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
sb.Append("<script language='javascript'>alert('HEY');</script>");
// if the script is not already registered
if (!Page.ClientScript.IsClientScriptBlockRegistered(Page.GetType(), "HeyPopup"))
ClientScript.RegisterClientScriptBlock(Page.GetType(), "HeyPopup", sb.ToString());
}
You can take a look at this http://www.dreamincode.net/forums/topic/185586-aspnet-calling-javascript-from-code-behind/ I hope it helps...
From the point of view of the client you've basically got two choices:
Trigger an AJAX call on page load to get the data asynchronously. (See Sjoerd's answer)
Get ASP to push the data directly into your HTML / JavaScript. (See Ewerton / Scorpio's answers)
If you're uncomfortable having ASP generate your JS dynamically you could also get it to output a script tag with your data in it:
<script type="text/json" id="strings">
<asp:Literal runat="server" ID="JavascriptData" />
</script>
Produces:
<script type="text/json" id="strings">
{ "div1" : "First String",
"div2" : "Second String",
"etc" : "And so on" }
</script>
And then read the data in your javascript:
var json = document.getElementById('strings').InnerHTML;
var strings = JSON.Parse(json);
ScriptManager.RegisterStartupScript will do the trick
To solve such a problem myself, I have made a HttpHandler that returns JSON:
public class JsonData : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var json = serializer.Serialize(GetData());
context.Response.ContentType = "application/json";
context.Response.Write(json);
}
}
In the Javascript of my ASPX I use jQuery to retrieve the data:
$.getJSON("/JsonData.ashx", null, function (data) { ... });
This is really an out-of-band solution, in that the ASPX file retrieves a second file with the data.
What I also sometimes see is something like this:
<script>
var myData = '<asp:Literal runat="server" ID="JavascriptData" />';
</script>
Where JavascriptData is then filled in the codebehind. I don't really like this method, but it is simple and it works. Don't forget to escape your quotes.
You can store your html content in a string format in hidden fields, or you can populate 12 separate divs from your server side code. Then write some javascript to show-hide divs based on the button clicks.
Related
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'm working on an ASP.Net project, with C#.
Usually, when I need to put Buttons that will execute some methods, I will use the ASP Controller (Button) inside a runat="server" form.
But I feel that this really limits the capabilities of my website, because when I used to work with JSP, I used jquery to reach a servlet to execute some codes and return a responseText.
I did not check yet how this is done in ASP.Net, but my question concerns controllers and the famous runat="server".
When I add a runat="server" to any HTML Element, I'm supposed to be able to manipulate this HTML element in C# (Server-Side), and this actually works, I can change the ID, set the InnerText or InnerHtml, but the thing that I can't get, is why can't I execute a method by clicking on this element?
The "onclick" attribute is for JavaScript I think, and OnServerClick doesn't seem to work as well. Is it something wrong with my codes? or this doesn't work at all?
You will have to handle the click in the div using the Jquery and call
server-side methods through JQuery
There are several way to execute server side methods by clicking on a div or anything on your page. The first is mentioned __dopostback, second is handling the click in javascript or with jQuery and calling a function in a handler or a page method in a webservice or a page method in your page behind code.
Here is the handler version:
$("#btn1").click(function() {
$.ajax({
url: '/Handler1.ashx?param1=someparam',
success: function(msg, status, xhr) {
//doSomething, manipulate your html
},
error: function() {
//doSomething
}
});
});
I think the second version is better, because you can make a partial postback without any updatepanel, asyncronously. The drawback is, the server side code is separated from your page behind code.
Handler:
public class Handler1: IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
var param1= context.Request.QueryString["param1"];
//param1 value will be "someparam"
// do something cool like filling a datatable serialize it with newtonsoft jsonconvert
var dt= new DataTable();
// fill it
context.Response.Write(JsonConvert.SerializeObject(dt));
}
}
If everything is cool, you get the response in the ajax call in the success section, and the parameter called "msg" will be your serialized JSON datatable.
You can execute a method from jquery click in server, using __doPostBack javascript function, see this threat for more details How to use __doPostBack()
Add this code in your jquery on div onclick and pass DIv id whcih call click
__doPostBack('__Page', DivID);
On page load add this code
if (IsPostBack)
{
//you will get id of div which called function
string eventargs = Request["__EVENTARGUMENT"];
if (!string.IsNullOrEmpty(eventargs))
{
//call your function
}
}
Make the div runat="server" and id="divName"
in page_Load event in cs:
if (IsPostBack)
{
if (Request["__EVENTARGUMENT"] != null && Request["__EVENTARGUMENT"] == "divClick")
{
//code to run in click event of divName
}
}
divName.Attributes.Add("ondivClick", ClientScript.GetPostBackEventReference(divName, "divClick"));
Hope it helps :)
if you are referring to divs with runat="server" attributes, they don't have onserverclick events, that's why it doesn't work
I'm wondering if anyone knows of a way to allow something like "<<" to be submitted, without setting validaterequest=false
I have a creole parser, and the recommended plugin/macro syntax is:
<<macro-name argo0=foo arg1=bar argN=qux>>
I wrote a little ‘encodeMyHtml’ JavaScript function that is called on the OnClick event when the HTML form’s submit button is clicked. The function encodes the user’s HTML input for the field I’ve specified into a harmless string before it is passed to the server. When I receive that input on the server I simply decode and go on my way.
ValidateRequest is happy, our users are happy, our peers are happy, heck we’re happy.
I add my ‘encodeMyHtml’ JavaScript function in my user control’s OnPageLoad method. This way I can make sure that my JavaScript is added to the parent page only once, no matter how many controls are on the page.
In my control’s OnPageLoad I call this:
private void addEditorJavaScript()
{
// create our HTML encoder javascript function
// this way it shows up once per page that the control is on
string scr = #"<script type='text/javascript'>function encodeMyHtml(name){
var content = document.getElementById(name).value
content = content.replace(/</g,'<');
content = content.replace(/>/g,'>');
document.getElementById(name).value = content;
}</script>";
// add the javascript into the Page
ClientScriptManager cm = Page.ClientScript;
cm.RegisterClientScriptBlock(this.GetType(), "GlobalJavascript", scr);
}
In my control’s ASPX I’m using a gridview. I wrap the gridview’s update asp:LinkButton in a span tag, and in that span tag I put my OnClickEvent.
<span onclick="encodeMyHtml('<%# UniqueID.Replace("$", "_") %>_FormViewContentManager_ContentTextBox')">
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update" Text="[Publish]" />
</span><span onclick="encodeMyHtml('
When I get the input on the server side I simply call a couple of Replace methods on the input string to decode the HTML, and I’m done.
You could do a javascript regex replace for "<\S" on the specific field on form submit. But it would fail for browsers that don't support javascript.
You can encode the "<<" on the client using Javascript:
<script language="javascript">
function encodeString(str) {
return str.replace(/</gi, '<').replace(/>/gi, '>');
}
</script>
And then on the server use Server.HtmlDecode to return the string to its original form.
i have been trying to create controls dynamically on my web page using the StringBuilder class..and i dont quite seem to get through...
any help would be appreciated.
i am trying to do this...
StringBuilder sbTest = new StringBuilder(string.Empty);
sbTest.Append("<input type=\"text\" id=\"txt1\" runat=\"server\" />");
Response.Write(sbTest.ToString());
The page for sure displays a TextBox on the browser which is easily accessible through JavaScript...but what i want is the control to be available on the Server Side too...so that when the page is posted back to the server i can easliy obtain the value that has been entered by the user into the textbox.
Can any 1 please help me with this....
thank you so much....
Like Torbjörn Hansson says, if you just add a name attribute (and maybe remove runat="server" from your original snippet) you'll be able to access the submitted value but you'll only have a client-side HTML <input /> element.
If you are wanting to dynamically create server-side controls then you'll have to do something like this:
TextBox textbox = new TextBox {
/* take care to create unique ID's if you're adding more than 1 TextBox */
ID = "foo",
Text = "bar"
};
Controls.Add(textbox);
In an answer almost about the something I answered this
You should do the things properly and not trying to reinvent the wheel.
Creating controls Dynamically you can choose 2 ways, the .NET way, or the Javascript way
Both are seen by any of the other, in other words, creating controls using the .NET way, javascript can see and use it and vice versa.
.NET way
in your HTML file add something like
<body>
<form id="form" runat="server">
<asp:PlaceHolder id="ph" runat="server" />
</form>
</body>
in your script part
TextBox txt = new TextBox();
txt.ID = "myTxt";
ph.Controls.Add(txt);
you can easily get that TextBox in javascript using:
var myTxtValue = $("#myText").value();
Javascript Way
var txt = $("<input />", {
id : "myTxt"
});
txt.AppendTo("body");
in .NET you get the value using
string value = Request["myTxt"];
NOTE All javascript lines uses jQuery for simplify results
Provide a name-attribute and access it with:
Request.Form["txt1"]
You can get the value from
Request["txt1"]
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} );