C# Target HTML button by class - c#

I want to click on a button which doenst have an ID. I used this stackoverflow question to get started, but I can't seem to make it work.
//Load page
WebBrowser webBrowser1 = new WebBrowser();
webBrowser1.Navigate("/login");
while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
//Log in
HtmlDocument doc = webBrowser1.Document;
doc.GetElementById("username").SetAttribute("Value", "--");
doc.GetElementById("password").SetAttribute("Value", "--");
doc.GetElementById("_submit").InvokeMember("Click");
WebBrowser webBrowser2 = new WebBrowser();
webBrowser2.Navigate("/Start");
while (webBrowser2.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
var buttons = webBrowser2.Document.GetElementsByTagName("button");
Console.WriteLine(buttons); **//Output here: 'System.Windows.Forms.HtmlElementCollection'**
foreach (HtmlElement button in buttons)
{
if (button.InnerText == "Filter ")
{
button.InvokeMember("Click");
Console.WriteLine("Clicked!"); **// This will never get writing into the console.**
}
}
}
The HTML:
<button class="down-arrow-btn" type="button" id="toggleFilterFieldsButton"
title="Overige filtervelden tonen/verbergen"> ▼
</button>
<button class="filter-btn" type="submit" name="filter_action" title="Filteren"
style="color: #7989a0"
value="filter">Filter
</button>
<button class="herstel-btn" type="submit" name="filter_action" title="Filteren opheffen, alles tonen"
value="reset">Herstel
</button>
In this case I want to press the second button.
Edit:
First solution:
var element = webBrowser2.Document.GetElementsByTagName("button")
.Cast<HtmlElement>()
Where(e => !String.IsNullOrEmpty(e.GetAttribute("name")) && e.GetAttribute("name") == "filter_action")
.FirstOrDefault();
Second solution:
var elementToClick = webBrowser2.Document
.GetElementsByTagName("button")
.Cast<HtmlElement>()
.FirstOrDefault(m => m.GetAttribute("className") == "filter-btn");
elementToClick.InvokeMember("Click");
Console.WriteLine(elementToClick);
I have tried multiple other solutions. But the htmlElement is always null.
I think the problem is due to the website being pretty secured. And the button I am targeting is not visible for the program? Even tho it's visible in the code.
If I copy the whole HTML code (view-source:https:// url ) and make it an local .html, it works fine. (all of the 3 solutions.)

Using only 1 web browser control did the trick.

Related

Set & Get input value in web browser in c#

I just try to understand the concept of in web browser control c# win app.
I have created a Windows app with web browser control. I have called a web page (which is my own) and try to set value in the web page from my app.
When i try with Google
webBrowser1.Navigate("http://google.com/search?q=" + "C#");
it works fine.
When i try in this way, it is not working.
HtmlElement textArea = webBrowser1.Document.All["q"];
textArea.InnerText = "dsfs";
Can anyone help me to achieve this?
You will need to wait for the WebBrowser to load before you access it (otherwise Document will be null until loaded) - subscribe a DocumentCompleted event handler for this. Also Document.All["q"] will return the first element with the name "q".
webBrowser1.Navigate("http://stackoverflow.com/questions/30431004");
webBrowser1.DocumentCompleted += (o, args) =>
{
var ele = webBrowser1.Document.All["q"];
if (ele.TagName.ToLower() == "input")
{
ele.InnerText = "dsfs";
}
};
If you want to change more than one such element, or if you want to locate elements by Id, Tag name etc, you will need to iterate the collection:
foreach (HtmlElement ele in webBrowser1.Document.All)
{
if (ele.TagName.ToLower() == "input")
{
ele.InnerText = "dsfs";
}
}

C# Forms -> Click button in webBrowser

I'm trying to programmatically click a button in a iframe form in webexplorer. The button is a bit nasty though, as its coded not to always be active. The HTML for the button is:
<input disabled="" class="submit ui-button ui-widget ui-state-default ui-corner-all ui-button-disabled ui-state-disabled" id="btnEntryAddSav" role="button" aria-disabled="true" type="submit" jQuery1418076056597="6" value="Add ->"/>
I've tried using invoke but not having any luck
HtmlElement ADD = frame.Document.GetElementById("btnEntryAddSav");
ADD.InvokeMember("Click");
It just doesn't seem to actually click. I can see the button highlighted, but nadda happens. Any thoughts?
//in chrome
try
{
HtmlDocument doc = webBrowser1.Document;
HtmlElement submit = doc.GetElementById("btnEntryAddSav");
submit.InvokeMember("click");
}
catch { }
//in IE try to find name tag and:
try
{
HtmlElementCollection Bpic = webBrowser1.Document.GetElementsByTagName("input");
foreach (HtmlElement bp in Bpic) {
string name = bp.Name;
if (name == "input_name")
bp.InvokeMember("click");
}
}
catch{}

Post to facebook group with C# code

I am working on a windows application where I embedded webbroswercontrol. I am trying to post sample message to a open facebook group. I am unable to change value of a textbox with c#. When ever I automate click it says textbox value is null. What would be the fix?
<input type="hidden" autocomplete="off" class="mentionsHidden"
name="xhpc_message" value="lklklkl">
HtmlElement textBox = this.FindControlByName("xhpc_message",
this.webBrowser.Document.All);
//Click Code
var elements = webBrowser.Document.GetElementsByTagName("button");
foreach (HtmlElement element in elements)
{
// If there's more than one button, you can check the
//element.InnerHTML to see if it's the one you want
if (element.InnerText.Contains("Post"))
{
if (textBox.InnerText.Trim() == "Write something...")
{
textBox.Focus();
textBox.GetAttribute("value").Equals("Test Message");
IHTMLElement nativeElement = element.DomElement as IHTMLElement;
nativeElement.click();
break;
}
}
}
1) I suggest you to ensure, that textbox is null, not the textBox.InnerText. Usually inner text for elements is null, so its better to check the "placeholder" attribute and update the code with:
// if (textBox.InnerText.Trim() == "Write something...")
if (textBox.GetAttribute("placeholder") == "Write something...")
2) This code doesn't set the value. It gets the value and compares to "Test message".
textBox.GetAttribute("value").Equals("Test Message");
Just use SetValue instead.
textBox.SetAttribute("value", "Test message");
3) Ensure, that all operations are made after page is loaded.
public SomeFormName()
{
...
webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
}
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs args)
{
// put your code here
}
4) Not sure, how the FindControlByName is working, so check a simple LINQ query to ensure that textbox is found.
var textbox = webBrowser.Document.All.OfType<HtmlElement>()
.Where(item => item.Name == "xhpc_message")
.FirstOrDefault()
;
Use the code below after the Document complete event has been fired completely in a separate function, after commenting your code.The URL in the webbrowser should be holding the Group Page on which the post is to happen.
private void AfteDocumentLoads()
{
HtmlElementCollection textBox = webBrowser.Document.GetElementsByTagName("textarea").GetElementsByName("xhpc_message");
HtmlElementCollection button = webBrowser.Document.GetElementsByTagName("button");
foreach (HtmlElement element in textBox)
{
foreach (HtmlElement btnelement in button)
{
if (btnelement.InnerText == "Post")
{
element.Focus();
element.InnerText = txtPortalUserId.Text.ToString();
btnelement.InvokeMember("Click");
}
}
}
}
I was also stuck as it was not posting earlier because I was using WebBrowser class to get current WebBrowser. Result was that the text was inputted to the Group as a 'dim' Comment. Even if I clicked manually on FB page it would say "This status update appears to be blank. Please write something or attach a link or photo to update your status."
I used the page's webbrowser & it worked cos' it came in proper manner on the page. Also little bit of changes are there in the LOCs

