Calling functions from different javascript files causing "undefined is not a function" - javascript

I'm trying to make some small changes to an existing vb.net website that was written by someone who no longer works for the company, but every time a javascript function is called from a script file other than the one it's defined in, I see "Uncaught Reference Error: undefined is not a function" in Chrome's console.
Some of the scripts are being loaded in the master file:
<script type="text/javascript" src="Scripts/jquery-1.8.3.min.js"></script>
<script type='text/javascript' src="Scripts/JSExtensions.js"></script>
<script type='text/javascript' src="Scripts/GlobalUtilityFunctions.js"></script>
<script language="javascript" type="text/javascript">
jQuery.event.add(window, "load", resizeFrame);
jQuery.event.add(window, "resize", resizeFrame);
function resizeFrame() {
}
</script>
And the rest are loaded in the page itself:
<script type='text/javascript' src="Scripts/GridCalcFunctions.js"></script>
<script type='text/javascript' src="Scripts/InputEventHandlers.js"></script>
<script type='text/javascript' src="Scripts/FocusHandlers.js"></script>
<script type='text/javascript' src="Scripts/ProjectPageFunctions.js"></script>
<script type="text/javascript">
$(document).ready(function () {
});
$(window).unload(function () {
SaveOnExit();
});
function setPIDNumberLabel(ctlID, strVal) {
var val = strVal;
var ctl = top.$get(ctlID);
if (ctl != null) {
ctl.innerHTML = val;
}
}
</script>
GlobalUtilitesFunctions has no trouble accessing JSExtensions on other pages, but does here even though both are loaded in the master. I thought that must mean that the problem is caused by one of the files loaded on this page, but commenting them all out doesn't fix the issue.
As a specific example, GlobalUtilitiesFunctions contains this:
function GetAttributeSelector(attName, attValue, attOperator,attNot) {
attOperator = String.deNullValue(attOperator, "=");
[more code]
}
And I get an error that String.deNullValue is undefined, but over in JSExtenstions is:
String.iifValueIsNullOrEmpty = function (val, trueVal,falseVal) {
falseVal = String.getArgValue(falseVal, val);
if (String.isNullOrEmpty(val)) {
return trueVal;
}
else {
return falseVal;
}
}
String.deNullValue = function (val,defaultVal) {
var ret = "";
defaultVal = String.iifValueIsNullOrEmpty(defaultVal,"");
ret = String.iifValueIsNullOrEmpty(val,defaultVal);
return ret;
}
I've also tried running the site on a server (instead of inside Visual Studio) without solving the problem. Does anyone have an idea what might be causing this?

Here you can see this:
"A variable declared (using var) within a JavaScript function becomes LOCAL to the function.
The variable gets a local scope: It can only be accessed from within that function."
try to define functions like
function deNullValue(val,defaultVal) {
var ret = "";
defaultVal = String.iifValueIsNullOrEmpty(defaultVal,"");
ret = String.iifValueIsNullOrEmpty(val,defaultVal);
return ret;
}

Related

Client Side Taxonomy Picker For SharePoint

On Premise SharePoint 2013, Implementing a Client Side Taxonomy Picker For SharePoint using below blogs:
https://www.c-sharpcorner.com/UploadFile/93cb27/client-side-taxonomy-picker-for-sharepoint-app/
https://blogs.msdn.microsoft.com/richard_dizeregas_blog/2014/03/13/taxonomy-picker-in-sharepoint-provider-hosted-app/
Added the code using a Script Editor, and the control shows only on Edit Mode - when I save the page, the control disappears and throws the following error "b.get_path is not a function"
Tried many combinations however it looks like a bug as the same code works fine in SharePoint Online.
<link href="https://server/sites/TeamSite/SiteAssets/CodeLibrary/styles/taxonomypickercontrol.css" rel="stylesheet"/>
<script type="text/ecmascript" src="https://server/sites/TeamSite/SiteAssets/CodeLibrary/jquery-1.9.1.js"></script>
<script type="text/ecmascript" src="https://server/sites/TeamSite/SiteAssets/CodeLibrary/taxonomypickercontrol.js"></script>
<script type = "text/javascript" src = "https://server/sites/TeamSite/SiteAssets/CodeLibrary/taxonomypickercontrol_resources.en.js"></script>
<script type = "text/javascript" src = "https://server/sites/TeamSite/_layouts/15/sp.core.js" ></script>
<script type = "text/javascript" src = "https://server/sites/TeamSite/_layouts/15/sp.runtime.js" ></script>
<script type = "text/javascript" src = "https://server/sites/TeamSite/_layouts/15/sp.taxonomy.js" ></script>
<script type = "text/javascript">
if (myStronglyTypedObj === undefined) {
var myStronglyTypedObj = {};
}
myStronglyTypedObj = {
// Object Globals
"g": {},
// Pre-initialization functions ensure scripts SharePoint dependencies are loaded
"preinit": function() {
// Load necessary libraries
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
// Register what you need from SharePoint (in this case the sp.runtime)
SP.SOD.registerSod('sp.runtime.js', SP.Utilities.Utility.getLayoutsPageUrl('sp.runtime.js'));
// Register what you need from SharePoint (in this case the term store)
SP.SOD.registerSod('sp.taxonomy.js', SP.Utilities.Utility.getLayoutsPageUrl('sp.taxonomy.js'));
// Load the registered items
SP.SOD.executeFunc('sp.taxonomy.js', 'SP.Taxonomy.TaxonomySession', myStronglyTypedObj.init());
});
},
// The main Initialization function
"init": function() {
/* Check if SP.Taxonomy actually exists yet
* PLEASE NOTE that it's common that these objects aren't available, even if you've properly loaded them in the "preinit" function.
* This bit of code checks if the object is available, and if it's not, waits for 200ms and then tries again until this object is loaded
*/
if (SP.Taxonomy) {
console.log("SP.Taxonomy ready... continuing scripts...");
myStronglyTypedObj.therest();
} else {
console.log("SP.Taxonomy not ready... set timeout and try again after 200ms");
setTimeout(myStronglyTypedObj.init, 200);
}
},
"therest": function() {
// Continue with your code here...
try {
var context = new SP.ClientContext()
$('#taxPickerKeywords').taxpicker({ isMulti: true, allowFillIn: true, termSetId: "63858201-dd9b-46b1-b1bb-b6a054fa7cb7" }, context);
}
catch(err) {
alert(err.message);
}
}
}
$(document).ready(function(){
myStronglyTypedObj.preinit();
});
</script>
<div>
<input type="hidden" id="taxPickerKeywords" />
</div>
As stated it works in SharePoint Online, though I checked the version of our Farm and it seems that our dev box was not up to date.
After patching, it worked fine.
Thanks for your valuable help.

