I'm trying to pull specific tag values on a page I created for experiment.I'm new to using Cefsharp. And I'm trying to experiment to improve myself.I was stuck for about two days in the EvaluateScriptAsync section.
I am trying to capture the values of the buttons in the specific label on the page I prepared.I run the following codes by pressing a button.My page has 3 buttons with the same label.However, it prints only one of them.
<input type="button" id ="button1" value="First Button">
<input type="button" id ="button2" value="Second Button">
<input type="button" id ="button3" value="Third Button">
These are the buttons I'm trying to find.
string script = #"(function() { " +
"var button = document.querySelectorAll('input[type = \"button\"]'); " +
"if(button != null) {for (var i = 0; i < button.length; i++) { return button[i].value;
}}else{alert('not found!');}" +
"})();";
chrome.EvaluateScriptAsync(script).ContinueWith(a =>{
var response = a.Result;
if (response.Success && response.Result != null)
{
string print = (string)response.Result;
MessageBox.Show(print.ToString());
}
}, TaskScheduler.FromCurrentSynchronizationContext());
I have tried many.I think I'm making a mistake in the javascript part.I've read most of the similar topics.But I could not find a solution.
output : First Button
This worked for me. The EvaluateScriptAsync funciton can only return 1 value or a string so I made sure to convert the results in JavaScript to a JSON string object.
Then when you retrieve the result back in C# land, you can then use JSON to convert it back to an object (in this case a list of strings) and perform any operations you need on the data.
// Step 01: Generate a HTML page
var htmlPage = #"
<html>
<body>
<p>Hello!!</p>
<input type='button' id='button1' value='First Button'>
<input type='button' id='button2' value='Second Button'>
<input type='button' id='button3' value='Third Button'>
</body>
</html>";
// Step 02: Load the Page
m_chromeBrowser.LoadHtml(htmlPage, "http://customrendering/");
// Step 03: Get list of buttons on page from C# land
var jsScript = #"
// define a temp function to retrieve button text
function tempFunction() {
var result = [];
var list = document.querySelectorAll('input[type=button]');
for(var i = 0, len = list.length; i < len; i++) {
result.push(list[i].value);
}
// Important: convert object to json string before returning to C#
return JSON.stringify(result);
}
// Now execute the temp function and returns result back to C#
tempFunction();";
var task = m_chromeBrowser.EvaluateScriptAsync(jsScript);
task.ContinueWith(t =>
{
if (!t.IsFaulted)
{
var response = t.Result;
if (response.Success == true)
{
// Use JSON.net to convert to object;
MessageBox.Show(response.Result.ToString());
}
}
}, TaskScheduler.FromCurrentSynchronizationContext());
Looking at your JavaScript code sample, the problem with your code is that in your loop you have a return statement that will just return the 1st button value it comes across. Thats your problem.
If you want to interact with the resulting list in C# land you will need to convert it back from a JSON string. Just go to nuget and install the 'Newtonsoft.Json' package into your project.
Then you can write something like:
// C# land
var list = new List<string>();
list = JsonConvert.DeserializeObject<List<string>>(response.Result.ToString());
Related
I have a controller in C# that, among other things, provides HTML for external links.
var htmlLinkBuilder = new StringBuilder($#"
<div>
<span>Dropdown</span>
</div>
<div class='dropdown-menu'>
");
foreach (var instance in thing.instances)
{
htmlLinkBuilder.AppendLine($#"
<a
class='dropdown-item'
href='{_configuration["Identity:Url"]}otherStuff/urlThings'
target='_blank'
rel='noopener noreferrer'
[onClickVar]
>
{instance.Name}
</a>
");
}
htmlLinkBuilder.AppendLine("</div>");
link.HtmlLink = htmlLinkBuilder.ToString();
I'm using dangerouslySetInnerHTML in a react js file which contains a handleNavClickLogging() function.
My question is, can I properly reference the function over each link with some form of
__html: htmlFromAbove.replaceAll("[onClickVar]", { () => handleNavClickLogging('External Link') } )
or how can I reference this function when clicking a dropdown item?
Expected output is an onclick function performed after clicking one of the dropdown items.
What I want to do is that I have created a asp.net web application and right now I m using XML to save my data (I AM NOT USING SQL)and my next task is to Generate A unique 8digits Alphanumeric Id for the users which will be used by them In future to track there request.
I have been given a particular format of this ID so I can't use 'GUID'.
The format given is this:
PR000000(PR stands for Project)
NP000000(NP stands for Non-Project)
So, the first two letters will be selected according to the user entry(if its a Project procurement request then 'PR' and in case of Non-project Procurement request 'NP') and rest 6 digits are simple integers which will keep increasing (000001,000002,000003....999999).
I have searched a lot everywhere but its all about php,uniquecode,GUID etc. but I just want a simple code which perform the above task with ease like IF-Else statement + keep increasing the count(000001...000002..).
This is the code for Project and Non project selection:
PROJECT<input type="radio" name="portal" id="radio1" onclick="changeMe(this);"/> <input type="text" name="textprojectOff" id="text1" value="Project Name" onclick="changeMe(this);"/>
NON-PROJECT<input type="radio" id="radio2" name="portal" onclick="changeMe(this)"/> <input type="text" name="textnonprojectOff" id="text2" value="Department" onclick="changeMe(this);"/>
<script type="text/javascript" >
function changeMe(inField)
{
var fieldId = inField.id;
var type = fieldId.substring(0, 4);
if (type == 'text') {
var name = fieldId.substring(4);
var radioButton = document.getElementById("radio" + name);
radioButton.checked = true;
} else {
var name = fieldId.substring(5);
var textField = document.getElementById("text" + name);
textField.focus();
textField.value ='';
}
}
If anyone require my xml code for my help then kindly tell me in the comment section I will post it at that time.
For your requirement, you will have to generate the unique ids from server-side code after checking the existing values in a Database.
you can use a Oracle Sequence if you want. Client side generation should not be used in this case because there is a change that multiple users can get the same unique id. So this generation should be handled server side / db side.
Here I got the solution of My Own problem ,So,I thought to share it with everyone so that other can get help from it. Without Using any typical Function I have generated an Unique Id for each and ever user.
.cs programming:
protected void GetId()
{
MSXML2.DOMDocument objXML = new MSXML2.DOMDocument();
string oPath = null;
oPath = Server.MapPath("PARNId.xml");
XmlDocument doc = new XmlDocument();
if (objXML.load(oPath) == true)
{
objNextId = objXML.selectSingleNode("//Id").text;
}
}
protected void SetId()
{
MSXML2.DOMDocument objXML = new MSXML2.DOMDocument();
string oPath = null;
oPath = Server.MapPath("PARNId.xml");
XmlDocument doc = new XmlDocument();
if (objXML.load(oPath) == true)
{
objXML.selectSingleNode("//Id").text = objNextId;
}
if (RadioButton2.Checked == true)
{
Label1.Text = "Your PURCHASE ACTION REQUEST NUMBER Is : PR" + objNextId;
}
else
{
Label1.Text = "Your PURCHASE ACTION REQUEST NUMBER Is :NP" + objNextId;
}
objXML.save(oPath);
}
Calling both the functions
GetId();
Label1.Text = objNextId;
objNextId = Convert.ToString(Convert.ToInt32(objNextId) + 1);
SetId()
I have created a separate XML file named Track.xml, in which I have assigned a node 100000,and this keep incrementing with every request made and finally I saved the label1.text and this keep record of all PARN generated with each user Hope it helps other!!
I am currently working on a C# project using ASP.NET. And I'd like to implement a list of dropboxes. So a User starts with a dropbox and can select a method and next to the dropbox is a + and - button, which enables a user to add more dropboxes. So I am wondering how can I implement that is it possible to build a List of dropboxes in ASP.NET?
You don't need any server side code for this, client side scripting is ideal solution for your needs.
Having such HTML:
<div id="MainPlaceholder">
<div id="DropDownPlaceholder">
<select name="myDropDown">
<option value="1">First</option>
<option value="2">Second</option>
<option value="3">Third</option>
</select>
<button type="button" onclick="AddDropDown(this);">+</button>
<button type="button" onclick="RemoveDropDown(this);">-</button>
</div>
</div>
You need the following pure JavaScript to make it work:
<script type="text/javascript">
var added_counter = 0;
function AddDropDown(sender) {
var parent = sender.parentNode;
//make fresh clone:
var oClone = parent.cloneNode(true);
//append to main placeholder:
parent.parentNode.appendChild(oClone);
//store change in global variable:
added_counter++;
}
function RemoveDropDown(sender) {
//don't allow to remove when there is only one left
if (added_counter <= 0) {
alert("One drop down must exist");
return;
}
var parent = sender.parentNode;
//disable so value won't be passed when form submitted:
parent.getElementsByTagName("select")[0].disabled = true;
//hide:
parent.style.display = "none";
//store change in global variable:
added_counter--;
}
</script>
The code has comments, but if you need any further explanation please feel free to ask.
Live test case.
Edit: As you need to read the selected values on the server side code, better approach would be to change the name of each cloned drop down:
var totalAddedCounter = 0;
function AddDropDown(sender) {
var parent = sender.parentNode;
//make fresh clone:
var oClone = parent.cloneNode(true);
//assign unique name:
oClone.getElementsByTagName("select")[0].name += "_" + totalAddedCounter;
//append to main placeholder:
parent.parentNode.appendChild(oClone);
//store change in global variable:
added_counter++;
totalAddedCounter++;
}
Now the tricky part is reading those values. Instead of plain dropboxlistID.Text you will have to iterate over all posted values looking for what you need:
foreach (string key in Request.Form.Keys)
{
if (key.StartsWith("dropboxlistID"))
{
string text = Request.Form[key];
//.....
}
I want to add a Header to my PDF with this:
--header-center TEST
and it works fine, but if i want to insert Whitespace:
--header-center TEST test
it wont be displayed. Do I have to write something instead of " "?
Another question is how to insert pagenumbers into the footer. I found this code-snippet, but I'm new in this issue and have no idea how to implement it:
var pdfInfo = {};
var x = document.location.search.substring(1).split('&');
for (var i in x) { var z = x[i].split('=',2); pdfInfo[z[0]] = unescape(z[1]); }
function getPdfInfo() {
var page = pdfInfo.page || 1;
var pageCount = pdfInfo.topage || 1;
document.getElementById('pdfkit_page_current').textContent = page;
document.getElementById('pdfkit_page_count').textContent = pageCount;
}
And my last question is how to insert Images into the footer with --header-html ~\image.html.
I inserted a link referencing a simple html with a picture but it wont be displayed.
I know... many questions. This issue is very tricky for me.
Thanks in advance!
LG FG
As in my comment, the whitespace in the text header should work if you surround it in quotes, ex --header-center "TEST test"
Okay, so I played around and found how to get the page numbers and image to work. Your header.html should look something like (notice how the image URL is the absolute path) :
<html>
<head>
<script type="text/javascript">
var pdfInfo = {};
var x = document.location.search.substring(1).split('&');
for (var i in x) { var z = x[i].split('=',2); pdfInfo[z[0]] = unescape(z[1]); }
function getPdfInfo() {
var page = pdfInfo.page || 1;
var pageCount = pdfInfo.topage || 1;
document.getElementById('pdfkit_page_current').textContent = page;
document.getElementById('pdfkit_page_count').textContent = pageCount;
}
</script>
</head>
<body onload="getPdfInfo()">
<img src="/var/sites/mysite/htdocs/images/logo.jpg" />
<br />Page <span id="pdfkit_page_current"></span> Of <span id="pdfkit_page_count"></span>
</body>
</html>
Then generate the with something like wkhtmltopdf --margin-top 40mm --header-html /var/sites/mysite/pdf/header.html content.html output.pdf
You'll have to play with --margin-top to get the right spacing. The same procedure should work for footers as well.
My source for this was http://metaskills.net/2011/03/20/pdfkit-overview-and-advanced-usage/ (PDFkit is a wrapper for wkhtmltopdf)
I've got a simple spam killer I'm trying to put together, but the text is not showing up on my form.
The javascript is:
<script language="javascript" type="text/javascript">
document.write("SPAM Killer: What is " + GetDateMonth() + " + " + GetDateDay() + "?")
</script>
In my .js file, I have these two functions defined:
function GetDateMonth() {
return date1.getMonth() + 1;
}
function GetDateDay() {
return date1.getDay() + 1;
}
The text shows up under IE8, but not under Chrome.
As a bonus: My OnClick method of my Submit form has this bit of code that is incorrectly adding my month and date:
string spamError = "The SPAM Killer answer was incorrect. ";
char[] split = spamTest.ToCharArray();
for (int i = 0; i < split.Length; i++) {
if (char.IsLetter(split[i])) {
Ok = false;
txtMessage.Text = spamError + "Non-numeric data entered.";
return;
}
}
int nTestValue = Convert.ToInt32(spamTest, 10);
if (nTestValue < 1) {
Ok = false;
txtMessage.Text = spamError + "Negatave or zero value found.";
}
DateTime dt = DateTime.Now;
int month = dt.Month;
int day = dt.Day;
int nCorrect = month + day;
if (nCorrect != nTestValue) {
Ok = false;
txtMessage.Text = spamError + string.Format("Expected {0}; Received {1}.", nCorrect, nTestValue);
return;
}
Using IE8, I see the following:
SPAM Killer: What is 2 + 3?
I enter 5, click Send, and get Expected 17; Received 5.
Don't reinvent the wheel, help read books with http://www.google.com/recaptcha
For C# code see http://code.google.com/apis/recaptcha/docs/aspnet.html
If you're adamant on sticking with your code, think about the problems around midnight, and users in other timezones. Also, a bot can very easily answer your anti-bot question, it would take me 45 seconds to code support for that, if I wrote bots.
If you're still adamant, you shouldn't use document.write anymore (not since 2002), but instead use DOM to insert the text to a tag ID like this: Change label text using Javascript
The answer, it seems, was in using the document.write() function with appending strings.
I redesigned my HTML to be more like this:
<table>
<tr>
<td colspan="2">
<b>[Human Check]</b><br />
Enter the text to the left and below exactly as it appears:
</td>
</tr>
<tr>
<td>
<script language="javascript" type="text/javascript">
document.write(GetSpamText())
</script>
</td>
</tr>
</table>
#serverfault: Thanks for your suggestion about the date property, though. That would have been a problem.
The text returned by GetSpamText() can be static or coded to create a random value (another topic).