I am trying to use SignalR for ASP.NET Core 2.0, but when I try to implement the SignalR client in my View, I get the error that the variable "signalR" is undefined despite auto-completion working fine in my editor, Here is the script :
<script type="text/javascript">
var _transport = signalR.TransportType.WebSockets; //HERE
var connection = new signalR.HubConnection(`http://${document.location.host}/chat`, {transport: _transport});
var messageInput = document.getElementById('message');
var name = '#User.Identity.Name';
var button = document.getElementById('sendMessage');
connection.on('broadcastMessage', (name, message) => {
var text = document.createElement('p');
text.innerHTML = '<strong>' + name + '</strong>' + " : " + message;
document.getElementById('messageArea').appendChild(text);
});
button.addEventListener("click", event => {
connection.invoke('send', name, messageInput.value);
messageInput.value = '';
messageInput.focus();
});
connection.start();
I have added the signalr.js in my _Layout.cshtml
Here is the tree structure of my wwwroot where I've added the .js files for signalr :
And finally, here is the debugger structure in Firefox where I can see that the signalr.js has been loaded, and so are jQuery and bootstrap..
So why is "signalR" undefined? What am I missing? Is it because I've added the signalr javascript files manually in my project? (Probably...)
I think your script is executed before the signalr.js is loaded. Try to use an event to execute your code. IF we do this on document load then we'll be sure that it's defined.
$(document).load(function(){
// your code here
});
Related
I'm trying to create a file in the File Cabinet and write to it in a Client Script. Checking the API reference, I see that all the File objects are Server-side only.
Does that mean you can't create and write to a file in a Client script? I tried to use the code in my Client script anyway, but got the error:
Fail to evaluate script: {"type":"error.SuiteScriptModuleLoaderError","name":"{stack=[Ljava.lang.Object;#59c89ae9, toJSON=org.mozilla.javascript.InterpretedFunction#5a4dd71f, name=MODULE_DOES_NOT_EXIST, toString=org.mozilla.javascript.InterpretedFunction#1818dc3c, id=, message=Module does not exist: N/file.js, TYPE=error.SuiteScriptModuleLoaderError}","message":"","stack":[]}
When I tried to save it in NetSuite as the script file. Does the above mean that the N/File object can't be loaded in a Client script?
Can I write to a file in a Client script?
Create a Client Script - this Script will contain the function to call the Suitelet and pass along information from the current record/session if needed.
function pageInit{
//required but can be empty
}
function CallforSuitelet(){
var record = currentRecord.get();
var recId = record.id;
var recType = record.type
var suiteletURL = url.resolveScript({
scriptId:'customscriptcase3783737_suitelet',// script ID of your Suitelet
deploymentId: 'customdeploycase3783737_suitelet_dep',//deployment ID of your Suitelet
params: {
'recId':recId,
'recType':recType
}
});
document.location=suiteletURL;
}
return {
CallforSuitelet : CallforSuitelet,
pageInit : pageInit
}
Create a Suitelet - this script will create the file
function onRequest(context) {
var requestparam = context.request.parameters;
var recId = requestparam.recId; //the same name of the fields specified in url.resolveScript parameters from Client Script
var recType = requestparam.recType;
var objRecord = record.load({
type: record.Type.___,//insert record type
id: recId
});
var content = 'Insert Content Here';
var xml = "<?xml version=\"1.0\"?>\n<!DOCTYPE pdf PUBLIC \"-//big.faceless.org//report\" \"report-1.1.dtd\">\n";
xml += "<pdf>\n<body font-size=\"12\">\n<h3>Sample PDF</h3>\n";
xml += "<p></p>";
xml += content;
xml += "</body>\n</pdf>";
context.response.renderPdf({xmlString: xml});
}
return {
onRequest: onRequest
}
As you've already discovered, server-only modules can't be called from client-side scripts directly, but this can be done via a Suitelet. You will need to decide how the Suitelet does it's work. An example of the principal at work can be found here and here
I have this line in my Razor :
#Html.Raw(File.ReadAllText(Server.MapPath("~/Views/Home/index.html")))
And in HTML file, I have this :
<li>Personal Records</li>
And in my js file I have this :
if ($(link).text() === 'Personal Records') {
$("#govde").load("PersonalRecords.html");
}
But when I click on that link, nothing happens. When I open Index.html directly from file browser, it works. How can I fix this?
EDIT :
In console, it has this :
http://localhost:12345/PersonalRecords.html 404 (Not Found)
I guess I have placed the html files to a wrong folder. Can you tell me where to place? Thanks.
EDIT2 :
I have this in my JS :
var upperMenu = document.getElementById('upperMenu');
var requests = document.getElementById('requests');
$(upperMenu ).click(function (event) {
ustMenu.childNodes.forEach((myList) => {
$(myList).attr('class', ' ');
});
var link = event.target;
var list = link.parentNode;
$(myList).attr('class', 'active');
if ($(link).text() === 'Personal Records') {
$("#govde").load('#Url.Content("~/PersonalRecords.html")');
}
});
.load function is created in this(seperate) JS file.
The problem started with file name mentioned in $("#govde").load method:
$("#govde").load("PersonalRecords.html");
This statement tries to load "PersonalRecords.html" which assumed exists in the project's root directory, but it returns 404 since the target file exist in different directory.
Hence, it should be mentions full absolute path URL to load HTML content first:
var url = '#Url.Content("~/Views/Home/PersonalRecords.html")';
Then, since load method placed inside separate JS file, putting them together should results like this:
Razor
<script src="#Url.Content("~/[path_to_your_JS_file]")" type="text/javascript"></script>
<script>
var url = '#Url.Content("~/Views/Home/PersonalRecords.html")';
loadRequest(url);
</script>
JavaScript file
function loadRequest(url) {
var upperMenu = $("#upperMenu").get(0);
var requests = $("#requests").get(0);
$(upperMenu).click(function (event) {
ustMenu.childNodes.forEach((myList) => {
$(myList).attr('class', ' ');
});
var link = event.target;
var list = link.parentNode;
$(myList).attr('class', 'active');
if ($(link).text() === 'Personal Records') {
$("#govde").load(url);
}
}
}
Next, as of first mentioned part:
#Html.Raw(File.ReadAllText(Server.MapPath("~/Views/Home/index.html")))
I considered this is not a good practice to read all file contents in view side, hence I prefer return the file contents from controller side using FilePathResult like #Guruprasad Rao said:
// taken from /a/20871997 (Selman Genç)
[ChildActionOnly]
public ActionResult GetHtmlFile(String path)
{
// other stuff
// consider using Server.MapPath(path) if in doubt determining file path
return new FilePathResult(path, "text/html");
}
Usage as link in view:
<li>#Html.ActionLink("HTML File", "GetHtmlFile", "Controller", new { path = "~/Views/Home/PersonalRecords.html" }, null)</li>
Similar issues:
Rendering .html files as views in ASP.NET MVC
Render HTML file in ASP.NET MVC view?
Is there a way to save the current webpage by using casperjs or phantomjs?
I tried to get the html and save it into a file. But the resulting file was a lot different from the screenshot of that time (with casper.capture). Is there a way to save the current webpage?
Andrey Borisko suggested to use the disk cache to retrieve the resources. My solution is not that efficient, but you don't need to decompress text files.
I use XMLHttpRequest to retrieve all resources after I registered them with the resource.received event handler. I then filter the resources into images, css and fonts. The current limitation is that remote resource paths that contain something like ../ or ./ are not handled correctly.
I retrieve the current page content with getHTML and iterate over all captured resources to replace the path used in the markup, that is identified by a portion of the complete resource URL, with a randomly generated file name. The file extension is created from the content type of the resource. It is converted using mimeType from this gist.
Since CSS files may contain background images or fonts, they have to be processed before saving to disk. The provided loadResource function loads the resource, but does not save it.
Since XMLHttpRequest to download the resources the script has to be invoked with the --web-security=false flag:
casperjs script.js --web-security=false
script.js
var casper = require("casper").create();
var utils = require('utils');
var fs = require('fs');
var mimetype = require('./mimetype'); // URL provided below
var cssResources = [];
var imgResources = [];
var fontResources = [];
var resourceDirectory = "resources";
var debug = false;
fs.removeTree(resourceDirectory);
casper.on("remote.message", function(msg){
this.echo("remote.msg: " + msg);
});
casper.on("resource.error", function(resourceError){
this.echo("res.err: " + JSON.stringify(resourceError));
});
casper.on("page.error", function(pageError){
this.echo("page.err: " + JSON.stringify(pageError));
});
casper.on("downloaded.file", function(targetPath){
if (debug) this.echo("dl.file: " + targetPath);
});
casper.on("resource.received", function(resource){
// don't try to download data:* URI and only use stage == "end"
if (resource.url.indexOf("data:") != 0 && resource.stage == "end") {
if (resource.contentType == "text/css") {
cssResources.push({obj: resource, file: false});
}
if (resource.contentType.indexOf("image/") == 0) {
imgResources.push({obj: resource, file: false});
}
if (resource.contentType.indexOf("application/x-font-") == 0) {
fontResources.push({obj: resource, file: false});
}
}
});
// based on http://docs.casperjs.org/en/latest/modules/casper.html#download
casper.loadResource = function loadResource(url, method, data) {
"use strict";
this.checkStarted();
var cu = require('clientutils').create(utils.mergeObjects({}, this.options));
return cu.decode(this.base64encode(url, method, data));
};
function escapeRegExp(string) {
// from https://stackoverflow.com/a/1144788/1816580
return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function replaceAll(find, replace, str) {
// from https://stackoverflow.com/a/1144788/1816580
return str.replace(find, replace);
}
var wrapFunctions = [
function wrapQuot1(s){
return '"' + s + '"';
},
function wrapQuot2(s){
return "'" + s + "'";
},
function csswrap(s){
return '(' + s + ')';
}
];
function findAndReplace(doc, resources, resourcesReplacer) {
// change page on the fly
resources.forEach(function(resource){
var url = resource.obj.url;
// don't download again
if (!resource.file) {
// set random filename and download it **or** call further processing which in turn will load ans write to disk
resource.file = resourceDirectory+"/"+Math.random().toString(36).slice(2)+"."+mimetype.ext[resource.obj.contentType];
if (typeof resourcesReplacer != "function") {
if (debug) casper.echo("download resource (" + resource.obj.contentType + "): " + url + " to " + resource.file);
casper.download(url, resource.file, "GET");
} else {
resourcesReplacer(resource);
}
}
wrapFunctions.forEach(function(wrap){
// test the resource url (growing from the back) with a string in the document
var lastURL;
var lastRegExp;
var subURL;
// min length is 4 characters
for(var i = 0; i < url.length-5; i++) {
subURL = url.substring(i);
lastRegExp = new RegExp(escapeRegExp(wrap(subURL)), "g");
if (doc.match(lastRegExp)) {
lastURL = subURL;
break;
}
}
if (lastURL) {
if (debug) casper.echo("replace " + lastURL + " with " + resource.file);
doc = replaceAll(lastRegExp, wrap(resource.file), doc);
}
});
});
return doc;
}
function capturePage(){
// remove all <script> and <base> tags
this.evaluate(function(){
Array.prototype.forEach.call(document.querySelectorAll("script"), function(scr){
scr.parentNode.removeChild(scr);
});
Array.prototype.forEach.call(document.querySelectorAll("base"), function(scr){
scr.parentNode.removeChild(scr);
});
});
// TODO: remove all event handlers in html
var page = this.getHTML();
page = findAndReplace(page, imgResources);
page = findAndReplace(page, cssResources, function(cssResource){
var css = casper.loadResource(cssResource.obj.url, "GET");
css = findAndReplace(css, imgResources);
css = findAndReplace(css, fontResources);
fs.write(cssResource.file, css, "wb");
});
fs.write("page.html", page, "wb");
}
casper.start("http://www.themarysue.com/").wait(3000).then(capturePage).run(function(){
this.echo("DONE");
this.exit();
});
The magic happens in findAndReplace. capturePage is completely synchronous so it can be dropped anywhere without much head ache.
URL for mimetype.js
No, I don't think there is an easy way to do this as phantomjs doesn't support rendering pages in mht format (Render as a .mht file #10117). I believe that's what you wanted.
So, it needs some work to accomplish this. I did something similar, but i was doing it the other way around I had a rendered html code that I was rendering into image/pdf through phantomjs. I had to clean the file first and it worked fine for me.
So, what I think you need to do is:
strip all js calls, like script tags or onload attributes, etc..
if you have access from local to the resources like css, images and so on (and you don't need authentication to that domain where you grab the page) than you need to change relative paths of src attributes to absolute to load images/etc.
if you don't have access to the resources when you open the page then I think you need to implement similar script to download those resources at the time phantomjs loads the page and then redirect src attributes to that folder or maybe use data uri.
You might need to change links in css files as well.
This will bring up the images\fonts and styling you are missing currently.
I'm sure there are more points. I'll update the answer if you need more info, once I see my code.
I am trying to build a chrome extension. Which would do some search on the page and post the results to the extensions.
I am having a hard time running this. Whenever I try to run the extension it is just stuck on Injecting Script.
my re.js
function printDetails(document_r) {
var test = document_r.body;
var text = test.innerText;
var delim="^^ validatedCache :";
var endlim="</site>";
var idx = text.indexOf(delim);
var endInd=text.indexOf(endlim);
var tag = "accountName";
var regex = "<" + tag + ">(.*?)<\/" + tag + ">";
var regexg = new RegExp(regex,"g");
var matches = [];
while (match = regexg.exec(text.substring(idx+delim.length,endInd))) matches.push("Account Name::::::"+match[1]);
return matches;
}
chrome.extension.sendMessage({
action: "getSource",
source: "\n\n\n DETAILS>>>>>\n\n"+printDetails(document)
});
selection.js
chrome.extension.onMessage.addListener(function(request, sender) {
if (request.action == "getSource") {
message.innerText = request.source;
}
});
function onWindowLoad() {
var message = document.querySelector('#message');
chrome.tabs.executeScript(null, {
file: "re.js"
}, function() {
// If you try and inject into an extensions page or the webstore/NTP you'll get an error
if (chrome.extension.lastError) {
message.innerText = 'There was an error injecting script : \n' + chrome.extension.lastError.message;
}
});
}
window.onload = onWindowLoad;
popup.html
<!DOCTYPE html>
<html style=''>
<head>
<script src='selection.js'></script>
</head>
<body style="background-image:url(12.png);width:400px; border: 2px solid black;background-color:white;">
<div id='message'>Injecting Script....</div>
</body>
</html>
I know there is some problem with these 2 lines only.
var test = document_r.body;
var text = test.innerText;
What I wan't is to extract the webpage ( contents ) into a string which I am hopefully doing by the above two lines of code.
Then do some string manipulation on the code.If I run directly this code in a console with a dummy string . I can execute it so figure something is wrong with these two lines.
My extension is stuck on " Injecting Script..."
Some help would be appreciated.
PS:yes I was able to run it earlier with the same code but somehow it doesn't run now.
When using server and client in same machine by ajax connectivity it shows the inactive state of server. On using dynamic script tag it doesn't reflect the inactivness of server. How could this be resolved?
we have included these functions in a .js file.
function JSONscriptRequest(fullUrl) {
this.fullUrl = fullUrl;
this.noCacheIE = '&noCacheIE=' + (new Date()).getTime();
this.headLoc = document.getElementsByTagName("head").item(0);
this.scriptId = 'JscriptId' + JSONscriptRequest.scriptCounter++;
}
JSONscriptRequest.scriptCounter = 1;
JSONscriptRequest.prototype.buildScriptTag = function () {
this.scriptObj = document.createElement("script");
this.scriptObj.setAttribute("type", "text/javascript");
this.scriptObj.setAttribute("charset", "utf-8");
this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
this.scriptObj.setAttribute("id", this.scriptId);
}
JSONscriptRequest.prototype.removeScriptTag = function () {
this.headLoc.removeChild(this.scriptObj);
}
JSONscriptRequest.prototype.addScriptTag = function () {
this.headLoc.appendChild(this.scriptObj);
}
and used the following code in jsp page
// The web service call
var req = <<<url of the service which resides in different server>>>&callback=<callback function>;
// Create a new request object
bObj = new JSONscriptRequest(req);
// Build the dynamic script tag
bObj.buildScriptTag();
// Add the script tag to the page
bObj.addScriptTag();