Cefsharp winforms: Inject jquery into page - c#

I'm using ChromiumWebBrowser to load a website, and after page loaded, I'll execute some script
browser.ExecuteScriptAsync(script)
But that website not use jquery, so difficult to code my script. I want to inject jquery into that site to write my script easier. How can I do it? Thank you very much
EDIT:
I have had a jquery file in my computer. And I would like to add it to the page where I want to crawl data. I tried using LoadingStateChanged event, but not worked.
private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
ChromiumWebBrowser browser = (ChromiumWebBrowser)sender;
lbStatus.SetText(e.IsLoading ? "Loading..." : browser.Address);
if (!e.IsLoading)
{
//Load jquery
}
else
{
}
}

Set this code to script variable as string and then call browser.ExecuteScriptAsync(script)
(function () {
// more or less stolen form jquery core and adapted by paul irish
function getScript(url, success) {
var script = document.createElement('script');
script.src = url;
var head = document.getElementsByTagName('head')[0],
done = false;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function () {
if (!done && (!this.readyState
|| this.readyState == 'loaded'
|| this.readyState == 'complete')) {
done = true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
getScript('http://code.jquery.com/jquery-latest.min.js', function () {
if (typeof jQuery == 'undefined') {
console.log('Sorry, but jQuery wasn\'t able to load');
} else {
console.log('This page is now jQuerified with v' + $.fn.jquery);
$(document).ready(function () {
alert(1);
//here you can write your jquery code
});
}
});
})();

i push the entire jquery js-file as inline-code and works great:
browser.ExecuteScriptAsync(File.ReadAllText(#"content\jquery.1.11.1.min.js"));
reduces loading times...

it's very easy :)
string script_1 = "document.getElementsByTagName('head')[0].appendChild(document.createElement('script')).src = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'";
browser.ExecuteScriptAsync(script_1);
and for call any custom jquery function or class:
string script_2 = "$('.contact').css('color','#aabbcc');";
browser.ExecuteScriptAsync(script_2);

Related

Dropdown not binding in IE 8

I am binding dropdown list using jquery and asp.net callbacks.
this is working in IE-9,11 and other browsers also but It is not working in IE-8.
and It is not showing any error also.
I am using bellow javascript function for binding dropdown
function ClientCallback(result, context) {
if (!$('#ddltest')) {
return;
}
$('#ddltest').length = 0;
if (!result) {
return;
}
$(result).find('Table1').each(function () {
var OptionValue = $(this).find('OptionText').text();
var OptionText = $(this).find('OptionText').text();
var option = $("<option>" + OptionText + "</option>");
option.attr("value", OptionValue);
$('#ddltest').append(option);
});
}
from code behind method I am returning dataset in the form of xml like return ds.GetXml();

Why Jquery is not working for asp.net textbox's CssClass Property?

I am tying to validate the textboxes for achieving 'alphabets only' property in asp.net page with Jquery.
Here is the code
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
.............codes.............
<script type="text/javascript">
$('.alph').keypress(function (e) {
var regex = new RegExp("^[a-zA-Z\s]+$");
var str = String.fromCharCode(!e.charCode ? e.which : e.charCode);
if (regex.test(str)) {
return true;
}
else {
e.preventDefault();
alert('Alphabets only');
return false;
}
});
</script>
.............codes.............
<asp:TextBox ID="txt_name" CssClass="alph" BorderColor="Gray" Font-Size="Large" Height="25" Width="250" runat="server"></asp:TextBox>
This code didn't work and I am sure my computer is connected to the internet to reach code.jquery.com. Help me please.
try this script code after Document.ready block
$(document).ready(function(){
$('.alph').keypress(function (e) {
var regex = new RegExp("^[a-zA-Z\s]+$");
var str = String.fromCharCode(!e.charCode ? e.which : e.charCode);
if (regex.test(str)) {
return true;
}
else {
e.preventDefault();
alert('Alphabets only');
return false;
}
});
});
Before you can safely use jQuery you need to ensure that the page is in a state where it's ready to be manipulated. With jQuery, we accomplish this by putting our code in a function, and then passing that function to $(document).ready(). The function we pass can just be an anonymous function.
My mistake! Since I am new to Jquery I didn't know about 'doc.ready' I corrected the code as
$(document).ready(function () {
$('#<%=txt_name.ClientID %>').keypress(function (e) {
var regex = new RegExp("^[a-zA-Z\s]+$");
var str = String.fromCharCode(!e.charCode ? e.which : e.charCode);
if (regex.test(str)) {
return true;
}
else {
e.preventDefault();
alert('Alphabets only');
return false;
}
});
});
Code works perfect!

check if website is online - problems with postback

I've got a webpage that people in my company are filling in using mobile handsets. Only problem is, if they move out of a signal area, then when they try and update their work the page will go to a "page not found" and they'll lose the work they've filled in.
I'm trying to remedy this and, at the moment, have this solution:
protected void Button1_Click(object sender, EventArgs e)
{
Session["Online"] = 0;
CheckConnect();
if ((int)Session["Online"] == 1) { Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "alertMessage", "alert('You are currently online')", true); }
if ((int)Session["Online"] == 0) { Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "alertMessage", "alert('You are currently offline')", true); }
}
protected void CheckConnect()
{
System.Uri Url = new System.Uri("http://www.mypage.com/pixel.jpg?" + DateTime.Now);
System.Net.WebRequest WebReq;
System.Net.WebResponse Resp;
WebReq = System.Net.WebRequest.Create(Url);
try
{
Resp = WebReq.GetResponse();
Resp.Close();
WebReq = null;
Session["Online"] = 1;
}
catch
{
WebReq = null;
Session["Online"] = 0;
}
}
Now, this will check if the pixel file at www.mypage.com exists (no, that's not actually my page, I've substituted it for this example) and, if so, it returns a 0, if not a 1. Which is fine and dandy.
However, pressing the button causes the page to be reloaded. Then, if it's offline, it does the usual "page not found" business. My button code is here:
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
Basically, I want it to not reload the page if we're offline (or indeed if we are online, as the code that does the updating handles that part anyway).
EDIT - alright, different approach now. Doing this entirely through javascript using the following:
<asp:Button ID="Button1" runat="server" OnClientClick="ifServerOnline()" Text="Button" />
<script type="text/javascript">
function ifServerOnline(ifOnline, ifOffline)
{
var img = document.body.appendChild(document.createElement("img"));
img.onload = function ()
{
ifOnline && ifOnline.constructor == Function && ifOnline();
};
img.onerror = function ()
{
ifOffline && ifOffline.constructor == Function && ifOffline();
};
img.src = "http://www.mypage.com/pixel.jpg?" + Date.now;
}
ifServerOnline(function ()
{
return confirm('Online');
},
function ()
{
return confirm('Offline');
});
</script>
Unfortunately still causing a page refresh.
In your page's javascript assign form onsubmit event handler, where you cancel default submit. Also, in this event handler, issue an ajax request to the server with a very brief response. In onsuccess event handler of this ajax request - resubmit the form, in onerror handler - tell the user that they lost connection to server.
You can't do postback to the server when you offline.
No way to do it..
But maybe you can do that's with javascript.. try this way.
Managed it with this...
<asp:Button ID="btnRouteC" runat="server" OnClientClick="return ifServerOnlineA(ifServerOnlineA1, ifServerOfflineA1);" Text="Route" Width="45%" />
<script type="text/javascript">
function ifServerOnlineA(ifOnline, ifOffline)
{
var img = document.body.appendChild(document.createElement("img"));
img.onload = function ()
{
ifOnline && ifOnline.constructor == Function && ifOnline();
};
img.onerror = function ()
{
ifOffline && ifOffline.constructor == Function && ifOffline();
};
img.src = "http://www.myserver.com/pixel.jpg?" + Date.now;
return false;
}
function ifServerOnlineA1()
{
document.getElementById('btnRoute').click();
return false;
}
function ifServerOfflineA1()
{
alert("There is no connection at the moment. Please try again later.");
return false;
}
</script>
As Itiel said, it won't work through the codebehind but will through the Javascript.

How to call C# method in javascript by using GeckoFX as the wrapper of XULRunner

I am using GeckoFX16 and xulrunner-16.0.2.en-US.win32 in my project.
The thing is, I want to call a C# method in javascript.
I am curious, is there a way to do this?
Just like below:
C# part:
private GeckoWebBrowser weBrowser;
public browser()
{
InitializeComponent();
Gecko.Xpcom.Initialize("xulrunner");
weBrowser = new GeckoWebBrowser();
weBrowser.Parent = this;
weBrowser.Dock = DockStyle.Fill;
weBrowser.Navigate("test.html");
}
public string loadData(){
//load data from local file.
return str;
}
javascript part:
<script type='text/javascript'>
var data = window.loadData();
alert(data);
</script>
I am new in this area, I’ll appreciate if it is possible!
Important update:
Currently code with event.initMessageEvent does not work because this construction has been replaced on
var event = new MessageEvent('yourEventName', { 'view': window, 'bubbles': false, 'cancelable': false, 'data': 'some data' });
You can use a MessageEvent to invoke code in c#, but as far as I know you can't then return a string like you're wanting to. One of the unit tests demonstrates how to invoke the c# code:
[Test]
public void AddEventListener_JScriptFiresEvent_ListenerIsCalledWithMessage()
{
string payload = null;
browser.AddMessageEventListener("callMe", ((string p) => payload = p));
browser.LoadHtml(
#"<!DOCTYPE html>
<html><head>
<script type='text/javascript'>
window.onload= function() {
event = document.createEvent('MessageEvent');
var origin = window.location.protocol + '//' + window.location.host;
event.initMessageEvent ('callMe', true, true, 'some data', origin, 1234, window, null);
document.dispatchEvent (event);
}
</script>
</head><body></body></html>");
browser.NavigateFinishedNotifier.BlockUntilNavigationFinished();
Assert.AreEqual("some data", payload);
}
I know it's awkward, but you could then use a c#-->javascript call to get data back to javascript-land. See This Question for how to do that. So your javascript would first send this message to c# land, then it would get a callback with the string value you need.
Hope that helps.
You can add message event listener to your web browser and call your method like this:
private void load()
{
browser.AddMessageEventListener("myFunction", ((string s) => this.showMessage(s)));
browser.LoadHtml
(
#"<!DOCTYPE html>
<html><head>
<meta http-equiv=""Content-Type"" content=""text/html; charset=UTF-8"">
<script type=""text/javascript"">
function fireEvent(name, data)
{
event = document.createEvent('MessageEvent');
event.initMessageEvent(name, false, false, data, null, null, null, null);
document.dispatchEvent(event);
}
</script>
</head>
<body>
<input type=""button"" onclick=""fireEvent('myFunction', 'some data');"" value=""SHOW DATA"" />
</body></html>"
);
}
...
private void showMessage(string s)
{
MessageBox.Show(s);
}
Now you can add more msg events to your msg listener (if you need to) and fire them all in the same way.

$find not working in firefox. ASP.NET Slideshow Extender

I have a asp.net ajax slideshow extender that I have hijacked and turned into a jquery like slide show control. It works wonderfully in every browser except for firefox. I have isolated the problem down to the $find call not working. Also I had to put in a setTimeout into the page to get pageLoad to call in firefox. This is also not necessary in chrome or IE.
Here is the code.
setTimeout ( pageLoad(), 250 );
function pageLoad(){
var slider1;
slider1 = $find('<%= slExtender.BehaviorID %>');
slider1.add_slideChanging(onSlideChanging);
}
function onSlideChanging(sender, args)
{
currentSlideIndex = args.get_slideIndex();
//Do what you want using this index
var arr = <%= serializer.Serialize(linkArray) %>;
for(var i = 0; i < arr.length; i++)
{
if(i == currentSlideIndex)
{
var link = document.getElementById(arr[i]);
link.className += "hovered";
}
else
{
var link = document.getElementById(arr[i]);
link.className = "";
}
}
}
function SlideClicked(slID) {
var ss = $find(slID);
var arr = <%= serializer.Serialize(urlArray) %>;
window.location = arr[ss._currentIndex];
}
It seems that the $find is returning null in firefox. Also, does anyway know why I have to put a timeout on the page to get pageload to call?.
Also the $find in SlideClicked does work. slID is the slExtender.BehaviorID
Update
If I add
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
with the following javascript:
$(document).ready(function () {
pageLoad();
});
function pageLoad(){
var slider1;
slider1 = $find('<%= slExtender.BehaviorID %>');
slider1.add_slideChanging(onSlideChanging);
}
function onSlideChanging(sender, args)
{
currentSlideIndex = args.get_slideIndex();
//Do what you want using this index
var arr = <%= serializer.Serialize(linkArray) %>;
for(var i = 0; i < arr.length; i++)
{
if(i == currentSlideIndex)
{
var link = document.getElementById(arr[i]);
link.className += "hovered";
}
else
{
var link = document.getElementById(arr[i]);
link.className = "";
}
}
}
function SlideClicked(slID) {
var ss = $find(slID);
var arr = <%= serializer.Serialize(urlArray) %>;
window.location = arr[ss._currentIndex];
}
To the page, everything works fine in firefox and no longer works in chrome or IE.
I already have 1.4.1 included on the masterpage.
The window object has an event 'onload', but this only works as expected in some browsers. With this, you would attach a callback to this and then execute all of your code that relies on the DOM. This isn't the same across browsers (sometimes onload is fired before the DOM is ready for traversal, which leads to problems), so you have to be clever.
Fortunately you're using a framework that supports it. jQuery has a convenience function ready(). Here's a basic example of how to use it (use this same form everywhere, since most scripts need the DOM):
$(document).ready(function () {
// execute your code here, like adding event listeners, doing find, etc
});
So, with your particular code, do something like this:
$(document).ready(function () {
pageLoad();
});
I would recommend using this model always. Never call code in the global scope, but execute it when the DOM is ready. Even if you don't use the DOM, you probably will eventually, so it makes sense.
$find('<%= slExtender.BehaviorID %>');
In the above line, if "slExtender" is a control then you need to add #.
Make it like : $find('#<%= slExtender.BehaviorID %>');
Try this.
And for pageload problem try
$(function() {
var slider1;
slider1 = $find('#<%= slExtender.BehaviorID %>');
slider1.add_slideChanging(onSlideChanging);
});

Categories

Resources