In short i want to make a backbone deep collection of other collections and models
the structure is like this
[{
mainCategory: "Something"
subCategories: [
{
category: "SomethgingElse",
labs: [
{
id: 1,
title: "Title",
description : "Lorem ipsum dolor sit amet"
availablelanguages: ["fr","en"]
},
{
id: 2,
title: "Another Title",
description : "Lorem ipsum dolor sit amet",
availablelanguages: ["fr","en"]
}]
},
{
category: "Testing",
labs: [
{
id: 1,
title: "ZZZZ",
description : "Lorem ipsum dolor sit amet"
availablelanguages: ["ar","en"]
},
{
id: 2,
title: "VVVVV",
description : "Lorem ipsum dolor sit amet",
availablelanguages: ["ar","en"]
}]
}
]
}]
i defined some collections and models like the following
var Item = Backbone.Model.extend({
defaults: {
title : '',
description: '',
availableLangagues : []
}
});
var Items = Backbone.Collection.extend({
model: Item
});
var Category = Backbone.Model.extend({
defaults: {
categoryName: '',
labsList: new Items()
}
});
var Categories = Backbone.Collection.extend({
model: Category
});
var TopCategory = Backbone.Model.extend({
defaults: {
topCategory: "",
categories: new Categories()
}
});
var TopCategories = Backbone.Collection.extend({
model: TopCategory
});
My problem here i want to call fetch on the TopicCategories i want to populate everything , the fetch will return a JSON like passed in the example, but if i called fetch on TopCategories it will return the data but the array will be just normal JavaScript array not a backbone collection like i wanted in the defaults
What you want to do is utilize your parse() function of your top model. In this modified, parse, what you do is tease out the different object/arrays from your response and transform them into the collections you desire. Example: parse() in the TopCategory model.
parse: function(response) {
if (response.subCategories){
if (!this.subCategories) {
this.subCategories = new Categories(response.subCategories);
} else {
this.subCategories.reset(response.subCategories);
}
delete response.subCategories;
}
return response;
}
You'll do this pattern in the parse definition for each parent model that has some sort of backbone collection that you want to parse out.
This link might give you some more ideas as to how this all works.
Dealing with nested collections
Related
I am pulling back data from an Apex class into an LWC. The data resembles the following structure:
[
{
questionId: 1,
responses: [{
responseId: 11,
responseText: 'lorem ipsom',
actions: [
{
actionId: 111,
actionTitle: 'dummy title 1'
},
{
actionId: 112,
actionTitle: 'dummy title 2'
}
]
},
{
questionId: 2,
responses: [
{
responseId: 22,
responseText: 'lorem ipsum text 2',
actions: [
{
actionId: 221
actionTitle: 'dummy title 3'
}
}]
},
{
responseId: 23,
responseText: 'lore ipsum text 3'
actions: [
{
actionId: 331,
actionTitle: 'dummy title 4'
}
]
}
]
}
]
A question could have multiple responses and a response could have multiple actions.
I need to render this data in a html table that should resemble the following:
Table result
I have previously tried using the rowspan attribute in html. I also tried creating multiple sub tables in each <td> in the table. This worked to an extent however the styling was misaligned. I a trying to find the cleanest way to have this done.
Hi to every one reading this. I am struggling with a PDF.js problem. I am using this library: https://github.com/edisonneza/jspdf-invoice-template to render a PDF with data that I am getting from an internal axios route that returns orders. This orders are listed with a checkbox, for the orders checked I generate a new array with the objects of the different orders checked.
Up to this I was doing fine, but the next thing I need is to generate this PDFs. I got it to work rendering one single pdf with the data order, but i would like to generete a PDF with (N) numbers of pages, using the checked orders to print with a button.
Below are the blocks of the code that i wrote.
printAllbtn.addEventListener('click',function(){
try {
if(ordersSelectedToPrint.length \> 1){
console.log(ordersSelectedToPrint);
for (let orderPrint of ordersSelectedToPrint) {
let pdfObject = jsPDFInvoiceTemplate.default(props);
console.log( 'object created' + pdfObject + orderPrint)
var props = {
outputType: jsPDFInvoiceTemplate.OutputType.Save,
returnJsPDFDocObject: true,
fileName: "remito",
orientationLandscape: false,
compress: true,
business: {
name: "Isidorito",
address: "San Pedro, Buenos",
phone: "(3329) 069 11 11 111",
email: "contacto#isidorito.com",
website: "www.isidorito.com.ar/nosotros",
},
contact: {
label: "Remito dirigito a:",
name: `${orderPrint.cliente.dueño}`,
address:`${orderPrint.cliente.direccion}`,
phone: `${orderPrint.cliente.telefono1}`,
email: `${orderPrint.cliente.correo}`,
},
invoice: {
label: "Pedido #",
num: 19,
invDate: `${orderPrint.createdAt}`,
invGenDate: `28/10/2022`,
headerBorder: false,
tableBodyBorder: false,
header: [
{
title: "#",
style: {
width: 10
}
},
{
title: "Productos descripción",
style: {
width: 70
}
},
{
title: "Cantidad ",
style: {
width:20
}
},
{ title: "Por Unidad",
style:{width:30}},
// { title: "Cantidad"},
{ title: "Por tot",
style:{
width:30
}},
{ title: "Total",
style:{
width:30
}}
],
table: Array.from(orderPrint.productosPedidosNombre).forEach(function(productoIm, index){[
index + 1,
`${productoIm.nombre} - ${productoIm.marca} - ${productoIm.presentacion}`,
`${productoIm.cantidad}`,
`${productoIm.cantidad}`,
`${productoIm.cantidad}`,
`${productoIm.cantidad}`,
]}),
invDescLabel: "Cliente:",
invDesc: `${orderPrint.cliente.nombreLocal}`,
},
footer: {
text: "Este remito generado digitalmente es valido para el pedido realizado",
},
pageEnable: true,
pageLabel: "Page ",
};
} } } catch (error) { console.log(error); }
});
The first note is that "orderPrint.productosPedidosNombre" is an array of products of the order. In the example from the documentation its represented in this way.
table: Array.from(Array(10), (item, index)=>([
index + 1,
"There are many variations ",
"Lorem Ipsum is simply dummy text dummy text ",
200.5,
4.5,
"m2",
400.5
])),
And the way I generate the PDF is:
let pdfObject = jsPDFInvoiceTemplate.default(props);
First I would like to know if it is possible the loops and iteration to generate this type of single file with N number of order pages, and each page with different data. It's possible with this library.
Thanks you. It's my second question I've asked in StackOverflow, so I welcome the feedback on the how to ask in stack overflow.
I have made a Model which I made to display the whole discography of a band which I get delivered by an API as JSON. So far so good, but I need to sort the albums by its releasedate, so I intent to use the comparator-method, which is not possible to use on Models. So I want to "transform" the Model into a Collection, or is there maybe a better way?
Here is my model I define on my discography.js:
ArtistDiscography.ArtistDiscographyModel = Backbone.Model.extend({
url: function() {
return App.APIO + '/i/artist/' + this.get('slug') + '/releases';
},
parse: function(response){
return response.data;
},
});
the slug value is the JSON value, which returns for example rihanna. The JSON file also contains a value called releaseDate.
In my maincontroller.js, I have this:
define(function (require, exports, module) {
var ArtistDiscographyModule = require('modules/discography');
)};
ArtistController.prototype.initDiscography = function(name) {
this.artistdiscographyModel = new ArtistDiscographyModule.ArtistDiscographyModel({slug: name});
this.artistdiscographyModel.fetch();
this.artistdiscographyModel.on('sync', function() {
this.artistDiscographyView = new ArtistDiscographyModule.View({model: this.artistdiscographyModel});
App.useLayout('artistDiscography', 'artistDiscography').setViews({
'.releasesDiv' : this.artistDiscographyView,
}).render();
}, this);
};
The JSON response is:
data: [{
"slug" : "rihanna",
"releases": {
"title" : "Music Of The Sun",
"releaseDate": "2005-08-29",
"tracks": [{ //array of tracks}]
}, {
"title" : "Pon de Replay",
"releaseDate": "2005-08-22"
"tracks" : [{ //array of tracks}]
}
}]
Can someone help me out? I would really appreciate it!
You can set collection as an attribute of model:
ArtistDiscography.ArtistDiscographyModel = Backbone.Model.extend({
defaults: {
slug: '',
releases: new Releases()
}
});
Releases = Backbone.Collection.extend({
model: Release
});
Release = Backbone.Model.extend({
defaults: {
title: '',
releaseDate: '',
tracks: []
}
});
Then you can add comparator into Releases collection.
Or you can go dirty and use the underscore's sort function for array:
_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
=> [5, 4, 6, 3, 1, 2]
Have you tried something along these lines?....
ArtistDiscographyCollection = Backbone.Collection.extend({
model: ArtistDiscography.ArtistDiscographyModel,
comparator: function (model) {
return (model.get('releases').releaseDate);
}
});
Please see example below.
JSFiddle: http://jsfiddle.net/R7UvH/2/
How do I make typeahead.js (0.10.1) search for matches in more than one property value? Ideally, within whole data (data.title, data.desc and in all data.category[i].name)
datumTokenizer: function(data) {
// **search in other property values; e.g. data.title & data.desc etc..**
return Bloodhound.tokenizers.whitespace(data.title);
},
Whole example:
var data = [{
title: "some title here",
desc: "some option here",
category: [{
name: "category 1",
}, {
name: "categoy 2",
}]
},
{
title: "some title here",
desc: "some option here",
category: [{
name: "category 1",
}, {
name: "categoy 2",
}]
}];
var posts = new Bloodhound({
datumTokenizer: function(data) {
// **search in other property values; e.g. data.title & data.desc etc..**
return Bloodhound.tokenizers.whitespace(data.title);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: data
});
posts.initialize();
$('#search-input').typeahead({
highlight: true
}, {
name: 'Pages',
displayKey: 'title',
source: posts.ttAdapter(),
templates: {
header: '<h3>Pages</h3>'
}
});
Typeahead 0.10.3 added "support to object tokenizers for multiple property tokenization."
So, your example becomes
var posts = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'desc'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: data
});
However, I don't think this will work for properties nested inside, that is, the data.category object in your case.
As a side note, if you are using prefetched data, be sure to clear the local storage first, otherwise the new tokenizer won't take effect (Because datumTokenizer is used when adding to the search index, and if data is already present in localStorage, then the search index will not be updated). I was stuck on this for a while!
return Bloodhound.tokenizers.whitespace(data.title) returns an array of strings.
So, instead of returning that value: save it (and your other desired values), then concatenate them and return that value...
x = Bloodhound.tokenizers.whitespace(data.title);
y = Bloodhound.tokenizers.whitespace(data.desc);
z = Bloodhound.tokenizers.whitespace(data.category[i].name);
return x.concat(y).concat(z);
I've implemented a solution here:
http://jsfiddle.net/Fresh/4nnnG/
As you have a local datasource you need to create individual datasets to enable you to match on multiple data properties. e.g.
$('#search-input').typeahead({
highlight: true
}, {
name: 'titles',
displayKey: 'title',
source: titles.ttAdapter()
}, {
name: 'descs',
displayKey: 'desc',
source: descs.ttAdapter()
}, {
name: 'cats',
displayKey: 'name',
source: cats.ttAdapter()
});
I am new to DOJO 1.6
I trying to display tree with sub folders.
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dijit.form.Button");
dojo.require("dijit.tree.TreeStoreModel");
dojo.require("dojo.store.Memory");
dojo.require("dijit.Tree");
dojo.addOnLoad(function() {
// Create test store, adding the getChildren() method required by ObjectStoreModel
var data = [ { id: 1, name: "answerTypeLabel", type:'scenario', children:[{_reference: 2}]},
{ id: 2, name: "acceptRequestLabel", type:'paragraph', data: "acceptRequestLabel"},
{ id: 3, name: "rejectRequestLabel", type:'scenario', children:[{_reference: 5},{_reference: 6}]},
{ id: 4, name: "MoreInformationLabel", type:'scenario', children:[{_reference: 7},{_reference: 8}]},
{ id: 5, name: "rejectRequestStatusLabel", type:'paragraph', data: "rejectRequestStatusLabel"},
{ id: 6, name: "rejectRequestNotCoveredLabel", type:'paragraph', data: "rejectRequestNotCoveredLabel" },
{ id: 7, name: "MoreInformationDocumentLabel", type:'paragraph', data: "MoreInformationDocumentLabel"},
{ id: 8, name: "MoreInformationDataLabel", type:'paragraph', data: "MoreInformationDataLabel"}
];
// Building the store object
var sortableStore = new dojo.data.ItemFileWriteStore({
data: {
identifier: 'id',
label: 'name',
items: data
},
});
// building the model
var model = new dijit.tree.ForestStoreModel({
store: sortableStore,
query: {
id: "*"
},
rootId: "root",
rootLabel: "sorting of tree"
});
// Building the tree
var tree = new dijit.Tree({
model:model,
'class': "tundra"
},
"resourceTree");
});
.
Here Id 2 in a child of Id 1 , so while displaying Id 2 must be inside Id 1.
But here Id 2 appears inside id 1 and also on the same level of id 1.(There is a duplication of all the all the child ids ).
This is case with id 2,5,6,7,8.
I want to remove the duplication.
Ouptput should be like
Reason is that you apply a non-hierachial store onto a tree which is not supposed to display items that has parents as a sibling to the root.
To 'fix' this, the referenced id's needs to not get matched by the model query.
In your case of data, it looks like the type:'paragraph' is supposed to be leaves. Therefore set the query to match type:'scenario' as opposed to your current ' id: "*" '
var model = new dijit.tree.ForestStoreModel({
store: sortableStore,
query: {
type:'scenario'
},
rootId: "root",
rootLabel: "sorting of tree"
});