jQuery Nested Templates using options parameter - jquery-templates

I don't understand how to reference the options parameter in nested templates.
Please see:
<div id="myContainer"></div>
<script type="text/javascript">
var tmplMain = "<div><span>${title}</span>" +
"<p style=\"border: solid 1px #f00\">${$item.details}</p>" +
"{{tmpl \"nestedTemplate\"}}</div>";
var tmplNested = "<p style=\"border: solid 1px #0f0\">${$item.details}</p>";
var _mainTemplate = jQuery.template("mainTemplate", tmplMain);
jQuery.template("nestedTemplate", tmplNested);
var _data = {title: "My Title"};
var _options = {details: "My Details};
jQuery.tmpl(_mainTemplate, _data, _options).appendTo("#myContainer");
</script>
Which will output this: http://i.stack.imgur.com/r7A7g.jpg
So either I'm not referencing "${$item.details}" correctly in the nested template or I'm not passing the options correctly in the {{ tmpl }} tag. I'm stumped.

You would need to pass any options that you want to the {{tmpl}} tag. Something like:
{{tmpl($data, { details: $item.details}) "nestedTemplate" }}
You could even just pass $item for the options to the nested template, but $item has more than just your options on it.
Sample here: http://jsfiddle.net/rniemeyer/Xzgpr/

Related

vue-chartjs and custom legend using generateLegend()

The generateLegend() wrapper does call the legendCallback defined in my Vue code but I'm lost to how to render the custom HTML in vue-chartjs. What do I do with htmlLegend as described in the vue-chartjs api docs like here.
Here is the line chart component I'm trying to render with a custom HTML object.
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
props: ['chartData','options'],
data: () => ({
htmlLegend: null
}),
mounted () {
this.renderChart(this.chartData, this.options);
this.htmlLegend = this.generateLegend();
}
}
Here is my vue template
<template>
<div class="col-8">
<line-chart :chart-data="datacollection" :options="chartOptions"></line-chart>
</div>
</template>
Well, htmlLegend holds the markup of the generated legend... so you can just put it into your tag via v-html
<template>
<div class="col-8">
<div class="your-legend" v-html="htmlLegend" />
<line-chart :chart-data="datacollection" :options="chartOptions"></line-chart>
</div>
</template>
mounted() {
this.renderChart( this.chartData , this.options );
var legend = this.generateLegend();
this.$emit('sendLegend', legend)
}
and then in the vue file add a new div to show the legend and also listen to the event to get the legend data
<div class="line-legend" v-html="chartLegend"></div>
<line-chart #sendLegend="setLegend" :chart-data="datacollection" :options="chartOptions"></line-chart>
and also add this to the data
chartLegend: null,
and you also need a method
setLegend (html) {
this.chartLegend = html
},

web.py markdown global name 'markdown' is not defined

Im trying to use markdown together with Templetor in web.py but I can't figure out what Im missing
Documentation is here http://webpy.org/docs/0.3/templetor#builtins
import markdown
t_globals = {
'datestr': web.datestr,
'markdown': markdown.markdown
}
render = web.template.render(globals=t_globals)
class Blog:
def GET(self, post_slug):
""" Render single post """
post = BlogPost.get(BlogPost.slug == post_slug)
render = web.template.render(base="layout")
return render.post({
"blogpost_title": post.title,
"blogpost_content": post.content,
"blogpost_teaser": post.teaser
})
here is how I try to use markdown inside the post.html template
$def with (values)
$var title: $values['blogpost_title']
<article class="post">
<div class="post-meta">
<h1 class="post-title">$values['blogpost_title']</h1>
</div>
<section class="post-content">
<a name="topofpage"></a>
$:markdown(values['blogpost_content'])
</section>
But Im getting this exception
type 'exceptions.NameError' at
/blog/he-ll-want-to-use-your-yacht-and-i-don-t-want-this-thing-smelling-like-fish/
global name 'markdown' is not defined
You're re-initializing render, once in global scope setting globals and once within Blog.GET setting base. Do it only once!

