DOM throwing error because of Multiple HTML files - javascript

I am trying to create a simple recipe-app with javascript.
I have 3 HTML files: index.html, create.html, edit.html
and 2 JS files.
I have a couple of DOM elements. One on index.html, Two on edit, Two on create.
Now when I open index.html I get an error:
recipe.js:14 Uncaught TypeError: Cannot set property 'value' of null
The problem here is that the code that the error is it's about edit.html not index.html.
Same problem on edit.html
Uncaught TypeError: Cannot read property 'appendChild' of null
at recipe.js:55
recipe.js code 55 is about index.html, not edit.html.
Is there a way to target an HTML file when using DOM.
document.getElementById("edit-body").value = getRecipeBody();
I want the code above to be only for edit.html, not for index.html or create.html.
edit-body is a form that is only on edit.html, not on index or create.html
document.getElementById('recipes').appendChild(recipeEl)
I want this code to be for index.html not for other HTML files because there is no #recipes ID on those files. The #recipes is only on index.html
I am using localStorage.

window.location.pathname would let you execute code for a specific path.
if(window.location.pathname === '/edit.html') {
document.getElementById("edit-body").value = getRecipeBody();
}
Note that if you load index.html by default (as in, http://localhost:80/ as opposed to http://localhost:80/index.html), then the pathname will simply be /, so make sure you handle both of those, i.e.:
if(window.location.pathname === '/index.html' || window.location.pathname === '/') {
document.getElementById('recipes').appendChild(recipeEl)
}
A better approach would be to code it defensively. Check that the element you're getting exists before running a function against it. For example:
var editEl = document.getElementById("edit-body");
if (editEl) {
editEl.value = getRecipeBody();
}
Instead of either of these, you could also just load index.js on index.html, edit.js on edit.html, etc., though you'd want to split out any shared functions into a separate (common) JS file.

Related

Cannot add external JavaScript file to React application

I have read all advices how to add external JavaScript file to React application but no one works for me. I'll describe my situation. I have created a tutorial React project and it works fine. Now I want to show a data that I get from server side in some grid , say, jqgrid. I have a JavaScript file that has a function showGrid() to show the grid. So I need to add this file to the project. More precisely I have a React component ShowInGrid and in
render()
method of it I write
let contents = this.state.loading
? <p><em>Loading...</em></p>
: ShowInGrid.renderGrid(this.state.data);
and then
static rendersGrid(data) {
return (
showGrid(data)
);
where showGrid is a function from JavaScript file. To reference to this file I used several ways:
in componentDidMount method I added
var script = document.createElement('script');
script.src = // path of external javascript file.
script.class = "external-script
document.body.appendChild(script);
I get a message
'showGrid' is not defined no-undef
I tried to use
import ScriptTag from 'react-script-tag';
with
< ScriptTag isHydrating={true} type="text/javascript" src="http://my path to js-file">
but I get the same result.
So I really need to know what's wrong and how properly to add JavaScript file to app. A real working example will be really appreciated.

Browser attempts to load JS file from invalid address, when accessing razor page through URL

I have set a razor page as the landing page for my application:
options.Conventions.AddAreaPageRoute("Home","/Home/Index", "");
My pages are all contained in areas, so in order to access them by url more easily I wanted to avoid writing the additional area name, so from Home/Home/page to Home/Index:
options.Conventions.AddAreaPageRouteModelConvention("Home", "/Home/Index", model =>
{
foreach (var selector in model.Selectors)
{
selector.AttributeRouteModel = new AttributeRouteModel
{
Template = new string(selector.AttributeRouteModel.Template.SkipWhile(c => c != '/').Skip(1).ToArray()),
};
}
});
I also modified my app settings:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "Default",
template: "{area=Home}/{page=Index}");
});
I removed all the other mapRoutes, including controller routing, etc.
After I added this snippet I tried accessing the pages by /Home/Index, and it worked, however my js scripts are not loading and thus not functioning. Then I removed the aforementioned option and attempted to access the page by Home/Home/Index and my scripts were still not loading. They do load property if I use the anchors I have set up:
<a class="nav-bar-brand" asp-area="Home" asp-page="/Home/Index">...</a>
The script file is included in the Layout:
<script src="js/site.js" type="text/javascript"></script>
The problem appears to be that the browser is looking for the file in the wrong place, this is the Request URL that the General header contains "https://localhost/Home/Home/js/site.js", while in reality the proper address is "https://localhost/js/site.js", why is this happening and how do I fix it?
<script src="**~/**js/site.js" type="text/javascript"></script>
You must update your code thats. (
/
or
~/
get starting on domain root folder)

