How to get an element that was created during page load? - c#

I'm creating elements dynamically based on SQL data server side.
I want to also edit some of those element's attributes after their creation.
They way I'm trying to go about this is by generating a string with the elements and inserting it into a div's innerHTML:
client side:
<div id=master runat="server"></div>
server side:
string textToDiv = "<div id='" +num +"'><ul><li></li><li></li></ul></div>";
master.innerHTML = textToDiv;
Looks something like this in chrome:
<div id="master" runat="server">
<div id='1'>
<ul>
<li></li>
<li></li>
</ul>
</div>
<div id='2'>
<ul>
<li></li>
<li></li>
</ul>
</div>
</div>
Now, I want to change one of the child div's attributes. How do i go about doing that?
All I found on the internet is for more static uses using the method I applied when changing the 'master' div's innerHTML attribute. Is there a get() function or something similar to document.getElementByID() I can use?

a better way to solve this, to just simply place your script under the html code, but still in the body, this will make sure, the script is just loaded, when everything was rendered to the screen, with this, you can instantly access the elements and you dont have to use the window.onload eventlistener

I think you need to use the onload event and then use a function for create the Element.
window.onload() => {
element = document.createElement(" ");
element.setAttribute(" ");
element.innerHTML = ' ';
document.getElementById(' ').appendChild(element);
}
I hope it's can help you

Update and my solution:
I ended up just changing the attribute when generating the string. Used if() statements to change only the element I wanted.
Also, I moved the whole thing into a function and I'm calling the function on page load.
That way I can update the content without reloading the page.

Related

How to sendkeys to a <p> tag through C# and Selenium

i want to sendkeys "description" within a textarea. I have tried all the possible ways but does not work.
HTML of the element :
<div class="ta-scroll-window ng-scope ta-text ta-editor form-control" ng-hide="showHtml">
<div class="popover fade bottom" style="max-width: none; width: 305px;">
<div class="arrow"></div>
<div class="popover-content"></div>
</div>
<div class="ta-resizer-handle-overlay">
<div class="ta-resizer-handle-background"></div>
<div class="ta-resizer-handle-corner ta-resizer-handle-corner-tl"></div>
<div class="ta-resizer-handle-corner ta-resizer-handle-corner-tr"></div>
<div class="ta-resizer-handle-corner ta-resizer-handle-corner-bl"></div>
<div class="ta-resizer-handle-corner ta-resizer-handle-corner-br"></div>
<div class="ta-resizer-handle-info"></div>
</div>
<div id="taTextElement737852736512107" contenteditable="true" ta-bind="ta-bind" ng-model="html" ta-keep-styles="true" class="ng-pristine ng-valid ta-bind ng-empty ng-touched" an-form-object-name="Açıklama" name="Açıklama">
<p>
<br>
</p>
</div>
</div>
Code trial :
Dim action2 = New Actions(driver)
Dim cekbul2 = driver.FindElement(By.XPath("//*#id=""taHtmlElement737852736512107""]"))
cekbul2.SendKeys("Açıklama")
Console.Write("textarea send description")
or
Dim cekbul2 = driver.FindElement(By.XPath("//textarea[#class='ng-pristine ng-untouched ng-valid ng-scope ta-bind ta-html ta-editor form-control ng-empty ng-hide' and #id='taHtmlElement737852736512107']"))
The error is :
"no such element: Unable to locate element does not work" give error
Your html does not have a text area input field inside it.
When you use an xPath that says
'//textarea' this means that you are looking for an element that has tags of <textarea> </textarea>
It looks like your html is actually div's that are styled up to look like text areas.
That is why your second attempt will never work - because you are looking for a textarea where none exists.
Typically, in the situation where a div is styled up to work like a text area or textbox, you will find that the div has a backing input behind it.
These must be located between the
<form> and </form> tags in the html - otherwise the server would never be able to receive the data. (Html 5 provides new ways of working with this - but that is another story)
Can you examine your full html, and see if you can find the actual text area objects or the input type objects that end up containing the text content.
Type some dummy text, and use an html inspector tool within chrome or firefox to look for your dummy text.
If however, the post is completed by javascript - you may find that the javascript does not use inputs or text areas for containing the text and instead posts it external to any form elements. This is common with richtext emulators such as forum post pages.
If that is the case- you may need to experiment and find the appropriate html element that you need to send keys to in order for the content to work.
Also - could you try
Dim cekbul2 = driver.FindElement(By.XPath("//div[#id='taHtmlElement737852736512107']"))
I couldnt help but notice it had an xPath syntax error - you had no starting [ square bracket ] - also, in programming it is sometimes considered lazy a bad practice to wildcard / work with dynamics. I recommend always using the tag type for your xpaths, as opposed to '//*'
Worse case scenario, I would say that you could probably get around this by using Javascript execution. Eg: Directly setting the text, instead of 'sending the key strokes'.
However, this does not emulate human behavior - but it may be a necessary evil depending on your situation.
To send text to the <p> tag you have to use the ExecuteScript() method from IJavaScriptExecutor Interface and you can use the following code block :
((IJavaScriptExecutor)driver).ExecuteScript("document.getElementsByTagName("p")[0].innerHTML="Hasan Sarıkaya";");
I want to highlight some points here
Most probably your locator which you are using is not correct.
There are three way which I know to enter text using selenium
1)Use driver.findElement(yourLoator).sendKeys("Stringvalue");
2)You can use action class to send keys
3)You can use javascript executor to change innerHtml code
Personally ill not prefer the third solution, because we are testers I believe changing dom attribute is a good practice
Hope this will give you some help. please Let me know in case any query.

