For each object Javascript - javascript

hope all is fine for you
I'm a beginner in javascript and i'm trying to integrate a video customer review API on my website.
The integration is working on all my pages but on one product page i'd like to init the sdk for each videos id returned by the object to display all the video reviews of this product.
The sdk returned an object as below : enter image description here
And i have to display the sdk like that :
SDK.init(
{
type: "player",
args: {
key: playerKey,
id: videoId, // Id returned by the object on the screenshot
width: '100%',
height: "inherit",
},
},
videoPlayer //=> my div element
)
i tried the for each method, objects as below but nothing work for me, each time only 1 player is displaying.
Object.keys(videos).forEach(id => {
console.log(videos);
SDK.init(
{
type: "player",
args: {
key: playerKey,
id: videoId,
width: '100%',
height: "inherit",
},
},
videoPlayer
)
});
I have no archive what i tried before this but i'm a little bit lost
Have a nice day and thank you

The documentation indicates that one HTML element should be dedicated to one player. So you cannot put several players in one element.
You could create child elements inside your container element.
Assuming that videos is an array, like depicted in the screenshot:
videos = [
{ id: '....' },
{ id: '....' }
]
then do this:
for (let {id} of videos) {
console.log("video ID", id);
const wrapper = document.createElement("div");
videoPlayer.appendChild(wrapper);
SDK.init(
{
type: "player",
args: {
key: playerKey,
id,
/* any other properties you want to add here */
},
},
wrapper
);
}

I didn't try the SDK, but as #T.J. Crowder mentioned in the comment you probably need to create new <div> for every init call, something like this:
Object.keys(videos).forEach(id => {
console.log(videos);
const node = document.createElement("div");
node.style.width = '500px';
node.style.height = '500px';
videoPlayer.appendChild(node)
SDK.init({
type: "player",
args: {
key: playerKey,
id: videoId,
width: '100%',
height: "inherit",
},
}, node)
});

Related

Can I access attributes with source meta from the Save class?

I've been building a plugin for a client that allows the user to select some colours and a set of fonts per post that is then applied throughout the post in every block.
The information is stored in the post's metadata
This is done through a sidepanel inside the post and since all blocks on the page need to access the data, the information is stored in the post's metadata.
Storing and retrieving the information is fine from the side panel and the retrieving information from the Edit class of each block is fine too (The blocks don't need to change the data).
Unfortunately, I'm having trouble with the Save class.
I know that I can't use the data module and withSelect from within the Save class, but the information in the documentation led me to believe that if I define the information as an attribute with source "meta" I could use it in the same way as a normal attribute.
"From here, meta attributes can be read and written by a block using the same interface as any attribute..."
- Documentation
This is what I've done with the Edit class successfully, but it doesn't work with the Save class. Instead, the attributes simply aren't available (ie. when I console log the attributes it doesn't include those ones).
My thought at the moment
I'm thinking the documentation must mean "only within the edit class", but I'd like to know if anyone else knows for sure...
The code
I don't think the code is very relevant because it works everywhere except the Save class, but here are my attribute definitions just fyi:
attributes: {
buttons: {
type: "array",
source: "query",
selector: "a",
query: {
text: {
type: "string",
source: "html",
attribute: "a"
},
url: {
type: "string",
source: "attribute",
attribute: "href"
},
colorKey: {
type: "string",
source: "attribute",
attribute: "data-color-key"
},
},
},
fontSetKey: {
type: "string",
source: "meta",
meta: "eimMeta_fontSetKey",
},
primaryColor: {
type: "string",
source: "meta",
meta: "eimMeta_primaryColor",
},
primaryContrastingShade: {
type: "string",
source: "meta",
meta: "eimMeta_primaryContrastingShade",
},
secondaryColor: {
type: "string",
source: "meta",
meta: "eimMeta_secondaryColor",
},
secondaryContrastingShade: {
type: "string",
source: "meta",
meta: "eimMeta_secondaryContrastingShade",
},
},
And here is my save function
import { Component } from "#wordpress/element";
import { RichText } from "#wordpress/editor";
import plugin from "../../plugin";
import category from "../category";
import block from "./block";
import { preparePostMetaForUse, getColorHexWithKey } from "../../common/values";
class Save extends Component {
render() {
const { attributes } = this.props;
const { className, buttons } = attributes;
console.log("Save attributes:");
console.log(attributes);
const postMeta = preparePostMetaForUse( attributes );
let jsxButtons = buttons.map((button) => ( <>
<RichText.Content
tagName="a"
value={button.text}
href={button.url}
data-color-key = {button.colorKey}
role="button"
target="_blank"
rel="noopener noreferrer"
style={{
fontFamily: postMeta.fontSet.body.fontFamily,
fontWeight: postMeta.fontSet.body.fontWeight,
fontSize: postMeta.fontSet.body.fontSize,
letterSpacing: postMeta.fontSet.body.letterSpacing,
lineHeight: postMeta.fontSet.body.lineHeight,
color: getColorHexWithKey(button.colorKey, postMeta.colorSet).contrastingShade,
backgroundColor: getColorHexWithKey(button.colorKey, postMeta.colorSet).color,
}}
/>
</> ));
return <div className={className}>{jsxButtons}</div>;
}
}
export default Save;