Cannot include wysiwyg.js script in Jade with Node.js

While trying to create a rich text editor, I cannot seem to add the js script for the buttons and form. Right now, most of the functions are inlined in the jade pages, but that is quite unelegant.
I have a layout.jade file:
doctype html
html
head
body
header
section.content
block content
And the create.jade script, where I want the rich text editor:
extends ../layout
block content
script(type='text/javascript', src='./css/js/wiz.js')
form(method="post", action=post ? '/post/edit/' + post.id : '/post/create', onload="iFrameOn()")
ul
p
input#title(name="title", placeholder="Title", value=post ? post.title : '', autocomplete='off')
p
#wysiwyg_cp(style="padding:8px; width:700px")
input(type="button", onClick="iBold();", value="B")
input(type="button", onClick="richTextField.document.execCommand(\"underline\",false,null);", value="U")
p
textarea#blogPostBody(style="display:none", name="blogPostBody", placeholder="Blog post text", rows="20", cols="50")
iframe#richTextField(name="richTextField", contentEditable="true", onLoad="richTextField.document.designMode = 'On';")
if(post)
| #{post.body}
else
| &#09
p
input(onClick="javascript:submit_form();", type="button", name="myBtn", value="Save")
The structure of the project looks like:
Proj
- css
-- js
--- wiz.js
- middleware
- node_modules
- public
- routes
- views
-- post
--- create.jade
-- layout.jade
-- home.jade
-- login.jade
- app.js
- package.json
When trying to open the create section of my blog, I get the following error message, as can be seen in the image below:
Uncaught SyntaxError: Unexpected token <
See chrome stack: http://i.stack.imgur.com/JyHs2.png
The wiz.js file looks like this:
function iFrameOn() { richTextField.document.designMode = 'On'; }
function iBold() { richTextField.document.execCommand("bold",false,null); }
function iUnderline(){ richTextField.document.execCommand("underline",false,null); }
function iItalic(){ richTextField.document.execCommand("italic",false,null); }
function iImage() {
var imgSrc = prompt("EnterImageLocation", '');
if(imgSrc!=null) {
richTextField.document.execCommand("insertimage",false,imgSrc);
}
}
function submit_form() {
var theForm = document.getElementById("myForm");
theForm.elements("myTextArea").value = window.frames['richTextField'].document.body.innerHTML;
theForm.submit();
}
I have also tried adding
app.set('view options', {locals:{scripts:['wiz.js']}});
and/or adding
app.use(express.static("./css/js"));
In the app.js file or in the middleware.
But these did not help. The problem seem to be in the "create.jade" script, when referencing the 'text/javascript' script, because the same error was obtained even when referencing a non-existant js file.
Could anyone have any idea what the problem could be?
[EDIT] SOLUTION that was implemented:
script
include ./../../css/js/wiz.js
The following snippet of code worked:
script
include ./../../css/js/wiz.js
Express's static middleware will by default mount the files to the root. So, if you include the middleware as above, the wiz.js file will be accessible at "/wiz.js" when your server's running -- this is the path you should put in the src attribute of your script tag in the jade file, not the local path (since local files are not accessible to the client unless they are served). If you want to change the mountpath (so, for example, that the file will be accessible on "/js/wiz.js", rather than the root), you can add it as a first argument, like below:
var localDirectoryPath = "./css/js";
// Or if you happened to want an absolute path
// (though it doesn't make a difference here):
// var localDirectoryPath = require("path").join(__dirname, "css", "js");
app.use("/js", express.static(localDirectoryPath));
The temporary solution that you've found (using Jade's include function) is merely loading the file's contents on the server (when Jade compiles the template) and inserting the code in between script tags on your page, which works but is certainly not ideal, since it will slow down the initial loading of your HTML, especially as the wiz.js file gets bigger.
And I won't even ask why your javascript directory is inside your css directory!

How to include JavaScript file into JSP?

I have the following script tag in my JSP file:
<script src="/js/CCTUtil.js"></script>
with the following function in it:
function disableButton(buttonID) {
document.getElementById(buttonID).setAttribute("disabled", "true");
return true;
}
and in my jsp I call it with:
onchange="disableButton('datasourceForm:cancel');
datasourceForm:cancel is just the ID, so don't worry about that.
This works if I hardcode the JS function in my JSP, but when exporting it to a file, it doesn't work. It recognizes the valid filepath (otherwise the server throws an exception) so it can see the file just fine, but when testing it in Internet Explorer the error is "Object expected", and points to the end of the JSP file, which of course isn't telling of anything.
Help please?
The SRC must not be correct then. Are you sure you have set the path correctly? It's not supposed to be "../js/CCTUtil.js" is it?
Instead of including script file, directly add javascript function in the jsp file.
Then try, if you are getting the same issue, might be some issue with javascript or ur id datasourceForm:cancel

