i have a html table which i want to pass to another page using session variable,how can it be done? I have tried this
Session["sumtable"] = (HtmlTable)htab;
Its not working...
On the other page
.aspx
<table id="tblsum" runat="server"></table>
.cs
if (Session["sumtable"] != null)
{
tblsum = (HtmlTable)Session["sumtable"];
}
Try this
//Page Source
Session["tbl"] = dt.Rows; // table id = td
Response.Redirect("WebForm4.aspx");
// page Destination
HtmlTableRowCollection tr = (HtmlTableRowCollection)Session["tbl"];
foreach (HtmlTableRow t in tr)
{
dt.Rows.Add(t); // table id = td
}
Related
I have a html table with onclick on the tr tag. This "click" send me to a new web page, and then I need to go back to previous page and continue to the next "tr click".
Until now, I achieve to execute the first onclick, then when I go back, Selenium give me this error.
stale element reference: element is not attached to the page document
The code I have
IWebElement table = driver.FindElement(By.Name("pg_table"));
IReadOnlyCollection<IWebElement> rows = table.FindElements(By.XPath(".//tr[#onclick]"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
int rowCurrent = 0;
foreach (IWebElement row in rows)
{
js.ExecuteScript($"arguments[{rowCurrent}].click();", row);
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("/html/body")));
//retreive data from the new page....
Thread.Sleep(1000);
driver.Navigate().Back();
++rowCurrent;
}
Can you help me.
Thanks in advance.
I solve this with this, first I get all the onclick javascript in a list
List<string> linksPbds = new List<string>();
IWebElement table = driver.FindElement(By.Name("pg_table"));
IReadOnlyCollection<IWebElement> rows = table.FindElements(By.XPath(".//tr[#onclick]"));
foreach (IWebElement row in rows)
{
linksPbds.Add(row.GetAttribute("onclick"));
}
then I iterate each member of the list and execute the javascript
foreach (var link in links)
{
js.ExecuteScript(link);
var airlineCode = driver.FindElement(By.XPath("/html/body/form/table[1]/tbody/tr[2]/td[1]")).Text;
.... other html element
}
I donĀ“t know if ths is best approach , but this work for me.
I want to verify the values from a register by using a css selector
[FindsBy(How = How.CssSelector, Using = "#grid_cases > table > tbody")]
private IWebElement CaseListGrid;
I have to return the WebElements value and store it to string
public List<CaseListEntry> GetCaseListEntries()
{
CaseListGrid.
return null;
}
You can get the text from your CaseListGrid element by using the following:
CaseListGrid.Text;
But you are retrieving a tbody, which probably doesn't have any text in it.
After you retrieved the CaseListGrid element, you could do something like this to retrieve all td tags inside the tbody.
CaseListGrid.FindElements(By.TagName("td"));
After that, loop over the elements and retrieve the text:
public List<CaseListEntry> GetCaseListEntries()
{
var elements = CaseListGrid.FindElements(By.TagName("td"));
var listEntries = new List<CaseListEntry>();
foreach (var element in elements)
{
var text = element.Text;
if (!string.IsNullOrWhiteSpace(text))
listEntries.Add(new CaseListEntry(text)); // I don't know what kind of class CaseListEntry is, so this is pseudo code
}
return listEntries;
}
It works
var CaseGridTrs = CaseListGrid.FindElements(By.XPath(".//tr"));
var entryList = CaseGridTrs.Select(x =>
{
var CaseEntryTds = x.FindElements(By.XPath(".//td"));
return new CaseListEntry
{ Register = CaseEntryTds.ElementAt(0).FindElement(By.XPath(".//a")).Text,
In my application FirstPage.aspx I am using a repeater to create a series of links:
<a href="MySecondPage.aspx?id=<%#DataBinder.Eval(Container.DataItem, "ValueID")%>">
<%#DataBinder.Eval(Container.DataItem, "ValueName")%></a>
Normally, in the page load of MySecondPage.aspx I would get the value of the QueryString like:
string OldID = Request.QueryString["id"];
num SkulloID = Convert.ToInt(SkulloID);
if(SkulloID > 5)
{
Response.Write("Hello World");
}
Instead of this, what I want to do is somehow on FirstPage.aspx get the value of the querystring in the anchor tag to do some logic on just as in the case of MySecondPage.aspx. Is something like this possible?
Edited to test solutions presented
#CodingBiz I tried the solution you presented and I am having trouble. Here is what I have tried.
In the Page_Load i added the following code to set the CommandArgument of the link button
//Error: The name containder does not exist in the current context
lbnTestLink.CommandArgument = DataBinder.Eval(container.DataItem, "ValueID");
In the asp:LinkButton click command
MyID = DataBinder.Eval(container.DataItem, "ValueID");
using (SqlConnection conn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString))
{
SqlCommand cmdzero = new SqlCommand(#"SELECT [num] FROM [My_Table] Where [ValueID] = #MyID AND [IsSubItem] = 1 AND [FiscalYear] = #FiscalYear", conn2);
cmdzero.Parameters.AddWithValue("#MyID", MyID);
cmdzero.Parameters.AddWithValue("#FiscalYear", strFiscalYear);
conn2.Open();
int countzero = (int)cmdzero.ExecuteScalar();
int myArgument = countzero;
if (MyID = myArgument)
{
strListLink = "FistPage.aspx";
}
else
{
strListLink = "SecondPage.aspx?id=<%#DataBinder.Eval(Container.DataItem, \"ValueID\")%>";
}
}
I don't understand where the querystring is supposed to get set here.
Asked this on the forums as well, but no luck as of yet. What I need to do is set the HTML content of each content block on a given page. It seems that I can set the html value okay, but saving it does not update the actual page.
I'm wondering if it's because there needs to be some sort of save call on the control. There doesn't seem to be any methods available for such an action.
foreach (var c in duplicated.Page.Controls)
{
// go through the properties, se the ID to grab the right text
foreach (var p in c.Properties)
{
if (p.Name == "ID")
{
var content = pageContent.Where(content_pair => content_pair.Key == p.Value).SingleOrDefault();
var control = pageManager.LoadControl(c);
if (control is ContentBlock)
{
var contentBlock = pageManager.LoadControl(c) as ContentBlock;
contentBlock.Html = content.Value;
}
}
}
}
pageManager.SaveChanges(); */
WorkflowManager.MessageWorkflow(duplicated.Id, typeof(PageNode), null, "Publish", false, bag);
The following code may help you achieve what you need.
It will first get the page by its title (I am looking for a page by the title "duplicated" as it's implied by your code).
It generates a new draft of the current page, then go over its controls.
Controls which are detected as content blocks are then iterated in a foreach loop.
As written in the comment inside the foreach loop, you may detect controls by their explicit ID (by the property named "ID") or by their related shared content block (by the property named "SharedContentID") or any other condition (or ignore this condition altogether, which would result in updating all the controls n the page.
Once we have a control to update at hand, you can set its new value depending on the localization settings of your project.
After that the draft is saved and published and optionally a new version is created for it.
PageManager pageManager = PageManager.GetManager();
VersionManager vmanager = VersionManager.GetManager();
PageNode duplicated = pageManager.GetPageNodes().FirstOrDefault(p => p.Title == "duplicate");
if (duplicated != null)
{
var draft = pageManager.EditPage(duplicated.Page.Id, true);
string contentBlockTypeName = typeof(ContentBlock).FullName;
PageDraftControl[] contentBlocks = draft.Controls.Where(contentBlock => contentBlock.ObjectType == contentBlockTypeName).ToArray();
foreach (PageDraftControl contentBlock in contentBlocks)
{
Guid contentBlockId = contentBlock.Id;
//User "SharedContentID" if you are looking up controls which are linked to a shared content block of a specific ID.
//If you you are trying to locate a specific control by its own ID, use the explicit "ID" property instead of "SharedCotentID"
if (contentBlock.Properties.Where(prop => prop.Name == "SharedContentID" && prop.Value.ToString() == contentItemIdstr).FirstOrDefault() != null)
{
ControlProperty htmlProperty = contentBlock.Properties.Where(prop => prop.Control.Id == contentBlockId && prop.Name == "Html").FirstOrDefault();
if (htmlProperty != null)
{
if (AppSettings.CurrentSettings.Multilingual)
{
htmlProperty.GetString("MultilingualValue").SetString(CultureInfo.CurrentUICulture, "New Value");
}
else
{
htmlProperty.Value = "New Value";
}
}
}
}
draft = pageManager.SavePageDraft(draft);
draft.ParentPage.LockedBy = Guid.Empty;
pageManager.PublishPageDraft(draft);
pageManager.DeletePageTempDrafts(draft.ParentPage);
//Use the 2 next lines to create a new version of your page, if you wish.
//Otherwise the content will be updated on the current page version.
vmanager.CreateVersion(draft, draft.ParentPage.Id, true);
vmanager.SaveChanges();
pageManager.SaveChanges();
}
I hope this code helps.
Alon.
Do I have to use XPath to link my XML document
to a repeater or is there another way.
here is my some of my code.
first page loop through data and store as XML:
public virtual void Button_Click(object sender, EventArgs args)
{
TableControl recControls = (TableControl)this.Page.FindControlRecursively("TableControl");
if (recControls != null)
{
TableControlRow[] rows = recControls.GetSelectedRecordControls();
this.Page.Session["RegistrationTableControl"] = rows;
// create XML writer to
using(System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(#"c:\temp\reg.xml"))
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.CloseOutput = false;
writer.WriteStartDocument();
writer.WriteStartElement("SubContractors");
foreach(TableControlRow rec in rows)
{
writer.WriteElementString("SubContrator1", rec.BUSINESSNAME.Text);
writer.WriteElementString("SubContactName1", rec.OWNERNAME.Text);
writer.WriteElementString("SubAddress1", rec.ADDRESS.Text);
writer.WriteElementString("SubCity1", rec.CITY.Text);
writer.WriteElementString("SubState1", rec.STATE.Text);
writer.WriteElementString("SubZipCode1", rec.ZIPCODE.Text);
writer.WriteElementString("SubPhone1", rec.PHONE.Text);
writer.WriteElementString("SubFax1", rec.FAX.Text);
writer.WriteElementString("SubEmail1", rec.EMAIL.Text);
writer.WriteElementString("Status1", "Please enter information");
writer.WriteElementString("Referral", "1");
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
}}
Which creates my xml document.
Page 2 Code: I need to take the data in the newly create XML document and
populate my table control repeater work with this code.
on page 2
public override void DataBind()
{
base.DataBind();
// Make sure that the DataSource is initialized.
if (this.DataSource == null)
{
return;
}
// Setup the pagination controls.
BindPaginationControls();
// Populate all filters data.
// Bind the repeater with the list of records to expand the UI.
System.Web.UI.WebControls.Repeater rep = (System.Web.UI.WebControls.Repeater)(this.FindControl("TableControlRepeater"));
rep.DataSource = this.DataSource;
rep.DataBind();
int index = 0;
foreach (System.Web.UI.WebControls.RepeaterItem repItem in rep.Items)
{
// Make sure that the DataSource is initialized.
// Loop through all rows in the table, set its DataSource and call DataBind().
TableControlRow recControl = (TableControlRow)(repItem.FindControl("TableControlRow"));
recControl.DataSource = this.DataSource[index];
recControl.DataBind();
recControl.Visible = !this.InDeletedRecordIds(recControl);
index += 1;
}
}
I have take the XML data and place them in page 2 become the data source of the repeater.
Any help or suggestion is very helpful. I would really not to have to rewrite the code.
LINQ-To-XML is probably the most simple way to accomplish this task. See Scott Gu's post on it.
pseudo-code:
var xml = XDocument.Load(...);
reapeater.DataSource = from x in xml.Descendents("z")
where x.Attributes("y").Equals("select value")
select new { Value1 = x.Element("Value1"), Value2 = x.Element("Value2") };
repeater.DataBind();
I use LINQ to XML
for querying XML documents it is much easier.