how to get the loginstatus using fbml and how to maintain the facebook session in my application? - fbml

Hi All below is the code which i use.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>ABI SocialWebConnect</title>
<style type="text/css" media="screen">
body {
font-family : arial, sans-serif;
}
#spacer { width : 10px; }
#friendWrapperCanvas {
border : 2px solid #979797;
width : 85%;
height : 100px;
}
#mapWrapperCanvas {
border : 2px solid #979797;
width : 85%;
height : 380px;
padding-top: 10%;
}
#mapCanvas {
border : 2px solid #979797;
height : 380px;
width : 100%;
}
#resultsCanvas {
position : relative;
top : 15px;
left : 0px;
height : 370px;
width : 280px;
}
#mapSearch {
position: relative;
top : 0px;
left : 0px;
}
.mapcanvastable td {
padding : 0px;
}
.mapcanvastable {
border-width : 0px;
border-spacing : 0px;
border-collapse : collapse;
border : none;
padding-top: 10%;
}
/* canvas view css over-rides */
#mapCanvas .gels {
width : 280px;
background-color: #ddeeff;
}
#mapCanvas .gels-form {
background-color: #ddeeff;
}
#mapWrapperCanvas .gels-controls {
position : absolute;
bottom : -2px;
left : 0px;
}
#mapWrapperCanvas .gels-app,
#mapWrapperCanvas .gels-extresults-active {
border : none;
}
#mapWrapperCanvas .gels-list-item {
margin-bottom : 2px;
}
#mapWrapperCanvas .gels-list-wrapper {
padding-left : 0px;
}
</style>
</head>
<body style="font-family: Arial;border: 0 none;">
<div id="friendWrapperCanvas">
<h3>Connect with Facebook</h3>
<form name="comment_form" method="post">
<div id="user">
<fb:login-button length='long' onlogin="update_user_box();" autologoutlink='true'>Logout</fb:login-button>
</div>
</form>
</div>
<script type="text/javascript">
function update_user_box() {
var user_box = document.getElementById("user");
user_box.innerHTML =
"<span>" +
"<table><tr>" +
"<td>" +
"<fb:profile-pic uid='loggedinuser' facebook-logo='true'></fb:profile-pic>" +
"</td>" +
"<td><fb:login-button length='long' autologoutlink='true'>Logout</fb:login-button></td>"+
"<td >" +
"<fb:name uid='loggedinuser' useyou='false'></fb:name>" +
"<input type=\"button\" onclick=\"submitComment();\" value=\"Post to Your Wall\"> ." +
"</td></tr><tr>" +
"<td colspan='3'>" +
"<fb:comments xid='user_comments' canpost='true' showform='true'>"+
"</fb:comments>"+
"</td>"+
"</tr></table></span>";
FB.XFBML.Host.parseDomTree();
}
function submitComment() {
FB.Connect.streamPublish(null, null, null, null, "Share your Search...", null, false, null);
}
</script>
<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" mce_src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"> </script>
<script type="text/javascript">
var api_key = "389895527688846";
var channel_path = "xd_receiver.htm";
FB.init(api_key, channel_path);
</script>
</body>
<script>
validateUserStatus();
var uid;
var accessToken;
function validateUserStatus(){
alert('called before getting login status');
FB.getLoginStatus(function(response) {
var user = document.getElementById("user");
if (response.status === 'connected') {
alert('called before getting login status : connected');
user.innerHTML =
"<span>" +
"<table> <tr>" +
"<td>" +
"<fb:profile-pic uid='loggedinuser' facebook-logo='true'></fb:profile-pic>" +
"</td>" +
"<td >" +
"<fb:name uid='loggedinuser' useyou='false'></fb:name>" +
" <input type=\"button\" onclick=\"submitComment();\" value=\"Post to Your Wall\"> ." +
"</td></tr><tr>" +
"<td colspan='2'>" +
"<fb:comments xid='user_comments' canpost='true' showform='true'>"+
" </fb:comments>"
+ "</td>"
"</tr></table>" +
+ "</span>";
uid = response.authResponse.userID;
accessToken = response.authResponse.accessToken;
} else if (response.status === 'not_authorized') {
alert('called before getting login status : not-connected');
user.innerHTML =
"<span>" +
"<table> <tr>" +
"<td>" +
"<fb:login-button length='long' onlogin='update_user_box();' autologoutlink='true'>Logout></fb:login-button>" +
"</td></tr></table>"+"</span>";
} else {
// the user isn't logged in to Facebook.
}
FB.XFBML.Host.parseDomTree();
});
}
</script>
</html>
i have two questions here.
FB.loginStatus is not giving me me the status
i get the user profile image with the name when i click on the user's image it goes to facebook but i don't want that go to facebook because i integrated this in my own application. so it should remain in the same window or application.
Please advise me how to go about.