Path to included Javascript page

How do I get the absolute or site-relative path for an included javascript file.
I know this can be done in PHP, (__file__, I think). Even for an included page, one can check the path (to the included file). Is there any way to have this self awareness in Javascript?
I know I can can get the page URL, but need to get the JS URL.
Eg. Javascript needs to modify the src of an image on the page. I know where the image is relative to the JavaScript file. I don't know where the Javascript is relative to the page.
<body>
<img id="img0" src="">
<script src="js/imgMaker/myscript.js"></script>
</body>
function fixPath(){
$$("#img0")[0].set('src','js/imgMaker/images/main.jpg');
}
Please do not tell me to restructure my function - the example is simplified to explain the need.
In the actual case, a Mootools class is being distributed and people can put it into whatever folder they want.
I would just read the src of the script element, but the class can be part of any number of javascript files, so I can't know what the element looks like.
JavaScript (not JScript) has no concept of file names. It was developed for Netscape back in the days. Therefore there is no __file__ feature or anything similar.
The closest you can come are these two possibilities:
What you already mentioned: Harvest all src attributes of all JS files and try to figure out which one is the right.
Make it a necessary option, that the path to the images must be set in the embedding HTML file. If not set, use a reasonable and well-documented default:
<script type="text/javascript">
var options = {
'path_to_images': '/static/images/' // defaults to '/js/img/'
};
</script>
Based on http://ejohn.org/blog/file-in-javascript/
(function(){
this.__defineGetter__("__FILE__", function() {
return (new Error).stack.split("\n")[2].split("#")[1].split(":").slice(0,-1).join(":");
});
})();
(function(){
this.__defineGetter__("__DIR__", function() {
return __FILE__.substring(0, __FILE__.lastIndexOf('/'));
});
})();
Then later
img.setAttribute('src', __DIR__ + '/' + file);
if you have folders:
/webroot
/images
/scripts
Then images would be an absolute path of /images/whatever.jpg and scripts would be an absolute path of /scripts/js.js
I'm using the following method to get the base URL and using it for loading the other prorotypes, maybe this is what you need. Lets say current script name is 'clone.js'.
/*
* get the base URL using current script
*/
var baseURL = '';
var myName = 'clone.js';
var myPattern = /(^|[\/\\])clone\.js(\?|$)/;
var scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
var src;
if (src = scripts[i].getAttribute("src")) {
if (src.match(myPattern)) {
baseURL = src.replace(myName, '');
break;
}
}
}
Var baseURL should contain what you need.
The path to the JS is irrelevant; links in the HTML file are always relative to the HTML file, even if you modify them from external JS.
[EDIT] If you need to build a path relative to the current web page, you can find its path in document.location.pathname. This path is relative to the web root but you should be able to find a known subpath and then work from there.
For example, for this page, it pathname would be /posts/1858724. You can look for posts and then build a relative path from there (for example posts/../images/smiley.png)
I know this question was asked awhile back but I have a similar situation to Sam's.
In my case, I have two reasons for the situation:
The user can access different sub-domains, each with its own index page.
The user can enter a password that causes index.php to adjust the paths.
Most of the references point to the same src locations for the scripts, but some do not. For instance, those at a different level of the tree would require a different path.
I addressed it by assigning an id to the index page's script tag. For example, the head might include...
<script id='scriptLocation' type='text/javascript' language='javascript' src='../scripts.test/script.js'></script>
My JavaScript is then able to read the path...
var myPath = document.getElementById("scriptLocation").src;
Found another approach, perhaps someone with more JS ninja can flush this out.
CSS stylesheet are able to find the node that called them using document.stylesheets.ownernode.
I could not find a similar call for javascript files.
But, in some cases, if one can include a CSS file together with the javascript, and give the first rule some unique identifier.
One can loop through all stylesheets till they find the one with the identifier [if(document.stylsheets[i].cssRules[0] == thisIs:myCSS)], than use ownerNode to get the path of that file, and assume the same for the JS.
Convoluted and not very useful, but its another approach - might trigger a better idea by someone.

Categories