Backbone: getting the html code of a view? - javascript

In order to write the HTML code of social icons (Twitter, Linkedin, etc) to a textarea so that the user can use that code elsewhere, I would like to get the HTML code of the view element, but I'm having some issues. To help illustrate this better, here is the code that creates the view:
define(function(require, exports, module) {
var _ = require('underscore');
var GridControlView = require('pb/views/grid-control');
var SocialiconsControlDialog = require('pb/views/socialicons-control-dialog');
var template = require('text!pb/templates/socialicons-grid-control.html');
var SocialiconsGridControlView = GridControlView.extend({
template: _.template(template)
,templateVars: {
partials: {
facebook: require('text!pb/templates/socialicons-grid-control-facebook.html')
,twitter: require('text!pb/templates/socialicons-grid-control-twitter.html')
,googleplus: require('text!pb/templates/socialicons-grid-control-googleplus.html')
,pinterest: require('text!pb/templates/socialicons-grid-control-pinterest.html')
,linkedin: require('text!pb/templates/socialicons-grid-control-linkedin.html')
}
}
,control_dialog: SocialiconsControlDialog
});
return SocialiconsGridControlView;
});
And, for example, the Linkedin template looks like this:
<script src="//platform.linkedin.com/in.js?<%- t.cache_buster %>" type="text/javascript">lang: en_US</script>
<script type="IN/Share" data-counter="<%- t.linkedin_option_countmode %>"></script>
What I would like to retrieve, is the parsed template code as text, something such as:
<script type="text/javascript" src="//platform.linkedin.com/in.js?0.4670609195438331">
<script data-counter="top" type="IN/Share+init">
But using something such as:
control_view.render().$el.innerHTML;, control_view.render().$el.html().text() or control_view.render().$el.html().replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, ""); doesn't return text; it returns the full HTML, and produces a Linkedin icon (when I just want the text to be written to a textarea).
Any thoughts?
Update **
I noticed that the code control_view.render().$el is working correctly on other places of the application, and returning HTML code, but for some reason in this view where I'm trying it doesn't. The code seems to break at:
$control = control_view.render().el;
and in the console I get an error which is:
TypeError: t is undefined - underscore-min.js (line 3)

Use the .outerHTML property of the $el.
var html = $('<script type="text/javascript" src="//platform.linkedin.com/in.js?0.4670609195438331">' +
'<script data-counter="top" type="IN/Share+init">');
var text = html[0].outerHTML;
$('textarea').val(text);
jsFiddle

Related

Javascript: Use "new Function()" to run code in a string and have it access class definitions

My actual code is dense, so I'm trying to reduce this to a minimal example.
I have MainUI.js which contains:
var MainUI = function(){
'use strict';
var singleton = null;
class MainUI {
makeSomethingHappen(){
console.log("MAGIC!");
}
}
return {
getSingleton: function(){
if (singleton == null) singleton = new MainUI();
return singleton;
}
};
}();
Then I have test.js which contains:
function test(code){
var uis = MainUI.getSingleton();
retValue = new Function("ui", "use strict'" + code)(uis);
}
This is all run from index.html which contains:
<html>
<script type="text/javascript" src="MainUI.js"></script>
<script type="text/javascript" src="test.js"></script>
<body onload="test('ui.makeSomethingHappen();');">
</body>
</html>
But when I call
test("ui.makeSomethingHappen();");
or even
test("console.log('NARF!');");
I get an exception with the message
MainUI is not defined
The singleton accessor and the MainUI works in all my code outside of "new Function()", so I know it's working (even if I made typographical error producing the minimal test).
So I'm hoping someone can tell me how I can give the code inside the Function access to the class definitions outside.
Make sure that the MainUI.js script is referenced correctly and that it is referenced prior to the test.js script that will use it.

How to pass a java ArrayList of Strings to JavaScript [duplicate]

