Underscore/jQuery template comments issue - javascript

I have this strange issue with _.template (or jQuery (or my knowlege of both)). I use Underscore to render templates and jQuery to append elements to DOM (and lots of other things).
Like this:
var $section = $(this.tmpl.section(data));
Everything works great, however when I add a html comment inside template html, like
<script id="section-template" type="text/template">
<!-- Section panel -->
<div class="panel section-panel panel-info section-<%= type %>" data-type="<%= type %>" data-layout="<%= layout %>">
<div class="panel-heading section-handle">
<h3 class="panel-title"><%= title %></h3>
</div>
<div class="panel-body"></div>
</div>
</script>
I receive an array of objects. I am probably missing some basic stuff here, but is this the way jQuery supposed to work given this html on input? I thought it's supposed to ignore comments.

I dont know if this can work for you, but I use the same tools on this way:
In my frontpage (a index.html page usually) I make a reference to my template
<script type="text/html" id="desktop" src="partials/desktop.html"></script>
<script src="js/app.min.js"></script>
Then in my main script (a app.min.js) I load the template this way:
$.get($("#desktop").attr("src"), function (res)
{
var template = res;
$("body").html(_.template(template));
}

Related

Angular ng-repeat, Jquery fail

So I am using ng-repeat to repeat some divs which show images out of my JSON file. What I want to do is that when I click on that image (whether its desktop or mobile) the image will scale. Now my problem is that when I want to create a click event on my image tag (which is inside that div that holds the ng-repeat), he doesn't do anything. He cant see the click.
I red something on the internet about issues with jquery and angular, but for me as a beginner its hard to understand what I have to do to make it work how I pleased. I just want to be able to put a jquery function on a image tag inside the ng-repeated divs, so I can manipulate the css from there.
I have a piece of the code posted below here, maybe I have to add something to my controller? I dont know, I am clueless at the moment. :-)
<section class="words">
<div class="colored-sidebar"></div>
<!-- content -->
<div class="previous-button"></div>
<div class="word-container" ng-controller="imageController as imageCtrl">
<h1><span>noun</span>words</h1>
<div class="category-body">
<p><span>noun</span>travel</p><hr>
<div class="category-section" ng-repeat="icon in imageCtrl.imageList.travel">
<!-- <div class="category-image" ng-include="icon.src"></div> -->
<div class="category-image">
<img src="{{icon.src}}" />
</div>
</div>
</div>
</section>
The angular file
(function() {
app.controller('imageController', function(){
this.imageList = imageJson;
});
var imageJson = {
//ALOT OF JSON DATA HERE//
};
})();
I hope this piece of code would be enough to help me :-)
Any tips are welcome, I love to learn this language better and also understand it better.
Thanks!
jQuery is not suitable here, because by the time you run your jQuery code inside jQuery.ready(), the elements in "category-image" class are not created yet.
For solution of your problem you can use two methods:
1) Use the "ng-click", as proposed before. You can also pass "$index" to function inside ng-click. This way you will know index of icon in imageList.travel that was clicked. But this way you will have no information about dom element.
2) Create a directive. The main difference between directives and controllers is that directive have information about dom object. You can treat element as typical jQuery object
JS:
app.directive('imageClick', [function () {
return {
link: function (scope, element, attr) {
element.on("click", function(e){
//do some stuff here
})
}
}
}]);
HTML
<section class="words">
<div class="colored-sidebar"></div>
<!-- content -->
<div class="previous-button"></div>
<div class="word-container" ng-controller="imageController as imageCtrl">
<h1><span>noun</span>words</h1>
<div class="category-body">
<p><span>noun</span>travel</p><hr>
<div class="category-section" ng-repeat="icon in imageCtrl.imageList.travel">
<!-- <div class="category-image" ng-include="icon.src"></div> -->
<div class="category-image">
<img image-click src="{{icon.src}}" />
</div>
</div>
</div>
</section>

How to change static text in a web page using inner html?

I have some text in a website that I want to change using javascript because I can't change it any other way.
In short, the site is laid out like such:
...some other divs before here, body, head, etc...
<div id="header" class="container-fluid clearfix">
<div class = "hero-unit">
<h1 class="title">Support Center</h1>
...some other divs for other parts of the page...
</div>
</div>
...more divs, footer, etc...
I don't need the text to change on click or anything like that I just want it to be set on load to something different than Support Center but I'm not sure if I'm placing the script in the correct place or if the syntax is wrong?
I've tried placing it before and after and it doesn't seem to work. Here is the code:
<script type="text/javascript">
var targetDiv = document.getElementByID("header").getElementsByClassName("hero-unit")[0].getElementsByClassName("title")[0];
targetDiv.innerHTML = "Please use the Knowledge Base to find answers to the most frequently asked questions or you may submit a support ticket which will be sent to your COM email account.";
</script>
Thank you.
Looking at the actual source of your page, your page does not contain a h1 element with a class of title.
Your actual source code
<div id="header" class="container-fluid clearfix">
<div class="hero-unit"></div>
<div class="container-fluid clearfix">
<div class="row-fluid">
<div class="leftcolumn"></div>
<div class="rightcolumn"></div>
</div>
</div>
</div>
This means it does not exist till some point after your page loads. You need to put your code after the code that generates the h1 title element
In jQuery (if you can use it), you'd use something like
$("#title").text("Something else");
it looks like you are not getting the specific class to change the html
try with querySelector like i have done
JS Fiddle
var targetDiv = document.querySelector('#header > .hero-unit > h1.title')
targetDiv.innerHTML = "Please use the Knowledge Base to find answers to the most frequently asked questions or you may submit a support ticket which will be sent to your COM email account.";