To answer your second question, to prevent the user's image from linking out to Facebook, you can use jQuery to remove the href attribute of the anchor tag that is generated.
$(".fb_profile_pic_rendered .fb_link").removeAttr("href");

Related

ESPAsyncWebServer request->send_P problem

I am doing a simple example using ESPAsyncWebServer on ESP32. In this context I wrote a html file (there are a slider and a button) and tested it on a browser until the content look well. Then I integrate it in the C++ source code for ESP32. It works and look as expected until I don't add a callback to read the value of the slider.
This is the complete source code:
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Replace with your network credentials
const char ssid[] = "Vodafone-A40881218";
const char pswd[] = "rJbFMktHCcqN67Ye";
const int output = 2;
String sliderValue = "0";
// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
const char* PARAM_INPUT = "value";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
#if 0
const char old_index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP Web Server</title>
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 2.3rem;}
p {font-size: 1.9rem;}
body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
.slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C; outline: none; -webkit-transition: .2s; transition: opacity .2s;}
.slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
.slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; }
button { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:20%;color:white;font-size:130%; }
.buttons { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:15%;color:white;font-size:80%; }
.buttonsm { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:9%; color:white;font-size:70%; }
.buttonm { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:15%;color:white;font-size:70%; }
.buttonw { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:40%;color:white;font-size:70%; }
.buttong { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:40%;color:white;font-size:130%; }
</style>
</head>
<body>
<h2>ESP Web Server</h2>
<p><span id="textSliderValue">%SLIDERVALUE%</span></p>
<p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="21" value="%SLIDERVALUE%" step="1" class="slider"></p>
<a href='/setup'><button class='button'>SETUP</button></a>
<script>
function updateSliderPWM(element) {
var sliderValue = document.getElementById("pwmSlider").value;
document.getElementById("textSliderValue").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
#endif
const char index_html[] = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP Web Server</title>
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 2.3rem;}
p {font-size: 1.9rem;}
body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
.slider { width: 360px; }
.slider::-webkit-slider-thumb { width: 50px; height: 50px; }
.slider::-moz-range-thumb { width: 50px; height: 50px; }
button { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:40%;color:white;font-size:130%; }
.buttons { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:15%;color:white;font-size:80%; }
.buttonx { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:9%; color:white;font-size:70%; }
.buttonm { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:15%;color:white;font-size:70%; }
.buttonw { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:40%;color:white;font-size:70%; }
.buttong { border-radius:0.5em;background:#C20000;padding:0.3em 0.3em;width:40%;color:white;font-size:130%; }
</style>
</head>
<body>
<h2>ESP Web Server</h2>
<p><span id="textSliderValue">%SLIDERVALUE%</span></p>
<p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="21" value="%SLIDERVALUE%" step="1" class="slider"></p>
<a href='/setup'><button class='button'>SETUP</button></a>
<script>
function updateSliderPWM(element) {
var sliderValue = document.getElementById("pwmSlider").value;
document.getElementById("textSliderValue").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
// Replaces placeholder with button section in your web page
String processor(const String& var)
{
//Serial.println(var);
if (var == "SLIDERVALUE"){
return sliderValue;
}
return String();
}
#include <Preferences.h>
Preferences Pref;
int32_t g_iVolume = 0;
void setup()
{
// Serial port for debugging purposes
Serial.begin(115200);
Pref.begin("datasetup", false);
g_iVolume = Pref.getInt("volume", 5);
Serial.print("volume="); Serial.println(g_iVolume);
sliderValue = String(g_iVolume);
Pref.end();
// Connect to Wi-Fi
WiFi.begin(ssid, pswd);
Serial.println("Connecting ...");
while (WiFi.status() != WL_CONNECTED)
{ // Wait for the Wi-Fi to connect: scan for Wi-Fi networks, and connect to the strongest of the networks above
delay(250);
Serial.print('.');
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
int ival = sliderValue.toInt();
Serial.print("ival="); Serial.println(ival);
Pref.begin("datasetup", false);
size_t st = Pref.putInt("volume", ival);
Pref.end();
Serial.print("st="); Serial.println(st);
Pref.begin("datasetup", false);
int vol = Pref.getInt("volume", -1);
Serial.print("volume="); Serial.println(vol);
Pref.end();
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
// Start server
server.begin();
}
//------------------------------------------------------------------------
void loop()
{
// put your main code here, to run repeatedly:
}
//------------------------------------------------------------------------
the 1st image is with nullptr instead of processor and the 2nd with processor callback.
I found the problem. The author of ESPAsyncWebServer decided to use the % character as the delimiter for placeholders for the template processor. Unfortunately, the % is quite common in CSS and JavaScript so, writing CSS and JavaScript in HTML file(s) or Strings does not work as expected because the wrong interpretation of % as delimiters of chuncks of text that are not placeholders but CSS or JavaScript code. At the moment there is not a workaround, just do not use % in CSS and JavaScript.
I had the same problem and I fixed it by changing the delimiter character (%) to a ($).
To do this you have to modify the definition of "TEMPLATE_PLACEHOLDER" which is in the file "ESPAsyncWebServer\src\WebResponseImpl.h"
#ifndef TEMPLATE_PLACEHOLDER
#define TEMPLATE_PLACEHOLDER '$' <<<<
#endif

Loading PartialView refreshes entire page using AJAX

At the core, I am trying to generate a table with links that can be clicked on a reload of a PartialView. Everything is working except I cannot get the page to stop refreshing. What I would like to do is only load the PartialView inside of the researchDiv. I do have <add key="UnobtrusiveJavaScriptEnabled" value="true" /> in the web.config.
I've changed the view and partialview to now use ajax, but the same issue is occurring and I'm not entirely sure of what to do. If I click a link the entire page refreshes instead of just the htmlContainer.
In my _LayoutDashboard I do have the unobtrusive jscripts, and when the page renders there are 0 Console errors.
<script src="~/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript">
This is the view
#model Stocks.BLL.ExecutingTrades.Model.WatchList.ExeTradesWatchList
#{
ViewBag.Title = "WatchList";
Layout = "~/Views/Shared/_LayoutDashboard.cshtml";
}
<style>
#customers {
font-family: Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 20%;
border: 1px solid black;
}
#customers td, #customers th {
border: 1px solid #ddd;
padding: 8px;
}
#customers tr:nth-child(even) {
background-color: #f2f2f2;
}
#customers tr:hover {
background-color: #ddd;
}
#customers th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #04AA6D;
color: white;
}
.float-container {
border: 3px solid #fff;
padding: 20px;
}
.float-childsmall {
float: left;
}
.float-child {
width: 80%;
float: left;
height: 1000px;
}
</style>
<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script>
<p>Last Update: #Html.Label(DateTime.UtcNow.ToString()) - Time in UTC</p>
<div class="float-container">
<div class="float-childsmall">
#foreach (var watchList in Model.ViewExecutingTradesUserWatchListFollowShort)
{
<table id="customers">
<caption class="text-center"><h2>#watchList.WatchListName</h2></caption>
<caption class="text-center"><p style="font:10px;">#watchList.WatchListDescription</p></caption>
<tr>
<th>Ticker</th>
</tr>
#foreach (var ticker in Model.ViewUserWatchListTickerModel.Where(y => y.UserWatchListId == watchList.UserWatchListId).ToList())
{
<tr>
<td><a target="_blank" href="https://finviz.com/quote.ashx?t=#ticker.Ticker">#ticker.Ticker </a></td>
<!--<td>
#{
<button type="button" class="btn" id='wlButton_#watchList.WatchListName+#watchList.UserWatchListId+#ticker.Ticker'>
#Html.DisplayFor(modelItem => #ticker.Ticker)
</button>
}
</td>-->
<div class="btnB" id='div_#watchList.WatchListName+#watchList.UserWatchListId+#ticker.Ticker'>
<p class="category-title">#ticker.Ticker</p>
</div>
</tr>
}
</table>
}
</div>
<div class="float-child" id="researchDiv">
<div id="htmlContainer">
#Html.Partial("_Research", new ExecutingTrades.Models.TickerInMem() { Ticker = "META" });
</div>
</div>
</div>
<script>
$(document).ready(function () {
$(".btnB").click(function () {
$.ajax({
url: '#Url.Action("_Research", "Dashboard")',
type: "GET",
data: { ticker: this.id.substring(this.id.lastIndexOf('+')) },
cache: false,
async: true,
success: function (data) {
$("#htmlContainer").html(data);
}
});
});
})
</script>
_Research which is the partialview
#model ExecutingTrades.Models.TickerInMem
<!-- TradingView Widget BEGIN -->
<style>
.tradingview-widget-container {
border: 3px solid #fff;
padding: 20px;
height: 650px;
}
</style>
<div class="tradingview-widget-container">
<div class="tradingview-widget-copyright"><span class="blue-text">#Model.Ticker</span> by TradingView</div>
<script type="text/javascript">
alert(#Model.Ticker);
</script>
<script type="text/javascript">
new TradingView.widget(
{
"autosize": true,
"symbol": "NASDAQ:#Model.Ticker",
"interval": "D",
"timezone": "Etc/UTC",
"theme": "light",
"style": "1",
"locale": "en",
"toolbar_bg": "#f1f3f6",
"enable_publishing": false,
"allow_symbol_change": true,
"container_id": "tradingview_37810"
}
);
</script>
</div>
And the Controller
public ActionResult _Research(string ticker)
{
if (string.IsNullOrWhiteSpace(ticker))
return View();
var model = new TickerInMem();
model.Ticker = ticker.Split('+').Last();
model.Exchange = "NASDAQ";
return PartialView("_Research", model);
}
When I debug - everything works, i can hit the partial view being called and the model is correct.
When the page loads:
When clicking on a link:
All I really want to do is load the 2nd graph which I click it to where the partial view in rendered on the view.
So my MVC and Ajax are correct, the real issue was inside of the tradingview control, I had removed the div it was referencing in the container.
"container_id": "tradingview_37810"

How to send data to multiple clients at once with ESP8266 on AP mode

So i have an ESP8266 (ESP-01) on AP mode and is working fairly good enough. I can receive data from the client and have used AJAX to handle the data. When connected to a single client, if i send data from the serial it shows up on the client webpage and is working as expected. But when i connect multiple clients, only the last connected client gets the data and the older ones remain static. Is there a way to send the data to multiple clients at once?
Here's the code.
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
const byte DNS_PORT = 53;
IPAddress apIP(172, 217, 28, 1);
DNSServer dnsServer;
ESP8266WebServer webServer(80);
void handleRoot() {
String html ="<!DOCTYPE html> <html style=\"text-align: center; background-color: #000000; border-style: solid; border-width: 5px; border-color: #FFFFFF;\"> <head> <title>EDNCS</title> <meta name=\"viewport\" content=\"width=device-width, minimumscale=1.0, maximum-scale=1.0, initial-scale=1\" /> </head> <body> <h1 style=\"color: #ff6600;\">Emergency Distributed Network Communication Service</h1> <p style=\"text-align: right; color: #ffff00;\">-Owned and maintained by Wolf Lusana.</p> <div style=\"color: #339966\"> <div> <strong><span style=\"color: #ff0000;\">Name: </span><input type=\"text\" id=\"name\"> <h2 span style=\"color: #ff6600;\">IMPORTANT BROADCASTS</h2> <div id=\"chatRoomDiv\" style=\"border:2px solid #ccc; width:300px; height: 300px; overflow-y: scroll; overscroll-behavior-x:unset; color:#FFFFFF; margin: 0 auto; display: flex; flex-direction: column-reverse;\"> <ul id=\"chatRoomList\" style=\"list-style-type: none; text-align: left;font-size: 14px; padding-left: 3px;\"></ul> </div> <br> <strong><span style=\"color: #ff0000;\">Message: </span> <input type=\"text\" id=\"message\"> <br><br> <button type=\"button\" onclick=\"sendData()\">CHAT</button> <button type=\"button\" >BROADCAST</button> <br> <script> function sendData() { var inputDataCH = document.getElementById(\"message\").value; var nameDataCH = document.getElementById(\"name\").value; var showDataCH = nameDataCH+\": \"+inputDataCH; if(nameDataCH==null||nameDataCH==\" \"||nameDataCH==\"\"||inputDataCH==null||inputDataCH==\" \"||inputDataCH==\"\"){ alert(\"Please enter your name and message. Thank you.\");} else{ var xhttpCH = new XMLHttpRequest(); xhttpCH.open(\"GET\", \"catchData?data=!\"+showDataCH, true); xhttpCH.send(); document.getElementById(\"message\").value = ''} } setInterval(function() { getData(); }, 500); function getData() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { updateChatRoom(this.responseText); } }; xhttp.open(\"GET\", \"throwData\", true); xhttp.send(); } function updateChatRoom(needData){ var ulCH = document.getElementById(\"chatRoomList\"); var liCH = document.createElement(\"li\"); var objDivCH = document.getElementById(\"chatRoomDiv\"); objDivCH.scrollTop = objDivCH.scrollHeight; liCH.appendChild(document.createTextNode(needData)); ulCH.appendChild(liCH); } </script> </html>";
webServer.send(200, "text/html", html);
}
void handleData() {
String dataChat = webServer.arg("data");
if(dataChat[0]=='!'){
dataChat[0] = '%';
Serial.println(dataChat);
}
}
void handleThrow() {
String throwData;
if (Serial.available() > 0) {
throwData = Serial.readString();
}
webServer.send(200, "text/plane", throwData);
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
WiFi.softAP("Emergency Network Service");
dnsServer.start(DNS_PORT, "*", apIP);
webServer.onNotFound([]() {
handleRoot();
});
webServer.on("/",handleRoot);
webServer.on("/catchData", handleData);
webServer.on("/throwData", handleThrow);
webServer.begin();
}
void loop() {
dnsServer.processNextRequest();
webServer.handleClient();
}
And here is the HTML code
<!DOCTYPE html>
<html style="text-align: center; background-color: #000000; border-style: solid; border-width: 5px; border-color: #FFFFFF;">
<head>
<title>EDNCS</title>
<meta name="viewport" content="width=device-width, minimumscale=1.0, maximum-scale=1.0, initial-scale=1" />
</head>
<body>
<h1 style="color: #ff6600;">Emergency Distributed Network Communication Service</h1>
<p style="text-align: right; color: #ffff00;">-Owned and maintained by Wolf Lusana.</p>
<div style="color: #339966">
<p>Please enter your name before sending your message on the network.</p>
<div>
<strong><span style="color: #ff0000;">Name: </span><input type="text" id="name">
<h2 span style="color: #ff6600;">IMPORTANT BROADCASTS</h2>
<div id="chatRoomDiv" style="border:2px solid #ccc; width:300px; height: 300px; overflow-y: scroll; overscroll-behavior-x:unset; color:#FFFFFF; margin: 0 auto; display: flex;
flex-direction: column-reverse;">
<ul id="chatRoomList" style="list-style-type: none; text-align: left;font-size: 14px; padding-left: 3px;"></ul>
</div>
<br>
<strong><span style="color: #ff0000;">Message: </span> <input type="text" id="message">
<br><br>
<button type="button" onclick="sendData()">CHAT</button> <button type="button" >BROADCAST</button>
<br>
<script>
function sendData() {
var inputDataCH = document.getElementById("message").value;
var nameDataCH = document.getElementById("name").value;
var showDataCH = nameDataCH+": "+inputDataCH;
if(nameDataCH==null||nameDataCH==" "||nameDataCH==""||inputDataCH==null||inputDataCH==" "||inputDataCH==""){
alert("Please enter your name and message. Thank you.");}
else{
var xhttpCH = new XMLHttpRequest();
xhttpCH.open("GET", "catchData?data=!"+showDataCH, true);
xhttpCH.send();
document.getElementById("message").value = ''}
}
setInterval(function() {
getData();
}, 500);
function getData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
updateChatRoom(this.responseText);
}
};
xhttp.open("GET", "throwData", true);
xhttp.send();
}
function updateChatRoom(needData){
var ulCH = document.getElementById("chatRoomList");
var liCH = document.createElement("li");
var objDivCH = document.getElementById("chatRoomDiv");
objDivCH.scrollTop = objDivCH.scrollHeight;
liCH.appendChild(document.createTextNode(needData));
ulCH.appendChild(liCH);
}
</script>
</html>
Thanks.

