I'm looking for a way to get the JavaScript code defined inside of onclick.
I'm using .NET 2.0 C# Visual Studio 2005.
Example:
<span id="foo" onclick+"window.location.href='someURL'>click here</span>
My goal is to get the string "window.location.href='someURL'".
Scenario:
A user clicks on web page element, the tag shown above for instance, inside of WebBrowser control. Then the clicked tag is refereed to HtmlElement object.
In WebBrowser control I then call HtmlElement object's getAttribute("onclick"), it just gives me "System.__ComObject".
I've searched how to deal with it then found that it can be casted then get the value.
if (tag.GetAttribute("onclick").Equals("System.__ComObject"))
{
Console.WriteLine("dom elem >>>>>>>>>>> " + tag.DomElement.ToString());
mshtml.HTMLSpanElementClass span = (mshtml.HTMLSpanElementClass)tag.DomElement;
Console.WriteLine("js value ===>" + span.onclick);
}
Output:
dom elem >>>>>>>>>>> mshtml.HTMLSpanElementClass
js value ===> System.__ComObject
As it shown, span.onclick still give me System.__ComObject, what am I doing wrong?
In Why does HtmlElement's GetAttribute() method return “mshtml.HTMLInputElementClass” instead of the attribute's value? this guy said it worked in his case, and I've followed it, but mine is somewhat not working...
UPDATE
Research, research.....
I can add reference VisualBasic.dll to my C# project then call the method to find out who is this System.__ComObject really is.
Console.WriteLine(Microsoft.VisualBasic.Information.TypeName(span.onclick));
Output:
JScriptTypeInfo
It looks like this is a JScript type... how can I access this object?
More detail
The above description is based on my current project. The project is to create something like Selenium IDE. It uses WebBrowser control instead.
Selenium IDE creates 3 different things to record an element in the web document.
1. actionType
2. xpath
3. value
For instance,
type, //input[#id=foo], "hello world"
clickAndWait, //link=login, ""
Selenium IDE recognize page load so it changes actionType between "click" and "clickAndWait". My case, I want to make it simple.
If I click on the element and if it is anchor tag or has page load kind of javascript
such as onclick=window.location.href='blah' then I want to set the actionType to "clickAndWait".
There are number of ways you can do it.
There is an Event object in DOM, which will give you information about which element generated this event.
You can look at here, http://msdn.microsoft.com/en-us/library/ff975965%28v=VS.85%29.aspx
This one is good, you can use this easily, you will get the event object as method parameter which you can investigate parameters to find out the source of the event. http://support.microsoft.com/kb/312777
Another alternative is to use a custom navigation url and act upon it
Override BeforeNavigate event
Check for Navigation url if it contains "mycommand:click" or "mycommand:clickandwait" 3. If it contains any of this, then set cancel as true. (this will stop navigation by browser).
Then you can navigate your webbrowser code from your C# code and pass cancel as true.
Another Alternative method is to use External object, WebBrowser allows you to set an ObjectForScripting which you can access within Javascript of HTML.
ObjectForScripting in .NET 2.0
[ComVisible(true)]
public class MyClass
{
// can be called from JavaScript
public void ShowMessageBox(string msg){
MessageBox.Show(msg);
}
}
myBrowser.ObjectForScripting = new MyClass();
// or you can reuse instance of MyClass
And you can call,
window.external.ShowMessageBox("This was called from JavaScript");
Cast the element object to mshtml.IHTMLDOMNode, then read the attributes via IHTMLDOMNode.attributes. HtmlElement.GetAttribute is getting the IDispatch interface of the jscript function generated from the embedded attribute.
As per Sheng Jiang's response, here is some working sample:
IHTMLElement element = YourCodeToGetElement();
string onclick = string.Empty;
IHTMLDOMNode domNode = element as IHTMLDOMNode;
IHTMLAttributeCollection attrs = domNode.attributes;
foreach (IHTMLDOMAttribute attr in attrs)
{
if (attr.nodeName.Equals("onclick"))
{
string attrValue = attr.nodeValue as string;
if (!string.IsNullOrEmpty(attrValue))
{
onclick = attr.nodeValue;
break;
}
}
}
You can try to parse webBrowser1.DocumentText property using HtmlAgilityPack and then get desired result using XPath.
If you don't HAVE to do it with C# (you can do it with JS and create a Postback) you should take a look at THIS question.
You can parse it yourself easily, by first reading obj.outerHtml. That should give you the entire html for that obj, then search it for the value onclick="????" and extract the ???? part.
Related
I'm working on a website that has a JavaScript function I want to call passing in a value when a hyperlink is clicked. I'm generating some table rows in the view like this:
foreach(var e in Model.Collection)
{
...
//This is just an example piece of code that tries to get the big picture
//across. I want to call the JS function below passing in the ShipAddress property
<td>#e.ShippedDate</td>
...
}
And I have a JavaScript function like this:
function popup(data)
{
$('#lblShipAddress').text(data.Address1);
...
// rest of code to fill out labels in a div
$('#divShipInfo').dialog('open');
}
I'm having issues getting the ShipAddress property(which has a number of properties i.e. Address1, Address2, etc.) passed into the JavaScript function from the View. The
href="javascript:popup(#e.ShipAddress)" part doesn't work, and I've also tried using data attributes e.g.
<a href="javascript:popup();" data-shipAddress="#e.ShipAddress" />
but have not had any luck.
EDIT: Added some clarity to what I'm looking for. If at all possible I would like to only pass the ShipAddress property to the function.
By default, just #e.ShipAddress is going to return the equivalent of .ToString(), which is not useful for your method as input. Instead, you'll want to JSON serialize the object like:
#e.ShippedDate
This will result in final html something like:
#e.ShippedDate
And so the popup method would have access to the object values.
Warning: make sure there aren't any fields on your address object that you don't want leaked to your end consumers - Json.Encode will serialize all public properties.
First, I wouldn't use javascript:popup() - try one of these. Also, don't use the quote marks with the razor syntax, or it probably won't evaluate the variable.
If none of that solves it, then it could be a timing issue. I've had a lot of trouble with MVC-controlled pages (as opposed to use JavaScript/jQuery and callbacks) not updating when you think they will. For some reason, the MVC controller deals with the button press, runs the server-side code, updates the page objects... THEN releases control to JavaScript, et. al.
It basically makes using JavaScript with the built-in Microsoft controls almost impossible.
I'm using telerik tools and have a tool that runs code server side from a class library on an ajax call.
This control can come from any page. And I can access the page by the telerik object that's passed in.
Now, some of these pages have a property that I want to access, but I want to keep it generic.
I can cast the page as a specific page type and expose the property, but that would require an update to the class library every time that property is added to a page.
What I'm wondering is if there is a way for me to check to see if a property exists on the page, then access it if it does?
((Telerik.Web.UI.ControlItemContainer)((RadComboBox)o)).Page
This is how I access the page, which just returns a page object. I want to check to see if that page object contains a property without casting it.
Or if I can cast the page with using gettype(), that would work as well.
Thanks
You could use reflection:
System.Reflection.PropertyInfo propInfo =
theObjectYouWantToReflect.GetType().GetProperty("YourPropertyName");
if (propInfo != null)
{
object value = propInfo.GetValue(Page, null);
// ...
}
I am very new to Selenium, so my apologies if it's a silly question.
I have successfully wired up IntelliJ (Play! framework) with Selenium, and created some tests using firefoxDrivers.
I'm trying to check if the page had been validated properly.
long story short, I'm selecting an element like this:
WebElement smallDecel = firefoxDriver.findElement(By.cssSelector("#configTable tr:nth-child(2) td .playerDecelInput"));
I do some further operations (clear and change the value, submit the 'form'), and then I want to check if the TD the input sits in was given another class.
So, the question is - is there a simple technique I can use to find out if a WebElement / DOM has a class specified?
To expand on Sam Woods' answer, I use a simple extension method (this is for C#) to test whether or not an element has a specified class:
public static bool HasClass( this IWebElement el, string className ) {
return el.GetAttribute( "class" ).Split( ' ' ).Contains( className );
}
Once you find the element, you can just call myElement.GetAttribute("class"). Then you can parse the string that is returned and see if it contains or does not contain the class name you care about.
You can use FindElement(By.ClassName(//name of your class)); I would recommend that you either loop through and search the DOM for a set period of time or set a Thread.sleep(xxxx) and then look for the appended class.
How Can I Evaluate a String in C# Windows Application because I need to Dynamically select object in a form based on the Combination of 2 String that give me the name of the needed object
You can tryControlCollection.Find method to find control by name.
For example:
MyForm.Controls.Find("FooButton", true);
Method returns an array of Control element with the Name property set to "FooButton".
There is no C# eval equivalent. But by the link you can find some useful answers. Ofc, if you want to find or evaluate something than winform controls
UPDATE: I think sometimes it is better get control by key directly. For example:
Control control = this.Controls["FooTxtBox"];
if(control==null)
{
MessageBox.Show("Control not found");
}
control.Text = "something";
This is a feature (compiler as a service) that should be available in the next version of the .NET Framework, version 5.
Perhaps reflection could be your solution for this?
Just use the string as the lookup for the Form.Controls collection. Then when you've got the instance of the control, just call whatever method you need on it to select it.
Have a look at this:
http://www.logiclabz.com/c/evaluate-function-in-c-net-as-eval-function-in-javascript.aspx (Link is dead, please provide an updated source)
Is it possible to create a property on a javascript object that behaves similar to a property in C#.
Example:
I've created an auto-sizing textarea widget using dojo. In order to get the "value" property out of my widget, I've hooked up to the onchange event and I'm setting a variable everytime the value of the textarea changes.
Is there a way to accomplish this without hooking up to the onchange event.
Edit
In other words, is it possible to write something in JavaScript that behaves like getters and/or setters.
It is possible in ECMAScript 5 implementations, which include recent versions of all major browsers. The ECMAScript 5 spec adds standardized getters and setters. One quirk is that IE 8 has this feature, but only on DOM nodes. This is what the syntax looks like:
var obj = {};
Object.defineProperty(obj, "value", {
get: function () {
return this.val;
},
set: function(val) {
this.val = val;
}
});
There has also been a proprietary implementation of getters and setters in Mozilla for a long time that was also later adopted by WebKit and Opera but this is not available in IE.
I'm not sure what you're asking here. You can always get the value of a textarea without the onchange event. you'd have to get the object then look at the value property.
for example, if your textarea has an id="mytext" you can do
var mytextarea = document.getElementById("mytext");
var text = mytextarea.value;