Filter custom JSON - javascript

I have this JSON
const Menu = [{
icon: "home",
text: "Inicio",
url: {
name: "home"
},
typeUrl: "exact"
},
{
heading: "Operaciones"
},
{
icon: "settings",
"icon-alt": "settings",
text: "Operación",
model: true,
children: [{
icon: "add",
text: "Cargar Pedidos",
url: {
name: "cargarpedidos"
}
},
{
icon: "playlist_add_check",
text: "Aprobar Pedidos"
},
{
icon: "content_copy",
text: "Remitir Pedidos"
}
]
},
{
heading: "Informes"
},
{
icon: "widgets",
"icon-alt": "widgets",
text: "Informe",
model: false,
children: [{
icon: "view_module",
text: "Usuarios"
},
{
icon: "view_module",
text: "Perfiles"
},
{
icon: "view_module",
text: "Permisos Perfiles"
},
{
icon: "view_module",
text: "Resetear Password"
},
{
icon: "view_module",
text: "Cambiar Password"
}
]
},
{
heading: "APSI"
},
{
icon: "view_module",
text: "Informes del APSI"
},
{
heading: "Administaciones"
},
{
icon: "extension",
"icon-alt": "extension",
text: "Administración",
model: false,
children: [{
icon: "face",
text: "Usuarios"
},
{
icon: "assignment_ind",
text: "Perfiles"
},
{
icon: "settings",
text: "Permisos Perfiles"
},
{
icon: "cached",
text: "Resetear Password"
},
{
icon: "fingerprint",
text: "Cambiar Password"
}
]
},
{
heading: "Mantenimientos"
},
{
icon: "build",
"icon-alt": "build",
text: "Mantenimiento",
model: true,
children: [{
icon: "group_work",
text: "Departamentos"
},
{
icon: "room",
text: "Locales"
},
{
icon: "donut_large",
text: "Unidades de Medida"
},
{
icon: "spellcheck",
text: "Articulos"
},
{
icon: "toc",
text: "Categorías"
},
{
icon: "supervisor_account",
text: "Usuario Aprobador"
}
]
}
];
export default Menu;
I use it to create the menu of my system that I am developing with VueJS + Vuetify and I need to filter it through the "text" field by words that contain it regardless of position, in the style of SQL's like '%filter%', also without distinguish upper and lower case. As far as possible don't distinguish accents (but this is already very picky, if it is not possible or it is very cumbersome, I can skip it).
Also in the case that the pattern of coincidence is in a child node and not in the father, does this father also have to appear in the filter, is it possible to do this with a Javascript function?
The menu looks like this:
I expect this behavior

I am not sure but if you want to get text fields of children, I think something like that should do it. You just need to initialize all your parents with empty children arrays:
tempArr = Menu.filter(function (elem) {
return elem.children == null ;
});
textFields = tempArr.map(({ text }) => text)

Here is how you can filter match regular expression in an array.
var arr = [{
icon: "add",
text: "Cargar Pedidos",
url: {
name: "cargarpedidos"
}
},
{
icon: "playlist_add_check",
text: "Aprobar Pedidos"
},
{
icon: "content_copy",
text: "Remitir Pedidos"
},
{
icon: "content_copy",
text: "Remitir Pedisddos"
},
{
icon: "content_copy",
text: "Remitir Pediados"
},
{
icon: "content_copy",
text: "Remitir asdaasd"
}
];
var name = "dido";
var regex = "/" + name + "/g";
var filtered = arr.filter(
(val) => val.text.match(name)
);
console.log(filtered);
These are the basics of filtering. If you want to search for any property in an array object than use this function:
var result = Menu.filter(function(o) {
return Object.keys(o).some(function(k) {
return o[k].toString().toLowerCase().indexOf('dido') != -1;
})
})
console.log(result)

Related

I need to filter an array of object that contains an array of object