WebBrowser control: click won't work

I used the DocumentComplete event to AutoComplete a form. Everything is OK except the checkbox. The html code is the following:
<span class="myClass" style="padding-left: 12px; vertical-align: bottom; cursor: pointer;">
<input id="ich_liebe_dich" type="checkbox" name="ich$liebe$dich">
<label for="ich_liebe_dich"> MyLabel</label>
</span>
I tried using:
webbrowser.Document.GetElementById("ich_liebe_dich").InvokeMember("click");
and
webbrowser.Document.GetElementById("ich$liebe$dich").InvokeMember("click");
and also:
foreach (HtmlElement current in webbrowser.Document.GetElementsByTagName(tag))
{
if (current.GetAttribute(attr).Equals(attName))
current.InvokeMember(invoke);
}
where attr="id", tag="input", invoke="click" and attName= either "ich_liebe_dich" or "ich$liebe$dich".
The best I got was a transiently - just for a fraction of a second - checked checkbox. Why would this happen? Any solutions?
leppie's answer made me curious because I've never read anywhere about InvokeMember("check") and I googled it! The first answer I got is this http://social.msdn.microsoft.com/forums/en-US/winforms/thread/750b11dc-08f8-4cb4-bcaf-80c91f0fd425/
I read the article and found a solution...
If I add this line on DocumentCompleted event then everything works ok!
if (webbrowser.ReadyState==WebBrowserReadyState.Complete)
It seems that the page has frames and the DocumentCompleted event fires before the whole page is loaded.
edit: I forgot to mention that the code I used (and works) is the following:
webbrowser.Document.GetElementById("ich_liebe_dich").InvokeMember("click");
I had already answered a similar question
webBrowser.Navigate("http://www.google.com");
if you have id use this:
webBrowser1.Document.GetElementById("id").InvokeMember("click");
if you have tagname use this
webBrowser.Navigate("http://www.google.com");
In Web Browser DocumentCompleted event
HtmlElement textElement = webBrowser.Document.All.GetElementsByName("q")[0];
textElement.SetAttribute("value", "your text to search");
HtmlElement btnElement = webBrowser.Document.All.GetElementsByName("btnG")[0];
btnElement.InvokeMember("click");
if you have name class use this:
HtmlElementCollection classButton = webBrowser1.Document.All;
foreach (HtmlElement element in classButton)
{
if (element.GetAttribute("className") == "button")
{
element.InvokeMember("click");
}
}
for add text in textbox google.com use this:
webBrowser1.Document.GetElementById("gs_tti0").InnerText = "hello world";

