Dynamically add a referenced field to another document using Sanity - javascript

I have a sanity v3 document. In which There is a Pin section which contains
Title -> String
about -> String
destination -> String
image -> Url
savedBy [ ] -> Array
commentedBy [ ] -> Array of referenced Value
QUESTION: So, the commentedBy section is an array of referenced object field, where it is pointing to the Comment document.
Now, If I want to add a comment to a Pin, first i have to manually create that comment (which is expected), after that I manually set/reference the comment to that pin.
Problem: Is that whenever i/someone creates a new comment that comment should automatically be added/referenced to the pin document! Which it does not do. For now Manually I have to do it!
Attempts:
I have tried adding referencing the comment section to the Pin document.
Tried creating a whole comment section inside of the Pin document. At the end it messes up with the code!
Work-around: Well there is a cheap solution to solve this problem. For example, whenever comment is made manually set the reference to the pin Section, simultaneously creating the comment. This might work around for small group of users but for large group of users this will put a lot of pressure to the backend.
Search: For these different approaches I looked into these websites! Sanity Doc v3,
Sanity Cross-Reference
Code:
// comment.js document
export default defineType({
name: 'comments',
title: 'Comments',
type: 'document',
fields: [
defineField({
name: 'pinId',
title: 'PinId',
type: 'reference',
to: [{type: 'pins'}],
}),
defineField({
name: 'postedBy',
title: 'PostedBy',
type: 'reference',
to: [{type: 'user'}],
}),
defineField({
name: 'comment',
title: 'Comment',
type: 'string',
}),
],
})
// pin.js document
export default defineType({
name: 'pins',
title: 'Pins',
type: 'document',
fields: [
defineField({
name: 'title',
title: 'Title',
type: 'string',
}),
defineField({
name: 'about',
title: 'About',
type: 'string',
}),
defineField({
name: 'destination',
title: 'Destination',
type: 'url',
}),
defineField({
name: 'category',
title: 'Category',
type: 'string',
}),
defineField({
name: 'userId',
title: 'userId',
type: 'string',
}),
defineField({
name: 'image',
title: 'image',
type: 'image',
options: {
hotspot: true,
},
}),
defineField({
name: 'postedBy',
title: 'Posted By',
type: 'reference',
to: [{type: 'user'}],
}),
defineField({
name: 'save',
title: 'Save',
type: 'array',
of: [{type: 'save'}],
}),
defineField({
name: 'comments',
title: 'Comments',
type: 'array',
of: [
{
type: 'reference',
to: [{type: 'comments'}],
},
],
}),
],
})

Related

TypeORM - One-To-Many relationship defined in EntitySchema

I'm using TypeORM with JS and it's docs are super minimal, so I couldn't find the solution for my question over there.
I want to create a one-to-many bi-directional relationship and can't get over the following exception:
TypeORMError: Entity metadata for Team#groups was not found. Check if you specified a correct entity object and if it's connected in the connection options.
Thats the definition of the two entities (one team might have multiple groups):
module.exports = new EntitySchema({
name: 'Team',
tableName: 'team',
columns: {
id: {
primary: true,
type: 'uuid',
generated: true,
},
name: {
type: 'varchar',
},
},
relations: {
groups: {
target: 'TeamGroups',
type: 'one-to-many',
inverseSide: 'team_id',
},
},
})
module.exports = new EntitySchema({
name: 'TeamsGroups',
tableName: 'team_group',
columns: {
team_id: {
primary: true,
type: 'uuid',
},
group_id: {
primary: true,
type: 'uuid',
},
},
relations: {
team_id: {
target: 'Team',
type: 'many-to-one',
joinColumn: true,
},
},
})
What am I missing?
I can't test but I'm fairly sure it's this, looking at the error & docs:
module.exports = new EntitySchema({
name: 'Team',
tableName: 'team',
columns: {
id: {
primary: true,
type: 'uuid',
generated: true,
},
name: {
type: 'varchar',
},
},
relations: {
TeamGroups: {
target: 'TeamGroups',
type: 'one-to-many',
inverseSide: 'team_id',
},
},
})
module.exports = new EntitySchema({
name: 'TeamsGroups',
tableName: 'team_group',
columns: {
team_id: {
primary: true,
type: 'uuid',
},
group_id: {
primary: true,
type: 'uuid',
},
},
relations: {
Team: {
target: 'Team',
type: 'many-to-one',
joinColumn: true,
},
},
})