PowerBI Embedded - how to customize menu operation/context and custom layout

I have integrated powerbi-embedded with Angular 9 web app also add code for custom layut but it's not working.
I want to customize operations menu /context and custom layout.
Configuration object -
const config: any = {
type: 'report',
uniqueId: 'report-id',
permissions: this.model.Permissions.All,
embedUrl: 'embed-url',
accessToken: 'access-token',
settings: {
layoutType: this.models.LayoutType.Custom,
customLayout: {
pageSize: {
type: this.models.PageSizeType.Custom,
width: 1600,
height: 1200
},
displayOption: this.models.DisplayOption.ActualSize,
pagesLayout: {
"MyReportSection007" : {
defaultLayout: {
displayState: {
mode: this.models.VisualContainerDisplayMode.Hidden
}
},
visualsLayout: {
"VisualContainer1": {
x: 1,
y: 1,
z: 1,
width: 400,
height: 300,
displayState: {
mode: this.models.VisualContainerDisplayMode.Visible
}
},
"VisualContainer2": {
displayState: {
mode: this.models.VisualContainerDisplayMode.Visible
}
},
}
}
}
}
}
};
Above config. not working. any idea how can i achived customization in menu operation and layout.
I'm following below docs -
https://microsoft.github.io/PowerBI-JavaScript/demo/v2-demo/index.html#
https://github.com/microsoft/PowerBI-JavaScript/wiki/Custom-Layout
Thanks,
Your query is not clear since you have not shared any error message.
Though, code snippet that you shared offers a correct solution but, it might be possible that you are using wrong names for visual containers (i.e. VisualContainer1 or VisualContainer2) or the report page name (i.e. MyReportSection007). Ensure that you are providing correct names.
And if possible, please share the error message as well.

How to add iframe in Grapesjs?

I tried some plugins but wasn't able to follow along.
Basically I want an iframe to add and preview podcasts and other things.
Is there any iframe block like youtube block which comes with grapesjs ?
To my knowledge, there is not a good grapesjs iframe plugin that already exists.
If your use-case is simple, you can just create your own iframe block that has the information you need:
var editor = grapesjs.init({...});
var blockManager = editor.BlockManager;
blockManager.add('iframe', {
label: 'iframe',
content: '<iframe src="<your iframe src here>"></iframe>',
});
If you'd like an iframe component with a customisable src trait, for example, you'd do it like this:
var editor = grapesjs.init({...});
editor.DomComponents.addType("iframe", {
isComponent: el => el.tagName === "IFRAME",
model: {
defaults: {
type: "iframe",
traits: [
{
type: "text",
label: "src",
name: "src"
}
]
}
}
});
editor.BlockManager.add("iframe", {
label: "iframe",
type: "iframe",
content: "<iframe> </iframe>",
selectable: true
});
Here's a working codesandbox: https://codesandbox.io/s/grapesjs-o9hxu
If you need more customization options, you can learn how to create custom blocks and components using the docs:
https://grapesjs.com/docs/modules/Blocks
https://grapesjs.com/docs/modules/Components
https://grapesjs.com/docs/modules/Traits

Vue.js - recursive call of the component through render function. (runtime only)