Creating a pdf with multiple pages per sheet

Is there a simple way to create pdfs with multiple pages per sheet using PuppeteerSharp (as per the option available when you print a pdf from Chrome) e.g. 1 / 2 / 4 / 6 / 9 / 16 pages per sheet?
There is a trick that I created where the viewport is set to a certain width and height, and then the container div of the page is set to the "contained" height after trial and error.
pdf generation function
public async Task<byte[]> GeneratePDF(string html)
{
var browser = await GetBrowserAsync();
var page = await browser.NewPageAsync();
// Here, we sit the viewport height to match a div height in html
await page.SetViewportAsync(new ViewPortOptions{Width = 720, Height = 1280 });
await page.SetContentAsync(html);
var data = await page.PdfDataAsync(new PdfOptions
{
PrintBackground = true,
Format = PaperFormat.A4,
DisplayHeaderFooter = false,
MarginOptions = new MarginOptions
{
Top = "60px",
Right = "40px",
Bottom = "60px",
Left = "40px"
}
});
return data;
}
private async Task<IBrowser> GetBrowserAsync()
{
var browserOptions = new BrowserFetcherOptions{ Path = AppContext.BaseDirectory };
using var browserFetcher = new BrowserFetcher(browserOptions);
await browserFetcher.DownloadAsync(BrowserFetcher.DefaultChromiumRevision);
string[] args = {"--no-sandbox"};
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
Args = args
});
return browser;
}
Razor page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Test Page</title>
<style>
:root {
--primary-color: #ffffff;
--accent-color: #f2f2f2;
--secondary-color: #5f7cb3;
--text-color: #000;
}
body {
font-family: Helvetica, sans-serif;
}
h1, h2, h3, h4, h5, h6 {
color: var(--secondary-color);
}
.page-height {
min-height: 870px; /*trial and error*/
height: 870px;
max-height: 870px;
padding: 30px 0;
}
</style>
</head>
<body>
<div class="page-height" style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
<img src="data:image/png;base64,BASE64_HERE" alt="logo.png" style="width: auto; height: 80px; padding: 20px 0;"/>
<h2 style="color: var(--text-color);">Title Here/h2>
<h3>Subtitle Here</h3>
</div>
<div class="page-height">
<p>Content of the first page.</p>
</div>
<div class="page-height">
<p>Content of the second page. Etc...</p>
</div>
</body>
</html>
This should do the trick.

