Ok, I hope I can explain this well enough.
I have one or more third party Up/Down Spinner+Textbox controls on my page that are black boxes that I can't change the source for.
I want the user to change the UpDownControl contents to choose a quantity and then click a calendar button which will:
Add the quantity of all Up/Down boxes.
Call a javascript popup to display a calendar with the count from step 1 in the url "...calendar.asp?qty=5".
My problem is getting the two steps to execute in the same click. As it stands I can click the button once and it counts
the items and adds them to the popup string and then I have to click it a second time to actually execute the JS popup window.
The code was originally written to "load up" the counts into a second button and then programmatically click it but that looks
like a popup to the browsers since the user didn't click that button.
Here is what I have so far that almost works --
On my page:
<asp:ImageButton ID="btnPrepCal" runat="server" Text="PrepCal" OnClick="btnPrepCal_Click" ImageUrl="~/images/Calendar.gif"/>
In code behind:
public void btnPrepCal_Click(object sender, EventArgs e)
{
StringBuilder sbParams = new StringBuilder();
int TotalQty = 0;
int basketItemCount = 0;
int rowIndex = 0;
string Sku = string.Empty;
foreach (GridViewRow varRow in VariantGrid.Rows)
{
int qnty = GetControlValue(varRow, "Quantity", 0);
if (qnty > 0)
{
basketItemCount++;
string optionList = (string)VariantGrid.DataKeys[rowIndex].Value;
ProductVariant variant = _VariantManager.GetVariantFromOptions(optionList);
if (variant != null)
{
BasketItem basketItem = GetBasketItem(optionList, varRow);
if (basketItem != null)
{
TotalQty += basketItem.Quantity;
Sku = variant.Sku;
}
}
}
rowIndex++;
}
if(Sku.Length > 4) Sku = Sku.Substring(0,4);
sbParams.Append(string.Format("?sku={0}&Qty={1}", Sku, TotalQty));
string popup = string.Empty;
popup = string.Format("window.open('http://trustedtours.org/store/egalaxycalendar.asp{0}','Reservation Calendar','width=265,height=465')",sbParams.ToString());
btnPrepCal.OnClientClick = popup;
}
I'm new to .NET and web programming so I'm probably going at it totally backwards so any help is appreciated. I apologize if it's not clear what I'm trying to do or how. If you need any more info please ask - the rest of the file is a lot of shopping cart mumbo jumbo so I left it out, I hope it's enough.
---- update ----
After looking at the referenced pages I get:
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
StringBuilder cstext1 = new StringBuilder();
cstext1.Append("<script type=text/javascript>" + popup + "<script>");
cs.RegisterStartupScript(cstype, "PopupCalendar", cstext1.ToString());
And I believe this is added after I set the value of popup near the bottom of my Click handler above, removing the OnClientClick part, right?
Should this popup the other window on a page reload after clicking the button? (I hate being a newb and asking what's probably obvious questions.)
You can accomplish what you're aiming for using the ClientScriptManager.RegisterStartupScript method. Instead of assigning the OnClientClick method of the button to your JS popup code, set that code to run when the page is reloaded using the RegisterStartupScript method.
This page has some good examples: http://dotnetslackers.com/articles/aspnet/JavaScript_with_ASP_NET_2_0_Pages_Part1.aspx
Ken is correct. To add to his answer and clarify why your code was not working - you were assigning the click-handler of your button to do a popup, but only after it was clicked. This is why you only saw the popup after the 2nd click - the handler was not there the first time you clicked it.
Related
While working on a small app that pulls test cases, runs, and results from an SQL Server Database, I encountered a dilemma in my methodology for attempting to create dynamic controller names in a TableLayoutPanel in WinForms. I am creating the rows dynamically when the user chooses the particular test case, and from there the TableLayoutPanel will open another window with the test steps preloaded and two radio buttons to indicate whether or not the test passed. My issue is that when I select one of the radio buttons on the right of the step, I get the same console read every single time. I need to be able to determine which exact radio button the user has pressed so I can therefore determine what row it's in and subsequently what test either passed or failed. My main code is as follows:
FormManualTest.cs (section when adding to the TableLayoutPanel)
private void addRowToolStripMenuItem_Click(object sender, EventArgs anotherEvent)
{
tableLayoutTest.RowStyles.Clear(); // Clear row styles to ensure a clean start when adding to the TableLayoutPanel
List<RadioButton> listOfRadioControls = new List<RadioButton>(); // Create array of radio buttons
List<UserCustomStep> listOfStepControls = new List<UserCustomStep>(); // Create array of custom controls
for (int i = 0; i < 5; i++)
{
UserCustomStep step = new UserCustomStep(Counter, "Step: " + i + " Push the button to elicit a response."); // Creates new user custom step control instance
RadioButton pass = new RadioButton();
pass.Text = "Pass";
pass.AutoSize = true;
RadioButton fail = new RadioButton();
fail.Text = "Fail";
fail.AutoSize = true;
fail.Margin = new Padding(3,3,20,3); // Needed to see the fail button without having to scroll over
listOfStepControls.Add(step); // Add step to UserCustomStep array
listOfRadioControls.Add(pass); // Add radio buttons to the RadioButton array
listOfRadioControls.Add(fail);
listOfRadioControls[i * 2].CheckedChanged += (s, e) => // Subscribes the pass radio button to listen for when a user has clicked on it
{
Console.WriteLine("Pass " + i + " was clicked");
};
listOfRadioControls[(i * 2) + 1].CheckedChanged += (s, e) => // Subscribes the fail radio button to listen for when a user has clicked on it
{
Console.WriteLine("Fail " + i + " was clicked");
};
tableLayoutTest.Controls.Add(listOfStepControls[i], 0, i); // Adds CustomStep to first column
tableLayoutTest.Controls.Add(listOfRadioControls[i*2], 1, i); // Adds Pass Radio Button to second column
tableLayoutTest.Controls.Add(listOfRadioControls[(i * 2) + 1], 2, i); // Add Fail Raido Button to third column
Counter++; // Increment couter to add subsequent steps underneath the previous ones.
}
}
Screenshots of App with Console Readout:
After Test Case Has Been Clicked and Radio Button Has Been Pressed
(From clicking this I would expect the console to read "Pass 1 was clicked")
Console Read:
Click Fail Button:
(I know from this image below that since the Pass button doesn't remain clicked I'm somehow using the same controller for all 5 of them)
Console Read
So from all of these issues that I've been presented with, I know that I'm somehow using the same controller for all 5 instances regardless of the fact that I'm storing everything in a controller array and grabbing from there. The for loop will have to be converted to a for each loop later, but that still doesn't solve my issue. I believe that if I could say something like:
RadioButton (pass+id) = new RadioButton();
or something similar while looping through to dynamically create the name for the controls, then each one would be a completely separate control and I could go from there. Any help would be greatly appreciated! I come from a heavy web background so my normal skills to remedy this in JS land aren't coming in handy as of right now. Thanks again for the assistance.
The Name property is optional, you don't need to specify it and it doesn't need to be unique. You can use property Tag for your own purpose (you can assign there ID or event instance of some object).
However you can also create your own control/usercontrol which encapsulate the whole row, and you can declare your own properties exactly for your purpose.
I'm newbie in C# and specially in Selenium. The code I'm providing works as intended, but I would like to add to it. Basically how to use Selenium to log into Linkedin, search for CURRENT EMPLOYEES of a company (Walmart for this example) and scrape the links for "send inmail" for every user.... clicking the "next" button on every page until there are no more. The following will open linkedin, login, enter walmart into searchbox, then click the next button.
I would like to write the links found within all the Send InMail buttons to a text file. Inspecting one of the Send InMail buttons gives the following:
<a class="primary-action-button label" href="/requestList?displayProposal=&destID=262919732&creationType=DC&authToken=BrmS&authType=name&trk=vsrp_people_res_pri_act&* amp;trkInfo=VSRPsearchId%3A5225861601486589992400%2CVSRPtargetId%3A262919732%2CVSRPcmpt%3Aprimary">Send InMail</a>
I would like to write all of these links into a text file as it cycles through all the "next" buttons. Also, I would like to know how to select a value from a drop down list that I haven't been able to "inspect" ... When you type "Walmart" or whatever into the search box, a drop-down gives you the option of selecting "people that currently work at walmart", etc. I haven't even been able to inspect that option in developer mode for some reason.
I've updated my code... This now SEEMS to WANT to do what i need...but there seems to be a timing issue where the "next" button might be loading before the "Send InMail" buttons...it will print a few results to the console and clicks next a few times, but then seems to melt down:
// Go to the home page
driver.Navigate().GoToUrl("https://www.linkedin.com");
// Get User Name field, Password field and Login Button
var userNameField = driver.FindElementById("login-email");
var userPasswordField = driver.FindElementById("login-password");
var loginButton = driver.FindElementByXPath("//input[#value='Sign in']");
// Type user name and password
userNameField.SendKeys("me#hotmail.com");
userPasswordField.SendKeys("Password123");
// and click the login button
loginButton.Click();
// perform search
var newSearch = driver.FindElementById("main-search-box");
var searchButton = driver.FindElementByName("search");
// search
newSearch.SendKeys("walmart");
searchButton.Click();
// Get all links from Send InMail buttons
List<IWebElement> elementList = new List<IWebElement>();
elementList.AddRange(driver.FindElements(By.LinkText("Next >")));
if (elementList.Count > 0)
{
foreach(IWebElement item in driver.FindElements(By.LinkText("Send InMail")))
{
Console.WriteLine(item.GetAttribute("href"));
var goForward = driver.FindElementByLinkText("Next >");
goForward.Click();
}
}
Console.ReadLine();
As far as I understand, after you perform search, there will be a search results which will be populated in the list like the ones in the figure attached.
screenshot of the Linkedin search result.
Then iterate through the results using similar method (code sample here is in Java, might be similar in C#)
List<WebElements> results_div = driver.findElemnts(By.xpath("//*[#id="results"]")) // where xpath of the <ul> element
int counter = 2 // because the data starts from id = 2. Refer image.
while(counter <= results_div)
{
WebElement element = driver.findElements(By.xpath("//*[#data-li-position=\"+counter+\"])) //xpath of the <li> element
String anchor_text = element.findElement(By.linkText("Send InMail")).getAtribute("href")
//Write a logic to save the data to a text file
}
Iterate the above until all the results are reached!
Hope it helps.
Edit : Try this, its not a working code! But try it on these grounds. It might help.
#Test(description = "Search the Site with some predefined words after Login and print the href attribute")
public void printUserID()
{
StartPage startPage = new StartPage(driver);
HomePage homePage = startPage.loginIntoAccount(LinkdinAccount.linkedEmail,LinkdinAccount.linkedPassword); // Logs in in to the account
driver.findElement(By.xpath("//*[#id=\"main-search-box\"]")).sendKeys("herbalife");
driver.findElement(By.xpath("//*[#id=\"global-search\"]/fieldset/button")).click();
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//*[#id=\"results\"]"))));
List<WebElement> results_div = driver.findElements(By.xpath("//*[#id=\"results\"]/li")); // where xpath of the <ul> element
System.out.println(results_div.size()); //*[#id="results"]
#driver.findElement(By.xpath("//*[#id=\"results-pagination\"]/ul/li[11]/a")).click();
int count = 1;
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//*[#id=\"results\"]"))));
while(driver.findElement(By.xpath("//*[#id=\"results-pagination\"]/ul/li[11]/a")).isDisplayed())
{
while(count <= results_div.size())
{
WebElement element = driver.findElement(By.xpath("//*[#data-li-position=\"" + count + "\"]"));
if(element.findElements(By.linkText("Send Inmail")).size() > 0)
{
String anchor_text = element.findElement(By.linkText("Send InMail")).getAttribute("href");
System.out.println(anchor_text);
}
count ++;
}
//for clicking the next button
driver.findElement(By.xpath("//*[#id=\"results-pagination\"]/ul/li[11]/a")).click()
}
I have a class called "is-active" and it has a colored arrow that sticks out from the nav into the main content based on which link the user clicked. The code runs a foreach and pulls all the categories from the database. How do I get the "is-active" class to display only for the current link? I know it works since I put it in the openList control and it displayed on all five categories, I just don't know how to get it to display on only the selected category.
I tried attaching jQuery to do it but adding the linkbutton is done all in the code behind so I am not sure how to attach the two. Is this the only way or is there another way?
Thank you in advance for your help!
Below is my code for the categories and link button:
protected override void CreateChildControls()
{
LiteralControl openingDiv = new LiteralControl("<div id='MainPanel'>");
LiteralControl closingDiv = new LiteralControl("</div>");
this.Controls.Add(openingDiv);
foreach (DataRow dr in ds.Tables[0].Rows)
{
LiteralControl openList = new LiteralControl("<li class='" + dr["CategoryColor"].ToString() + "'>");
LiteralControl closeList = new LiteralControl("</li>");
Label lblNumber = new Label();
LinkButton myLinkButton = new LinkButton();
myLinkButton.Text = "<span class='number'>" + dr["CategoryNumber"] + "</span>"+ dr["CategoryName"].ToString();
myLinkButton.CommandArgument = dr["Category_ID"].ToString();
myLinkButton.Click += myLinkButton_Click;
this.Controls.Add(openList);
this.Controls.Add(myLinkButton);
this.Controls.Add(closeList);
}
this.Controls.Add(closingDiv);
}
void myLinkButton_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton)(sender);
Session["CategoryID"] = btn.CommandArgument;
Response.Redirect(Request.RawUrl);
}
Its tricky because your response.redirecting in the button click handler which recreates the pages viewstate.
This means that your page will always appear as fresh and the fact a user has clicked that link has been lost.
as a workaround you could place the link id in a session variable before you response.redirect and then recall it when the page reloads.
then when in your loop, if the session variable matches the current button instance.id you set cssclass equal to is-active.
remember to clear the session variable too after you set the cssclass to is-active to avoid confusion in other pages.
also, you will have to do the id comparison after you add the button to the control tree, because this is where the system automatically generates the id for you. I can give you a full example if you wish.
keep in mind that this is a workaround and a different approach would be best.
by this I mean that if you were to use an ispostback wrapper instead of a redirect, then on postback you could set the id to isactive much easier.
Page lifecycle is an important thing to get your head around in .net if you wish to be more proficient, especially as you mention that your using ajax update panels.
Read this: http://msdn.microsoft.com/en-us/library/ms178472(VS.100).aspx it's a lot of information to take in, so bookmark it for later too as you will use it a lot.
I am dynamically creating buttons in C# with this logic
for (int i = 1; i <= vap; ++i)
{
newButtons[i] = new Button();
newButtons[i].BackColor = Color.Gray;
newButtons[i].Name = "Button4" + i.ToString();
newButtons[i].Click += new EventHandler(NewButtons_Click);
newButtons[i].Location = new System.Drawing.Point(width,height);
newButtons[i].Size = new System.Drawing.Size(76, 38);
tabPage5.Controls.Add(newButtons[i]);
}
This is creating a button and the click event is also working but my problem is I don't know how to get the text of the newly created button. On form load I am putting the text of button from database and this also happening correctly, but I want to know how to get the text of dynamically created buttons.
You won't be able to get the text until after you populate it from the database (careful not to try and get the text too early).
But this should work:
string buttonText = FindControl("Button41").Text;
Update
Since you want the button text from within the click event, you can access the sender object:
Button button = sender as Button;
string buttonText = button.Text;
You just have to set the Text property of the button when you add it.
Using something along the lines of...
string BtnTxt = FindControl("ExampleButton1").Text;
should work fine.
This may cause problems later on however if you are trying to pull text content of buttons in a random order.
hi I have a radio button list inside a repeater , the repeater is inside a Datalist.i need to get the value of the selected radio button. Also I need to select only a single radio in entire datalist using javascript.
You can do it with pure client side JavaScript regardless of Repeater, DataList or anything.
Have this code in your page:
<script type="text/javascript">
function GetSelectedRadioButtonValue(strGroupName) {
var arrInputs = document.getElementsByTagName("input");
for (var i = 0; i < arrInputs.length; i++) {
var oCurInput = arrInputs[i];
if (oCurInput.type == "radio" && oCurInput.name == strGroupName && oCurInput.checked)
return oCurInput.value;
}
return "";
}
</script>
Then to get the selected value call the function passing the name of the radio buttons group - all radio buttons with same name considered a group and the browser will let the user select only one of these.
Live test case: http://jsfiddle.net/yahavbr/BL9xJ/
I would use the normal HTML Radio Button control. Everything else is pretty complicated.
Then you can use the following code to figure out which one is selected:
http://remy.supertext.ch/2008/02/find-checked-radio-button-in-aspnet/