I want to create an application for WP8 that shows the content of a web page. I'm not writing the code yet, but but i know that i can take the page content using xpath. My problem is that the content i want to take is not in a single page. I have to press the "Next" button to go to the next page. The code for the button is this.
<td class="pager-next" style="padding:0;margin:0;">
<a id="ctl00_ContentPlaceHolder1_LinkButton2" class="buttondiego buttondiego_small buttondiego_arrow" href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$LinkButton2','')"></a>
</td>
And this is the JS function in the header:
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
Is it possible to go to the next page with my code? How should i do?
You will either have to:
Deeply analyze their JavaScript, and do some reverse engineering on the required POST values to fetch a specific page. You can see what requests are sent using Firebug or Chrome Developer Tools network view. The URL definitely is
<http://www.starcomics.com/UsciteMensili.aspx?AspxAutoDetectCookieSupport=1
but simply POSTing the monitored "interesting looking" fields
__ASYNCPOST:true
__EVENTTARGET=ctl00$ContentPlaceHolder1$DataPager2$ctl00$lnkNextPage
was not sufficient.
Alternatively, you could use some headless browser implementation which actually executes the JavaScript. They will be more complicated to setup and be less performant, but you won't have to care about the logic behind loading the pages any more. I think the most common used headless browser is PhantomJS, but I don't know whether and how to employ it with Windows Phone and C#, you might want to set it up on your own server and proxy the data.
Related
I've created a socket listener, and I need to display a div (keep it hidden, then make it visible), when the server detects a certain socket data.
I've tried to use a thread, but it doesn't update the UI in realtime, only if the page is reloaded or if you do a post back.
Here is an example of what I want to do, in this case I only want to update a textbox with codebehind data, I would like to do it without ajax, javascript or jQuery, if possible.
Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
Thread t = new Thread(TestThread);
t.Start();
}
private void TestThread()
{
for (int i = 0; i <= 1000000000; i++)
{
myTextbox.Text += "1";
}
}
Webpage:
<asp:UpdatePanel runat="server" ID="myPanel" >
<ContentTemplate>
<asp:TextBox runat="server" ID="myTextbox" />
</ContentTemplate>
</asp:UpdatePanel>
what you are trying to do is change the UI (modify client components) from server code (code behind) in asp.net when the server already sent the data to the client.
you have to use client side scripting/coding.
As far as I know, this is not possible without using ajax or JavaScript.
ASP.NET is only responsible for generating the html that is sent from your web-server to the client. Once that html is rendered in the browser, the only way to update the html is via JavaScript.
You can do a Partial Render in WebForms using their AJAX handler without having to write jQuery by enabling a partialRenderingEnabled attribute in the ScriptManager tag. There's no way to do this without scripting or AJAX, the content has to get back to the server to run your code-behind somehow, but at least this way you don't have to write any JavaScript yourself.
For real-time web functionality check out :
SignalR
In a web enviornment, there is no way for the server side to reach out for the client except in the request-response scenario, where the client has to send a request to the server side, the server side handles the request and replies with a response.
EDIT :
SignalR uses the best available technique, websockets when available, if not, AJAX long polling technique in which the client polls(sends a request) to the server, and the server replies only when a certain change to the observed data happens, else SignalR tries repetitve AJAX requests, polling the server over and over until the server replies with the change on the observed data (Worst scenario !).
Also, HTML 5 contains web-sockets, i don't have enough information about it, but it maybe interesting to check out.
With minimal JavaScript you could utilise Server Sent Events for simplex data (from server to client) It doesn't have the overhead of Websockets which has a bit of cost in terms of establishing a connection. However I don't think all browsers are supported but there might be polyfill available for it (library to provide functionality in absence of native support)
Checkout:
http://www.html5rocks.com/en/tutorials/eventsource/basics/
In ASP.NET Threads gets aborted as soon as the page unloads, so this is not possibler you way, sorry.
Your approach could be using AJAX to poll the status from the server on regular intervals. Server on the other hand, will reply according to change in data.
in your ASP.NET Page, add the following script
<head>
<script type="text/javascript" language="javascript">
function poll()
{
var ajax;
if(window.XMLHttpRequest)
ajax = new XMLHttpRequest();
else
ajax = new ActiveXObject("Microsoft.XMLHTTP");
url = "yourPageOrHandler.aspx";
ajax.onreadystatechange = function()
{
if (ajax.readyState == 4 && ajax.status == 200)
{
// success
var receivedText = ajax.responseText;
}
else
{
// error, do the needful
}
}
ajax.open("GET", url, true);
ajax.send();
setTimeout("poll()", 1000); //polls every 1 second, you can change the duration here.
}
</script>
</head>
Start the polling before page finishes
<body>
.
.
.
.
<script type="text/javascript" language="javascript">
poll();
</script>
</body>
Alternatively, you can use the ASP.NET AJAX controls, but that will be heavier compared to JavaScript AJAX.
Glad to help! Please remember to accept the answer if you found it helpful.
I'm building a web application on ASP.NET with C#.
On a button click I show a loading image, while the database query is being executed. Then I dynamically create an Excel file and send it to the client like this:
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".xlsx");
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Unicode;
HttpContext.Current.Response.BinaryWrite(p.GetAsByteArray());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
I get the dialog box, and the loading image stays there.
I've tried placing call to a javascript function (with ClientScript.RegisterStartupScript function) before the code above, it didn't work. As I understand all javascript code is run after all the code-behind has executed, but in this case it doesn't execute at all once the file is sent to the client.
I've also tried creating a separate thread, and removing the loading image there. I put the breakpoint to trace it, code in the thread does execute, but the image still stays there.
Does anyone have an idea how this can be handled? Thank you!
You can only send or transmit 1 mime type in one request/response cycle. (My knowledge in this area is debatable).
That said, you can design a hack around this. Use an iframe on the client to "download the file". You can point its src to an ashx file that does the same.
You need to wire the iframe's onload event, so your web page has someway of knowing that download is done; thats where you can execute your logic.
Solution Update:
Well, after digging around, I've discovered my answer is half-baked!
The issue is that iframes don't trigger their onload event after they download something. The onload event will trigger iff there the url pointed to by src actually navigates to a different page. This is by design I suppose. And I learn that today!
So what then is the work-around?!
Fortunately, you can transmit cookies to the client. On the client your web page has to keep polling for the presence of this cookie. So once your web page is able to detect the presence of the cookie, it means that the browser has completed with the download request. This has been discussed in great detail in the following post:
http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx
I'll just show you some code relating to the handler file (which simulates a download), and the client (which has an iframe doing the job). This should pretty much give you the gist:
Webform1.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.FileDownload.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>iFrame Download</title>
<script type="text/javascript" src="Scripts/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="Scripts/jquery.cookie.js"></script>
<script type="text/javascript">
function foo() {
console.log('foo');
//execute post-download logic here
}
$(function () {
$('input').click(function () {
//make sure we get rid of the
//cookie before download
$.removeCookie('downloaded');
var intrvl = setTimeout(function () { //this function polls for the cookie through which we track that the file has indeed been downloaded
console.log('timer');
var value = $.cookie('downloaded');
if (value == 'true') {
clearTimeout(intrvl);
foo();
}
}, 1000);
//this initiates the download
$('iframe').attr({
'src': 'download.ashx?id=' + $('#tbxRandomNumber').val()
});
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="tbxRandomNumber" runat="server"></asp:TextBox>
<input type="button" value="Download" />
<iframe src="about:blank" style="display:none"></iframe>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Next Random Number" />
</div>
</form>
</body>
</html>
I've made used of jquery cookies plugin to help me with handling cookies.
download.ashx:
using System;
using System.Web;
namespace WebApp.FileDownload
{
/// <summary>
/// Summary description for download
/// </summary>
public class download : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.SetCookie(new HttpCookie("downloaded","true")); //setting cookie in the response
string id = context.Request.QueryString["id"] == null ? "NULL" : context.Request.QueryString["id"];
string str = string.Format("Content with id {0} was generated at {1}", id, DateTime.Now.ToLongTimeString());
context.Response.AddHeader("Content-Disposition", "attachment; filename=test.txt");
context.Response.AddHeader("Content-Length", str.Length.ToString());
context.Response.Write(str);
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
It looks like you have a couple of misunderstandings here. You only have one request, and one response from the server. Making new threads is something that only happens on the server, and won't create additional responses.
When you're sending the Excel file, you're using:
HttpContext.Current.Response.Clear();
By clearing the response, you're losing the JavaScript that you added previously. It will never get to the client.
If the processing is fairly trivial (always just a couple of seconds), I'd just set the loading animation to run for a couple of seconds and stop, by setting a timeout on the initial onclick event. It's not perfect, but it'll give the user some immediate feedback.
If the processing is going to take a long or very variable amount of time, then the animation is more important to get right. You can try loading your Excel file in a hidden <iframe>, and attaching an onload event to remove the loading animation.
You would need to create a separate page to handle generating the Excel file, rather than doing it in a server-side OnClick handler. However, I seem to remember that support for onload events on <iframe> can be spotty with older IE versions.
javascript run in the client when page is loading in the browser. You may have a hidden textbox, at the end of you event yo can put a value into that textbox:
txtHidden.Text = "Hola Mundo"
You have to check the value on page load:
<script type="text/javascript">
$(document).ready(function(){
if($("#txtHidden").length > 0 && $("#txtHidden").val() != '')
{
alert($("#txtHidden").val());
}
});
</script>
You can put this in a web user control.
Another solution:
<div class='button' id='btnGenerateDownload' onClick='GenerateDownload(this)'>
Click here <div id='loadingImage' class='loadingImage'></div>
</div>
JQuery:
function GenerateDownload(caller)
{
//add loading gif:
var $loagingGIF = $(caller).children('#loadingImage').eq(0);
$loagingGIF.addClass('loadingImage');
var fileGeneratorUrl = 'ghFileGenerator.ashx';
var downloadHandlerUrl = 'ghDownloadHandler.ashx';
$.post({data: "File1"}, function(response){
//remove gif
$loagingGIF.removeClass('loadingImage');
if(response != '') //file key
{
downloadHandlerUrl += '?key=' + response;
var $link = $("<a />").attr('href', downloadHandlerUrl).html('download');
$link.appendTo($(caller));
}
});
}
css:
.loadingImage{background: transparent url(images/loading.gif);}
.ashx:
string filekey = context.Current.Request.Form("key");
Functionality I need to achieve is:
Confirmbutton_Click
Show a popup/dialogbox:
On click of Yes, I need to validate Email-Id and other personal details submitted.
If validation fails, show error messages and return false.
If email-id and other details are correct, then hide/show few Divs.
I had achieved this functionality in jQuery but now I am supposed to do it in server side. Firstly because the Divs were not showing up each time correctly and secondly due to security concern.
The suggestions I got on googling ask to write complete code (in script tag) at server side. That would be too much as I need to validate many fields.
Also, is there a way I can just do the validations at client side and come back to server side and show my Divs depending upon the validation result ? The client script will be executed before server side, so it is achievable.
I don't want to create a new popup page for this.
If anyone could help me with correct code or pointers to one, how to validate and show divs(showing div to be done from server side).
UPDATED:
I am midway, if anyone could help me any:
In page load(not post back) I hv added:
btnConfirm.Attributes.Add("onclick", "if(confirm('Confirm - Are you sure you want to go ahead.')) onConfirm(); else return false;");
In jQuery code i have added validations as:
function onConfirm() {
//Check if email-id is not blank, else show message and return to the page
if (isBlank($('#emailAddress').val()) == false) {
$('#errorBlankEmail').show();
return false;
}
}
//Text validation functions
function isBlank(valueSent) {
if ($.trim(valueSent) == "")
return false;
else
return true;
}
and the button code as:
<asp:Button ID="btnConfirm" runat="server" Text="Confirm" onclick="Confirm_Click" />
And the server side code for this:
protected void Confirm_Click(object sender, EventArgs e)
{
divConfirm.Visible = true;
}
Now when I click on button, it works until I validate and validation fails, it executes the server side code. Is there a way where I can avoid the server-side code if result is false in client click code ?
You may want to try using http://www.telerik.com/ ASP.net AJAX controls, or Ajax Control Toolkit Modal Extender. Ive used both and they are exactly what your after.
I woudn't suggest to do it this way , but maybe this will point you to better solution.
From server side as you mentioned you can use static function
var script = #"<script> $("#somediv").dialog() </script>", false);
ClientScript.RegisterClientScriptBlock(GetType(), "some", , false);
(#somediv) is encaplulated with user control and contains all validation logic.
The problem is server validation of your div , since after postback on div ( on server side validation) your div will be closed , and again you need to pup it up from server ,
This approach will mess up things ... I'd use new popup window that will return result.
you won't get a confirmation on the server. the server has not concept of user interaction within the request/response. it can only receive the request, process it, and send a response.
what you can do is send a request to generate a response which will ask for the user to confirm. the user would then click "yes" which will create another request. the server will receive the request, process the request and send a response.
but what you cannot do is ask the user to confirm the request while processing it on the server. that confirmation must have already been done.
you can validate the request the request on the server, but that is just standard validation. nothing fancy to do there.
you can use jQuery ui Dialog - Modal Confirmation
and on confirm use __doPostback to fire the event 'Confirmbutton_Click'
It is just another way, but it won't be as easy as telerik controls..
<script>
$(function() {
$( "#dialog-confirm" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"Confirm": function() {
$( this ).dialog( "close" );
__doPostBack('#<%= Confirmbutton.UniqueID %>', null)
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
});
</script>
And as html,
<div id="dialog-confirm" title="Empty the recycle bin?">
<p><span class="ui-icon ui-icon-alert" style="float: left; margin: 0 7px 20px 0;"></span>These items will be permanently deleted and cannot be recovered. Are you sure?</p>
</div>
<asp:button id="Confirmbutton" runat="Server" OnClick="Confirmbutton_Click" style="display:none;" />
I've been trying to add the plus one button on our company's product page. We have a multi - subdomain website which has language translated content for that particular subdomain. The user's language preference is remembered via cookies.
Now when when I hit the +1 button, and try to share the page on google+ I do not see the translated description come up on it. It somehow grabs the "English" description. When I try to look at my "MetaDescription" tag it is in the foreign language.
What I've been guessing is that google was trying to call the URL I was trying to share and crawling it instead of crawling the very page I was clicking the +1 button on. What would be the best way to make google detect the language setting on the page i want to share?
To get the API to load in the different languages, you should specify the lang in the config. Do this BEFORE the plusone.js can load. That should make the button and it's screens display with that language.
Here's an example:
<html>
<head>
<title>+1 Demo: Async render</title>
<link rel="canonical" href="http://www.example.com" />
</head>
<body>
<g:plusone></g:plusone>
<script type="text/javascript">
window.___gcfg = {
lang: 'zh-CN'
};
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</body>
</html>
However, for the share part of it, can you be sure that when Google scrapes the page you're sharing that it is picking up the correct language? Since the user agent Google is using might not specify a language, your page is being rendered to Google's scrapers as the default language. Maybe you should have a canonical URL for each language for your page that google can scrape correctly.
I want to use a javascript function inside a c# function
protected void button1_Click(object sender,EventArgs e){
//javascript function call ex.
/*
boolean b=the return of:
<script type="text/javascript">
function update() {
var result = confirm("Do you want to delimit the record?")
if (result) {return true;}
else {
return false;
}
}
</script>
*/
}
how can i do such a thing? i want when user press yes return true and i know he pressed yes...can i do so?
If you're trying to add JavaScript to your page from asp.net, you can use the ClientScript class.
string script = "function update() { var result = confirm(\"Do you want to delimit the record?\") if (result) {return true; } else { return false; } }";
ClientScript.RegisterClientScriptBlock(this.GetType(), "someKey", script, false);
If you're trying to call (client side) JavaScript functions from your asp.net code behind, then absolutely not. When the page posts and your C# is run, any JavaScript that was on the page no longer exists.
You're mixing two different technologies. C# runs on the server. It renders an HTML page (which may include Javascript). This page is then sent to a client's browser, where Javascript finally gets executed.
In Javascript you can prompt user about record deletion or whatever, and then you have to either navigate to another page or use AJAX to send result to the server.
I suggest that you get a good ASP.NET book. It will clear many uncertainties for you.
If you're putting this message on an <asp:Button> with postback just add the confirm dialog to the OnClientClick attribute like so:
<asp:Button ID="Button1" runat="server"
OnClientClick="return confirm('Do you want to delimit the record?');" />
If you're simply trying to create the functionality of letting the server know that a button was clicked, you're over complicating things. If you really need to dynamically insert Javascript then what Adam mentioned is worth looking into. But I highly doubt that this is the correct approach for what you're trying to do.
You should really only dynamically insert Javascript when you're worried about performance AND you have a lot of content to send.
If dynamically inserting Javascript (ie. lazy loading) is not your main concern, then here is a very simple example of what most folks would usually do to achieve the functionality you're aiming for.