Here's how my data looks exactly, coming back from the server:
[
{
"sprout-framework": {
"state": {
"string": "Activate",
"decision": "activate"
},
"data": [
{
"name": "Sprout Framework",
"slug": "sprout-framework",
"source": "C:\\xampp\\htdocs\\wordpress/wp-content/themes/amaranth/Includes/Plugins/sprout-framework.zip",
"required": true,
"version": "1.0",
"force_activation": false,
"force_deactivation": false,
"external_url": "",
"is_callable": "",
"file_path": "sprout-framework/index.php",
"source_type": "bundled"
}
]
}
},
{
"elementor": {
"state": {
"string": "Install",
"decision": "install"
},
"data": [
{
"name": "Elementor",
"slug": "elementor",
"source": "C:\\xampp\\htdocs\\wordpress/wp-content/themes/amaranth/Includes/Plugins/elementor.2.1.6.zip",
"required": false,
"version": "2.1.6",
"force_activation": false,
"force_deactivation": false,
"external_url": "",
"is_callable": "",
"file_path": "elementor",
"source_type": "bundled"
}
]
}
}
]
For each one of these items, I render a <li> containing the details but depending on its [key].state.decision, I might choose to render it different or even show some buttons. For example, if an item comes back with the state.decision: activate back, I will have to hide the install button and instead show the activate one.
I'm currently rendering (using an older version of Mustache) as such:
/**
*
* #param {*} pluginsData
*/
const generateRequriedPluginsMarkup = (pluginsData) => {
const allPluginsTemplate = $('#plugins-to-install-list');
const individualPluginTemplate = $('#plugins-to-install-item');
let html = '';
for(let i = 0; i < pluginsData.length; i++) {
for(const property in pluginsData[i]) {
if (pluginsData[i].hasOwnProperty(property)) {
html += mustache(individualPluginTemplate.html(), {
'pluginSlug': pluginsData[i][property].data[0].slug,
'pluginState': pluginsData[i][property].state.decision,
'pluginName': pluginsData[i][property].data[0].name,
'translatedText_installPlugin': 'Install',
'translatedText_activatePlugin': 'Activate'
});
}
}
}
html = mustache(allPluginsTemplate.html(), {
plugins: html
});
return html;
}
With the Mustache templates being:
<!-- Plugins to Install -->
<script type="template/mustache" id="plugins-to-install-list">
<ul id="plugins-to-install-list">
{{{plugins}}}
</ul>
</script>
<!-- Plugins to Install Item-->
<script type="template/mustache" id="plugins-to-install-item">
<li id="install-plugin-{{{pluginSlug}}}" class="plugin-to-install" data-state="{{{pluginState}}}" data-failed="no" data-installed="no" data-activated="no">
<h4 class="plugin-name">{{{pluginName}}}</h4>
<div class="plugin-buttons">
<button class="install-plugin">{{{translatedText_installPlugin}}}</button>
<button class="activate-plugin hidden">{{{translatedText_activatePlugin}}}</button>
</div>
</li>
</script>
Is this possible?
Related
I am currently making a breadcrumbs section for a website. Ignoring files, I want the folders to appear in the breadcrumbs when the folder name is clicked in the sidebar.
However, when there are 2 folders inside the same folder and I click the both of them, I want the latest folder clicked to appear on the breadcrumbs, and not the both of them. Is this possible?
I am currently using sveltekit and breadcrumbs from DaisyUI.
Currently, I have a function sidebarfolder in sidebar.svelte that changes currentFolder when folder name is clicked
When currentFolder changes, it gets added to currentFolderFlow. This currentFolderFlow will then be the sequence of the breadcrumbs
Folders.json
[
{
"name": "Documents",
"files": [
{
"name": "Quarterly Results"
}
]
},
{
"name": "Favourites",
"files": [
{
"name": "Brawl Stars",
"files": [
{
"name": "NS dying in 5 seconds"
},
{
"name": "Josiah raping NS"
}
]
},
{
"name": "Coding",
"files": [
{
"name": "Coding is so fun"
},
{
"name": "I love svelte",
"files": [
{
"name": "REPL"
},
{
"name": "oh nooo"
}
]
}
]
},
{
"name": "Favourites 1"
},
{
"name": "Favourites 2"
},
{
"name": "Favourites 3"
}
]
},
{
"name": "Knowledge Base 1"
}
]
Sidebar.svelte
<script>
export let currentFolder
export let currentFolderFlow
export let expanded = false;
export let name;
export let files;
const sideBarFolder = (folderName) => {
if (currentFolder === folderName) {
return false
}
currentFolder = folderName
if (!currentFolderFlow.includes(folderName)) {
currentFolderFlow = [...currentFolderFlow, folderName]
} else {
currentFolderFlow = currentFolderFlow.filter(i => currentFolderFlow.indexOf(i) <= currentFolderFlow.indexOf(folderName))
}
}
</script>
<button class=" pl-1" on:click={() => sideBarFolder(name)}>{name}</button>
Main page
<script>
import TreeView from './side-bar.svelte'
let currentFolderFlow = ['Knowledge Base']
let currentFolder = 'Knowledge Base'
</script>
<!-- Breadcrumbs -->
<div class="flex-1 px-3">
<div class="text-md breadcrumbs border rounded-lg p-3">
<ul id="breadcrumbs">
{#each currentFolderFlow as folderFlow}
<li>{folderFlow}</li>
{/each}
</ul>
</div>
</div>
I am building an add-on for Google Workspace using Apps Script and the card based GUI.
I am having trouble aligning a button set to the right/end using Apps Script syntax.
Using the Card Builder Tool allows to align button sets to the start, center or end. The JSON output shows a key value pair of "horizontalAlignment": "END" for the widget.
{
"sections": [
{
"widgets": [
{
"buttonList": {
"buttons": [
{
"text": "Button 1",
"onClick": {
"action": {
"function": "TODO",
"parameters": []
}
}
},
{
"text": "Button 2",
"onClick": {
"action": {
"function": "TODO",
"parameters": []
}
}
},
{
"text": "Button 2",
"onClick": {
"action": {
"function": "TODO",
"parameters": []
}
}
}
]
},
"horizontalAlignment": "END"
}
],
"header": ""
}
]
}
However, no apps script output is generated.
function buildCard() {
let cardSection1ButtonList1Button1Action1 = CardService.newAction()
.setFunctionName('TODO')
.addParameters({});
let cardSection1ButtonList1Button1 = CardService.newTextButton()
.setText('Button 1')
.setTextButtonStyle(CardService.TextButtonStyle.TEXT)
.setOnClickAction(cardSection1ButtonList1Button1Action1);
let cardSection1ButtonList1Button2Action1 = CardService.newAction()
.setFunctionName('TODO')
.addParameters({});
let cardSection1ButtonList1Button2 = CardService.newTextButton()
.setText('Button 2')
.setTextButtonStyle(CardService.TextButtonStyle.TEXT)
.setOnClickAction(cardSection1ButtonList1Button2Action1);
let cardSection1ButtonList1Button3Action1 = CardService.newAction()
.setFunctionName('TODO')
.addParameters({});
let cardSection1ButtonList1Button3 = CardService.newTextButton()
.setText('Button 2')
.setTextButtonStyle(CardService.TextButtonStyle.TEXT)
.setOnClickAction(cardSection1ButtonList1Button3Action1);
let cardSection1ButtonList1 = CardService.newButtonSet()
.addButton(cardSection1ButtonList1Button1)
.addButton(cardSection1ButtonList1Button2)
.addButton(cardSection1ButtonList1Button3);
let cardSection1 = CardService.newCardSection()
.addWidget(cardSection1ButtonList1);
let card = CardService.newCardBuilder()
.addSection(cardSection1)
.build();
return card;
}
I tried experimenting with the CardService.HorizontalAlignment.END ENUM but didn't find where to set it and couldn't find it in the documentation.
Anybody found a solution?
EDIT: I also filed a request to Issue Tracker
I have a need to get a list of all nodes (guid) in my json doc where the enabled key is set to true. What is the best and most effective way to read all parent nodes as well as possible children. In my case children will always be under the items key and children can also have there own children. I came up with some basic script that will check 2 levels deep but i was hoping there is a better approach which will make this more flrxible where i dont have to hardcode each level.
const enabledguid = []
function getenabled() {
mydata.jsondoc.forEach(i => {
if (i.enabled === true) {
enabledguid.push(i.guid)
}
// Check if Parent has children
if (i.items && i.items.length > 0){
console.log('we have children ' + i.items.length)
i.items.forEach(i => {
if (i.enabled === true) {
enabledguid.push(i.guid)
}
if (i.items && i.items.length > 0){
console.log('Child has children ' + i.items.length)
i.items.forEach(i => {
if (i.enabled === true) {
enabledguid.push(i.guid)
}
})
}
})
}
})
console.log(enabledguid)
}
getenabled()
Here is a sample of a json file
[
{
"enabled": true,
"guid": "F56AAC06-D2EB-4E1C-B84D-25F72973312E",
"name": "Farms",
"items": [
{
"enabled": true,
"guid": "144C0989-9938-4AEC-8487-094C23A5F150",
"name": "New Farm List"
},
{
"enabled": false,
"guid": "8FBA7B0B-566E-47CD-885B-1C08B57F34F6",
"name": "Farm Lists"
},
{
"enabled": true,
"guid": "FCD36DBD-0639-4856-A609-549BB10BEC1A",
"name": "Farm Upload"
},
{
"enabled": false,
"guid": "4264DA98-1295-4A65-97C6-313485744B4D",
"name": "Campaign",
"items": [
{
"enabled": false,
"guid": "9CBDC6BB-5B3D-4F53-B846-AFE55F34C1E9",
"name": "New Campaign"
},
{
"enabled": true,
"guid": "281490B5-C67D-4238-9D52-DE1DFA373418",
"name": "Campaign List"
}
]
}
]
},
{
"enabled": true,
"guid": "1A9127A3-7AC7-4E07-AFA0-B8F8571B1B14",
"name": "Vendor",
"items": [
{
"enabled": true,
"guid": "6E6B4DA9-D99D-42D8-A4FE-7C7A82B9F1BE",
"name": "Vendor List"
},
{
"enabled": false,
"guid": "63A61762-75FB-466A-8859-25E184C3E016",
"name": "Add Vendor"
}
]
}
]
This is a great exercise to learn about recursive functions, look it up.
In this problem the base case will be when you get to an item that does not have a subset of items.
const enabledguid = []
function getenabled(items) {
items.forEach(item => {
if (item.enabled === true) {
enabledguid.push(item.guid)
}
if (item.items) {
getenabled(item.items)
}
})
}
getenabled(jsondoc)
console.log(jsondoc)
based on what i found on recursive I came up with this one which does also do the same job.
mydata.filter( item => {
iratedObject(item)
})
function iratedObject(obj) {
for (prop in obj){
if(typeof(obj[prop]) =="object"){
iratedObject(obj[prop]);
} else {
if(obj['enabled'] === true && prop === 'guid'){
enabledguid.push(obj['guid'])
}
}}
}
I have got a list of image url form an api endpoint, and i wish to generate a video with these images in javascript.
after the video is created i'd display it on the page, im using react btw.
images = [
"https://some-bucket.s3.amazonaws.com/demo/0173.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0126.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0160.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0184.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0177.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0166.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0174.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0167.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0187.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0197.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0190.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0192.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0189.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0188.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0182.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0198.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0196.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0163.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0117.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0199.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0191.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0148.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0132.jpg"
]
I think what you might be looking for is the Transloadit /video/merge robot. For example, this template here will take all of the files uploaded and then convert them into an animated gif in order to be exported to an Amazon S3 bucket.
{
"steps": {
":original": {
"robot": "/upload/handle"
},
"animated": {
"robot": "/video/merge",
"use": {
"steps": [
{
"name": ":original",
"as": "image"
}
]
},
"result": true,
"duration": 7.8,
"framerate": "10",
"ffmpeg_stack": "v4.3.1",
"ffmpeg": {
"f": "gif",
"pix_fmt": "rgb24"
},
"resize_strategy": "pad"
},
"exported": {
"use": [
":original",
"animated"
],
"robot": "/s3/store",
"credentials": "YOUR_AWS_CREDENTIALS",
"url_prefix": "https://demos.transloadit.com/"
}
}
}
While, transloadit doesn't have native react integration, it can be used through uppy's robodog service. Here's a small React snippet that will take an array of files, run it through a specified template, and then output an array of results, using the template from before.
import Uppy from '#uppy/core'
import { Dashboard } from '#uppy/react'
import { Transloadit } from '#uppy/transloadit'
import '#uppy/core/dist/style.css'
import '#uppy/dashboard/dist/style.css'
const url_list = ["www.link1.com/image.png", "www.link2.com/image.png", "www.link3.com/image.png"]
const uppy = new Uppy()
.use(Transloadit, {
params: {
"auth": {
"key": "YOUR_TRANSLOADIT_AUTH_KEY"
}
"steps": {
"imported": {
"robot": "/http/import",
"url": url_list
},
"animated": {
"robot": "/video/merge",
"use": {
"steps": [
{
"name": "imported",
"as": "image"
}
]
},
"result": true,
"duration": 7.8,
"framerate": "10",
"ffmpeg_stack": "v4.3.1",
"ffmpeg": {
"f": "gif",
"pix_fmt": "rgb24"
},
"resize_strategy": "pad"
},
"exported": {
"use": [
"imported",
"animated"
],
"robot": "/s3/store",
"credentials": "YOUR_AWS_CREDENTIALS",
"url_prefix": "https://demos.transloadit.com/"
}
}
}
});
uppy.on("complete", (result) => {
console.log("Upload complete! We've uploaded these files: ", result.successful)
})
export default function Home() {
return (
<div className="container">
<Dashboard
uppy={uppy}
/>
</div>
)
}
I want to create HTML elements dynamically using JSON file.
{"myObject": {
"JAVA": {
"id": "JAVAsubj",
"path": "json/data.json"
},
"C#": {
"id": "JAVAsubj",
"path": "json/data1.json"
},
"C++": {
"id": "JAVAsubj",
"path": "json/data2.json"
}
}
}
This is my JSON file. i want to create HTML buttons dynamically. Buttons should be create like JAVA,C#,C++. if i add something next to C++ then that button should get created dynamically
You can try something like this FIDDLE
however, i changed the myObject to an array of json objects as follows:
var jsonObj = {"myObject":
[
{
title: 'JAVA',
id: "JAVAsubj",
path: "json/data.json"
},
{
title: "C#",
id: "JAVAsubj",
path: "json/data1.json"
},
{
title: "C++",
id: "JAVAsubj",
path: "json/data2.json"
}
]
}
var count = Object.keys(jsonObj.myObject).length;
var container= document.getElementById('buttons'); // reference to containing elm
for(var i=0;i<count;i++){
var obj= jsonObj.myObject[i];
var button = "<input type='button' value="+obj.title+"></input>"
container.innerHTML+=button;
}
First thing you need to do that get your JSON into js object :
var myJSON= {"myObject": {
"JAVA": {
"id": "JAVAsubj",
"path": "json/data.json"
},
"C#": {
"id": "JAVAsubj",
"path": "json/data1.json"
},
"C++": {
"id": "JAVAsubj",
"path": "json/data2.json"
}
}
}
now get the value of your object into dictionary like below :
var dctLanguages = myJSON["myObject"];
now to render buttons dynamically, just do this :
var strHTML = '';
for (var key in dctLanguages)
{
var language = dctLanguages[key];
strHTML += '<input type="button" id="'+language.id+'" value="'+key+'"/>';
}
and append this HTML into your container div as follows :
$(strHTML).appendTo("#container");
Hope this will work for you..
const info = [
{
"id": 1,
"img": "a.jpg",
"name": "Avinash Mehta",
"desc": "I am Web Developer"
},
{
"id": 2,
"img": "c.jpg",
"name": "Avinash",
"desc": "I am Web"
},
{
"id": 3,
"img": "b.jpg",
"name": "Mehta",
"desc": "I am Developer"
},
]
const main = document.querySelector(".main");
window.addEventListener("DOMContentLoaded", function(){
let displayInfo = info.map(function(profile){
return` <div class="profile">
<img src="${profile.img}" alt="">
<h2>${profile.name}</h2>
<p>${profile.desc}</p>
</div>`
});
displayInfo = displayInfo.join("");
main.innerHTML = displayInfo
})
This shoule help you
const info = [
{
"id": 1,
"img": "a.jpg",
"name": "Avinash Mehta",
"desc": "I am Web Developer"
},
{
"id": 2,
"img": "c.jpg",
"name": "Avinash",
"desc": "I am Web"
},
{
"id": 3,
"img": "b.jpg",
"name": "Mehta",
"desc": "I am Developer"
},
]
const main = document.querySelector(".main");
window.addEventListener("DOMContentLoaded", function(){
let displayInfo = info.map(function(profile){
return` <div class="profile">
<img src="${profile.img}" alt="">
<h2>${profile.name}</h2>
<p>${profile.desc}</p>
</div>`
});
displayInfo = displayInfo.join("");
main.innerHTML = displayInfo
})