How do I programmatically click on a div in a web browser?

I have been trying for a few days now and still have had no success in programmatically clicking on this div. All of the other input fields and buttons are working fine using InvokeMember("click") and RaiseEvent("onclick"), but I am unable to click on the following div:
<div class="pump request"> onclick="$(this).push('kjhzsd94vibjktj584ed01', null, event)" </div>
This div is repeated several times on a page, but I just want to click on the first occurrence.
This is what I have done so far:
HtmlElementCollection c1 = wbc1.document.GetElementsByTagName("div");
foreach (HtmlElement e2 in c1)
{
if (e2.GetAttribute("class").Contains("pump request"))//also this condition is not returning true
{
e2.RaiseEvent("onclick");
}
}
#bleepzter
what if "somecontrol" is a class of the div instead of div's id?
since in my case i have div class "pump request" so (if i write "pump request" as somecontrol in above example) it return me Null in someDiv
<div class="pump request"> onclick="$(this).push('kjhzsd94vibjktj584ed01', null, event)" </div>
#Cameron
yep i did entered the break; but the problem is the if condition never returns true so
HtmlElementCollection c1 = wbc1.document.GetElementsByTagName("div");
foreach (HtmlElement e2 in c1)
{
if (e2.GetAttribute("class").Contains("pump request"))//--> This condition is not returning true
{
e2.RaiseEvent("onclick");
break;
}
}
#Ilya Kogan
yea i just did a watch on e2.GetAttribute("class") and the weird thing happened that being reading the actual div (which i want to click) the value of class was empty :-o
try this one
if (e2.GetAttribute("className").Contains("pump request"))
{
e2.InvokeMember("Click");
}
you can try this piece of code by using a web browser control.
// browser is the web browser control
HtmlElementCollection col = browser.Document.GetElementsByTagName("div");
foreach (HtmlElement helemnt in col)
{
if (helemnt.InnerText !=null && helemnt.InnerText=="something")
{
helemnt.InvokeMember("Click");
break; // break the loop
}
}
It is simple. Here is an example which assumes your browser control is called browser, and the div you are looking for is called somecontrol (i.e. the id of the div is somecontrol):
HtmlElement someDiv = browser.Document.All["somecontrol"];
object someDivElement = someDiv.DomElement;
MethodInfo clickMethod = someDivElement.GetType().GetMethod("click");
clickMethod.Invoke(someDivElement, null);
All this is possible via reflection.

Categories