referring to this question here, context is not defined javascript
I am just throwing out another question in regards of the error where document.getElementById is returning a null even though the template is already compiled.
A brief background, I am using handlebar template, jquery and I want a googlemap to appear in 1 of the handlebar template.
my html:
<script id="employee-tpl" type="text/x-handlebars-template">
<div class='header'>Back<h1>Gloop</h1></div>
<div class='details'>
<img class='employee-image' src='img/{{firstName}}_{{lastName}}.jpg' />
<h1>{{name}}</h1>
<h2>{{address}}</h2>
<h2>{{phone}}</h2>
<span class="location"></span>
<ul>
<li><div id="map-canvas"> </div></li>
</ul>
</div>
</script>
and my js
this.render = function(){
this.el.html(EmployeeView.template(employee));
console.log(document.getElementById("map-canvas"));
};
this.initialize = function(){
this.el=$('<div/>');
};
this.initialize();
}
EmployeeView.template = Handlebars.compile($("#employee-tpl").html());
notice that the call to console will log a null value and this js is called at the bottom of my html file
<script src="lib/iscroll.js"></script>
<script src="lib/handlebars.js"></script>
<script src="lib/jquery-1.8.2.min.js"></script>
<script src="js/storage/cafe-memory-store.js"></script>
<script src="js/EmployeeView.js"></script>
<script src="js/main.js"></script>
</body>
</html>
my understanding it that the my compilation will render the div which then should be able to be seen but this is not the case. Anyone knows why?
Is that fiddle all the code you have? If I add this to the JS it works.. but it's hard to see what you're after.
var source = $("#employee-tpl").html();
var template = Handlebars.compile(source);
var data = { //your data here }
$('body').append(template(data));
Related
I'm trying to use a variable from a page loaded inside a DIV in another DIV.
The text in the "bar" DIV on the "index.html" page should be replaced by the item id selected from the "page.html" loaded as an <object></object> inside the "content" DIV.
Or the item id should at least be stored in a global variable - which hasn't been working either - because when I run a function from the "index.html" page to retrieve it, it displays as "undefined".
All the code is below:
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="index_style.css">
<title>Access element of other DIV</title>
</head>
<body>
<div id="bar">This text should be replaced by the Item ID selected below</div>
<div id="content">
<object type="text/html" data="page.html" width="100%" height="100%"></object>
</div>
</body>
</html>
index_style.css
body{
margin: 0px;font-family:arial;font-size:30px;text-align:center;color:#fff;
}
#bar{
position:relative;height:100px;line-height:100px;background-color:#555c60;color:#74de90;
}
#content{
position:absolute;top:100px;bottom:0px;right:0;left:0;overflow-y:hidden;
}
page.html
<link rel="stylesheet" href="page_style.css">
<script type="text/javascript" src="main.js"></script>
<center>
This is <b>page.html</b> which has been loaded <u>inside</u> the "content" DIV<br><br>
</center>
<div class="items" onclick="use_item_id(this);" id="item1">Item 1</div>
<div class="items" onclick="use_item_id(this);" id="item2">Item 2</div>
<div class="items" onclick="use_item_id(this);" id="item3">Item 3</div>
page_style.css
body{font-family:arial;font-size:30px;color:#fff;background-color:#1b1e4b;text-align:center;}
.items{cursor:pointer;}
.items:hover{color:#ff0000;}
main.js
function use_item_id(selected)
{
current_item = selected.getAttribute("id");
document.getElementById('bar').innerHTML = current_item;
alert(current_item);
}
The line document.getElementById('bar').innerHTML = current_item; in "main.js" seems to be the problem and I can't get it to work. The alert(current_item); works fine when the line above it isn't there so it's definitely getting the item id's correctly from "page.html". It's just not setting them as the innerHTML on the "index.html" page, or even storing them in a global variable to be retrieved from a function run on the "index.html" page (as mentioned above). Any code examples would be greatly appreciated.
I think it might be because the use_item_id() function is being executed from another page, so I might need some alternatives or other functions to get it to work.
It'd be great if anyone knows what the issue is. I appreciate all replies. Thanks in advance :)
You are not on the same document ... then in main.js
replace
document.getElementById('bar').innerHTML = current_item;
with
parent.document.getElementById('bar').innerHTML = current_item;
this solves your problem.
If you're trying to access variables from HTML documents it's highly recommended to use the data attribute. This is an example for a comment section:
In my item I set the data key for loading
<div class='resp-col col-12 comment-user-data'>
<div class='resp-col col-9'>
<div class="post-profile-image" style='background-image:url("<?=$user->profile_image?>")'></div>
<?=Html::a("<p class='post-user'>".$username."</p>", Url::to(['/account/'.$user->id.'/'.$user->username]))?>
</div>
<div class='resp-col col-3'><button class='reply-to' data-assoc-id='<?=$model->id?>' data-assoc-name='<?=$username?>'><i class="material-icons">reply</i></button></div> <-- set the data-assoc-id
</div>
<div class='resp-col col-12 comment-content-data'>
<?=$model->content?>
</div>
jQuery to load data key
$('.reply-to').on('click',function(){
$('#submit-comment').data('assoc-id', $(this).data('assoc-id'));
$('#comment-content').val('#'+$(this).data('assoc-name')+' ');
$('.base-modal').animate({
scrollTop: $("#comment-content").offset().top
}, 2000);
if($('#comment-content').css('display') == 'none'){
toggleCommentVisibility();
}
});
I am struggling with my page that can't load properly. I am using a simple header-body-footer structure in html5 and CSS3.
+----------+
| HEADER |
+---+----------+---+
| BODY |
+---+----------+---+
| FOOTER |
+----------+
What I am doing right now is create a svg with D3 inside the body space, reading width and height dynamically after window is loaded (and pictures also).
Now I want to add angular to avoid code redundancy inside each page of the site and I did this:
(function() {
var app = angular.module('neo4art', []);
var pages = {
"genesis.html": "The genesis of the project",
"about.html": "About Us",
"team.html": "The Team",
"index.html": "Traversing Art Through Its Connections"
}
app.directive("header", function() {
return {
restrict : 'E',
templateUrl : 'header.html'
};
});
app.directive("footer", function() {
return {
restrict : 'E',
templateUrl : 'footer.html'
};
});
app.controller('menuController', function($scope, $location, rememberService){
$scope.isActive = function(route){
return rememberService.getActualPage() === route;
};
});
app.controller('MainController', function(Page){
this.page = pages;
});
app.factory('rememberService', function($location) {
return {
getActualPage: function(){
var arr = $location.$$absUrl.split("/");
var pageName = arr[arr.length -1];
return pageName;
}
};
});
app.factory('Page', function(rememberService) {
return {
getTitle: function(){
return "neo4Art - "+ pages[rememberService.getActualPage()];
}
};
});
})();
To handle footer and header with Directives (< header>< /header>)
this is (part of) the code used to create the svg. I will only show you what I am interested in, the part that read the "on-field" measurements.
function Search(){
var width = $(".container-svg").width();
var height = $(".container-svg").height();
console.log("width:" + width + " - height:"+ height);
}
Before the use of angular I was using this in:
$(window).load(function(d) {
var search = new Search();
});
and all was going pretty well.
now using:
angular.element(window).load(function() {
var search = new Search();
});
I have a wrong height inside the var. It seems like the "new Search()" is called when the svg is still too high (the header is not yet rendered)
This is the html of the index (simplified)
<!DOCTYPE html>
<html lang="it-IT" ng-app="neo4art" ng-controller="MainController as mc">
<head>
<meta charset="utf-8">
<script src="resources/js/jquery/jquery-2.1.3.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<link rel="stylesheet" type="text/css" media="screen" href="resources/css/style.css" />
<link rel="stylesheet" type="text/css" media="screen" href="resources/css/style-index-new.css" />
<link rel="stylesheet" type="text/css" href="resources/css/font-awesome-4.3.0/css/font-awesome.min.css" />
<title>{{"neo4Art - " + mc.page["about.html"]}}</title>
</head>
<body>
<script type="text/javascript" src="resources/js/angular.min.js"></script>
<script type="text/javascript" src="resources/js/search.js"></script>
<script type="text/javascript" src="resources/js/neo4art.js"></script>
<div class="container-page scrollbar-macosx" when-ready="isReady()">
<div class="content-home">
<header></header>
<div class="text-home">
<svg class="container-svg">
</svg>
</div>
<div class="footer">
© 2015 neo4<span class="palette-dark-blue">A</span><span class="palette-blue">r</span><span class="palette-orange">t</span> - All
rights reserved <a href="//www.iubenda.com/privacy-policy/430975" class="iubenda-white iubenda-embed"
title="Privacy Policy">Privacy Policy</a>
</div>
</div>
</div>
</body>
</html>
This is the code of the header:
<div class="header">
<div class="logo">
<img src="resources/img/neo4art-logo-big.png" />
<div class="motto">Traversing Art through its connections</div>
</div>
<form method="get" action="graph.html" name="query">
<div class="menu">
<div class="search-bar-container">
<span class="icon"><i class="fa fa-search"></i></span><input type="search" id="search" placeholder="Search..." name="query" />
</div>
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>GENESIS</li>
<li>TEAM</li>
</ul>
</div>
</form>
</div>
Without angularjs it is rendered correct, with angular I have a wrong value like the image is not loaded at all.
I hope my question is clear enough, the problem I think is in when each function is called during the load of the page.
EDIT: It's strange also that sometimes the page is loaded correctly (random occurency)
AngularJS version 1.3.16
So you are having this weird cross road in understanding of angular. First lets talk about angular.element is not the same as a jquery element. You shouldn't be doing DOM manipulation from an element you create like that you should have a directive with a link function to make sure this is happening in the digest cycle when you want it to. This is a hard concept to get but I think the best example I can find is from this other question.
Angular.js: set element height on page load
This does a reasonable job of showing and explaining what we are talking about.
A simple trick to see if it's related to initialization of the page would be to wrap you measuring code in a setTimeout call and delay it for 500ms. If this fixes the measurement you'd have to go a search for the actual correct place to put your measuring code :-)
Hi i am trying to dynamically set some of the contents of an html5 body with var strings defined in a JS.
below is what i have written so far and it doesnt seem to display the value specified.
<link href="src/jquery.mobile-1.0.min.css" rel="stylesheet" type="text/css"/>
<script src="src/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="src/jquery.mobile-1.0.min.js" type="text/javascript"></script>
<body>
<script>
var name = "John Smith";
</script>
<div data-role="page" id="page">
<div data-role="header">
<button></button>
<h1>New Claim</h1>
</div>
<div data-role="content">
<ul data-role="listview">
<li> <p><h3>Your Name: <var>name</var></h3></p></li>
</ul>
</div>
<div data-role="footer">
<h4>Page Footer</h4>
</div>
</div>
</body>
i am trying to insert John Smith inside the "Your Name: text.
Thanks
You will have to use JavaScript to "print" the contents of a variable, to the HTML-source. Here's an example:
<div id="test"></div>
document.getElementById('test').innerHTML = 'This goes into the element!';
But since you're using jQuery, you could do this as well:
$('#test').text('This goes into the element!');
You should either give the VAR-Tag itself or it's wrapping LI-Tag an unique ID.
In HTML
<li>
<p>
<h3>Your Name: <var id="name">name</var></h3>
</p>
</li>
JavaScript
var name = "John Smith";
$("#name").text(name);
And by the way:
You shouldn't nest a Heading inside of a Paragraph, this doesn't make any sense.
Paragraphs are INLINE while Headings are BLOCKELEMENTS.
Check out this FIDDLE
You probably want something like below. Have global JS variables assigned, reference them with a VAR html5 tag, use JS at the end of body (or after DOM load) to substitute the keys in the VAR tags with the values held in the global VARS object.
<script>
VARS = {};
VARS.name = "John Smith";
VARS.age = 45;
</script>
...
Name : <var>name</var><br/>
Age : <var>age</var>
...
<script>
// run once at end of body
var all = document.getElementsByTagName("var");
for(var i=0; i<all.length; i++) {
var elm = all[i];
var key = elm.innerHTML;
if(VARS[key] != null)
elm.innerHTML = VARS[key];
else
elm.innerHTML = "";
}
</script>
The tag isn't supposed to be used this way
Try this:
<link href="src/jquery.mobile-1.0.min.css" rel="stylesheet" type="text/css"/>
<script src="src/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="src/jquery.mobile-1.0.min.js" type="text/javascript"></script>
<body>
<script>
var name = "John Smith";
$(document).ready(function() {
$("#name").text(name);
});
</script>
<div data-role="page" id="page">
<div data-role="header">
<button></button>
<h1>New Claim</h1>
</div>
<div data-role="content">
<ul data-role="listview">
<li> <p><h3>Your Name: <span id="name"></span></h3></p></li>
</ul>
</div>
<div data-role="footer">
<h4>Page Footer</h4>
</div>
</div>
</body>
Edit: just to clarify one thing. The tag isn't supposed to be used to hold the place to the value of a variable. It's correct semantic meaning is more to represent a mathematical variable or a programming variable when you are showing some code on your page. If I'm wrong here, please someone correct me.
try this
$(document).ready(function() {
$("h3").text("Your name : John Smith");
});
Add some classes on your divs, to easuly select the good tags
I've checked the other posts on this topic, but none of them match my problem. Here is the code for my template:
<script id ="postingcell" type="text/html">
<li class="postinglistcell">
<div class = "postinfowrapper">
<table class="centermargins">
<tr>
<td>
<div class="posttitle">{{Title}}</div>
</td>
</tr>
</table>
</div>
</li>
</script>
And here is the code where I call the ICH:
$(document).ready(function() {
var p = ich["postingcell"](thisobj);
});
I can get an error telling me that ich["postingcell"] is not defined, but it has been in the above script tag. Does anyone know what im doing wrong here?
ICanHaz also uses jQuery for setting up. One possible reason is your code runs before the ich.grabTemplates() call.
if (ich.$) {
ich.$(function () {
ich.grabTemplates();
});
}
You may try calling ich.grabTemplates() in your code:
$(document).ready(function() {
ich.grabTemplates();
var p = ich["postingcell"](thisobj);
});
I'm having a problem using knockout and a form and getting bindings to apply without throwing errors.
I would like to split the logic for the form into several view models but I'm getting errors with bindings in bars and foos not being found when I attempt to bind foobar
I've tried to display this in the example below.
Is there a way to achieve the desired behaviour? Is there a way to say combine all the bindings from the three view models then assign them to foobar?
bars_observable is a ko.observable created in the contructor of barViewModel.
<div id="foobar">
<form data-bind="with: newFooBar, submit: submitFooBar">
<section id="bars">
<div data-bind="text: bars_observable"></div>
</section>
<section id="foos">
foo stuff
</section>
</form>
</div>
<script type="text/javascript">
$(function () {
var foobarViewModel, fooViewModel, barViewModel;
foobarViewModel = new ViewModels.FoobarViewModel({
fooViewModel: new ViewModels.FooViewModel({}),
barViewModel: new ViewModels.BarViewModel({})
});
ko.applyBindings(foobarViewModel, document.getElementById("foobar"));
});
</script>
The error would be
"Uncaught Error: Unable to parse bindings. Message: ReferenceError: bars_observable is not defined;"
I would recommend to put fooViewModel and barViewModel objects into FoobarViewModel. In this case you have to call ko.applyBindings only once.
<div id="foobar">
<form data-bind="with: newFooBar, submit: submitFooBar">
<section id="bars" data-bind="with: barViewModel">
<div data-bind="text: bars_observable"></div>
</section>
<section id="foos" data-bind="with: forViewModel">
foo stuff
</section>
</form>
</div>
<script type="text/javascript">
$(function () {
var foobarViewModel = new ViewModels.FoobarViewModel({});
ko.applyBindings(foobarViewModel, document.getElementById("foobar"));
});
function ViewModels.FoobarViewModel() {
var self = this;
self.fooViewModel = new ViewModels.FooViewModel({});
self.barViewModel = new ViewModels.BarViewModel({});
...
}
</script>
If you are writing a modular system, creating a top level view model may not be possible. In knockout 2.0 you can tell knockout to stop parsing bindings at a certain point. Then you can call applyBindings again for the container. Here is an article which explains how to do it.
http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html