Angular template within template

Lets see if I can describe my setup here...
I'm designing an angular app, as of now everything is all one page. Basically, when the user clicks a button, the controller sets which
"<ng-include>"
tag is visible. So my html looks something like this.
<html ng-app= "myApp">
<head>
<!-- header stuff -->
<!-- all the includes and everything -->
</head>
<body>
<div>
<!-- page nav bar, its a lot of html but it works -->
</div>
<!-- content area -->
<div ng-show= "showHome">
<ng-include= "home.html">
</div>
<div ng-show= "showProfile">
<ng-include= "profile.html">
</div>
<!-- etc... -->
</body>
</html>
And then in my controller, I'm just setting the proper "showHome", "showProfile", etc... as appropriate. My question is, this seems like a terrible way to scale, and this is my first attempt at an app like this.
So to reiterate. I want to give the user the appearance of a single page app, while swapping in html templates. Any ideas? Multiple pages would be ok, but I want to keep the same navbar at the top of every page.
I'd use ui-router instead.
It is a popular alternative for ngRoute and supports nested templates really well.

Initiating same angularjs app in two places

I have a html template that is being used for multiple projects. In that template I have two places where I can set the content.
The layout is something similar to this:
<body>
<div>Navbar from TEMPLATE</div>
<div>
<div>other TEMPLATE stuff</div>
<div id="content1">CONTENT can be set here</div>
</div>
<div id="content2">CONTENT can also be set here</div>
</body>
My question is is it possible to use the same angular app in both #content1 and #content2? Can the ng-app="main" be used twice?
If something like this isn't possible to do I can add an ng-app attribute to the template but would rather not have to do this as, as I said, the template is used for multiple projects a lot of which won't be using angular.
Edit:
Just to clarify, I'm using a tal template from zope. In that template I have two fill slots, I would like to use the same angular app in both fill slots without having to change the original tal template if possible.

Javascript: Dynamically created html elements referencing an instantiated object

(For further background, this relates to the same piece of work as a previous question)
I'm creating a JavaScript based webchat system using jQuery to make life much easier. All the webchat JavaScript code is in an external js file, which is then referenced and instantiated by the html page.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>WebchatV3</title>
<script type="text/javascript" src="/JavaScript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="WebchatV3.js"></script>
<link rel="stylesheet" href="WebchatV3.css" />
</head>
<body>
<div id="WebchatSurround">
<div style="float:right;width:300px;">
<div id="MembersBox">
Members
<ul id="MembersList">
</ul>
</div>
<div id="QuestionsBox">
Questions
<div id="QuestionsList">
</div>
</div>
</div>
<div style="margin-right:310px;" id="ChatBox">
<div id="ChatData">
<ul id="ChatDataList"></ul>
</div>
<div id="ChatInput">
<div id="ChatInputCharRemainText">Characters remaining <span id="ChatInputCharRemain"></span></div>
<input type="text" maxlength="1000" id="ChatInputTextbox" />
</div>
</div>
</div>
<script type="text/javascript">
var webchat;
webchat = new AvonAndSomerset.WebchatV3(123, 'passcode', false);
</script>
</body>
</html>
In the JavaScript there is code to dynamically create a list of active chat members from a JSON query. This code creates a series of html DIVs and then injects this html into the 'QuestionsList' DIV present in the html.
Now here's the question :)
Within each question are elements with JavaScript onclick events that allows actions to be taken against the question shown. How can I create the onclick code without hard coding the reference to 'webchat' - is there an elegent and acceptable way?
My initial thoughts are to pass in the instance name of the 'webchat' instance when it's created, so it can then be used inside the JavaScript when creating dynamic JavaScript...
Example of code with hard coded reference to instantited 'webchat':
<div id="QuestionsBox">
Questions
<div id="QuestionsList">
<div class="Question">
<div class="QuestionInnerControls">
<img src="images/arrow_up.png" alt="" class="ControlIcon" onclick="webchat.Questions.Move(1,1);" >
<img src="images/arrow_down.png" alt="" class="ControlIcon" onclick="webchat.Questions.Move(1,-1);">
<img src="images/delete.png" alt="" class="ControlIcon" onclick="webchat.Questions.Delete(1);">
</div>
<div class="QuestionInnerText">
1) <b>Peter Bridger</b>: This is the question text
<br style="clear: right;">
</div>
</div>
</div>
</div>
While I think the live idea will most likely work for you, my initial thought was to create a template div in the initial stages of the code, and then use the clone(true) method to create dynamic copies of the template and its methods. Then within the javascript "loop" each copy could be customised as needed before being appended into the DOM.
http://docs.jquery.com/Manipulation/clone#bool
Your description is a bit in depth and I hope that I am following it correctly but it seems to me that you are trying to attach a click event(s) to all of the items as well as all of the items that will be created in the future. Rather than specifying the onclick event when creating the you should use the new jQuery feature that came out in jQuery 1.3+ that allows you to specify an event for every element that matches the Selector... even future elements like the ones you will be adding via json.
$("p").live("click", function(){
$(this).after("<p>Another paragraph!</p>");
});
http://docs.jquery.com/Events/live
Thanks for your input everyone, I've decided to pass in the instance name of the Webchat when instancing it:
var webchat;
webchat = new AvonAndSomerset.WebchatV3(123, 'passcode', false , 'webchat' );
Then inside the JavaScript I'm referencing the passed in referenced when dynamically building html with JavaScript in it:
onclick="' + this.instanceName + '.popupMemberDetailsShow(' + this.Members.collection[i].memberId + ');

Categories