I am attempting to build a site using angularJS and symfony, and in my site
I want to add a simple Facebook comments box and twitter timeline shown here, respectively:
https://developers.facebook.com/docs/reference/plugins/comments/
https://twitter.com/settings/widgets/370693822461657088/edit?focus_textarea=1¬ice=WIDGET_CREATED
in my JavaScript i have set up angular routing which routes the user to different views, but the problem is the comments box and twitter timeline don't show up in these views.
They DO however, work perfectly fine when they are placed outside of the ng-view tags.
Here is a VERY simplified code snippet of my problem:
<html ng-app="myApp">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block custom_stylesheets %}
{% endblock %}
</head>
<body>
{% block body %}
<div id = "container">
<!-- twitter and facebook work outside of here -->
<div ng-view>
<!-- but not in here -->
</div>
</div>
{% endblock %}
{% block custom_javascripts %}
{% endblock %}
</body>
</html>
Is there something specific i need to do to get twitter/facebook working?
it seems as if the javascript is broken, the twitter feed still displays a "tweets by #google" link
You need directives because the JavaScript needs to execute whenever some set of DOM elements is present:
(function() {
var createDirective, module, pluginName, _i, _len, _ref;
module = angular.module('FacebookPluginDirectives', []);
createDirective = function(name) {
return module.directive(name, function() {
return {
restrict: 'C',
link: function(scope, element, attributes) {
return typeof FB !== "undefined" && FB !== null ? FB.XFBML.parse(element.parent()[0]) : void 0;
}
};
});
};
_ref = ['fbActivity', 'fbComments', 'fbFacepile', 'fbLike', 'fbLikeBox', 'fbLiveStream', 'fbLoginButton', 'fbName', 'fbProfilePic', 'fbRecommendations'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
pluginName = _ref[_i];
createDirective(pluginName);
}
}).call(this);
I found this one on the internets that handles the Facebook one's in a pretty simple way I believe the definition even stays the same as the original usage, you just do something like:
<div class="fb-comments" data-href="http://pyramidplayersproductions.org" data-width="292" data-num-posts="10"></div><br/>
<div class="fb-like-box" data-href="http://www.facebook.com/pyramidplayersproductions" data-width="292" data-show-faces="true" data-stream="true" data-show-border="true" data-header="true"></div>
You'll still have to roll your own for the twitter feed (or search google for Angular twitter directive and see what surfaces). If nothing does the general formula for building a directive will be:
angular.module("customDirectives", []).directive("myTwitterDirective", function() {
return {
//C means class E means element A means attribute, this is where this directive should be found
restrict: 'E',
link: function(scope, element, attributes) {
//do javascript you need to here to get data or initialize
//twitter. you can access the dom element using element[0]
//element is the angular wrapped element object attributes
//has any HTML attributes like attribute.myAttribute would be 'something if <my-twitter-directive myAttribute='something'>
}
};
});
//probably in another file
angular.module("mainApp", ["customDirectives"]);
Usage would look like:
<my-twitter-directive></my-twitter-directive>
Wrapping this stuff up in a directive keeps the DOM manipulation code out of the services or controllers (and presentation) code, keeping all of them easily testable without the need for an actual browser or dependencies on the view.
I decided to follow my own advice above and I think I'm right:
http://jsfiddle.net/MPnES/
The JS
angular.module("mainApp", []).directive("twitterTimeline", function() {
return {
//C means class E means element A means attribute, this is where this directive should be found
restrict: 'C',
link: function(scope, element, attributes) {
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
}
};
});
The HTML
<body ng-app="mainApp">
<a class="twitter-timeline" href="https://twitter.com/pattonoswalt" data-widget-id="370757361348014081">
Tweets by #pattonoswalt
</a>
</body>
Related
Is it possible for me to write one shortcode, and it would trigger several others?
Let's say I have shorcode using njk:
{% card %}
inside, let's say the following code:
eleventyConfig.addNunjucksShortcode("card", function() {
return `
<div class="card">
</div>
`
});
And I have another shortcode:
{% img "path-to-img.jpg" %}.
It has an img src parameter, and will render to some img.
eleventyConfig.addNunjucksShortcode("img", function(path) {
return `
<img src="${path}">
`
});
I need that when I call the card shortcode, it called the img shortcode and passed the parameter to it.Let's say that I write:
{% card 'path-to-img.jpg' %}
And it will render at:
<div class="card">
<img src="path-to-img.jpg">
</div
Just in case, I need to call one shortcode, paired and nested shortcodes will not suit me:
{% column %}
{% img 'path-to-img.jpg' %}
{% endcolumn %}
While not really a 'shortcode calling a shortcode', I'd take the logic of img and abstract it into a method. Have the img shortcode call that to handle it's logic, and then card call the abstracted out method to get it's HTML result as well. Let me know if that doesn't make sense.
I got this way (there is not a img, but the meaning is the same):
eleventyConfig.addNunjucksShortcode("inner", function() {
return `<div class="inner">`;
});
eleventyConfig.addNunjucksShortcode("endinner", function() {
return `</div>`;
});
eleventyConfig.addShortcode("card", function(text) {
return `<div class="card">
${eleventyConfig.nunjucksShortcodes.inner()}
${text}
${eleventyConfig.nunjucksShortcodes.endinner()}
</div>`;
});
And call it:
{% card "text" %}
IziModal is beautiful but Jquery selectors cannot see or find the modal elements it hides. So this code: var nextmodal = $(this).next('.izra'); $(nextmodal).iziModal('open'); , which can see any div hidden by display:none, can find any element EXCEPT divs hidden by Izimodal.
https://jsfiddle.net/zmbth7u9/4/ (Stack code snippet below)
Izimodal can find its own hidden div with class .izra but no Jquery selector can?
I've tried everything including div: $(this).next($(":hidden:first"));
console.log($(hiddenstuff))
The above code SKIPS OVER the Izimodal hidden div and finds the second!
I need to activate modals with generic classes repeated throughout documents for footnotes, saving code, markup and time.
Any idea how I can get Jquery selectors to find the div with the .izra class so I can act on it?
Since we cannot find siblings because IziModal hides them beyond reach, perhaps modal divs should begin without the .izra class (set to display:none by css) and dynamically add the .izra modal class upon hitting the click trigger? We could find the divs first with next(), then add the izra class, or would that put us back at square one?
Thank you!
https://jsfiddle.net/zmbth7u9/4/ The modal and finding divs in this fiddle works, and shows the lines that inexplicably don't work.
//How things should Work generically
$('.generictrigger').click(function () {
var nextmodal = $(this).next('.genericmodal');
$(nextmodal).modal('show');
});
//IziModal Initialize and fire on open
$(function () {
$(".izra").iziModal();
$('.izra').iziModal('open'); // This works!
});
//Proof hidden divs easily found when NOT hidden by IziModal
$(".trigger2").click(function () {
var hiddenstuff = $(this).next($(":hidden:first")); // This works!
console.log($(hiddenstuff))
});
//Proof IziModal divs cannot be found by Jquery selectors
$(document).on('click', '.trigger', function (event) {
event.preventDefault();
// $('.izra').iziModal('open'); // THIS WORKS!
var nextmodal = $(this).next('.izra'); // Should work but does not
console.log($(nextmodal));
$(nextmodal).modal('open'); // Should work but does not <<<<<<
});
.hidden { display: none; }
.c1 { background-color:#33ccff; }
.c2 { background-color:#ffff99; }
.c3 { background-color:#80ff80; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/izimodal/1.5.1/css/iziModal.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/izimodal/1.5.1/js/iziModal.js"></script>
<!-- Finding divs hidden by IziModal Begin -->
<!-- How things should generically work calling Next() -->
<div class="containerdivforchildren">
<div class="c1 generictrigger">Click for Generic Modal FOUND by NEXT Selector </div>
<div class="genericmodal modal fade modal-body modal-content"><a title="Close"><i data-dismiss="modal" class="glyphicon glyphicon-remove icon-arrow-right pull-left"></i></a>Generic Bootstrap Modal</div>
</div>
<!-- This section proves any div can be found EXCEPT divs touched by IziModal -->
<div class="modaltriggercontainer">
<div class="trigger2 c3">Click to Log var hiddenstuff = $(this).next($(":hidden:first"));to console</div>
<div class="trigger c2">Click to Open Izra (will fail but logs results of $(this).next() to console</div>
<div class="izra">Unretrievable modal div when hidden by IziModal class</div>
<!--Above DIV IS SKIPPED AND CANNOT BE FOUND!-->
<div id="incognito" class="c1 oddlynamed hidden">hidden by style but found using $(this).next()</div>
</div>
<!-- Above div is the first div found by any selector looking for the .next()-->
I have created a Tumblr blog that shows photos of my interest. I am looking to have my tumblr photo posts to be displayed in random order such that every-time the page is loaded, the order of posts in my grid theme is randomly shown. This way everyone can see all my posts without scrolling.
Does anyone know a code that I can simply insert to my theme so that posts are shown in random order and be shown in random order every time the page loads.
I am not entirely familiar with Tumbler, but I am willing to bet there is a unique class name for those image blocks. You can insert JavaScript on Tumbler as well. see: http://www.problogtricks.com/2013/12/add-custom-css-javascript-code-to-tumblr-blog.html
That said, randomizing elements with JavaScript is super easy. Here is a demo of how that is done. After identifying a unique classname that applies only to those elements, you can change the parameter inside the JavaScript function below.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style>
.putauniqueclassnamehere{
}
</style>
<script src="jquery-1.11.2.min.js"></script>
<script>
$(document).ready(function (name) {
return function () {
var max = $(name).length;
$.each($(name), function (p1, p2) {
var randPos = Math.floor(Math.random() * (max - 0 + 1) + 0);
$(p2).insertBefore($(name)[randPos]);
})
return ;
}
}(".putauniqueclassnamehere"))
</script>
</head>
<body>
<div class="mytest">Test 1</div>
<div class="mytest">Test 2</div>
<div class="mytest">Test 3</div>
<div class="mytest">Test 4</div>
<div class="mytest">Test 5</div>
</body>
</html>
Just paste this at the end of your theme:
{block:IndexPage}
<script>
$(document).ready(function (name) {
return function () {
var elts = $(name);
var max = elts.length;
$.each(elts, function (index, elt) {
var randPos = Math.floor(Math.random() * (max - 0 + 1) + 0);
$(elt).insertBefore(elts[randPos]);
})
return ;
}
}(".entry"))
</script>
{/block:IndexPage}
All the credit goes to Joshua Dannemann. I just pasted the relevant part of the code with the class to use with my theme: entry. It could be post or something else. Post a link to your tumblr and I can help you some more.
Edits:
renamed p1 and p2
added {block:IndexPage} and {/block:IndexPage} tags (without them, post pages are broken)
Normally, when a template uses inheritance, it's possible to render the contents of parent template. For example, in Twig:
{% extends "base.html" %}
{% block sidebar %}
{{ parent() }}
...
{% endblock %}
It means that if I sometimes don't need the contents of parent template, I just simply remove the parent() function. How can I achieve this in Scala template?
You can create a HTML block in child view first and then pass it to parent (layout):
#sidebar = {
<div>MySidebar</div>
}
#parent(sidebar){
<div>Main content of the child view</div>
}
So in parent.scala.html layout you will use it just like
#(sidebar: Html = null)(content: Html)
<div id="parent-wrap">
#sidebar
#content
</div>
Of course if you gonna to use the same HTML code for many subpages you'll do better if you use a tag instead of declaring #sidebar block in each view. Remember that tag is nothing more then just a scala view (template) and you can include it as any other view. Just create a normal view in app/views/tags i.e.: sidebar.scala.html with required HTML block, so you can later use it somewhere like:
<div class="span3">#tags.sidebar("content to pass")</div>
or as a block passed to higher level layout, etc :
#parent(tags.sidebar(additionalContent)){
<div>Main content of the child view</div>
}
TBH I never knew what's the difference between including views and tags ;)
Well, views are just functions in play. You cannot inherit them, but you can easily define reusable blocks:
#parent() = {
...
}
And then reuse it anywhere:
<div ....sidebar>
#parent()
</div>
The working example would look like this:
base.scala.html
#(title: String)(content: Html)
<html>
<head><title>#title</title></head>
<body>
<div class=...>#content</div>
</body>
</html>
index.scala.html
#(someParam: String)
#base("index") {
<h1>#someParam</h1>
}
If you don't need your index page to share the base's behaviour - just don't use #base:
index.scala.html
#(someParam: String)
...some other content
#someParam
...more content
Like this:
parent.scala.html
#(title: String)(content: (() => Html) => Html) {
<div class="parent">
<h2>#title</h2>
#content { () =>
<p>This is the parents optional contribution to the sidebar.</p>
}
</div>
child.scala.html
#parent("Some title") { parentSidebar =>
<p>Blah blah blah.</p>
<div class="sidebar">
...
#parentSidebar()
</div>
}
So the parent takes a function that takes a function that returns HTML.
I am using the DurandalJS framework for my PHP web application. I am exploiting DurandalJS framework features for showing modal views.
I have a homepage, home.html which contains a link to a page called, autocomplete.html. When this link is clicked, it opens the autocomplete.html page inside a modal view (a feature provided by DurandalJS).
I am also using the jQuery-UI autocomplete feature to create an autocomplete for a textbox. When a user types anything into the textbox, he gets a list of suggestions based on the characters he enters through the keyboard.
The problem here is that the autocomplete feature works if the autocomplete.html page is run independently in the browser. However, this feature doesn't run when the page is shown in the modal i.e. by running (navigating) the project through the DurandalJS framework.
Can anyone please tell me where exactly am I going wrong? Replies at the earliest will be highly appreciated.
The source code for my project is given below. Please note that the order in which I have provided the source code is in the same order in which the DurandalJS navigation call stack is executed. The flow of my application is, index.php >>> main.js >>> shell.js >>> shell.html >>> home.js >>> home.html >>> autocomplete.js >>> autocomplete.html.
The autocomplete.js >>> autocomplete.html call stack is executed when the user clicks on the Go to Autocomplete link on the home.html page.
main.js
require.config({
paths: {
'text': 'durandal/amd/text'
}
});
define(function (require) {
var app = require('durandal/app'),
viewLocator = require('durandal/viewLocator'),
system = require('durandal/system'),
router = require('durandal/plugins/router');
//>>excludeStart("build", true);
system.debug(true);
//>>excludeEnd("build");
app.start().then(function () {
//The following statement is to help DurandalJS to find files only according to their names.
//Replace 'viewmodels' in the moduleId with 'views' to locate the view.
//Look for partial views in a 'views' folder in the root.
viewLocator.useConvention();
//configure routing
router.useConvention();
router.mapNav("pages/home");
router.mapNav("pages/autocomplete");
app.adaptToDevice();
//Show the app by setting the root view model for our application with a transition.
app.setRoot('viewmodels/shell', 'entrance');
});
});
shell.js
define(function (require) {
var router = require('durandal/plugins/router');
return {
router: router,
activate: function () {
return router.activate('pages/home');
}
};
});
shell.html
<br />
<br />
<br />
<br />
<div class="container-fluid page-host">
<!--ko compose: {
model: router.activeItem, //wiring the router
afterCompose: router.afterCompose, //wiring the router
transition:'entrance', //use the 'entrance' transition when switching views
cacheViews:true //telling composition to keep views in the dom, and reuse them (only a good idea with singleton view models)
}--><!--/ko-->
</div>
home.js
// JavaScript Document
//This file loads the respective page's ViewModel (<Page>.js) and displays the View (<page>.html)
define(function (require) {
self.app = require('durandal/app');
return {
movies: ko.observable(),
activate: function() {
var self = this;
//The following code in the function creates a modal view for the autocomplete page
self.viewAutoCompleteModal = function(AutoComplete, element) {
app.showModal("viewmodels/pages/autocomplete");
};
}
};
});
home.html
<div id="applicationHost">
<div class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<div class="container">
<a class="brand">
<span>My application</span>
</a>
</div>
</div>
</div>
</div>
<!--The following lines of code create href links for the My Application pages and directs the DurandalJS to the respective pages. The data-bind attribute calls the view<Page>Modal functions (which create a Modal view) which is defined in the ViewModel (<Page>.js file)-->
<br />
<br />
Go to Autocomplete
autocomplete.js
// JavaScript Document
define(function (require) {
var router = require('durandal/plugins/router');
var moviesRepository = require("repositories/moviesRepository");
return {
activate: function (context) {
}
};
});
autocomplete.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<title>jQuery-UI Autocomplete Demo</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="http://localhost/rockontechnologies/Scripts/Script1.10.3/jquery-1.9.1.js"></script>
<script src="http://localhost/rockontechnologies/Scripts/Script1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script>
$(function() {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$( "#tags" ).autocomplete({
source: availableTags
});
});
</script>
</head>
<body>
<div class="modal-footer">
<ul class="btn-group">
<button class="btn" data-bind="click: closeModal">Exit</button>
</ul>
</div>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
</body>
</html>
For help on DurandalJS, I have referred to:
http://durandaljs.com/
For help on Autocomplete, I have referred to: [http://jqueryui.com/autocomplete/][3]
Thank you in advance.
ive answered a similar question here which will help you.
But your autocomplete.html is wrong and will not work when composed by Durandal. You need to convert that to a durandal style html page.
Add your script tags to your host page. In Hot Towel this is managed by bundles so im not entirely sure where you add these if using PHP.
Remove the HTML, SCRIPT, META etc... Just leave the pure HTML markup.
e.g:
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
Then in your autocomplete.js file, add an attached method or if using Durandal < 2.0.0 you add a viewAttached method.
define(function (require) {
var router = require('durandal/plugins/router');
var moviesRepository = require("repositories/moviesRepository");
return {
activate: function (context) {
},
attached: function (view) {
var $tagInput = $(view).find('#tags');
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$tagInput.autocomplete({
source: availableTags
});
}
};
});
Let me know if you are still having issues and ill be pleased to help.