make dynamically generated href call a c# function - c#

I am trying to build a dropdown as below.
I am generating html ul & li tags as below and works fine. However, everytime there is an anch tag (see the in-line comment); I need to be able to call a function and pass a text that was clicked. How can I do this?
foreach (var productType in productTypesNames.Keys)
{
var li = new HtmlGenericControl("li");
nav.Controls.Add(li);
var ul = new HtmlGenericControl("ul");
var anchor = new HtmlGenericControl("a");
anchor.Attributes.Add("href", "#");
foreach (var pName in productTypesNames[productType] )
{
var subLi = new HtmlGenericControl("li");
var anch = new HtmlGenericControl("a");
anch.Attributes.Add("href", "#");
//**THIS NEEDS TO CALL A C# FUNCTION AND PASS pName; instead of #**
anch.InnerHtml = pName;
subLi.Controls.Add(anch);
ul.Controls.Add(subLi);
}
anchor.InnerHtml = productType;
li.Controls.Add(anchor);
li.Controls.Add(ul);
}

If you don't mind a postback, or want it, use a LinkButton control, easily built dynamically instead of your HtmlGenericControl("a"), and have the server-side onclick method call your other method.
Otherwise you need AJAX as others have explained.

Have your href execute a JS function and that can call the server via AJAX. You can had code your own, or use jQuery or [WebMethod]s with ASP.NET Ajax.
The idea is that you can execute a server-side method by calling the server via Ajax.
Also, look at the way JSONP works - maybe you can "ping" another page with URL parameters of your choosing to do a one-way async call.

Related

How to create HTML page by code [duplicate]