jQuery not executing because of asp:Panel

I am using the jQuery plug in contentcarousel. It is a good plugin and all but I need the ability to dynamically create a certain number divs according to the user.
To achieve this I am using an <asp:panel> and then running a Literal & foreach in C# to populate the panel. The problem comes in when the <asp:panel> is used.
It seems as if the jQuery plugin can only work if the divs occur in a certain order.
ie.
<div id="ca-container" class="ca-container">
<div class="cawrapper">
<div class="ca-item ca-item-2">
<div class="ca-item-main">
When the panel is used, then the order becomes
<div id="ca-container" class="ca-container">
<div class="cawrapper">
<div id="panelinfo">
<div class="ca-item ca-item-2">
<div class="ca-item-main">
And the plugin stops working. At least I am assuming so due to the fact that the arrows dont show up, none of the buttons work, etc.
Does anyone know if there is a way around this? Maybe a way to "hide" the div that the panel becomes?
It sounds like you want to have a control that acts like a Panel in server side code, but instead of being rendered as a div just plops all of whatever would have been inside of it without adding anything "extra". That's pretty much the definition of an asp:Placeholder. Just use that instead of a Panel.
Try moving your JQuery code into window.load. I'm assuming you have your jquery in document.ready which will fire the second the dom is ready.
$(window).load(function(){/*Your code*/}

Appending Data to a <div> tag with .NET

So i have the following situation in my html file:
<div id = "imagePreview">
<div id = "earlyDetectionPlots">
<div id = "earlyDetectionScoreMetricsPlots">
</div>
<div id = "earlyDetectionVariableMetricsPlots">
</div>
<div id = "earlyDetectionPseudoStandardizedCoefficientPlots">
</div>
</div>
</div>
I have a jQuery function as follows:
$(document).on('click', 'a[data-link]', function () {
var $this = $(this);
url = $this.data('link');
$("#imagePreview").load("imageProcess.aspx?" + url);
});
where url has GET parameters in the form of something like m=2k01&type=EarlyDetection etc.
In my imageProcess.aspx file, I'm using regular expressions to grab a bunch of images from a folder.
However, each of the divs above are going to have different data in them. I know how to decide which images go where, but I don't know how to use c# to say something like #earlyDetectionScoreMetricsPlots.append("image.png"), since I don't want to append the images directly to imagePreview but rather to the sub div within it, and as far as I know, I can't use jQuery within the imageProcess file.
(I think there might be a way to call specific functions within the imageProcess.aspx file corresponding to the different <divs>, but I don't know how to do that with jQuery). Any help would be much appreciated.
You either need more complex jQuery or return the actual content you want in #imagePreview from imageProcess.aspx

adding conditional requiredFieldValidators to dynamically created form in c# asp.net

Ok,
i have a fully rendered dynamic form ( i do not know the content of the form, it is provided to my via a webservice )
i used asp.net RequiredFieldValidator for validation, because i read in this article that we could dynamically switch validators on and off depending if the field is visible or not
with the ValidatorEnable(val, enabled) function.
though now that i got the form rendered, i'm running into a bit of trouble with this javascript, as i don't want to put it in the aspx file itself, (don't have a control there anyway since the form is build up in codebehind from the webservice data...)
so i took a look at the clientId and it turns out the validator's client ID is the id of the span it renders to.
so i tried running this in firebug to test if i could enable / disable one of those validators, but that seems not to be possible, a jQuery span element does not have a property to enable it.
ValidatorEnable($("#ContentPlaceHolderDefault_MasterWithNavContent_Poll_4_reqAnswer_373ac8b7_8da9_467b_b9b4_d586e45a7504"), false);
and the html that goes with this
<div class="question-container question-odd" id="ContentPlaceHolderDefault_MasterWithNavContent_Poll_4_question-373ac8b7-8da9-467b-b9b4-d586e45a7504">
<div class="question-meta">
<h3 class="validation-label">Which club have you visited?</h3>
<span style="display: block; margin-bottom: 10px; margin-top: 5px;" class="error validation" id="ContentPlaceHolderDefault_MasterWithNavContent_Poll_4_reqAnswer_373ac8b7_8da9_467b_b9b4_d586e45a7504">Please fill out this field.</span>
</div>
<input type="text" class="answer-container text" id="ContentPlaceHolderDefault_MasterWithNavContent_Poll_4_answer_373ac8b7_8da9_467b_b9b4_d586e45a7504" name="ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MasterWithNavContent$Poll_4$answer_373ac8b7_8da9_467b_b9b4_d586e45a7504">
</div>
Does someone know where i'm going wrong here?
maybe I'm to quick to jump from the serverside ClientId to the <span> which the RFV renders into? but they seem exactly the same.
hope someone can point me in the good direction!
Maybe a better approach would be to loop through the client-side array of validators (Page_Validators) and find the validator which you want to disable.
See also this MSDN page and this codeproject article for more information.
Perhaps a more appropriate way to do this would be
ValidatorEnable($("<%= reqAnswer.ClientID %>")[0], false);
Using <%= reqAnswer.ClientID %> avoids having to guess at or hard-code the client-side ID of the validator. Adding [0] after the jQuery $() gets the actual validator DOM element instead of the jQuery wrapper.
Source for [0]

how to assign a class to one of the <li> in master page through c# from child page?

I have a master page with a bunch of menu like:
<ul id="ulMenu" runat="server">
<li id="A">
<li id="B">
<li id="C">
..and so on ..
</ul>
and i have a function in master page which i call from child pages, like:
Master.setCurrentMenu("A");
and in the SetCurrentMenu() of the Masterpage, since I have my < UL > set to run at server, i am changing it dynamically, like:
StringBuilder myMenu = new StringBuilder(ulMenu.InnerHtml);
//replace and add class for current page
myMenu .Replace("<li id=\"" + cp + "\"", "<li class='selected' id=\""+ cp +"\"");
ulMenu.InnerHtml = myMenu.ToString();
(where cp is the "A" in the current context)
This way I am changing the innerHTML and theoretically its supposed to work just fine. but, in my < UL > i have a few server tags in between like <% ... %> so now the asp.net tells me very cheerfully that :
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
What is the best thing I can do in this scenario?
Many thanks!
ps: edited this coz my < ul > were being taken as an html instead of showing up.. hmm
It's a known issue. I would suggest not using code blocks in this case (it's considered a best practice use as little code blocks as possible).
This link has the correct answer, infact, somebody can delete this question since its a repeated one, I dint realize it.
I finally got this to work via:
C# - How to change HTML elements attributes

Categories

Resources