I want to build a webpage containing jquery draggables in asp.net (c#).
How can I add my jquery code to my page in an object oriented way?
So I want to make a c# myDraggables.cs class that I add to the asp page with the htmlgenericcontrol. How do I add this jquery code (eg: $('#mydraggables').draggable(); ) in my class.
I could do it with the htmlgenericcontrol by adding a "script"-tag. But isn't there a way to do it with a jquery helper (can't find that)?
tx
A sample:
Basicly, in my myDraggables-class I could have;
public HtmlControl Draw()
{
HtmlGenericControl aDiv= new HtmlGenericControl("div");
aDiv.Attributes.Add("id", "dragtest");
return aDiv;
}
public HtmlControl DrawJquery()
{
HtmlGenericControl js = new HtmlGenericControl("script");
js.Attributes["type"] = "text/javascript";
js.InnerHtml = "$('#dragtest').draggable();";
return js;
}
And the code behind of my asp.page would look like;
protected void Page_Load(object sender, EventArgs e)
{
myDraggables md = new myDraggables ('..some props ..');
Page.Header.Controls.Add(md.DrawJquery());
myPlaceHolder.Controls.Add(md.Draw());
}
That works, but jquery-code will become more complex. And will not be readable anymore...
how can this be achieved in json? Or another more readable way?
Thanks
If I understand you correctly, you want to write a strongly-typed .NET class in the back-end which also functions as a jQuery object on the front-end, right? If so, the best way to do it is probably to serialize your .NET object into JSON format, store it in a variable and print it out in a script tag when generating the markup. Then, on the front-end, parse the JSON string into a Javascript object and you can use it from there.
Can you post any .NET and JS code you have already?
Related
I have a simple Blazor component that take some inputs (some lists of object and few strings) and formats them into simple HTML for display, (tables generated from the lists of objects, simple text, etc.).
This HTML is a report that is intended to be both displayed to users in the app and also emailed to various people (via SendGrid). For compatibility, we are keeping the email HTML as simple as possible.
The component works fine, however I am not sure how to translate a component's markup portion into a simple string of escaped HTML so that I can pass the string to SendGrid and fire off an email.
I am aware of MarkupStrings, but I have only used them in reverse--to write a string containing HTML tags that will be properly displayed in my app. I can't find any suggestions for doing the conversion the way that I need it done.
Is there any simple way to have a component write all of its markup into a string so that I can email it out?
Or, would I be better off writing a .cs file with a static method that takes in the parameters in question, renders it into a MarkupString, and then passes the string both to SendGrid for email and also to a Blazor component for in-app display?
The simplest way to do that is to employ JSInterop to retrieve the Html markup for the component, produced by the browser. Let's say You've defined a child component, and you want to retrieve its html source. You can do that like this:
Define the child...
SelectGender.razor
<div id="selectGender">
<h1>Select Gender</h1>
<select>
#foreach (var gender in genders)
{
<option>#gender</option>
}
</select>
</div>
#code {
private List<string> genders = new List<string> { "Male", "Female", "Other" };
}
Usage
#page "/"
#inject IJSRuntime JSRuntime
<div>#((MarkupString) html)</div>
<SelectGender />
<button #onclick="GetHtml">Get Html</button>
#code{
private string html;
protected async Task GetHtml()
{
html = await JSRuntime.InvokeAsync<string>("myJsFunctions.getHtml");
}
}
_Host.cshtml
<script>
window.myJsFunctions =
{
getHtml: function () {
return document.getElementById("selectGender").innerHTML;
}
};
</script>
Is there any simple way to have a component write all of its markup into a string so that I can email it out?
No, your C# code has no simple way to do this - you could use JS Interop to get the rendered HTML from the dom, but nothing built in for it.
Or, would I be better off writing a .cs file with a static method that takes in the parameters in question, renders it into a MarkupString, and then passes the string both to SendGrid for email and also to a Blazor component for in-app display?
That is a possibility - I can't comment on the value of that to you, but it is a technique that could work if the component you are rendering is static,
I am using a 3rd party control for GIS map related functions.
I had the need to call a C# Method from within javascript. I chose to use PageMethods like this:
PageMethods.getFeature(x,y)
Works like a charm as long as you convert your method to a [WebMethod]
In this method I am passing in the coordinates of the mouse and it returns me map features. That I will highlight on the map.
From researching I found that you cant directly access the UI from inside a [WebMethod] so I decided to set a session variable and postback. On postback if the session variables exist I would make the necessary UI changes.
My WebMethod looks like this:
[WebMethod(EnableSession = true)]
public static void getFeature(float x, float y)
{...
some code in here.
}
Update
This is my jQUery:
<script>
$(document).ready(function (e) {
$(".MyMap").click(function (e) {
var posX = $(this).position().left;
var posY = $(this).position().top;
PageMethods.getFeature(e.pageX-posX, e.pageY-posY);
});
});
</script>
How do I force a postback inside of a WebMethod. Most of the ways I know to postback don't work.
Special Thanks to #BenRobinson for assisting me in the right direction. Here is what I came up with. I am posting this for other people who may make a similar mistake. The short answer is: **You Cant
My main issue was I was using a [WebMethod] so my c# code could be called from jQuery. This worked perfectly until I needed access to the UI. Well technically a 'WebMethod' is almost like calling a web service. You cant have a remote web service update the UI. What you can do is after your function in jQuery runs that calls the [WebMethod], is have it call a new page (window.location). That location can call the original page (in my case Default.aspx). I passed parameters in the request field that I needed to send to the UI, and I basically put code in that if on load you see a particular request variable then do something... It worked like a charm.
Here's a rough example:
In my jQuery page I did this (to navigate to a new page):
window.location.replace("ZoomAndCenter.aspx?x=" + (e.pageX - posX) + "&y=" + (e.pageY - posY))
Here is what my ZoomAndCenter.aspx looked like:
protected void Page_Load(object sender, EventArgs e)
{
int x = 0;
double y = 0;
x = Int32.Parse(Request["x"].ToString());
y = Double.Parse(Request["y"].ToString());
//Run some more code
Response.Redirect("Default.aspx?Param1=xxxx&Param2=xxxx");
//passed the params in the redirect.
}
Then in the Default.aspx
if(request["param1"] == "something")
{
//do something
}
I have a published project which is used by side company and which can not be updated now. The application got quite some changes which should not be published to this certain URL. Instead on one aspx page.
Question - how can I create DLL for one single aspx page inside big project so I will be able publish only it.
Thank you
Encapsulate all logic in a class library :
public class MyBusinessLogic
{
public bool DoSomethingWithFormData(string val1, string val2)
{
//do your logic here...
}
}
And create your Aspx page , in the code behind use :
protected void YourButtonOnPage_Click(object sender, EventArgs e)
{
MyBusinessLogicm = new MyBusinessLogic();
m.DoSomethingWithFormData(txt1.Text,txt2.Text);
}
In this way you have to publish only a dll and an aspx page.
Note that the code is not clean.. don't pass textbox data to business in this way but do some validation first.
I have an ASMX service which serves some partial-HTML to a web-app as part of a JSON object. Until now, I've just been building the HTML in code, using StringBuilders. This is a huge pain since the formatting is really hard to read and I can't use any of Visual Studio's/Resharper's code completion, syntax highlighting, and other convenient features.
I tried to solve this with User Controls (I'm not committed to this approach if there is a better way. All I need are some very simple parametrized static partial HTML pages), but now I am running into problems when I try to render the control like this:
public override string Html
{
get
{
StringWriter writer = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
CreateTestWizardPartials.TestPeriods testPeriodsHtml = new CreateTestWizardPartials.TestPeriods();
testPeriodsHtml.RenderControl(htmlWriter);
htmlWriter.Flush();
return writer.ToString();
}
}
This always returns an empty string. I've read you need to use Page.LoadControl() to dynamically load User Controls but there is no Page for me to use it with. Is there a workaround or a better solution than User Controls?
Thanks!
You could load static HTML file that contain the partial bits of markup you need. If you need to somehow bind the markup with dynamic data, then render the HTML files through a template engine.
Here's and older post regarding some template systems for ASP.Net:
Can you recommend a .net template engine?
And another more recent post regarding ASP.Net MVC:
JQuery's $ is in conflict with that of StringTemplate.Net in ASP.Net MVC
Whenever i want to add a javascript library programatically, say jquery for example, it generally involves making sure there is a placeholder at the footer of my page, then calling a codebehind method that will take a link to the src as a parameter and return an htmlgeneric control, which is then added to this placeholder.
Is this still the neatest way to do it, even with .net 4.0 out?
I think a better way is to use the RegisterStartupScript method:
http://msdn.microsoft.com/en-us/library/z9h4dk8y.aspx
And even better in your case RegisterClientScriptInclude:
http://msdn.microsoft.com/en-us/library/kx145dw2.aspx
EDIT:
Here's a sample of RegisterClientScriptInclude:
if (!Page.ClientScript.IsClientScriptIncludeRegistered("myJsInclude"))
Page.ClientScript.RegisterClientScriptInclude("myJsInclude", "myJsFile.js");
EDIT2:
Here's a sample of an include with RegisterStartupScript:
string jsBlock = "<script src='myJsFile.js'></script>";
if (!Page.ClientScript.IsStartupScriptRegistered("myJsInclude"))
Page.ClientScript.RegisterStartupScript(typeof(string), "myJsInclude", jsBlock, false);
You should add things like language="text/javascript" to the script tag, but for readability I didn't add them.
Sorry... I decided to move my comment to an answer.
I personally add all of my JS to the ScriptManager. It helps lower the number of Http calls that the page has to make.
ScriptManager1.CompositeScript.Scripts.Add(New ScriptReference("~/Page/To/Jquery.js"))
But this is only if you're already using a ScriptManager on your page
Also, if you don't want to add it from CodeBehind, you can do it right in your page.
<ScriptManager>
<CompositeScript>
<Scripts>
<-- your scripts in here -->
</Scripts>
</CompositeScript>
</ScriptManager>
So by doing this, you're able to add all of your JS to a single HTTP Request rather than having a bunch of different requests all at once.
Then in the ScriptManager tag, you can add LoadScriptsBeforeUI="false" to have them put to the bottom of the page.
Sorry but that was never the cleanest way to inject script into an asp.net page.
Look at the ClientScript object. There are several methods that will suit your needs without resorting to placeholders.
ScriptManager is a good way to do this, as mentioned above. If you are not using MS Ajax and ScriptManager, then I suggest you write your own control. It should be very simple control at that. Add a public variable List and override RenderContents method to walk through your list of strings and render on the page. Sample code:
public class CustomScriptManager : WebControl
{
private List<string> scripts = new List<string>();
public List<string> Scripts
{
get { return scripts; }
set { scripts = value; }
}
protected override void RenderContents(HtmlTextWriter writer)
{
foreach (string script in scripts)
{
writer.Write("<script language=\"JavaScript\" type=\"text/javascript\" src=\"" + script + "\"></script>");
}
}
}
P.S. I haven't verified above code, but I thing you get the idea.