How would I open a new window in JavaScript and insert HTML data instead of just linking to an HTML file?
I would not recomend you to use document.write as others suggest, because if you will open such window twice your HTML will be duplicated 2 times (or more).
Use innerHTML instead
var win = window.open("", "Title", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=200,top="+(screen.height-400)+",left="+(screen.width-840));
win.document.body.innerHTML = "HTML";
You can use window.open to open a new window/tab(according to browser setting) in javascript.
By using document.write you can write HTML content to the opened window.
When you create a new window using open, it returns a reference to the new window, you can use that reference to write to the newly opened window via its document object.
Here is an example:
var newWin = open('url','windowName','height=300,width=300');
newWin.document.write('html to write...');
Here's how to do it with an HTML Blob, so that you have control over the entire HTML document:
https://codepen.io/trusktr/pen/mdeQbKG?editors=0010
This is the code, but StackOverflow blocks the window from being opened (see the codepen example instead):
const winHtml = `<!DOCTYPE html>
<html>
<head>
<title>Window with Blob</title>
</head>
<body>
<h1>Hello from the new window!</h1>
</body>
</html>`;
const winUrl = URL.createObjectURL(
new Blob([winHtml], { type: "text/html" })
);
const win = window.open(
winUrl,
"win",
`width=800,height=400,screenX=200,screenY=200`
);
You can open a new popup window by following code:
var myWindow = window.open("", "newWindow", "width=500,height=700");
//window.open('url','name','specs');
Afterwards, you can add HTML using both myWindow.document.write(); or myWindow.document.body.innerHTML = "HTML";
What I will recommend is that first you create a new html file with any name.
In this example I am using
newFile.html
And make sure to add all content in that file such as bootstrap cdn or jquery, means all the links and scripts. Then make a div with some id or use your body and give that a id. in this example I have given id="mainBody" to my newFile.html <body> tag
<body id="mainBody">
Then open this file using
<script>
var myWindow = window.open("newFile.html", "newWindow", "width=500,height=700");
</script>
And add whatever you want to add in your body tag. using following code
<script>
var myWindow = window.open("newFile.html","newWindow","width=500,height=700");
myWindow.onload = function(){
let content = "<button class='btn btn-primary' onclick='window.print();'>Confirm</button>";
myWindow.document.getElementById('mainBody').innerHTML = content;
}
myWindow.window.close();
</script>
it is as simple as that.
You can also create an "example.html" page which has your desired html and give that page's url as parameter to window.open
var url = '/example.html';
var myWindow = window.open(url, "", "width=800,height=600");
Use this one. It worked for me very perfect.
For New window:
new_window = window.open(URL.createObjectURL(new Blob([HTML_CONTENT], { type: "text/html" })))
for pop-up
new_window = window.open(URL.createObjectURL(new Blob([HTML_CONTENT], { type: "text/html" })),"width=800,height=600")
Replace HTML_CONTENT with your own HTML Code
Like:
new_window = window.open(URL.createObjectURL(new Blob(["<h1>Hello</h1>"], { type: "text/html" })))
if your window.open() & innerHTML works fine, ignore this answer.
following answer only focus on cross-origin access exception
#key-in_short,workaround:: [for cross-origin access exception]
when you exec code in main.html -- which tries to access file window_ImageGallery.html by using window.open() & innerHTML
for anyone who encounter cross-origin access exception
and you dont want to disable/mess_around_with Chrome security policy
-> you may use query string to transfer the html code data, as a workaround.
#details::
#problem-given_situation,#problem-arise_problem::
say you exec following simple window.open command as other answer suggested.
let window_Test = window.open('window_ImageGallery.html', 'Image Enlarged Window' + $(this).attr('src'), 'width=1000,height=800,top=50,left=50');
window_Test.document.body.innerHTML = 'aaaaaa';
you may encounter following cross-origin access exception
window_Test.document.body.innerHTML = 'aaaaaa'; // < Exception here
Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.
=> #problem-solution-workaround::
you may use query string to transfer the html code data, as a workaround. <- Transfer data from one HTML file to another
#eg::
in your main.html
// #>> open ViewerJs in a new html window
eleJq_Img.click(function() {
// #>>> send some query string data -- a list of <img> tags, to the new html window
// #repeat: must use Query String to pass html code data, else you get `Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.` (cross origin access issue)
let id_ThisImg = this.id;
let ind_ThisImg = this.getAttribute('data-index-img');
let url_file_html_window_ImageGallery = 'window_ImageGallery.html'
+ '?queryStr_html_ListOfImages=' + encodeURIComponent(html_ListOfImages)
+ '&queryStr_id_ThisImg=' + encodeURIComponent(id_ThisImg)
+ '&queryStr_ind_ThisImg=' + encodeURIComponent(ind_ThisImg);
// #>>> open ViewerJs in a new html window
let window_ImageGallery = window.open(url_file_html_window_ImageGallery, undefined, 'width=1000,height=800,top=50,left=50');
});
in your window_ImageGallery.html
window.onload = function () {
// #>> get parameter from URL
// #repeat: must use Query String to pass html code data, else you get `Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.` (cross origin access issue)
// https://stackoverflow.com/questions/17502071/transfer-data-from-one-html-file-to-another
let data = getParamFromUrl();
let html_ListOfImages = decodeURIComponent(data.queryStr_html_ListOfImages);
let id_ThisImgThatOpenedTheHtmlWindow = decodeURIComponent(data.queryStr_id_ThisImg);
let ind_ThisImgThatOpenedTheHtmlWindow = decodeURIComponent(data.queryStr_ind_ThisImg);
// #>> add the Images to the list
document.getElementById('windowImageGallery_ContainerOfInsertedImages').innerHTML = html_ListOfImages;
// -------- do your stuff with the html code data
};
function getParamFromUrl() {
let url = document.location.href;
let params = url.split('?')[1].split('&');
let data = {};
let tmp;
for (let i = 0, l = params.length; i < l; i++) {
tmp = params[i].split('=');
data[tmp[0]] = tmp[1];
}
return data
}
#minor-note::
(seems) sometimes you may not get the cross-origin access exception
due to, if you modify the html of 'window_ImageGallery.html' in main.html before window_ImageGallery.html is loaded
above statement is based on my test
& another answer -- window.open: is it possible open a new window with modify its DOM
if you want to make sure to see that Exception,
you can try to wait until the opening html window finish loading, then continue execute your code
#eg::
use defer() <- Waiting for child window loading to complete
let window_ImageGallery = window.open('window_ImageGallery.html', undefined, 'width=1000,height=800,top=50,left=50');
window_ImageGallery.addEventListener("unload", function () {
defer(function (){
console.log(window_ImageGallery.document.body); // < Exception here
});
});
function defer (callback) {
var channel = new MessageChannel();
channel.port1.onmessage = function (e) {
callback();
};
channel.port2.postMessage(null);
}
or use sleep() with async What is the JavaScript version of sleep()?
eleJq_Img.click(async function() {
...
let window_Test = window.open( ...
...
await new Promise(r => setTimeout(r, 2000));
console.log(window_Test.document.body.innerHTML); // < Exception here
});
or you get null pointer exception
if you try to access elements in window_ImageGallery.html
#minor-comment::
There are too many similar Posts about the cross-origin issue. And there are some posts about window.open()
Idk which post is the best place to place the answer. And I picked here.

how to passing value codebehind C# to javascript

Any one can help me..I want to pass the C# value to javascript..I only get pass 2 values only to the javascript..I dont know how to pass a tbSTime,tbETime and tbIndo2..Please help me..Thank You
This is code behind:
{
// get the meeting info based on the id
int id = Convert.ToInt32(Request["id"]);
MeetingClass.MeetingInfo m = MeetingClass.MeetingInfo.GetInfo(id);
// fill data
tbtitle2.Value = m.Title;
tbdate2.Value = m.Date.ToShortDateString();
tbSTime.Value = m.StartTime.ToShortTimeString();
tbETime.Value = m.EndTime.ToShortTimeString();
tbIndo2.Value = m.Desc;
}
And this is javascript:
function getInfo() {
$('#<%=tbtitle.ClientID%>').val($('#<%=tbtitle2.ClientID%>').val());
$('#<%=tbdate.ClientID%>').val($('#<%=tbdate2.ClientID%>').val());
}
From what I can tell on your code, you are setting an asp:HiddenField (since you are using .Value) and then using that to populate your asp:TextBox w/ jQuery. If that is the case, then you need to do something like this.
$('#<%=aspTextBoxName1.ClientID%>').val($('#<%=tbSTime.ClientID%>').val());
$('#<%=aspTextBoxName2.ClientID%>').val($('#<%=tbETime.ClientID%>').val());
$('#<%=aspTextBoxName3.ClientID%>').val($('#<%=tbIndo2.ClientID%>').val());
Where aspTextBoxName1, aspTextBoxName2, aspTextBoxName3 are the names of your new textboxes.
I don't know if you really need those hidden form fields, there are easier ways to do this if you don't.
in controller:
ViewBag.tbSTime = tbSTime;
in view:
$('#<%=tbtitle.ClientID%>').val("<%= ViewBag.tbSTime %>");
Iam sorry but iam not sure what exactly you need, but from what i understood i can provide you with this:
If You want to send some value from Server side variables to Javascript function one way you can do this as follows,
function abc(x,y)
{
//Do you things here
}
and from server side call javascript code as follows
string a=textbox1.text;
string b=textbox2.text;
ScriptManager.RegisterStartupScript(this, GetType(), "displayalertmessage", "abc("+a+","+b+");", true);

C# WPF WebBroswer Control: How to use JavaScript

I am using WPF WebBrowser control and I want to acces some of the JavaScript functions but there is the problem.
I can use InvokeScript and execute browser.InvokeScript("alert", "Hello");q but how to get element by ID or by TAG and how to assign that element to javascript var?
Example:
Javascript:
var elements = document.getElementsByTagName("embed");
elements[0].doSomething();
C#:
How?
I tryed everything but nothing worked. Can anyone help me :(
Quite a late answer, but if anyone else needs it:
The direct C#: http://msdn.microsoft.com/en-us/library/system.windows.forms.htmldocument.getelementsbytagname.aspx
HtmlElementCollection elems = webBrowser1.Document.GetElementsByTagName("embed");
foreach (HtmlElement elem in elems)
{
elem.InvokeMember("doSomething");
}
The alternative: http://msdn.microsoft.com/en-us/library/a0746166
Basically you should create a function in JS:
var myCustomFunc = function(tagName) {
var elements = document.getElementsByTagName(tagName); elements[0].doSomething();
}
And then call it from C# with
webBrowser1.Document.InvokeScript("myCustomFunc ", new String[] { "embed" });
The variable "tagName" gets replaced with "embed"

Binding Data to YUI Treeview control in c#

How can I bind data to YUI Treeview control http://developer.yahoo.com/yui/examples/treeview/default_tree.html
here is sample JavaScript code that have been used in the above URL
<div id="treeDiv1">
</div>
<script type="text/javascript">
var tree;
(function() {
function treeInit() {
buildRandomTextNodeTree();
}
function buildRandomTextNodeTree() {
tree = new YAHOO.widget.TreeView("treeDiv1");
for (var i = 0; i < 5; i++) {
var tmpNode = new YAHOO.widget.TextNode("label-" + i, tree.getRoot(), false);
buildLargeBranch(tmpNode);
}
tree.draw();
}
function buildLargeBranch(node) {
if (node.depth < 8) {
YAHOO.log("buildRandomTextBranch: " + node.index, "info", "example");
for (var i = 0; i < 8; i++) {
new YAHOO.widget.TextNode(node.label + "-" + i, node, false);
}
}
}
YAHOO.util.Event.onDOMReady(treeInit);
})();
</script>
The problem is, YUI treeview control is binded in javascript, but I want to bind in C# code, because I need to get data from Database, here is how I am binding data to asp.net treeview control
if (dsSalesRepresent.Tables[0].Rows.Count > 0)
{
dsSalesRepresent.Relations.Add("Children", dsSalesRepresent.Tables[0].Columns["NodeId"], dsSalesRepresent.Tables[0].Columns["ParentId"]);
trvSalesRepresent.Nodes.Clear();
foreach (DataRow masterRow in dsSalesRepresent.Tables[0].Rows)
{
if (masterRow["ParentId"].ToString() == "")
{
TreeNode masterNode = new TreeNode((String)masterRow["JobTitle"], Convert.ToString(masterRow["NodeId"]));
trvSalesRepresent.Nodes.Add(masterNode);
TreeNode FirstchildNode = new TreeNode((String)masterRow["UserName"], Convert.ToString(masterRow["ParentId"]));
masterNode.ChildNodes.Add(FirstchildNode);
foreach (DataRow childRow in masterRow.GetChildRows("Children"))
{
TreeNode childNode = new TreeNode((String)childRow["UserName"], Convert.ToString(childRow["ParentId"]));
masterNode.ChildNodes.Add(childNode);
}
}
}
trvSalesRepresent.ExpandAll();
}
All of my comments are assuming you mean WebForms and not MVC.
The YUI framework is purely client side. It is intended to be able to used with any website regardless of the server platform. The ASP.NET tree view is used only with ASP.Net and so doesn't have that limitation. It is a server control and so it actually emits everything the client needs even though it looks like you are binding directly to it.
A couple of options, but there's lots:
Use an AJAX/JSON to call back to your website to get the data in JSON format which you can then handle client side.
Just the way that you're asking this question makes me think that you aren't that familiar with "real" AJAX, so that's why I've got the next option:
Emit the Java YUI code directly from your code behind. Javascript is just more text that the server sends to the client and you can dynamically emit it just like any other part of your client script. ScriptManager can help here as far as getting it to the right spot on the page, but you could theoretically do it with just a place holder or literal control. Alternately, you could put most of the code in the markup and use <% %> to replace the parts that need to come from the server side. Either way, you need to write all the code to render your tree, then figure out the "Replaceable" bits and supply them from the server side code. BUT make sure that none of the info coming back is data that was entered by an end user otherwise you could end up with a Cross Site Scripting vulnerability.

How to execute a Javascript function from a C# WebBrowser?

I'm doing some web automation via C# and a WebBrowser. There's a link which I need to 'click', but since it fires a Javascript function, apparently the code needs to be executed rather than just having the element clicked (i.e. element.InvokeMember("click")). Here's the href for the element, which opens an Ajax form:
javascript:__doPostBack("ctl00$cphMain$lnkNameserverUpdate", "")
I've tried:
webBrowser1.Document.InvokeScript("javascript:__doPostBack", new object[] { "ctl00$cphMain$lnkNameserverUpdate", "" });
and:
webBrowser1.Document.InvokeScript("__doPostBack", new object[] { "ctl00$cphMain$lnkNameserverUpdate", "" });
and a few other things. The code gets hit, but the script doesn't get fired. Any ideas would be most appreciated.
Gregg
BTW Here's the full element in case it's useful:
NS51.DOMAINCONTROL.COM<br/>NS52.DOMAINCONTROL.COM<br/>
Have a look at this link:
http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting.aspx
I've actually used this in the past, and it works perfectly.
HtmlDocument doc = browser.Document;
HtmlElement head = doc.GetElementsByTagName("head")[0];
HtmlElement s = doc.CreateElement("script");
s.SetAttribute("text","function sayhello() { alert('hello'); }");
head.AppendChild(s);
browser.Document.InvokeScript("sayHello");

Categories