D3.js DOM manipulation with dynamic siblings - d3.js

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.

Related

Vuejs tags and ajax

Hello
i am coding a web page of posts, where I'd like to add a tag system, something like stack overflow.
I have found many useful codes already made like Tag it by: aehlke.
The problem it´s that i want to use almost all the code by vuejs.org.
I am at laravel 5.3 framework and vuejs also using jquery.
Coul you please help me with the js to make a "separated by comma" tag that only can use the tags already in Tags table.
i used the example in vuejs.org to make made a searchbox that searches at a vue var and displays it at the bottom, i tought i coul use laravel variables to make the vuejs var and then search, but how could i make that each time a value its clicked on the table at bottom, the text fields updates with a tag inside.
<script type="text/x-template" id="grid-template">
<table>
<tbody>
<tr v-for="
entry in data
| filterBy filterKey
| orderBy sortKey sortOrders[sortKey]">
<td v-for="key in columns">
{{entry[key]}}
</td>
</tr>
</tbody>
</table>
</script>
<div id="demo">
<form id="search">
Search <input name="query" v-model="searchQuery">
</form>
<demo-grid
:data="gridData"
:columns="gridColumns"
:filter-key="searchQuery">
</demo-grid>
</div>
Vue.component('demo-grid', {
template: '#grid-template',
props: {
data: Array,
columns: Array,
filterKey: String
},
methods: {
sortBy: function (key) {
this.sortKey = key
this.sortOrders[key] = this.sortOrders[key] * -1
}
}
})
// bootstrap the demo
var demo = new Vue({
el: '#demo',
data: {
searchQuery: '',
gridColumns: ['tag'],
gridData: [
{ tag: 'Movies'},
{ tag: 'Tv Shows' },
{ tag: 'Books'},
{ tag: 'Comics' }
]
}
})
Help.
This isn't a "code-this-for-me"-site so if you want some help you need to post some code and someone might tell you what's wrong with it.
Anyhow, one of these JS libraries might be of interest to you:
https://select2.github.io/
http://selectize.github.io/selectize.js/

DustJS xpath next sibling axis equivalent

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.

knockout with dynamic viewmodels

There's a ton of info on the interwebs about how to handle dynamic views (via ajax calls) with Knockout, but is there a best practice for dynamic viewmodels?
For instance, say I have a single page app that renders (via ajax) different types of forms (with different input fields) based on role, user choices, contexts, etc. Not only would I use templates for each form, but I'd like to do the same for the viewmodel, since each viewmodel may have many very different properties and it wouldn't be practical to have one massive viewmodel for every possible template.
I'm a bit of a rookie with ko, and it may not be meant to be used in this fashion. Any advice is much appreciated.
A popular way to do this type of thing is to have a main view model that hosts sub-view models.
Here is a really basic example of defining "model" objects that have a template and associated data.
function Model(key, template, data) {
this.key = key;
this.template = ko.observable(template);
this.data = data;
}
var viewModel = {
models: ko.observableArray([
new Model("user", "userTmpl", { first: "Bob", last: "Smith" }),
new Model("item", "itemTmpl", { name: "MyItem", description: "Here are some details" })
]),
selectedModel: ko.observable()
};
ko.applyBindings(viewModel);
Then, you could use it like:
<select data-bind="options: models, optionsText: 'key', optionsCaption: 'select a model...', value: selectedModel"></select>
<hr />
<div data-bind="with: selectedModel">
<div data-bind="template: { name: template(), data: data }"></div>
</div>
<script id="userTmpl" type="text/html">
<span data-bind="text: last"></span>, <span data-bind="text: first"></span>
</script>
<script id="itemTmpl" type="text/html">
<h3 data-bind="text: name"></h3>
<div data-bind="text: description"></div>
</script>
http://jsfiddle.net/rniemeyer/29kWf/
Obviously, you wouldn't likely bind the selection of the model in a select, but it helps show how it can work. Rather than an array your models could be an object with the property names matching the key.
The "data" in the "model" objects would be your sub-view models.
I'm Facing the same problem.
Try Knockout Namespaces

Multiple mouseovers links changing a separate DIV Content