TinyMCE: get values from a listbox in a modal window

I'm creating a TinyMCE Plugin for Wordpress. It has a textbox and a listbox field, both staying in a modal window.
Code below:
(function () {
tinymce.create('tinymce.plugins.windowdata', {
init : function(ed, url) {
ed.addButton('showModal', {
title: 'Show Modal',
image: url + '/img/button.png',
onclick: function () {
ed.windowManager.open({
title: 'Minestra',
body: [
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n'}, //textbox
{type: 'listbox', label: 'Listbox', classes: 'i1lb', values: [
{text: '', value: ''},
{text: 'Number', value: 'lone_number'},
{text: 'Bar', value: 'bar'},
]}, //listbox
],
onsubmit: function () {
var n1 = document.getElementsByClassName('mce-i1n')[0].value; //textbox value
var t1 = document.getElementsByClassName('mce-i1lb')[0].getElementsByTagName('button')[0].getElementsByClassName('mce-txt')[0].innerHTML; //listbox value
ed.execCommand('mceInsertContent', 0, n1+' is of type '+t1) //write contents
}
})
}
});
}
)
My question is about how to get the field values. What i did works very well with the textbox (the n1 var inside the onsubmit() method), but the listbox gets the same text that is shown to TinyMCE user (the text var in each listbox item).
What i want is a way to get the value instead; plus, i suppose i didn't get the right way to do it, not even with textbox. Anyone can help me? Thank you.
Better way to generate content is:
onsubmit: function (e) {
// Insert content when the window form is submitted
e.insertContent('Textbox content: ' + e.data.Field);
e.insertContent('Listbox content: ' + e.data.Listbox)
}
I solved by my own: i had to give a name to all of my fields:
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n'}, //textbox
{type: 'listbox', name: 'Listbox', label: 'Listbox', classes: 'i1lb', values: [
{text: '', value: ''},
{text: 'Number', value: 'lone_number'},
{text: 'Bar', value: 'bar'},
]
At this point, to generate my content i got values this way:
onsubmit: function (e) {
e.data.Field;
e.data.Listbox;
}
and used this to write in TinyMCE textarea. To get values back i had to modify textbox field this way:
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n', value: ed.selection.getContent()}
Similarly with listbox

Angularjs delete JSon object

So I have little dilemma here. I have a nested json object that is inside ng-repeat and is sortable using AngularJS UI Sortable (based on JQuery UI Sortable):
$scope.rootItem = {
id: '1',
type: 'course',
title: 'Adobe Photoshop CC for beginners',
items: [{
id: '2',
type: 'label',
title:'label',
items:[{
id: '3',
type: 'module',
title:'Module title',
items: [{
id: '4',
type: 'topic',
title:'Topic title',
items: [{
id: '5',
type: 'content',
title:'Content title'
}, {
id: '6',
type: 'content',
title:'Content title'
}]
}]
},{
id: '7',
type: 'resources',
title:'Resources'
},{
id: '8',
type: 'module',
title:'Module title',
items: [{
id: '9',
type: 'topic',
title:'Topic',
items: [{
id: '10',
type: 'question',
title:'Question title'
}]
}, {
id: '11',
type: 'topic',
title:'Topic title',
items: [{
id: '12',
type: 'content',
title:'Content title'
}]
}]
}]
},{
id: '14',
type: 'assessmentLabel',
title: 'Assessment Label',
items: [{
id: '15',
type: 'assessment',
title: 'Assessment Title',
items: [{
id: '16',
type: 'courseAssessment',
title: 'Course Question Group',
items: []
}]
}]
}]
};
What I should be able to do is remove any of the items within this object, and if it has any children they need to be remove too.
So what I would generally think is passing either $index and use splice to remove it (if it was an array).
But for objects doesnt seem to work this way, I read online that delete should be used instead...
On my button I try to pass the object itself as in:
data-ng-click="removeItem(ngModelItem)"
and in my controller do something like this:
// Remove Item from the list
$scope.removeItem = function(item) {
};
Any suggestions?
Use ngModelItem
<li ng-repeat="innerItem in ngModelItem.items">
Delete me
in your controller,
$scope.deleteItem = function(collection, index){
collection.splice(index,1);
};
Demo
For removing json elements from a json object you use the delete operator. But in your case, I assume you want to remove a json object from a json array, so you should really use splice() instead.
You should receive both the list and the index in your removeItem() function so you can remove the indexed element and angularjs will update your view.

Extend from custom model class in ExtJS 4

How to extend from custom model in extjs.
Is there any method which can directly club the fields of User and BusinessUser fields when I'll refer the fields from BusinessUser class in example below.
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'age', type: 'int'},
{name: 'phone', type: 'string'},
{name: 'alive', type: 'boolean', defaultValue: true}
],
});
Ext.define('BusinessUser', {
extend: 'User',
fields: [
{name: 'businessType', type: 'string'},
{name: 'company', type: 'string'}
],
});
You don't need to join the fields manually because it's done automatically. Check the outputs in the code bellow based on your question:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'age', type: 'int'},
{name: 'phone', type: 'string'},
{name: 'alive', type: 'boolean', defaultValue: true}
],
});
Ext.define('BusinessUser', {
extend: 'User',
fields: [
{name: 'businessType', type: 'string'},
{name: 'company', type: 'string'}
],
});
// instantiating a User object
var u = Ext.create('BusinessUser', {
name: 'John Doe',
age: 30,
phone: '555-5555'
});
// instantiating a BusinessUser object
var bu = Ext.create('BusinessUser', {
name: 'Jane Doe',
age: 40,
phone: '555-5556',
businessType: 'analyst',
company: 'ACME'
});
console.log(Ext.getClassName(bu)); // "BusinessUser"
console.log(Ext.getClassName(u)); // "User"
console.log(u instanceof User); // true
console.log(bu instanceof User); // true
console.log(u instanceof BusinessUser); // false
console.log(bu instanceof BusinessUser); // true
console.log(u instanceof Ext.data.Model); // true
console.log(bu instanceof Ext.data.Model); // true
console.log(u instanceof Ext.data.Store); // false, just to check if it's not returning true for anything
console.log(bu instanceof Ext.data.Store); // false
console.log("name" in u.data); // true
console.log("name" in bu.data); // true
console.log("company" in u.data); // false
console.log("company" in bu.data); // true
Although it should work automatically, use the below if you are having troubles for some reason.
Use the constructor to join the fields:
Ext.define('BusinessUser', {
extend : 'User',
constructor : function(){
this.callParent(arguments);
this.fields.push([
{name: 'businessType', type: 'string'},
{name: 'company', type: 'string'}
]);
}
});

How to sort ArrayStore?

I have a object:
store: Ext.create('Ext.data.ArrayStore',{
sortInfo: { field: "uniq_users", direction: "DESC" },
fields: [
{name: 'Country', type: 'string'},
{name: 'uniq_users', type:'int'}],
data: [{Country: 'Ed', users: 'Spencer'}]
})
store.loadData(...)
Why default sort don't work for field ?
The sortInfo property is available for ExtJS 3.x and not for the latest version. With release of version 4, the sorting is implemented through the mixin Ext.util.Sortable. You should be using the property sorters to define your sorting parameters..
Here is what you should be doing:
store: Ext.create('Ext.data.ArrayStore',{
sorters: [
{property : 'uniq_users',direction: 'DESC'}
],
fields: [
{name: 'Country', type: 'string'},
{name: 'uniq_users', type:'int'}
],
data: [{Country: 'Ed', users: 'Spencer'}]
});
store.loadData(...);

Categories