Nivo Slider breaks after I navigate away and back to home page while using Ajax

I'm using a Nivo Slider in a website that uses Ajax to load its content. It saves the user from loading new pages every time they click on a link.
My problem is that when I load the home page initially, the slider works fine; but if I navigate away from that page then back to it, it just has the loading gif on a loop. Can anyone help?
My index.php is this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>I.C.T - St. Patrick's Academy, Lisburn</title>
<script type="text/javascript" src="assets/js/jqmin.js"></script>
<link rel="stylesheet" type="text/css" href="assets/css/style.css" media="all" />
<script type="text/javascript" src="assets/js/js.js"></script>
<link rel="stylesheet" type="text/css" href="assets/css/nivo.css" media="all" />
<script type="text/javascript" src="assets/js/sliderpack.js"></script>
<script type="text/javascript" src="assets/js/slide.js"></script>
</head>
<body>
<div id="wrap">
<div id="head">
<div id="links">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
<li>Learn</li>
</ul>
</div>
<img src="assets/images/logo.png" alt="logo" />
</div>
<div id="screen">
<div id="pad"></div>
<div id="cont_wrap">
<div id="cont">
<h2>Home</h2>
<div class="slider-wrapper">
<div id="slider" class="nivoSlider">
<img src="assets/images/slide1.jpg" alt="1" />
<img src="assets/images/slide2.jpg" alt="2" />
<img src="assets/images/slide3.jpg" alt="3" />
</div>
</div>
</div>
</div>
</div>
<div id="foot">
<p align="center"><i>Copyright 2013 - Finbar Maginn - St. Patrick's Academy, Lisburn</i></p>
</div>
</div>
</body>
</html>
(Note that my Nivo Slider initialization is inside slide.js and looks like this:)
$(window).load(function() {
$('#slider').nivoSlider({
effect: 'random', // Specify sets like: 'fold,fade,sliceDown'
slices: 16, // For slice animations
boxCols: 6, // For box animations
boxRows: 3, // For box animations
animSpeed: 1000, // Slide transition speed
pauseTime: 5000, // How long each slide will show
startSlide: 0, // Set starting Slide (0 index)
directionNav: false, // Next & Prev navigation
controlNav: false, // 1,2,3... navigation
controlNavThumbs: false, // Use thumbnails for Control Nav
pauseOnHover: false, // Stop animation while hovering
manualAdvance: false, // Force manual transitions
prevText: 'Prev', // Prev directionNav text
nextText: 'Next', // Next directionNav text
randomStart: false, // Start on a random slide
beforeChange: function(){}, // Triggers before a slide transition
afterChange: function(){}, // Triggers after a slide transition
slideshowEnd: function(){}, // Triggers after all slides have been shown
lastSlide: function(){}, // Triggers when last slide is shown
afterLoad: function(){} // Triggers when slider has loaded
});
});
The Ajax jQuery file I'm using is this:
$(document).ready(function() {
var hash = window.location.hash.substr(1);
var href = $('#links li a').each(function(){
var href = $(this).attr('href');
if(hash==href.substr(0,href.length-3)){
var toLoad = hash+'.php #cont';
$('#cont').load(toLoad)
}
});
$('#links li a').click(function(){
var toLoad = $(this).attr('href')+' #cont';
$('#cont').fadeOut('fast',loadContent);
$('#load').remove();
$('#wrap').append('<span id="load">LOADING...</span>');
$('#load').fadeIn('fast');
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-4);
function loadContent() {
$('#cont').load(toLoad,'',showNewContent());
}
function showNewContent() {
$('#cont').fadeIn('fast',hideLoader('fast'));
}
function hideLoader() {
$('#load').fadeOut('fast');
}
return false;
});
});
And here is my CSS:
body {
font-size:95%;
font-family:georgia;
line-height:1.576;
}
h2 {
padding:0;
margin:0;
}
#wrap {
margin:0 auto;
width:784px;
}
#head {
width:100%;
height:175px;
}
#links {
width:300px;
height:30px;
padding:140px 0 0 0;
float:right;
text-align:right;
}
#links ul {
margin:0;
padding:0;
}
#links ul li {
display:inline;
margin:0 -2px 0 -2px;
}
#links ul li a {
font-size:1em;
-webkit-transition: 0.1s;
-moz-transition: 0.1s;
-ms-transition: 0.1s;
-o-transition: 0.1s;
text-decoration:none;
color:black;
background:-webkit-linear-gradient(bottom, white, #74b998);
background:-o-linear-gradient(bottom, white, #74b998);
background:-ms-linear-gradient(bottom, white, #74b998);
background:-moz-linear-gradient(bottom, white, #74b998);
padding:3px 5px 3px 5px;
}
#links ul li a:hover {
background:-webkit-linear-gradient(top, white, #74b998);
background:-o-linear-gradient(top, white, #74b998);
background:-ms-linear-gradient(top, white, #74b998);
background:-moz-linear-gradient(top, white, #74b998);
padding:7px 5px 7px 5px;
}
.left {
border-bottom-left-radius:10px;
-webkit-border-bottom-left-radius:10px;
-moz-border-bottom-left-radius:10px;
-ms-border-bottom-left-radius:10px;
-o-border-bottom-left-radius:10px;
border-top-left-radius:10px;
-webkit-border-top-left-radius:10px;
-moz-border-top-left-radius:10px;
-ms-border-top-left-radius:10px;
-o-border-top-left-radius:10px;
}
.right {
border-bottom-right-radius:10px;
-webkit-border-bottom-right-radius:10px;
-moz-border-bottom-right-radius:10px;
-ms-border-bottom-right-radius:10px;
-o-border-bottom-right-radius:10px;
border-top-right-radius:10px;
-webkit-border-top-right-radius:10px;
-moz-border-top-right-radius:10px;
-ms-border-top-right-radius:10px;
-o-border-top-right-radius:10px;
}
.radius {
border-radius:10px;
-webkit-border-radius:10px;
-moz-border-radius:10px;
-ms-border-radius:10px;
-o-border-radius:10px;
}
#screen {
width:100%;
height:480px;
background-image:url(../images/bckgrnd.png);
}
#pad {
width:100%;
height:29px;
}
#cont_wrap {
overflow:auto;
margin:0 auto;
width:724px;
height:335px;
padding: 0 0 0 6px;
}
#load {
display: none;
position: absolute;
top: 150px;
left: 950px;
text-indent: -9999em;
width: 16px;
height: 16px;
background: url(../images/load.gif) no-repeat;
}
#cont {
}
#foot {
width: 100%;
font-size:90%;
color:gray;
}
#slider {
margin: 0 auto;
width: 700px;
height: 273px;
}
.nivoSlider {
position: relative;
background: url(../images/load.gif) no-repeat 50% 50%;
}
.nivoSlider img {
position: absolute;
top: 0px;
left: 0px;
display: none;
}
.nivoSlider a {
border: 0;
display: block;
}

Resources