I am using Thymeleaf as template engine. How I pass a variable from Spring model to JavaScript variable?
Spring-side:
#RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("message", "hello");
return "index";
}
Client-side:
<script>
....
var m = ${message}; // not working
alert(m);
...
</script>
According to the official documentation:
<script th:inline="javascript">
/*<![CDATA[*/
var message = /*[[${message}]]*/ 'default';
console.log(message);
/*]]>*/
</script>
Thymeleaf 3 now:
Display a constant:
<script th:inline="javascript">
var MY_URL = /*[[${T(com.xyz.constants.Fruits).cheery}]]*/ "";
</script>
Display a variable:
var message = [[${message}]];
Or in a comment to have a valid JavaScript code when you open your template file in a static manner (without executing it at a server).
Thymeleaf calls this: JavaScript natural templates
var message = /*[[${message}]]*/ "";
Thymeleaf will ignore everything we have written after the comment and before the semicolon.
More info: http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#javascript-inlining
var message =/*[[${message}]]*/ 'defaultanyvalue';
According to the documentation there are several ways to do the inlining.
The right way you must choose based on the situation.
1) Simply put the variable from server to javascript :
<script th:inline="javascript">
/*<![CDATA[*/
var message = [[${message}]];
alert(message);
/*]]>*/
</script>
2) Combine javascript variables with server side variables, e.g. you need to create link for requesting inside the javascript:
<script th:inline="javascript">
/*<![CDATA[*/
function sampleGetByJquery(v) {
/*[+
var url = [[#{/my/get/url(var1=${#httpServletRequest.getParameter('var1')})}]]
+ "&var2="+v;
+]*/
$("#myPanel").load(url, function() {});
}
/*]]>*/
</script>
The one situation I can't resolve - then I need to pass javascript variable inside the Java method calling inside the template (it's impossible I guess).
MAKE sure you have thymleaf on page already
//Use this in java
#Controller
#RequestMapping("/showingTymleafTextInJavaScript")
public String thankYou(Model model){
model.addAttribute("showTextFromJavaController","dummy text");
return "showingTymleafTextInJavaScript";
}
//thymleaf page javascript page
<script>
var showtext = "[[${showTextFromJavaController}]]";
console.log(showtext);
</script>
I've seen this kind of thing work in the wild:
<input type="button" th:onclick="'javascript:getContactId(\'' + ${contact.id} + '\');'" />
If you use Thymeleaf 3:
<script th:inline="javascript">
var username = [[${session.user.name}]];
</script>
If you need to display your variable unescaped, use this format:
<script th:inline="javascript">
/*<![CDATA[*/
var message = /*[(${message})]*/ 'default';
/*]]>*/
</script>
Note the [( brackets which wrap the variable.
Another way to do it is to create a dynamic javascript returned by a java controller like it is written here in the thymeleaf forum: http://forum.thymeleaf.org/Can-I-use-th-inline-for-a-separate-javascript-file-td4025766.html
One way to handle this is to create a dynamic javascript file with the
URLs embedded in it. Here are the steps (if you are using Spring MVC)
#RequestMapping(path = {"/dynamic.js"}, method = RequestMethod.GET, produces = "application/javascript")
#ResponseStatus(value = HttpStatus.OK)
#ResponseBody
public String dynamicJS(HttpServletRequest request) {
return "Your javascript code....";
}
Assuming request attribute named "message":
request.setAttribute("message", "this is my message");
To read it in the html page using Thymeleaf template:
<script>
var message = "[[${message}]]";
alert(message);
</script>

Getting compiled html from template in AngularJS

I must confess that it's not easy to find some basic and easy to understand guide about compiling templates in AngularJS.
Here is the deal:
In my main html-page I have this:
<div>
<div data-ng-include="'./views/testTemplate.html'"></div>
</div>
<div>
<input type=button ng-click="func()" />
</div>
testTemplate.html contains this:
hello {{myname}}
Im my javascript-controller I have this:
$scope.myname = 'max';
Now, when I view the page I see the text "hello max".
Im my javascript-controller I also have this:
$scope.func = function(){
var newScope = $scope.$new();
var newElem = '<ng-src><div ng-include="\'./views/testTemplate.html\'" ></div></ng-src>';
$compile(newElem)(newScope);
console.log('newElem');
console.log(newElem);
});
In the console I can see this:
newElem
<ng-src><div ng-include="'./views/testTemplate.html'" ></div></ng-src>
So, the template is not getting compiled? What am I missing?
***************EDIT***************
The thing is that Im trying to print to console the content of the new element because it needs to be mailed. So I need to send a mail with the compiled content from the template.
Having looked at the answers below, I now have this:
var newElem = '<ng-src><div ng-include="\'./views/testTemplate.html\'" ></div></ng-src>';
var compiledElem = $compile(newElem)(newScope);
console.log('compiledElem[0]');
console.log(compiledElem[0]);
If I use this:
$window.location.href = 'mailto:mailmail.com?subject=sub&body=' + compiledElem[0].innerHTML;
then the body of the mail contains this (uncompiled template):
<!-- ngInclude: './views/matching/testTemplate.html' -->
If I use this:
$window.location.href = 'mailto:mailmail.com?subject=sub&body=' + compiledElem[0];
then the body of the mail contains this:
[object HTMLElement]
So none of them is showing the html-content in the mail I want to send. I know its not exactly the original question, but it was a part of the issue.
I think the variable 'newElem' is not modified by the $compile command. It has a return value which you should use.
var compiledElement = $compile(newElem)(newScope);
console.log('compiledElement');
console.log(compiledElement);
You are missing adding your HTML to the DOM.
$scope.func = function(){
var newScope = $scope.$new();
var newElem = '<ng-src><div ng-include="\'./views/testTemplate.html\'" ></div></ng-src>';
//Append to DOM
document.querySelector('#some-id').append($compile(newElem)(newScope));
console.log('newElem');
console.log(newElem);
});
In my example I'm using document.querySelector that is raw js. But we can use the $element service, or if we are in a directive's link function, it receives a param representing the current element where the directive is being applied.
EDIT:
If you want to send your compiled HTML in an email, then, you will need to wait until all the $digest finish to compile your template.
$scope.func = function(){
var newScope = $scope.$new();
var newElem = angular.element('<ng-src><div ng-include="\'./views/testTemplate.html\'" ></div></ng-src>');
$compile(newElem)(newScope);
$timeout(function(){
$window.location.href = 'mailto:mailmail.com?subject=sub&body=' + newElem.html();
//console.log('newElem');
//console.log(newElem.html());
});
});
Create your template using angular.element, use $timeout to wait until the end and then use newElem.html();.

