This way i try to add html data to web browser control.
private void Adddata()
{
webBrowser1.DocumentText =
"<html><body>Please enter your name:<br/>" +
"<input type='text' name='userName'/><br/>" +
"<a href='http://www.microsoft.com'>continue</a>" +
"</body></html>";
}
This works but when i call the Adddata() routine repeatedly then only first time data gets added but from the next time no data is getting added. i just want to add the data repeatedly. is there any way out.
You can use this:
webBrowser1.DocumentText +=
But now when you can't add this code with many body and html tags.
Always build new String with one html and body tag.
Just append html code inside.
Change
webBrowser1.DocumentText = //blah
to
webBrowser1.DocumentText += //blah
Well, not really. It wouldn't be the best of ideas to do that for html. What I would do is
//in class def
bool firstTime;
//in method
bool firstTimeLcl = firstTime
firstTime = false;
if (firstTimeLcl)
{
//write header
}
else
{
String.Replace(/*closing tags*/, "");
}
//write everything within body
//write closing tags
Related
I am tryong to do the following in a Row_Command event of a gridview. But the the pop up box never comes up, I have tried it in so many different ways.. but yet no luck. Please if someone can see the issue i would really appreciate a pointer.
protected void Gridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "Merchant")
{
if (ItemsAvailable)
{
StringBuilder sb = new StringBuilder();
MyClass class = new MyClass();
TList<LineItems> otherItems = MyClass.GetItems(id);
bool IsNotAvailable = false;
foreach (LineItems item in otherItems)
{
Merchandise skuMerchandise = skuMerchandise.GetMerchandise(otherItems.mid);
if (skuMerchandise != null)
{
if (skuMerchandise.AvailableItems <= 0)
{
sb.Append(OtherItems.Name);
sb.Append(Environment.NewLine);
IsNotAvailable = true;
}
}
}
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
"function Redirect() {location.href = 'homePage.aspx';}
if(confirm('The items : "+sb.ToString()+" will arrive in 1 month.
Do you wish to continue?') == true){Redirect();};", true);
}
}
}
Everytime i click the button, it just passes like nothing.. never prompts eveb though IsNotAvailable is true when I add a breakpoint.
You can go for a simpler way,
Define the javascript function in the design/separate script file so that it accepts the name of item. eg. myFunction(itemName)
And in your CS file, simply add a call to that function,
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
"myFunction('" + itemName + "')
}
}
It will make things simpler and you would be able to confirm if this is a Javascript issue or a problem in how you are writing it through CS file.
Update:
Your first goal should be to make sure that your JS function is working for you, so before anything, add the following code in an empty html file and run it,
<script type='text/javascript'>
ItemNotInStock('item');
function ItemNotInStock(itemName)
{
var message = "The following items are no longer in stock :" + itemName + ".
Would you like to continue?";
if (confirm(message) == true)
{ location.href = "homePage.aspx"; }
}
If you redirect correctly then do what's mentioned below.
Define the following javascript in your design file(tested it locally, working for me in chrome,)
<script type='text/javascript'>
function ItemNotInStock(itemName)
{
var message = "The following items are no longer in stock :" + itemName + ".
Would you like to continue?";
if (confirm(message) == true)
{ location.href = "homePage.aspx"; }
}
In your C# code, add following line
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
string.Format("ItemNotInStock('{0}');", itemName);
}
}
Make sure your JavaScript code is executed by using breakpoints available in the developer tools of the browser of your choice, like Chrome Developer Tools: Breakpoints
BTW: Why do you create an instance of Merchandise if you instantly discard it with the next line?
I am just learning how to use classes in my projects. I have been working on a DataAccessClass.cs and am doing well (I think).
Taking a break from data access, I decided to try to make a void into a class. This void sends a message to the client as a javascript alert. It works well, but has to be included on each page. When I tried to make it a class, I was informed that my class does not contain a definition for ClientScript. I included all the "using" directives from the original page to no avail... Any hints or suggestions would be greatly appreciated.
The original code:
//------------------------------------------------------------------------------
//Name: SendErrorMessageToClient
//Abstract: show alert on client side
//------------------------------------------------------------------------------
protected void SendErrorMessageToClient(string strErrorType, string strErrorMessage)
{
string strMessageToClient = "";
//Allow single quotes on client-side in JavaScript
strErrorMessage = strErrorMessage.Replace("'", "\\'");
strMessageToClient = "<script type=\"text/javascript\" language=\"javascript\">alert( '" + strErrorType + "\\n\\n" + strErrorMessage + "' );</script>";
this.ClientScript.RegisterStartupScript(this.GetType(), "ErrorMessage", strMessageToClient);
}
Messages are sent into this void like this:
if (DataAccessClass.OpenSqlConnection(ref Conn, strConn, out strErrorMessage) == false)
{
string strErrorType = "Database Connection Error:";
SendErrorMessageToClient(strErrorType, strErrorMessage);
}
Or this:
catch (Exception excError)
{
string strErrorType = "Unhandled Exception:";
string strErrorMessage = excError.Message;
SendErrorMessageToClient(strErrorType, strErrorMessage);
}
You are receiving the error as 'Clientscript' is a property derived from a System.Web.UI.Page and by moving into a separate class file, you no longer have access to this property.
You could solve this by passing in the page as well, and amending the code to
protected void SendErrorMessageToClient(string strErrorType, string strErrorMessage, Page page)
{
string strMessageToClient = "";
//Allow single quotes on client-side in JavaScript
strErrorMessage = strErrorMessage.Replace("'", "\\'");
strMessageToClient = "<script type=\"text/javascript\" language=\"javascript\">alert( '" + strErrorType + "\\n\\n" + strErrorMessage + "' );</script>";
page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorMessage", strMessageToClient);
}
ClientScript Property is part of the Page class that every ASPX page inherit from. Therefore you can not just use it from inside your class unless it (i.e. your class) has Page as its base class.
this. is for fields in your method in classes.
Why do you want to make this a class? It shouldn't be a class, it doesn't have any properties or fields, unless you can think of one. You do understand if you make it a class you would still have to intialize it on every page.
You could make it a static string method you would still have to include this on every page.
this.ClientScript.RegisterStartupScript(this.GetType(), "ErrorMessage", strMessageToClient);
You'll need to pass the page into the function
SendErrorMessageToClient(Page page, string strErrorType, string strErrorMessage)
so that you can change
this.ClientScript...
to
page.ClientScript...
The reason being that ClientScript is part of the Page class
Or, possibly better, pass the ClientScript object, rather than page.
So your definition would look like
SendErrorMessageToClient(ClientScript clientScript, string strErrorType, string strErrorMessage) {
string strMessageToClient = "";
//Allow single quotes on client-side in JavaScript
strErrorMessage = strErrorMessage.Replace("'", "\\'");
strMessageToClient = String.Format("<script type='text/javascript' language='javascript'>alert('{0}\\n\\n{1}');</script>",
strErrorType, strErrorMessage);
clientScript.RegisterStartupScript(this.GetType(), "ErrorMessage", strMessageToClient);
}
I have a project that I am working on in VS2005. I have added a WebBrowser control. I add a basic empty page to the control
private const string _basicHtmlForm = "<html> "
+ "<head> "
+ "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/> "
+ "<title>Test document</title> "
+ "<script type='text/javascript'> "
+ "function ShowAlert(message) { "
+ " alert(message); "
+ "} "
+ "</script> "
+ "</head> "
+ "<body><div id='mainDiv'> "
+ "</div></body> "
+ "</html> ";
private string _defaultFont = "font-family: Arial; font-size:10pt;";
private void LoadWebForm()
{
try
{
_webBrowser.DocumentText = _basicHtmlForm;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
and then add various elements via the dom (using _webBrowser.Document.CreateElement). I am also loading a css file:
private void AddStyles()
{
try
{
mshtml.HTMLDocument currentDocument = (mshtml.HTMLDocument) _webBrowser.Document.DomDocument;
mshtml.IHTMLStyleSheet styleSheet = currentDocument.createStyleSheet("", 0);
TextReader reader = new StreamReader(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),"basic.css"));
string style = reader.ReadToEnd();
styleSheet.cssText = style;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Here is the css page contents:
body {
background-color: #DDDDDD;
}
.categoryDiv {
background-color: #999999;
}
.categoryTable {
width:599px; background-color:#BBBBBB;
}
#mainDiv {
overflow:auto; width:600px;
}
The style page is loading successfully, but the only elements on the page that are being affected are the ones that are initially in the page (body and mainDiv). I have also tried including the css in a element in the header section, but it still only affects the elements that are there when the page is created.
So my question is, does anyone have any idea on why the css is not being applied to elements that are created after the page is loaded? I have also tried no applying the css until after all of my elements are added, but the results don't change.
I made a slight modification to your AddStyles() method and it works for me.
Where are you calling it from? I called it from "_webBrowser_DocumentCompleted".
I have to point out that I am calling AddStyles after I modify the DOM.
private void AddStyles()
{
try
{
if (_webBrowser.Document != null)
{
IHTMLDocument2 currentDocument = (IHTMLDocument2)_webBrowser.Document.DomDocument;
int length = currentDocument.styleSheets.length;
IHTMLStyleSheet styleSheet = currentDocument.createStyleSheet(#"", length + 1);
//length = currentDocument.styleSheets.length;
//styleSheet.addRule("body", "background-color:blue");
TextReader reader = new StreamReader(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "basic.css"));
string style = reader.ReadToEnd();
styleSheet.cssText = style;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Here is my DocumentCompleted handler (I added some styles to basic.css for testing):
private void _webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlElement element = _webBrowser.Document.CreateElement("p");
element.InnerText = "Hello World1";
_webBrowser.Document.Body.AppendChild(element);
HtmlElement divTag = _webBrowser.Document.CreateElement("div");
divTag.SetAttribute("class", "categoryDiv");
divTag.InnerHtml = "<p>Hello World2</p>";
_webBrowser.Document.Body.AppendChild(divTag);
HtmlElement divTag2 = _webBrowser.Document.CreateElement("div");
divTag2.SetAttribute("id", "mainDiv2");
divTag2.InnerHtml = "<p>Hello World3</p>";
_webBrowser.Document.Body.AppendChild(divTag2);
AddStyles();
}
This is what I get (modified the style to make it as ugly as a single human being can hope to make it :D ):
one solution is to inspect the html prior to setting the DocumentText and inject CSS on the client side. I don't set the control url property but rather get the HTML via WebCLient and then set the DocumentText. maybe setting DocumentText (or in your case Document) after you manipulate the DOM could get it to re-render properly
private const string CSS_960 = #"960.css";
private const string SCRIPT_FMT = #"<style TYPE=""text/css"">{0}</style>";
private const string HEADER_END = #"</head>";
public void SetDocumentText(string value)
{
this.Url = null; // can't have both URL and DocText
this.Navigate("About:blank");
string css = null;
string html = value;
// check for known CSS file links and inject the resourced versions
if(html.Contains(CSS_960))
{
css = GetEmbeddedResourceString(CSS_960);
html = html.Insert(html.IndexOf(HEADER_END), string.Format(SCRIPT_FMT,css));
}
if (Document != null) {
Document.Write(string.Empty);
}
DocumentText = html;
}
It would be quite hard to say unless you send a link of this.
but usually the best method for doing style related stuff is that you have the css already in the page and in your c# code you only add ids or classes to elements to see the styles effects.
I have found that generated tags with class attribute does not get their styles applied.
This is my workaround that is done after the document is generated:
public static class WebBrowserExtensions
{
public static void Redraw(this WebBrowser browser)
{
string temp = Path.GetTempFileName();
File.WriteAllText(temp, browser.Document.Body.Parent.OuterHtml,
Encoding.GetEncoding(browser.Document.Encoding));
browser.Url = new Uri(temp);
}
}
I use similiar control instead of WebBrowser, I load HTML page with "default" style rules and I change the rules within the program.
(DrawBack - maintainance, when I need to add a rule, I also need to change it in code)
' ----------------------------------------------------------------------
Public Sub mcFontOrColorsChanged(ByVal isRefresh As Boolean)
' ----------------------------------------------------------------------
' Notify whichever is concerned:
Dim doc As mshtml.HTMLDocument = Me.Document
If (doc.styleSheets Is Nothing) Then Return
If (doc.styleSheets.length = 0) Then Return
Dim docStyleSheet As mshtml.IHTMLStyleSheet = CType(doc.styleSheets.item(0), mshtml.IHTMLStyleSheet)
Dim docStyleRules As mshtml.HTMLStyleSheetRulesCollection = CType(docStyleSheet.rules, mshtml.HTMLStyleSheetRulesCollection)
' Note: the following is needed seperately from 'Case "BODY"
Dim docBody As mshtml.HTMLBodyClass = CType(doc.body, mshtml.HTMLBodyClass)
If Not (docBody Is Nothing) Then
docBody.style.backgroundColor = colStrTextBg
End If
Dim i As Integer
Dim maxI As Integer = docStyleRules.length - 1
For i = 0 To maxI
Select Case (docStyleRules.item(i).selectorText)
Case "BODY"
docStyleRules.item(i).style.fontFamily = fName ' "Times New Roman" | "Verdana" | "courier new" | "comic sans ms" | "Arial"
Case "P.myStyle1"
docStyleRules.item(i).style.fontSize = fontSize.ToString & "pt"
Case "TD.myStyle2" ' do nothing
Case ".myStyle3"
docStyleRules.item(i).style.fontSize = fontSizePath.ToString & "pt"
docStyleRules.item(i).style.color = colStrTextFg
docStyleRules.item(i).style.backgroundColor = colStrTextBg
Case Else
Debug.WriteLine("Rule " & i.ToString & " " & docStyleRules.item(i).selectorText)
End Select
Next i
If (isRefresh) Then
Me.myRefresh(curNode)
End If
End Sub
It could be that the objects on the page EXIST at the time the page is being loaded, so each style can be applied. just because you add a node to the DOM tree, doesnt mean that it can have all of its attributes manipulated and rendered inside of the browser.
the methods above seem to use an approach the reloads the page (DOM), which suggests that this may be the case.
In short, refresh the page after you've added an element
It sounds as though phq has experienced this. I think the way I would approach is add a reference to jquery to your html document (from the start).
Then inside of the page, create a javascript function that accepts the element id and the name of the class to apply. Inside of the function, use jquery to dynamtically apply the class in question or to modify the css directly. For example, use .addClass or .css functions of jquery to modify the element.
From there, in your C# code, after you add the element dynamically invoke this javascript as described by Rick Strahl here: http://www.west-wind.com/Weblog/posts/493536.aspx
I have an aspx page which has some javascript code like
<script>
setTimeout("document.write('" + place.address + "');",1);
</script>
As it is clear from the code it will going to write something on the page after a very short delay of 1 ms. I have created an another page to get the page executed by some query string and get its output. The problem is
I can not avoid the delay as simply writing document.write(place.address); will not print anything as it takes a little time to get values so if I set it in setTimeout for delayed output of 1 ms it always return me a value
If I request the output from another page using
System.Net.WebClient wc = new System.Net.WebClient();
System.IO.StreamReader sr = new System.IO.StreamReader(wc.OpenRead("http://localhost:4859/Default.aspx?lat=" + lat + "&lng=" + lng));
string strData = sr.ReadToEnd();
I get the source code of the document instead of the desired output.
I would like to either avoid that delay or else delayed the client request output so that I get a desired value not the source code.
The JS on default.aspx is
<script type="text/javascript">
var geocoder;
var address;
function initialize() {
geocoder = new GClientGeocoder();
var qs=new Querystring();
if(qs.get("lat") && qs.get("lng"))
{
geocoder.getLocations(new GLatLng(qs.get("lat"),qs.get("lng")),showAddress);
}
else
{
document.write("Invalid Access Or Not valid lat long is provided.");
}
}
function getAddress(overlay, latlng) {
if (latlng != null) {
address = latlng;
geocoder.getLocations(latlng, showAddress);
}
}
function showAddress(r) {
place = r.Placemark[0];
setTimeout("document.write('" + place.address + "');",1);
//document.write(place.address);
}
</script>
and the code on requestClient.aspx is as
System.Net.WebClient wc = new System.Net.WebClient();
System.IO.StreamReader sr = new System.IO.StreamReader(wc.OpenRead("http://localhost:4859/Default.aspx?lat=" + lat + "&lng=" + lng));
string strData = sr.ReadToEnd();
I'm not a JavaScript expert, but I believe using document.write after the page has finished loading is a bad thing. You should be creating an html element that your JavaScript can manipulate, once the calculation is complete.
Elaboration
In your page markup, create a placeholder for where you want the address to appear:
<p id="address">Placeholder For Address</p>
In your JavaScript function, update that placeholder:
function showAddress(r) {
place = r.Placemark[0];
setTimeout("document.getElementById('address').innerHTML = '" + place.address + "';",1);
}
string strData = sr.ReadToEnd();
I get the source code of the document instead of the desired output
(Could you give a sample of the output. I don't think I've seen a web scraper work that way so that would help me to be sure. But if not this is a good example web scraper)
Exactly what are you doing with the string "strData" If you are just writing it out, I recommend you putting it in a Server side control (like a literal). If at all possible, I'd recommend you do this server side using .net rather than waiting 1 ms in javascript (which isn't ideal considering the possibility that 1 ms may or may not be an ideal amount of time to wait on a particular user's machine hence: "client side"). In a case like this and I had to do it client side I would use the element.onload event to determine if a page has finished loading.
I found a good way to check if a file exists and read the contents if it does, but for some reason I can't create a method out of it.
Here's what I have so far:
<script runat="server">
void Page_Load(Object s, EventArgs e) {
lblFunction.Text = mwbInclude("test.txt");
}
string mwbInclude(string fileName) {
string inc = Server.MapPath("/extra/include/" + Request["game"] + "/" + fileName);
string valinc;
if(System.IO.File.Exists(inc))
{
valinc = System.IO.File.ReadAllText(inc);
}
return valinc;
}
</script>
I wish I could provide more info, but the server this is on doesn't show any feedback on errors, just a 404 page.
I think
valinc = Response.Write(System.IO.File.ReadAllText(inc));
should be
valinc = System.IO.File.ReadAllText(inc);
Why are you setting the Text property and calling Response.Write? Do you want to render the text as a label, or as the whole response?
If you're getting a 404, it's because your page isn't being found, not because there's a problem with the script itself. Have you tried ripping out all of the code and just sticking in some HTML tags as a sanity check?