So here's my data, I need to reduce? or filter it based on the given search string.
const contents = [
{
title: "Accounts",
links: [
{
header: "Accounts by Status",
},
],
},
{
title: "Executions",
links: [
{
header: "Purchase and Sales",
},
{
header: "AMLA Transactions Proof List",
},
{
header: "Account Ranking",
},
{
header: "Trading Summary",
},
],
},
];
const search = "account";
console.log(
contents.filter((content) =>
content.links.some((link) =>
link.header.toLowerCase().includes(search.toLowerCase())
)
)
);
.as-console-wrapper { max-height: 100% !important; }
Can someone guide me in the right direction? I think reduce with filter can do the job but I don't know where to start. Thanks!
If my search string is 'account'
My desired output should be something like this
[{
title: 'Accounts',
links: [{
header: 'Accounts by Status'
}]
},
{
title: 'Executions',
links: [{
header: 'Account Ranking'
}]
}
]
You need to rebuild content with links, if they match.
const
contents = [{ title: 'Accounts', links: [{ header: 'Accounts by Status' }] }, { title: 'Executions', links: [{ header: 'Purchase and Sales' }, { header: 'AMLA Transactions Proof List' }, { header: 'Account Ranking' }, { header: 'Trading Summary' }] }],
search = 'account',
result = contents.flatMap(content => {
const links = content.links.filter(({ header }) => header
.toLowerCase()
.includes(search.toLowerCase())
);
return links.length
? { ...content, links }
: [];
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This solution filters the links array by search string, and if non is found removes the item all together. The test input contains one more item that produces no hit: { title: 'No hit', links: [{ header: 'Something else' }] }
const input = [
{ title: 'Accounts', links: [{ header: 'Accounts by Status' }] },
{ title: 'Executions', links: [{ header: 'Purchase and Sales' }, { header: 'AMLA Transactions Proof List' }, { header: 'Account Ranking' }, { header: 'Trading Summary' }] },
{ title: 'No hit', links: [{ header: 'Something else' }] }
];
const searchString = 'account';
// for performance perform lowercase once ahead of time:
const search = searchString.toLowerCase();
const result = input.map(obj => {
let arr = obj.links.filter(o => o.header.toLowerCase().includes(search));
if(arr.length) {
// don't change original input, but return a filtered copy
return {
title: obj.title,
links: arr
};
} else {
return null;
}
}).filter(Boolean);
console.log(result);

Sanity CMS and Leaflet.Js while using geolocation API

I have created a sanity schema which works perfectly according to the tutorial. However I have a leaflet.js plugin and I am trying to get it to auto find my location when I create a new template in the sanity studio. This was already done in the tutorial below, but when I do it, I get the sanity map showing up but I do not get the marker on my current location. Instead I get the default San-Francisco.
In the tutorial the lady gets allows the browser to share her location. However I do not get that prompt. Is this something to do with localhost?
I am following this tutorial but I don't know what I missed.
Relevant parts from 31.00-37.00. Tutorial below:
https://www.youtube.com/watch?v=YtFfUER8ta8
Below is my posts.js
const getPosition = (options) => {
if (navigator.geolocation) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, options);
});
}
};
export default {
name: "post",
title: "Blog Post",
type: "document",
initialvalue: async () => ({
postedAt: await getPosition()
.then(({ coords }) => {
const { latitude, longtitude, altitude } = coords;
return {
_type: "geopoint",
lat: latitude,
lng: longtitude,
alt: altitude || undefined,
};
})
.catch(() => undefined),
}),
fields: [
{
name: "title",
title: "Title",
type: "string",
},
{
name: "postedAt",
type: "geopoint",
title: "Location",
},
{
name: "slug",
title: "Slug",
type: "slug",
options: {
source: "title",
maxLength: 96,
},
},
{
name: "author",
title: "Author",
type: "reference",
to: { type: "author" },
},
{
name: "mainImage",
title: "Main image",
type: "image",
options: {
hotspot: true,
},
},
{
name: "categories",
title: "Categories",
type: "array",
of: [{ type: "reference", to: { type: "category" } }],
},
{
name: "publishedAt",
title: "Published at",
type: "datetime",
},
{
name: "body",
title: "Body",
type: "blockContent",
},
],
preview: {
select: {
title: "title",
author: "author.name",
media: "mainImage",
},
prepare(selection) {
const { author } = selection;
return Object.assign({}, selection, {
subtitle: author && `by ${author}`,
});
},
},
};
leaflet-input.json
{
"tileLayer": {
"attribution": "© OpenStreetMap contributors",
"url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
}
}

How to add objects to an array during creation using a loop in Javascript?