Google prettify plugin on IE browser not working

I am using Google Prettify to generate a JavaScript document preview.
The plugin works in Chrome (if I refresh the page 2 to 3 times), but not in IE9 and IE11.
Due to dynamic rendering, I can't set onload="prettyPrint();" on my body tag, so I am using
<script>window.onload = prettyPrint </script>
I also tried this, with the same result
<script>
$(document).ready(function () {
prettyPrint()
});
</script>
I tried to debug run_prettify.js but it says undefined
var prettyPrint;
Here is the documentation
calling js file in end of body.
<script src="${url.context}/res/components/preview/code-prettify-master/prettify.js?autoload=true&lang=css'" />
<script src="${url.context}/res/components/preview/code-prettify-master/run_prettify.js" />
<script src="${url.context}/res/components/preview/code-prettify-master/lang-css.js" />
this is the code, where i am generating <pre> tags
var resultDiv = YAHOO.util.Dom.getElementsByClassName("previewer CodePrettifyMaster")[0];
var preDiv = document.createElement('pre');
preDiv.id = this.wp.id + '_prettify';
preDiv.className = "prettyprint lang-scm linenums";
var ganttContentDiv = document.createElement('div');
ganttContentDiv.id = 'contentContainer';
ganttContentDiv.appendChild(preDiv);
resultDiv.appendChild(ganttContentDiv);

Generate javascript file on the fly in asp.net mvc

