How do I use parameters in DustJS? I made a jsfiddle where I want to print key value pairs where the key = [parameter].
In the fiddle I just want to display Larry, Moe and Curly's weight (not their height).
In XSLT this is easy. Just use Xpath to find prop[#name="weight"] then the following-sibling axis.
Fiddle: http://jsfiddle.net/6YrCg/
<script id="entry-template">
{title}
<ul>
{#names}
<li>{name}</li>{~n}
<ul><li>Weight:{#props.name}{value}{/props.name}</li></ul>
{/names}
</ul>
</script>
<div id="output"></div>
$(document).ready(function () {
var data = {
"title": "Famous People",
"names" : [{ "name": "Larry", "props":[{"name":"height","value":"5.8"},{"name":"weight","value":"160"}] },{ "name": "Curly", "props":[{"name":"height","value":"5.9"},{"name":"weight","value":"200"}]},{ "name": "Moe", "props":[{"name":"height","value":"5.8"},{"name":"weight","value":"160"}]}]
}
var source = $("#entry-template").html();
var compiled = dust.compile(source, "intro");
dust.loadSource(compiled);
dust.render("intro", data, function(err, out) {
$("#output").html(out);
});
});
Here is one solution, using the {#eq} helper to only output the value if the name key is equal to "weight".
{title}
<ul>
{#names}
<li>
{name}
<ul><li>Weight: {#props}{#eq key=name value="weight"}{value}{/eq}{/props}</li></ul>
</li>
{/names}
</ul>
Context helpers such as {#eq} are functions that augment the core syntax of Dust. For more information about this helper and other officially-supported helpers, check out the dustjs-helpers wiki page.
Related
I'm new to ReactJS and I fell I'm missing some fundamental information.
I am working on simple TODO list, where you click on <li> and it gets transfered to Finished section.
http://jsbin.com/gadavifayo/1/edit?html,js,output
I have 2 arrays that contain list of tasks, when you click on one task <li> it is removed from array and transferred to other array. After that clicked <ul> is updated but not the one where task went.
When using it you may notice that <ul> is updated only when clicked.
How can I update both <ul> when clicking on only one?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Testing</title>
<link rel="stylesheet" href="bootstrap.css">
</head>
<body>
<div id="react-app"></div>
<script src="https://fb.me/react-0.14.3.js"></script>
<script src="https://fb.me/react-dom-0.14.3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script type="text/babel">
/*
* Components
*/
var pendingItems = [
'Clean the room',
'Get milf',
'Sellout and stuff'
];
var finishedItems = [
'Clean the room',
];
var TodoList = React.createClass({
getInitialState: function() {
return { items: this.props.list };
},
handleClick: function(i) {
console.log('You clicked: ' + i + ':' + this.props.listString);
if (this.props.listString == "pendingItems") {
var removed = this.state.items.splice(i, 1);
finishedItems.push(removed);
};
if (this.props.listString == "finishedItems") {
var removed = this.state.items.splice(i, 1);
pendingItems.push(removed);
};
this.forceUpdate()
},
render: function() {
return (
<ul>
{this.state.items.map(function(item, i) {
return (
<li onClick={this.handleClick.bind(this, i)} key={i}>{this.state.items[i]}</li>
);
}, this)}
</ul>
);
},
});
var Layout = React.createClass({
render: function (){
return (
<div className='col-xs-12'>
<div className='col-xs-6'>
<TodoList list={pendingItems} listString="pendingItems"/>
</div>
<div className='col-xs-6'>
<TodoList list={finishedItems} listString="finishedItems"/>
</div>
<div className='col-xs-6'></div>
</div>
)
}
});
ReactDOM.render(<Layout />, document.getElementById('react-app'));
</script>
</body>
</html>
You need to use the states. In getInitialState you put your two list, onclick do whatever transformationyou want (you then have for example updated_list1 and updated_list2 and then you set the list like that:
this.setState({ list1: updated_list1, list2: updated_list2 }); in your case this.setState({ pendingItems: pendingItems ... after the .push
the setState function will automatically rerender, no need to call forceupdate.
The second thing important here is that you have to make the two list communication kinda, so my advise would be to put your both ul in the same component (so you can manage the lists in the same component state as mentionned above).
However this is not the only way to go and you may choose the put the states of your two list in the parent component (Layout). In this case you should use this way to go. https://facebook.github.io/react/tips/expose-component-functions.html
In any case you need (if you want to keep it simple and without external model management like backbone or flux pattern) to put lists states in the same component state. (reminder: method 1 => ul in the same componenet so the states too, method 2 => keep state in the parent component)
I'm wondering how to handle the creation of dynamic objects with dynamic siblings. DOM manipulation in D3 is kind of hard to wrap your head around I think. There's a lot of text but hang on - I'm probably messing up something really simple. Anyways, I have this kind of data:
{
name: "Data",
children: [
{
name: "SomeSite",
children: [
{
title: "Some title of a post",
href: "http://example.com/sometitleofapost"
},
{
title: "The title of another post",
href: "http://example.com/thetitleofanotherpost"
}
]
},
{
name: "SomeOtherSite",
children: [
{
title: "Post from another site",
href: "http://example.com/postfromanothersite"
}
]
}
]
}
This data will be reloaded with the JSON-function once in a while and I will use D3 to built a table of the data (I know D3 is maybe not the best choice for this kind of thing but it's part of an already D3-heavy app). I'd like D3 to make a list for each site ("SomeSite", "SomeOtherSite"). These must of course be dynamic in themselves as the JSON might update with data that does not contain this site anymore.
I've managed to built a basic list of all the "posts" in a structure like this:
<ul>
<li><a>Post 1</a></li>
<li><a>Post 2</a></li>
<li><a>Post 3</a></li>
</ul>
Using this code:
var control_list = d3.select("body").append("div")
.attr("id", "control-list")
.attr("class", "control-list");
var control_list_links = control_list.append("div")
.attr("id", "control-list-links")
.attr("class", "control-list-links");
var link_container = control_list_links.selectAll(".link-container")
.data(data.children);
link_container.enter()
.append("ul")
.attr("class", "link-container");
var link_links = link_container.selectAll('li')
.data(function(d) { return d.children });
link_links.enter()
.append("li")
.append("a");
link_links.select("a").text(function(d) { return d.title })
.attr("href", function(d) { return d.href });
link_container.exit().remove();
link_links.exit().remove();
This works as intended and updates correctly. However, I'd like to include a headline above the list, in a structure like this.
<div>
<h1>SomeSite</h1>
<ul>
<li><a>Post 1</a></li>
<li><a>Post 2</a></li>
</ul>
</div>
<div>
<h1>SomeOtherSite</h1>
<ul>
<li><a>Post 3</a></li>
</ul>
</div>
I've tried a lot of different things now and just can't seem to get it to work. I've tried wrapping a div around and appending/inserting the h1-tag along with the ul-tag but it always ends up inside the ul instead. I've been through the (very good) documentation but I have a hard time finding really good examples of exactly how especially "insert" works.
Any help would be much appreciated. :)
This is an example where nested selections should be used.
I'd like to do something like this fiddle only this works on buttons instead of links:
http://jsfiddle.net/qNhZj/
I need it to work on links and also i have an intro div which gets hidden after clicking on one of the links.
Can anyone help me out please.
You just have to declare link instead of input.
In the class list, add the id of the div you want to show.
Click a button to make it visible:
<div id="intro-tekst">Intro text here !</div>
<div class="boxes" id="coke">Coke is awesome!</div>
<div class="boxes" id="bubble-tea">Bubble tea is da bomb!</div>
<div class="boxes" id="milk">Milk is healthy!</div>
<br />
<p>
I change my mind:
<ul>
<li>Coke</li>
<li>Bubble Tea</li>
<li>Milk</li>
</ul>
</p>
And bind it like this :
$(document).ready(function() {
var url = window.location.href;
var option = url.match(/option=(.*)/);
if (option !== null) {
$(".link ." . option[1]).trigger('click');
}
$(".link").bind('click', function () {
$('#intro-tekst').hide();
$('.boxes').hide();
$('.link').removeClass('selected');
$(this).removeClass('link');
$('#' + $(this).prop('class')).show();
$(this).addClass('link selected');
});
});
JsFiddle code here : http://jsfiddle.net/Pq5Cv/8/
I'm sure this is a common question but I have an input field and a button. Whenever the button is pressed an ajax call is performed returning a string. I understand that if you attach it to a div in the original file, that div will erase any strings or numbers in it and replace with the returned string. What would be the most efficient way to allow for every single callback to be displayed on the screen real time? I attempted it but it appears that dynamically changing the javascript variable that assigns which div tag the ajax callback inserts into does not work. Does anyone know either what is wrong with this code or a more efficient way to write this code, i.e. with php, etc.
<div id="part1">
<input type="text" id="text"/>
<input type="button" value="button" id="button"/>
</div>
<div id="hidden" class="2"></div>
<div id="part2"></div>
<div id="part3"></div>
<div id="part4"></div>
<div id="part5"></div>
<script type="text/javascript" >
$('#button').click(function () {
var text = $('#text').val();
$.post('ajaxskeleton.php', {
red: text
}, function(){
var number = $('#hidden').attr("class");
$('#part' + number).html(text);
var number = number+1;
var class_name = $('#hidden').attr('class')
$('#hidden').removeClass(class_name);
$('#hidden').addClass(number);
$('#text').val('');
});
});
</script>
Instead of erasing its contents with .html(), you could append the new results to an existing div . For example, suppose you want to append the results to a div with id results:
$('#button').click(function () {
var text = $('#text').val();
$.post('ajaxskeleton.php', { red: text }, function() {
$("<li>" + text + "</li>").appendTo($("#results"));
});
});
Here's a DEMO.
I think something like the following would work.
<div id="container">
<input type="text" id="text"/>
<input type="button" value="button" id="button"/>
</div>
<ol id="responses"></ol>
$("#button").click(function() {
$.post('ajaxskeleton.php', {red:text}, function(data) {
$("#responses").append("<li>" + data + "</li>");
});
});
This just builds up an ordered list with the responses that come back from the Ajax calls, which I think is what your aiming to do.
Hi I'm trying to display subjects names from my database using AJAX.
That's my output right now:
[{"pk": 1, "model": "school.subjects", "fields": {"name": "Math 140"}},
{"pk": 2, "model": "school.subjects", "fields": {"name": "English 102"}},
{"pk": 3, "model": "school.subjects", "fields": {"name": "CS210"}}]
But I want to display only : How can I do that?
Math 140
English 102
CS210
Thats my view:
#csrf_exempt
def subjects_list(request):
if request.is_ajax():
user = request.user
subjects = Subjects.objects.filter(user__exact = user)
result = serializers.serialize("json", subjects, fields=('name'))
else:
result = "blablabl"
return HttpResponse(result)
And thats my test.html
{% extends "base.html" %}
{% block main-menu %}
<div id="result"></div>
<script type="text/javascript">
$(function() {
$.get("/subjects-list", function(data){
$("#result").append(data);
});
});
</script>
{% endblock %}
It is because the data you get back from the server is JSON. This needs to be parsed before it is loaded into your DOM. You could do something like this:
Copying, then adding to your test.html...
{% extends "base.html" %}
{% block main-menu %}
<div id="result"></div>
<script type="text/javascript">
$(function() {
$.get("/subjects-list", function(data){
var $results = $("#result");
for (var i = 0; i < data.length; i++) {
$results.append(data[i]["fields"]["name"] + "<br/>");
}
}, "json");
});
</script>
{% endblock %}
With that said though, you may want to look into using a javascript templating library. There are a LOT of them out there. The general idea is that the library can handle turning the AJAX responses into HTML.
There are some stackoverflow question answering the question of which to use here:
Recommended JavaScript HTML template library for JQuery?
What is the preferred template library for jQuery?
In order to find more about this, you'll want to search for "javascript templating".
Don't serialize your models directly, it isn't safe as users would see sensible internal fields.
You want to use a real API engine, like django-tastypie or django-piston. With this kind of engine, you'll be able to select fields that you want to show, manage authorizations, output formats, etc...
For instance, with tastypie:
class SubjectResource(ModelResource):
class Meta:
queryset = Subject.objects.all()
resource_name = 'subjects'
fields = ['name']
Will produce:
{
"objects": [
{"name": "Math 140"},
{"name": "English 102"},
{"name": "CS210"},
]
}
Of course, you can delete the objects wrapper with the following instance method:
def alter_list_data_to_serialize(self, request, data):
data[self.Meta.resource_name] = data['objects']
del data['objects']
del data['meta']
return data
That's the cleanest way to go.