How can I generate pages in Assemble based on an different json files?

So I have a folder rules that that looks like this:
rule-001.json
rule-002.json
rule-003.json
Each *.json file is of a unified format:
{ name: 'AAA', descriptions: 'BBB' }
How can I generate a pages based on these files in Assemble?
The short answer is that you need to load your JSON data in your Gruntfile and use it to replace the Assemble pages object.
I have written a blog post about generating pages from data, based on the Assemble Blog Theme sample. In both cases, the pages data was stored in a single JSON file.
In your case, you need to load the data from all of JSON files in your Gruntfile, and transform the data into the pages format. You can do this any number of ways, but one simple way would be to write a function in your Gruntfile that does this:
function loadDataPages (jsonFileSpec) {
var path = require("path");
var jsonPaths = grunt.file.expand(jsonFileSpec);
var jsonPages = jsonPaths.map(function (jsonPath) {
var jsonData = grunt.file.readJSON(jsonPath);
var outputFileName = path.basename(jsonPath, path.extname(jsonPath)) + ".html";
var jsonPage = {
"data": jsonData,
"content": "This is the body content for page " + outputFileName,
"filename": outputFileName
};
return jsonPage;
});
return jsonPages;
}
and then you need to load this data object in your Grunt config and pass it to Assemble's pages option:
grunt.initConfig({
assemble: {
data: {
options: {
flatten: true,
layout: "source/templates/layouts/custom-data-layout.hbs",
pages: loadDataPages("source/custom-data/*.json")
},
files: {
"output/custom-data-pages/": ["source/custom-data/index.hbs"]
}
}
}
// ...
});
Here is what the layouts might look like:
custom-data-layout.hbs
<!DOCTYPE html>
<html>
<head>
<title>Custom Data - {{name}}</title>
</head>
<body>
<h1>Custom Data - {{name}}</h1>
<p>{{ description }}</p>
{{> body }}
</body>
</html>
index.hbs
---
layout: false
title: Custom Data Index
---
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<ul>
{{#each pages }}
<li>{{basename}}</li>
{{/each}}
</ul>
</body>
</html>
Something like this should work for you. You just create separate Assemble tasks and call the main Assemble task with grunt.
https://gist.github.com/davidwickman/a0bf961e3099ea6b9c35

Facebook comment plugin Angularjs

I am facing a strange error while adding the facebook comment plugin in my AngularJS app.
The simplified structure of the app page is
<html ng-app="myapp">
<head>
...
</head>
<body>
<div>
...
</div>
<div ng-view></div>
...
</body>
</html>
The page with fb comment box is loaded in ng-view. The structure of page that contains fb comment box is as follows
<div id="fb-comment-box>
<div class="fb-comments" data-href="http://mydomain.com/page/{{ page.id }}" data-numposts="5" data-colorsheme="light"></div>
</div>
The page is angularjs scope variable which comes from controller. When i load this page in browser and do inspect element. It shows the correct page id i.e. data-href is
data-href = "http://mydomain.com/page/2"
But below the fb comment box, Facebook shows following error
Warning: http://mydomain.com/page/%7B%7B%20page.id%7D%7D is
unreachable.
I can see the angularJS scope variable is not binding. Does anyone know how to solve this issue?
This is probably due to the fact that the FB functionality kicks in before Angular is able to change the data-href attribute.
A directive seems like a good choice here:
You basically need to create the comment-box after Angular can provide the correct URL.
Because this involves asynchronous DOM manipulation, you need to use FB.XFBML.parse() to let FB process the comment-box once the data-href attribute is changed.
The directive:
.directive('dynFbCommentBox', function () {
function createHTML(href, numposts, colorscheme) {
return '<div class="fb-comments" ' +
'data-href="' + href + '" ' +
'data-numposts="' + numposts + '" ' +
'data-colorsheme="' + colorscheme + '">' +
'</div>';
}
return {
restrict: 'A',
scope: {},
link: function postLink(scope, elem, attrs) {
attrs.$observe('pageHref', function (newValue) {
var href = newValue;
var numposts = attrs.numposts || 5;
var colorscheme = attrs.colorscheme || 'light';
elem.html(createHTML(href, numposts, colorscheme));
FB.XFBML.parse(elem[0]);
});
}
};
});
The HTML:
<div id="fb-comment-box" dyn-fb-comment-box
page-href="https://example.com/page/{{page.id}}"
numposts="5"
colorscheme="light">
</div>
NOTE:
The directive's scope will constantly watch for changes in the page-href attribute and update the comment-box. You can change this to suit your needs (e.g. also watch for changes in the other attributes or bind it once and stop watching).
See, also, this short demo.

Auto complete with multiple keywords

I want . Auto complete text box with multiple keyword. it's from database. if I use jQuery and do operation in client side mean. If the database size is huge, it leads to some issues. I need to know how this is done on the server side and get proper result.
I have already seen this topic but the operation is done on the client side. I need it from the database directly.
<html>
<head>
<title>Testing</title>
<link href="css/jquery-ui-1.10.3.custom.css" rel="stylesheet" type="text/css" />
<style type="text/css">
.srchHilite { background: yellow; }
</style>
<script src="scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="scripts/jquery-ui-1.10.3.custom.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
NewAuto();
});
function NewAuto() {
var availableTags = ["win the day", "win the heart of", "win the heart of someone"];
alert(availableTags); // alert = win the day,win the heart of,win the heart of someone
$("#tags").autocomplete({
source: function(requestObj, responseFunc) {
var matchArry = availableTags.slice(); // Copy the array
var srchTerms = $.trim(requestObj.term).split(/\s+/);
// For each search term, remove non-matches.
$.each(srchTerms, function(J, term) {
var regX = new RegExp(term, "i");
matchArry = $.map(matchArry, function(item) {
return regX.test(item) ? item : null;
});
});
// Return the match results.
responseFunc(matchArry);
},
open: function(event, ui) {
// This function provides no hooks to the results list, so we have to trust the selector, for now.
var resultsList = $("ul.ui-autocomplete > li.ui-menu-item > a");
var srchTerm = $.trim($("#tags").val()).split(/\s+/).join('|');
// Loop through the results list and highlight the terms.
resultsList.each(function() {
var jThis = $(this);
var regX = new RegExp('(' + srchTerm + ')', "ig");
var oldTxt = jThis.text();
jThis.html(oldTxt.replace(regX, '<span class="srchHilite">$1</span>'));
});
}
});
}
</script>
</head>
<body>
<div>
<label for="tags">
Multi-word search:
</label>
<input type="text" id="tags" />
</div>
</body>
</html>
take a look to Select2 it may help you.
Select2 is a jQuery based replacement for select boxes. It supports
searching, remote data sets, and infinite scrolling of results.
link
In your code, you have provided source as array. As you mentioned in comments, problem is how to get the data to source in jquery.
To make this work,
You need to do following
load jquery in header, which is you have already done.
Provid array,string or function for the source tag. [See api for
the source tag][1]
[1]: http://api.jqueryui.com/autocomplete/#option-source
In your serverside script, provid Jason encoded string.
If you check the API, you can see they have clear mentioned this.
Here is the jquery code
$(function() {
$( "#option_val" ).autocomplete({
dataType: "json",
source: 'search.php',
minLength: 1,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value );
}
});
});
</script>
Here is the php code, Sorry if you use differnt serverside script language.
<?php
// Create connection
$con=mysqli_connect("localhost","wordpress","password","wordpress");
// Check connection
if (mysqli_connect_errno($con))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result=mysqli_query($con,"select * from wp_users");
while($row = mysqli_fetch_array($result))
{
$results[] = array('label' => $row['user_login']);
}
echo json_encode($results);
mysqli_close($con);
?>