Friends,
I am trying to use DyGraph in my application. Please look at the code below -
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
<title>crosshairs</title>
<script type="text/javascript" src="dygraph-combined.js"></script>
<script type="text/javascript" src="data.js"></script>
</head>
The code uses data.js file containing function to get some static data.
I want data.js to be generated using a controller method so that it will generate data using database.
Can anybody help me out to resolve this issue.
Thanks for sharing your valuable time.
You could define a controller action:
public ActionResult Data()
{
// Obviously this will be dynamically generated
var data = "alert('Hello World');";
return JavaScript(data);
}
and then:
<script type="text/javascript" src="<%= Url.Action("Data", "SomeController") %>"></script>
If you have some complex script that you don't want to generate in the controller you could follow the standard MVC pattern by defining a view model:
public class MyViewModel
{
... put required properties
}
a controller action which would populate this view model and pass it to the view:
public ActionResult Data()
{
MyViewModel model = ...
Response.ContentType = "application/javascript";
return PartialView(model);
}
and finally a view which in this case will be the javascript representation of the view model (~/Views/SomeController/Data.ascx):
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<MyViewModel>" %>
alert(<%= new JavaScriptSerializer().Serialize(Model.Name) %>);
Full Disclosure
This answer is copy/pasted from another question:
Dynamically generated Javascript, CSS in ASP.NET MVC
This answer is similar to other answers here.
This answer uses cshtml pages rather than ascx controls.
This answer offers a View-Only solution rather than a Controller-Only solution.
I don't think my answer is 'better' but I think it might be easier for some.
Dynamic CSS in a CSHTML File
I use CSS comments /* */ to comment out a new <style> tag and then I return; before the closing style tag:
/*<style type="text/css">/* */
CSS GOES HERE
#{return;}</style>
Dynamic JS in a CSHTML File
I use JavaScript comments // to comment out a new <script> tag and then I return; before the closing script tag:
//<script type="text/javascript">
JAVASCRIPT GOES HERE
#{return;}</script>
MyDynamicCss.cshtml
#{
var fieldList = new List<string>();
fieldList.Add("field1");
fieldList.Add("field2");
}
/*<style type="text/css">/* */
#foreach (var field in fieldList) {<text>
input[name="#field"]
, select[name="#field"]
{
background-color: #bbb;
color: #6f6f6f;
}
</text>}
#{return;}</style>
MyDynamicJavsScript.cshtml
#{
var fieldList = new List<string>();
fieldList.Add("field1");
fieldList.Add("field2");
fieldArray = string.Join(",", fieldList);
}
//<script type="text/javascript">
$(document).ready(function () {
var fieldList = "#Html.Raw(fieldArray)";
var fieldArray = fieldList.split(',');
var arrayLength = fieldArray.length;
var selector = '';
for (var i = 0; i < arrayLength; i++) {
var field = fieldArray[i];
selector += (selector == '' ? '' : ',')
+ 'input[name="' + field + '"]'
+ ',select[name="' + field + '"]';
}
$(selector).attr('disabled', 'disabled');
$(selector).addClass('disabled');
});
#{return;}</script>
No Controller Required (using Views/Shared)
I put both of my dynamic scripts into Views/Shared/ and I can easily embed them into any existing page (or in _Layout.cshtml) using the following code:
<style type="text/css">#Html.Partial("MyDynamicCss")</style>
<script type="text/javascript">#Html.Partial("MyDynamicJavaScript")</script>
Using a Controller (optional)
If you prefer you may create a controller e.g.
<link rel="stylesheet" type="text/css" href="#Url.Action("MyDynamicCss", "MyDynamicCode")">
<script type="text/javascript" src="#Url.Action("MyDynamicJavaScript", "MyDynamicCode")"></script>
Here's what the controller might look like
MyDynamicCodeController.cs (optional)
[HttpGet]
public ActionResult MyDynamicCss()
{
Response.ContentType = "text/css";
return View();
}
[HttpGet]
public ActionResult MyDynamicJavaScript()
{
Response.ContentType = "application/javascript";
return View();
}
Notes
The controller version is not tested. I just typed that off the top of my head.
After re-reading my answer, it occurs to me it might be just as easy to comment out the closing tags rather than use the cshtml #{return;}, but I haven't tried it. I imagine it's a matter of preference.
Concerning my entire answer, if you find any syntax errors or improvements please let me know.

Categories

Resources