I am trying to write some meta information for a website (using vue-meta) and I need to add some tags as objects within an array named meta.
The code is like this:
metaInfo() {
return {
htmlAttrs: { lang: "en"
},
title: this.Post.Title,
meta: [
{
name: "description", content: this.Post.Title
},
{
name: "date", content: this.Post.DateCreated
},
{
name: "author", content: this.Post.Author
},
// Now I need multiple objects of: {name: "tag", content: "Tags.TagName"} like this but doesn't work:
function() {
this.Tags.forEach(function (TagName, index) {
{ property: "tag", content: "TagName" }
})
}
],
}
}
How can I create my array so that I end up with this for example:
meta: [
{
name: "description", content: "Javascript question"
},
{
name: "date", content: "20200421"
},
{
name: "author", content: "volumeone"
},
{ property: "tag", content: "Javascript" }
,
{ property: "tag", content: "Programming" }
,
{ property: "tag", content: "Newbie" }
]
you can do such sort of thing.
var meta = [{
name: "description", content: this.Post.Title
},
{
name: "date", content: this.Post.DateCreated
},
{
name: "author", content: this.Post.Author
}]
this.Tags.forEach(function (TagName, index) {
meta.push({ property: "tag", content: "TagName" })
})
metaInfo() {
return {
htmlAttrs: { lang: "en"
},
title: this.Post.Title,
// or you can just write "meta" instead of "meta: meta" its an shorthand // code
meta: meta
}
}
Unless I'm missing something, you can just use push and pass the object.
var meta = [];
meta.push({"property" : "tag","content" : "test"});
console.log(meta);

v2 Wix React-native-navigation: how to actually implement side Menu with bottomTabs?

I am having a bit of trouble implementing the sideMenu to the following code: (see the startTabs).
I call this after "login" is clicked on my root screen. The root screen looks like the following:
Navigation.setRoot({
root: {
stack: {
children: [{
component: {
name: "navigation.playground.WelcomeScreen",
passProps: {
text: "stack with one child"
},
alignment: "center",
options: {
topBar: {
visible: true,
title: {
text: "main screen"
}
}
}
}
}]
}
}
});
const startTabs = () => {
Promise.all([
Icon.getImageSource("md-map", 30),
Icon.getImageSource("ios-share-alt", 30)
]).then(sources => {
Navigation.setRoot({
root: {
bottomTabs: {
children: [{
stack: {
children: [{
component: {
name: "navigation.playground.FindPlaceScreen",
options: {
bottomTab: {
text: "Find Place",
icon: sources[0]
},
topBar: {
visible: true,
title: {
text: "Find Place"
}
}
}
}
}
]
}
},
{
stack: {
children: [{
component: {
name: "navigation.playground.SharePlaceScreen",
options: {
bottomTab: {
text: "Share Place",
icon: sources[1]
},
topBar: {
// visible: true,
title: {
text: "Share Place"
}
}
}
}
}]
}
}
]
}
}
});
});
};
Now in order for me to implement sideMenu after login, Would I implement it in the "startTabs"? or elsewhere?
Solved this. Sorry I am a new programmer, so I had a spelling mistake in my sideDrawer component where "render" was spelled "redner". Took me the longest time to figure this out!!!
Otherwise the code I pasted in initial question is correct (for anyone who looks at this for reference). Thanks!

get path from JSON model

I already created dropdown menu. I have a problem with event press. I want get context from JSON when I press the menu.
JSON:
dropdownMenu: {
kepesertaan:[
{
name: "Menu1",
icon: "sap-icon://crop",
sub: [
{
name: "Submenu1-1",
icon: "sap-icon://create-session"
},
{
name: "Submenu1-2",
icon: "sap-icon://create-form"
}
]
},
{
name: "Menu2",
icon: "sap-icon://detail-view",
sub: [
{
name: "Submenu2-1",
icon: "sap-icon://add-activity"
},
{
name: "Submenu2-2",
icon: "sap-icon://action"
}
]
},
{
name: "Menu3",
icon: "sap-icon://delete",
sub: [
{
name: "Submenu3-1",
icon: "sap-icon://add-favorite"
},
{
name: "Submenu3-2",
icon: "sap-icon://add-document"
}
]
}
]
}
JS:
handleMenuItemPressKepesertaan: function(oEvent) {
var app = sap.ui.getCore().byId("menuEventingKepesertaan");
var oModel = app.getModel("kepesertaanmodel");
var oContext = oModel.getProperty("/1"); // get context from property by path
alert(oContext.name);
// alert(oContext.sub[0].name);
var bindingContext = sap.ui.getCore().getBindingContext();
var path = bindingContext.getPath();
alert(path);
}
I tried and alert path but failed. getPath() is not a function or undefined.
and this path will change the code "var oContext = oModel.getProperty("/1");". value "/1" is a path. and how to fix this problem? for information, the menu in fragment xml.

Categories