How can I inject JS and collect alert message from website?

I am trying to collect alert from website by using overwrite method. I searched on google and found wappalyzer, a Chrome/Firefox extension to detect software on website. It injects a script inject.js when page load and collect information. My method is similar. I make a local website and test it. When I inject overwrite_alert.js manually then it works.
But I want to do it dynamically and apply to other website. So I use headless browser like PhantomJS. The following code which I tried in PhantomJS but it does not work.
I am trying to inject a JavaScript on phantom JS. Like this code:
<!DOCTYPE html>
<html>
<head>
<title>Test alert</title>
<!-- !!! Inject here !!! <script src="overwrite_alert.js"></script> -->
<script type="text/javascript" src="other_script.js"> </script>
<script type="text/javascript">
alert("Alert content");
</script>
</head>
<body>
<h1>website content</h1>
</body>
</html>
overwrite_alert.js file from this question:
(function() {
var _alert = window.alert; // <-- Reference
window.alert = function(str) {
// do something additional
if(console) console.log(str);
//return _alert.apply(this, arguments); // <-- The universal method
_alert(str); // Suits for this case
};
})();
I tried with onLoadStarted event and My PhantomJS code:
var webPage = require('webpage');
var page = webPage.create();
var url = "https://localhost:5000/alert.html";
page.onConsoleMessage = function(msg, lineNum, sourceId) {
console.log('CONSOLE> ' + msg);
};
page.onLoadStarted = function() {
if (page.injectJs('do.js')) {
var title = page.evaluate(function() {
// returnTitle is a function loaded from our do.js file - see below
console.log("evaluate completed");
});
console.log(title);
}
}
page.open(url, function(status) {
if (status === "success") {
if (page.injectJs('do.js')) {
var title = page.evaluate(function() {
// returnTitle is a function loaded from our do.js file - see below
console.log("evaluate completed");
});
console.log(title);
phantom.exit();
}
page.render("onOpen.png");
}
});
Result:
$ phantomjs test_inject.js
CONSOLE> from onLoadStarted completed
null
CONSOLE> from page.open
null
Since the page.open callback is called after a page is loaded, it would be simply to late to change the implementation of window.alert. You would need to use earlier events such as page.onInitialized, page.onLoadStarted, etc.
Since you're interested in alerts, you don't need to do that at all, because PhantomJS provides an event for that: page.onAlert

Why does Signalr function still exist in the DOM scope when going from one page to another - Single Page App