I have five links that I want to change the content in the same separate DIV. There's different content corresponding to each link. On the mouseleave, I need the default text to return inside the separate DIV.
Has anyone already done this or can guide me? I prefer jquery.
Thanks!
$("a.link").mouseleave(function() {
$("#sepdiv").text($(this).text());
});
//share the same class ("link" as an example) with all your links. and have an id for the separate div
You question isn't clear and I don't have any code that I can base this on but I hope this is what you where looking for. let me know so I can edit my answer!
Edit:
After looking at the website shared in the comment:
js
$(document).ready(function() {
//this is your code - just add it all under one document load
$.preloadCssImages();
$('#slider').nivoSlider();
$('a.share-links').hover(function() {
$('#ms').text($(this).text());
}, function() {
$('#ms').text(function() {
return $(this).attr("title");
});
});
});
css
.share-links
{
text-indent:-9999px;
}
html
<div id="ms" title="Our crusade to feed every orphan in the world.">
Our crusade to feed every orphan in the world.
</div>
<div id="nc_wrap2">
<a class="nc1 share-links" href="#">Facebook</a>
<a class="nc2 share-links" href="#">Twitter</a>
<a class="nc3 share-links" href="#">..</a>
<a class="nc4 share-links" href="#">..</a>
<a class="nc5 share-links" href="#">..</a>
</div>
I hope this is better!

Extjs AJAX Language Api

can we use google AJAX Language API with EXTjs?????
i have tried example for translitration i have one html file
and typemarathi.js
google.load("elements", "1", { packages: "transliteration" });
function onLoad() {
var options = {
sourceLanguage: google.elements.transliteration.LanguageCode.ENGLISH,
destinationLanguage: [google.elements.transliteration.LanguageCode.MARATHI],
shortcutKey: 'ctrl+g',
transliterationEnabled: true
};
// Create an instance on TransliterationControl with the required
// options.
var control = new google.elements.transliteration.TransliterationControl(options);
// Enable transliteration in the editable DIV with id
// 'transliterateDiv'.
control.makeTransliteratable([myname]);
}
google.setOnLoadCallback(onLoad);
it works fine.
but if i write the textfield in extjs
Ext.onReady(function(){
var form1=new Ext.FormPanel({
renderTo:document.body,
frame:true,
title:'My First Form',
widyh:250,
items:[{ xtype:'textfield', fieldLabel:'First name', name:'firstname'}]
});
});
and try to pass firstname (name attribute to control.makeTransliteratable([firstname])) then it does not work... it says invalid id error
but if i pass->(html textfiled name to it) control.makeTransliteratable([myname]) it works fine
(i want to type and display multiple nonEnglish languages data
programatically frontend i used EXTjs is there any another way to do so if yes the suggest me. pls..
Yes you can.
Besides someone should clean his code, thats hurrible.
Yes, you can. But you should know that ExtJs automatically generates identifiers for html elements:
html:
<div class="x-form-item x-form-label-left x-box-item" id="ext-gen27" style="left: 0px; top: 0px;">
<label style="width: 55px;" class="x-form-item-label" id="ext-gen28">Send To:</label>
<div style="padding-left: 60px; width: 668px;" class="x-form-element" id="ext-gen26">
<div class="x-form-field-wrap x-form-field-trigger-wrap x-trigger-wrap-focus" id="ext-gen24" style="width: 668px;">
<input type="text" name="to" id="ext-comp-1002" autocomplete="off" size="24" class=" x-form-text x-form-field x-form-focus" style="width: 651px;">
</div>
</div>
</div>
js:
....
items: [{
xtype: 'combo',
store: ['test#example.com', 'someone-else#example.com' ],
plugins: [ Ext.ux.FieldReplicator, Ext.ux.FieldLabeler ],
fieldLabel: 'Send To',
name: 'to'
}]
As I understand you need to translate the label. In order to do this you should get the id of the label. To do this you can use TextField's label property (myField.label.id). If you want to translate a lot of elements then probably it'll be better for you to use something like this:
var control = new google.elements.transliteration.TransliterationControl(options);
var labelIds = [];
Ext.each(Ext.select('label'), function(item){
labelIds.push(item.id);
});
control.makeTransliteratable(labelIds);
But be aware that you should call this only after rendering all elements. Also you can write a some plugin that will inject this functionality into 'render' method. Writing a plugin is a better but a bit more harder way.

Resources