I have one big request for you. I am a high-school student and I want to create an app for students with my friend. In the begining we wanted to use React for our reactive components, but then we saw Vue and it looked really good. But because of the fact, that we already have a big part of the app written in twig, we didn't want to use Vue.js standalone, because we would have to change a lot of our code, especially my friend, which is writing backend in Sympfony. So we use the runtime only version, which does not have a template option, so i have to write render functions for our components. And i am stucked with one particular problem.
I am writing a file-manager, and i need to render layer for every folder. Code is better then million words, so, take a look please :
var data = {
name: 'My Tree',
children: [
{
name: 'hello',
isFolder: false,
},
{
name: 'works',
isFolder: true,
children: [
{
name: 'child2',
isFolder: true,
},
{
name: 'child3',
isFolder: false,
},
]
}
]
}
Vue.component('layer', {
render: function renderChild (createElement) {
if(data.children.length){
return createElement('ul', data.children.map(function(child){
return createElement('li', {
'class' : {
isFolder: child.isFolder,
isFile: !child.isFolder
},
attrs: {
id: "baa"
},
domProps: {
innerHTML: child.name,
},
on:{
click: function(){
console.log("yes");
},
dblclick: function(){
console.log("doubleclicked");
if(child.children.length){
// if this has children array, create whole "layer" component again.
}
}
}}
)
}))
}
},
props: {
level: {
type: Number,
required: true
},
name: {
type: String,
}
}
})
new Vue({
el: '#fileManagerContainer',
data: data,
render (h) {
return (
<layer level={1} name={"pseudo"}>
</layer>
)
}
})
My question is, how to write that recursive call, which will render the whole Layer component on the doubleclick event, if the element has children array.
Thank you in advance for any reactions, suggestions or answers :)
I know this is a very old question, so my answer won't be useful to the OP, but I wanted to drop in to answer because I found myself with the very same problem yesterday.
The answer to writing these recursive render functions is to not try to recurse the render function itself at all.
For my example, I had a set of structured text (ish) - An array of objects which represent content - which can be nested, like so:
[
// each array item (object) maps to an html tag
{
tag: 'h3',
classes: 'w-full md:w-4/5 lg:w-full xl:w-3/4 mx-auto font-black text-2xl lg:text-3xl',
content: 'This is a paragraph of text'
},
{
tag: 'img',
classes: 'w-2/3 md:w-1/2 xl:w-2/5 block mx-auto mt-8',
attrs: {
src: `${process.env.GLOBAL_CSS_URI}imgsrc.svg`,
alt: 'image'
}
},
{
tag: 'p',
classes: 'mt-8 text-xl w-4/5 mx-auto',
content: [
{
tag: 'strong',
content: 'This is a nested <strong> tag'
},
{
content: ' '
},
{
tag: 'a',
classes: 'underline ml-2',
content: 'This is a link within a <p> tag',
attrs: {
href: '#'
}
},
{
content: '.'
}
]
}
]
Note the nested elements - These would need recursion to render properly.
The solution was to move the actual rendering work out to a method as follows:
export default {
name: 'block',
props: {
block: {
type: Object,
required: true
}
},
methods: {
renderBlock (h, block) {
// handle plain text without a tag
if (!block.tag) return this._v(block.content || '')
if (Array.isArray(block.content)) {
return h(block.tag, { class: block.classes }, block.content.map(childBlock => this.renderBlock(h, childBlock)))
}
// return an html tag with classes attached and content inside
return h(block.tag, { class: block.classes, attrs: block.attrs, on: block.on }, block.content)
}
},
render: function(h) {
return this.renderBlock(h, this.block)
}
}
So the render function calls the renderBlock method, and that renderBlock method is what calls itself over and over if it needs to - The recursion happens within the method call. You'll see that the method has a check to see whether the content property is of an Array type - At this point it performs the same render task, but rather than passing the content as-is, it passes it as an Array map, calling the same render method for each item in the array.
This means that, no matter how deeply the content is nested, it will keep calling itself until it has reached all the way to the "bottom" of the stack.
I hope this helps save someone some time in the future - I certainly wish I'd had an example like this yesterday - I would have saved myself a solid couple of hours!

Meteor js: Create text index in collection

I created a category collection with a name and description field. i.e
Categories = new Meteor.Collection('categories');
CategoriesSchema = new SimpleSchema({
translation:{
type: [Object]
},
"translation.$": {
type: Object
},
"translation.$.name": {
type: String
},
"translation.$.description": {
type: String
}
});
Categories.attachSchema( CategoriesSchema );
I need to create a text index to find categories by name or description.
i saw Meteor js: Create index in user collection but that not about my need i also tried
Meteor.startup(function () {
Categories._createIndex(
{ 'translation.$.name' : "text" },
{ 'translation.$.description' : "text" },
{ default_language: "english" }
);
});
I read about create Index in the meteor but it did not work or I did that wrong? any help will be greatly appreciated.
You are using the wrong API.
You should be calling _ensureIndex on your collection.

Categories

Resources