I have created a Single Page App, and this is my first one so maybe I'm on the wrong path.
I am using master-page in which I'm loading two other pages. Also, I'm using javascript modules so that I can use private variables and functions.
In the master-page, or Mail.html, I start the signalr connection, and I initialize the modules.
In the inbox sub-page I'm waiting "mail" from the server, and in the outbox I'm displaying all sent messages. In order to accomplish this I'm using two different modules (Inbox and Outbox).
My issue occurs when I load the second page (in this example Outbox) after inbox.html is loaded, in this scenario
signalr still works which is strange because that connection is used just in the Inbox page, in that module.
I've tried many things to prevent this, like unloading the current page before loading the next one, and I've also tried removing the scripts, starting a connection just in the inbox page, but nothing helps.
Also, I can't find where exactly is this function stored in the DOM when Outbox.html is loaded.
Here is my code:
Mail.html
<html>
<head>
//scripts
//css
</head>
<body>
<div class="page" id="Inbox">Inbox</div>
<div class="page" id="Outbox">Outbox</div>
<div id="loadPage">
</div>
<script type="text/javascript">
var SignalRHub = $.connection.hubs;
$.connection.hub.start();
var MailModule = {};
$('body').off('click', '.page').on('click', '.page', function () {
MailModule = {};
if ($(this).attr('id') == 'Inbox') {
$("#loadPage").empty().load("/Home/Inbox", function () {
MailModule.Inbox.Init();
});
}
if ($(this).attr('id') == 'Outbox') {
$("#loadPage").empty().load("/Home/Outbox", function () {
MailModule.Outbox.Init();
});
}
});
</script>
<body>
</html>
Inbox.html
<div id="items"></div>
<script>
(function (mail, $) {
mail.Inbox = (function () {
var ReceiveMail = function () {
// This is still active when there is new 'mail' from server
// even though I'm not on this page
SignalRHub.client.receiveMail = function (UserName, Title){
$("#items").append("<p>"+UserName+"-"+Title+"</p>");
}
};
var init = function () {
ReceiveMail();
};
return {
Init: init
};
}());
}(window.MailModule = window.MailModule || {}, jQuery));
</script>
Outbox.html
<div id="items"></div>
<script>
(function (mail, $) {
mail.Outbox = (function () {
var GetSend = function () {
$.get("URL", { UserId: UserId }, function (result) {
$("#items").append("<p>"+result[0].UserName+"-"+result[0].Title+"</p>");
}
};
var init = function () {
GetSend();
};
return {
Init: init
};
}());
}(window.MailModule = window.MailModule || {}, jQuery));
</script>
Note: Maybe this pattern is not right, and I'll be grateful if you give me a lead on how I can accomplish a better one

Common function for calling debugger; in Javascript

How can I make a common function in my global.js to for calling debugger; in JS. I'll basically set a value whether to debug or not. I tried the following but it's not working. Any lead will be appreciated.
<script type="text/javascript">
var debugModeVal = 1;
debugMode = function()
{
if(debugModeVal)
{
debugger;
}
return;
}
</script>
I am calling from my html file like this
<script type="text/javascript">
function callAnotherFunction()
{
debugMode;
}
</script>
use debugMode() instead of debugMode; in callAnotherFunction().
For debugging, use step out of the debugMode function to find yourself in the caller. Thanks to Jan Dvorak.

How to use an external javascript file in asp.net

I wrote a script to hide and show a loader for my asp.net web application. The script works great when placed inline. I tried to extract the script to an external file and received the following error:
Error: The value of the property 'Pausing' is null or undefined, not a Function object
I tried to look up the error, but I was unable to find a solution to the problem. I am new to asp.net so it may be that I'm not sure how to search for the right question.
My inline code that works is:
<script type="text/javascript">
function Pausing() {
window.setTimeout(ShowLoader, 1);
}
function ShowLoader() {
if ((typeof Page_IsValid === 'undefined') ||
(Page_IsValid != null && Page_IsValid)) {
var i = document.getElementById("loader");
var img = document.getElementById("img");
i.style.display = "block";
setTimeout("document.images['img'].src=document.images['img'].src", 10);
Endpausing();
}
}
function HideLoader() {
var i = document.getElementById("loader");
i.style.display = "none";
}
function Endpausing() {
window.setTimeout(HideLoader, 4000);
}
</script>
The event call is attached to an asp:button control below:
<asp:Button ID="btnGetReport" runat="server" OnClick="btnGetReport_Click" OnClientClick="Pausing();" />
I removed the inline script and replaced with this...
<script type="text/javascript" src="../../Scripts/Loader.js"></script>
Added script to external file:
window.onload = initAll;
function initAll() {
function Pausing() {
window.setTimeout(ShowLoader, 1);
}
function ShowLoader() {
if ((typeof Page_IsValid === 'undefined') || // asp page has no validator
(Page_IsValid != null && Page_IsValid)) {
var i = document.getElementById("loader");
var img = document.getElementById("img");
i.style.display = "block";
setTimeout("document.images['img'].src=document.images['img'].src", 10);
Endpausing();
}
}
function HideLoader() {
var i = document.getElementById("loader");
i.style.display = "none";
}
function Endpausing() {
window.setTimeout(HideLoader, 4000);
}
}
Then I receive the previously mentioned error.
Any help would be greatly appreciated!
Always use ResolveUrl to call your script files like this
Lets assume your script is in Script folder of your root path with a file Name as MyScriptFile.js
<script type="text/javascript" src="<%= ResolveUrl ("~/Scripts/MyScriptFile.js") %>"></script>
EDIT : you can use ResolveUrl or ResolveClientUrl based on your needs
ResolveUrl creates the URL relative to the root where as
ResolveClientUrl creates the URL relative to the current page.
Based on your question : How to use an external javascript file in asp.net
<script type="text/javascript" src="http://www.xyz.com/test.js"></script>

Categories