$find not working in firefox. ASP.NET Slideshow Extender - c#

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);
});

Related

Cefsharp winforms: Inject jquery into page

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);

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!

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.

I have two javascript block in the page , one is adding dynamicllay which is , providing all images. should add above existing javascript on page

i am using following code to add javascript dynamically
HtmlGenericControl scriptTagLinks = new HtmlGenericControl("script");
scriptTagLinks.Attributes["type"] = "text/javascript";
var scrip = "var aImgs=[" + appendString.ToString().TrimEnd(new char[] { ',' }) + "]";
scriptTagLinks.InnerHtml = scrip;
Javascript is adding to ascx page . But my problem I have two javascript block in the page , one is adding dynamicllay which is , providing all images. another one javascript as follows .
<script type="text/javascript>
window.onload = function () {
for (var i = 0; i < aImgs.length; i++) {
var oImg = new Image();
oImg.src = aImgs[i];
aImages.push(oImg);
oImg.onload = function () {
textureWidth = oImg.width;
textureHeight = oImg.height;
}
}}
</script>
but dynamically created javascript is being added below the script . But should add above the script like this .
<script type="text/javascript">
var aImgs = [
'DesktopModules/DNAiusCubeImages/Check/pic1.jpg',
'DesktopModules/DNAiusCubeImages/Check/pic2.jpg',];
</script>
<script type="text/javascript>
window.onload = function () {
for (var i = 0; i < aImgs.length; i++) {
var oImg = new Image();
oImg.src = aImgs[i];
aImages.push(oImg);
oImg.onload = function () {
textureWidth = oImg.width;
textureHeight = oImg.height;
}
}}
</script>How can i achieve this .
Can you try doing this.
// Form the script that is to be registered at client side.
String scriptString = "<script language=JavaScript> function DoClick() {";
scriptString += "myForm.show.value='Welcome to Microsoft .NET'}<";
scriptString += "/";
scriptString += "script>";
if(!this.IsClientScriptBlockRegistered("clientScript"))
this.RegisterClientScriptBlock("clientScript", scriptString);
Example in MSDN
http://msdn.microsoft.com/en-us/library/system.web.ui.page.registerclientscriptblock%28v=vs.71%29
The client-side script is emitted just after the opening tag of the Page object's element. The script block is emitted as the object that renders the output is defined, so you must include both tags of the element.
By identifying the script with a key, multiple server control instances can request the script block without it being emitted to the output stream twice.
Take a look at ScriptManager.RegisterStartupScript.
You can add a script without an event onLoad. Just a function that recieves your array of image paths.
And then using Page.ClientScript.RegisterStartupScript(...); from OnLoad event on server-side code, you can call your Javascript function and pass the parameters (Array) you need.

SignalR site is not staying in sync when page is open in more than one tab

I'm working through a SignalR demo that displays database info in a list when a button is hit.
My Hub has 2 functions: One to remove DB objects from a list, and one to re-add DB objects to that list.
These functions are performed in my View and perform great when I only have the page open once. But if I open the page in another tab (can be the same browser or a different one), the pages do not stay in sync.
Meaning, when one page's button is hit, the other page is not displaying the data correctly.
Often times one page will do fine, while the other will perform the remove but not the add! It's mind-boggling. They should just be reflections of each other from my understanding.
Has anyone else run into something similar?
Thanks in advance for any help!
Here's my Hub :
[HubName("hubtest")]
public class HubTest : Hub
{
CmsContext db = new CmsContext();
public void showdata()
{
var f = from x in db.Data
select x;
Clients.remove();
Clients.add(f);
}
}
And here's the javascript in my View for the functions:
<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR-0.5.2.min.js" type="text/javascript"></script>
<script src="/signalr/hubs" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
var hubtest = $.connection.hubtest;
hubtest.remove = function () {
//clear list of any prior values
var list = document.getElementById('dataList');
while (list.hasChildNodes()) {
list.removeChild(list.childNodes[0])
}
};
hubtest.add = function (data) {
//populate with updated values
for (var i = 0; i < data.length; i++) {
var element = data[i];
$('#dataList').append('<li>' + element.Question + '</li>');
}
};
$("#broadcast").click(function () {
hubtest.showdata();
});
// Start the connection
$.connection.hub.start();
});
</script>
<input type="button" id="broadcast" value="broadcast" />
<ul id="dataList">
</ul>
Try this instead:
<script type="text/javascript">
$(function () {
var hubtest = $.connection.hubtest;
hubtest.add = function (data) {
//clear the values first.
var list = $('#dataList');
list.empty();
//populate with new values
for (var i = 0; i < data.length; i++) {
var element = data[i];
list.append('<li>' + element.Question + '</li>');
}
};
$("#broadcast").click(function () {
hubtest.showdata();
});
// Start the connection
$.connection.hub.start();
});
</script>
And this:
[HubName("hubtest")]
public class HubTest : Hub
{
TestDatabaseEntities db = new TestDatabaseEntities();
public void showdata()
{
var f = from x in db.FAQs
select x;
Clients.add(f);
}
}
First of all thanks for your replies. I really appreciate your feedback!
I eventually got it to where my pages are staying in sync when open in multiple tabs by altering how my data is sent to the View.
Where I was performing the for loop in my Javascript to display each piece of data, now I am doing that in my Hub like so:
[HubName("hubtest")]
public class HubTest : Hub
{
CmsContext db = new CmsContext();
public void showdata()
{
Clients.clearlist();
var faqs = from x in db.Faqs
select x;
foreach (Faq faq in faqs)
{
Clients.add(faq.Question.ToString());
}
}
}
Then my Javascript is just appending that FAQ question to the list:
$(function () {
var hubtest = $.connection.hubtest;
hubtest.clearlist = function () {
var list = $('#datalist');
list.empty();
};
hubtest.add = function (data) {
$('#datalist').append('<li>' + data + '</li>');
};
$("#broadcast").click(function () {
hubtest.showdata();
});
// Start the connection
$.connection.hub.start();
});
Sending just a simple string of my data to be printed individually seems to allow my page to stay in sync.
Before the data I was sending was a list of DB objects and my Javascript was looping through each and adding that object's Question column to the list. Not sure why this was such an issue - especially since it would work on one open tab but not all open tabs - but that simple change fixed my site sync issues.
Thanks again!

Categories

Resources