i am using google.maps.places.Autocomplete services.
autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete_textarea')),
{ types: ['geocode'] });
google.maps.event.addListener(autocomplete, 'place_changed', function() {
fillInAddress();
});
but i am curious, can i exclude specific country in search box? Means i dont want to populate search result in input field for US.
Related
I want to add content to a repeatable component in my beforeUpdate hook. (adding a changed slug to a “previous slugs” list)
in v3, I could just push new data on the component array and it would save.
in v4, it doesn’t work like that. Component data now holds __pivot: and such. I do not know how to add new data to this. I’ve tried adding a component with the entityService first, and adding that result to the array. It seemed to work, but it has strange behavior that the next saves puts in two entries. I feel like there should be an easier way to go about this.
It seems like the way to go about this is to create the pivot manually:
// create an entry for the component
const newRedirect = await strapi.entityService.create('redirects.redirect', {
data: {
from: oldData.slug,
},
});
// add the component to this model entry
data.redirects = [...data.redirects, {
id: newRedirect.id,
__pivot: { field: 'redirects', component_type: 'redirects.redirect' },
}];
But this feels pretty hacky. If I change the components name or the field key, this will break. I'd rather have a Strapi core way of doing this
the way strapi currently handles components is by providing full components array, so in case you want to inject something, you have to read components first and then apply full update, if it makes it clear.
Update
So after few hours of searching, had to do few hours of trail and error, however here is the solution, using knex:
module.exports = {
async beforeUpdate(event) {
// get previous slug
const { slug: previousSlug } = await strapi.db
.query("api::test.test")
.findOne({ where: event.params.where });
// create component
const [component] = await strapi.db
// this name of components table in database
.connection("components_components_previous_slugs")
.insert({ slug: previousSlug })
.returning("id");
// append component to event
event.params.data.previousSlugs = [
...event.params.data.previousSlugs,
{
id: component.id,
// the pivot, you have to copy manually
// 'field' is the name of the components property
// 'component_type' is internal name of component
__pivot: {
field: "previousSlugs",
component_type: "components.previous-slugs",
},
},
];
},
};
So, seems there is no service, or something exposed in strapi to create component for you.
The stuff that also required to be noted, on my first attempt i try to create relation manually in tests_components table, made for me after i added a repeatable component, to content-type, but after an hour more i found out that is WRONG and should not be done, seems strapi does that under the hood and modifying that table actually breaks logic...
so if there is more explanation needed, ping me here...
result:
You can update, create and delete component data that is attached to a record with Query Engine API, which is provided by Strapi.
To modify component data you just need the ID.
const { data } = event.params;
const newData = {
field1: value1,
etc...
};
await strapi.query('componentGroup.component').update({
where: { id: data.myField.id },
data: newData
})
When you have a component field that equals null you need to create that component and point to it.
const tempdata = await strapi.query('componentGroup.component').create(
{ data: newData }
);
data.myField = {
id: tempdata.id,
__pivot: {
field: 'myField',
component_type: 'componentGroup.component'
}
}
Se the Strapi forum for more information.
I have a gatsby site with the contentful plugin and graphql queries (setup is working).
[EDIT]
My gatsby setup pulls data dynamically using the pageCreate feature. And populates my template component, the root graphql query of which I've shared below. I can create multiple pages using the setup if the pages on contentful follow the structure given in the below query.
[/EDIT]
My question is about a limitation I seemed to have come across or just don't know enough grpahql to understand this yet.
My high level content model 'BasicPageLayout' consists of references to other content types through the field 'Section'. So, it's flexible in terms of which content types are contained in the 'BasicPageLayout' and the order in which they are added.
Root page query
export const pageQuery = graphql`
query basicPageQuery {
contentfulBasicPageLayout(pageName: {eq: "Home"}) {
heroSection {
parent {
id
}
...HeroFields
}
section1 {
parent {
id
}
...ContentText
}
section2 {
parent {
id
}
...ContentTextOverMedia
}
section3 {
parent {
id
}
...ContentTextAndImage
}
section4 {
parent {
id
}
...ContentText
}
}
}
The content type fragments all live in the respecitve UI components.
The above query and setup are working.
Now, I have "Home" Hard coded because I'm having trouble creating a flexible reusable query. I'm taking advantage of contentful's flexible nature when creating the models, but haven't found a way to create that flexibility in the graphql query for it.
What I do know:
Graphql query is resolved at run time, so everything that needs to be fetched should be in that query. It can't be 'dynamic'.
Issue: The 'Section' fields in the basicPageLayout can link to any content type. So we can mix and match the granular level content types. How do I add the content type fragment (like ContentTextAndImage vs ContentText) so it is appropriate for that section instance ('Section' field in the query)?
In other words
I'd like the root query to get 'Home' data which might have 4 sections, all of type - ContentTextOverMedia
as well as 'About ' data that might have also have 4 sections but with alternating types - ContentText and ContentTextAndImage
This is the goal because I want to create content (Pages) by mix-matching content types on contentful, without needing to update the code each time a new Page is created. Which is why Contentful is useful and was picked in the first place.
My ideas so far:
A. Run two queries, in series. One fetches the parent.id on each section and that holds the content type info. Second fetches the data using the appropriate fragment.
B. Fetch the JSON file of the basicPageLayouts content instance (such as 'Home') separately through Contentful API, and using that JSON file create the graphql string to be used in each instance (So, different layout for Home, About, and so on)
This needs more experimentation, not sure if it's viable, could also be more complex then it needs to be.
So, please share thoughts on the above paths that I'm exploring or another solution that I haven't considered using graphql or gatsby's features.
This is my first question on SO btw, I've spent some time on refining it and trying to follow the guidelines but please do give me feedback in comments so I can improve even if you don't have an answer to my question.
Thanks in advance.
If I understood correctly you want to create pages dynamically from the data coming from Contentful.
You can achieve this using the Gatsbyjs Node API specifically createPage.
In your gatsby-node.js file you can have something like this
const fs = require('fs-extra')
const path = require('path')
exports.createPages = ({graphql, boundActionCreators}) => {
const {createPage} = boundActionCreators
return new Promise((resolve, reject) => {
const landingPageTemplate = path.resolve('src/templates/landing-page.js')
resolve(
graphql(`
{
allContentfulBesicPageLayout {
edges {
node {
pageName
}
}
}
}
`).then((result) => {
if (result.errors) {
reject(result.errors)
}
result.data.allContentfulBesicPageLayout.edges.forEach((edge) => {
createPage ({
path: `${edge.node.pageName}`,
component: landingPageTemplate,
context: {
slug: edge.node.pageName // this will passed to each page gatsby create
}
})
})
return
})
)
})
}
Now in your src/templates/landing-page.js
import React, { Component } from 'react'
const LandingPage = ({data}) => {
return (<div>Add you html here</div>)
}
export const pageQuery = graphql`
query basicPageQuery($pageName: String!) {
contentfulBasicPageLayout(pageName: {eq: $pageName}) {
heroSection {
parent {
id
}
...HeroFields
}
section1 {
parent {
id
}
...ContentText
}
section2 {
parent {
id
}
...ContentTextOverMedia
}
section3 {
parent {
id
}
...ContentTextAndImage
}
section4 {
parent {
id
}
...ContentText
}
}
}
note the $pageName param that's what was passed to the component context when creating a page.
This way you will end up creating as many pages as you want.
Please note: the react part of the code was not tested but I hope you get the idea.
Update:
To have a flexible query you instead of having your content Types as single ref field, you can have one field called sections and you can add the section you want there in the order you desire.
Your query will look like this
export const pageQuery = graphql`
query basicPageQuery($pageName: String!) {
contentfulBasicPageLayout(pageName: {eq: $pageName}) {
sections {
... on ContentfulHeroFields {
internal {
type
}
}
}
}
Khaled
I want to use kendo AutoComplete in a kendoGrid for inline editing. When user inputs anything I'd use it to call a RESTful web service to return a list of products with names that start with the input value.
My questions are:
My web service expects a request looks like http://localhost/myService/appl where "appl" is the value that user enters and the prefix. However, kendo seems to always format the request something like http://localhost/myService?product=appl. How do I change the format?
How do I get the value that user has input in the grid (the AutoComplete textbox) so I can pass it in the request URL?
Define in the DataSource of your autocomplete an url function.
In that function, you can get typed value as:
var val = op.filter.filters[0].value;
and then return the url with the composed value.
Then it is something like:
dataSource: new kendo.data.DataSource({
transport: {
read: {
url: function (op) {
var val = op.filter.filters[0].value;
return "/myService/" + val;
}
}
}
})
I queried my database using Breezejs using the following code:
viewModel = {
products = ko.observableArray([])
};
var manager = new entityModel.EntityManager('/api/Products');
manager.executeQuery(query)
.then(function (data) {
viewModel.products.removeAll();
viewModel.products(data.results);
});
However the products rows contain numeric properties like Quantity which are wired to my page using the data-bind property. On saving the model through manager.saveChanges() I get a validation error. This is because KnockoutJS saves the edited numbers as strings.
What's the recommended way to get around this issue?
As of breeze v 0.80.2, this capability is now supported. ( along with the capability to customize type coercion)
One option is to create a CustomBinding.
I use this for decimals:
ko.bindingHandlers.decimal = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
$(element).blur(function () {
var value = valueAccessor();
var valor = Globalize.parseFloat($(element).val());
if (ko.isWriteableObservable(value)) {
value(valor);
ko.bindingHandlers.decimal.update(element, valueAccessor);
}
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).val(Globalize.format(value, "n2"));
}
};
It's a good question.
Currently, breeze does not attempt type coercion, but...
We have discussed having Breeze automatically attempt to coerce any values used within a set operation to the datatype of the property being set ( as defined in breeze metadata). This would occur across all binding libraries, (i.e angular, backbone etc) as well as knockout.
Please feel free to add this to the breeze User Voice. We take these submissions very seriously.
If column names are sidx,sord,filters , jqGrid getting data is broken. I tried to add underscores to them using code below but those parameters are still passed without underscores. Other parameters like _rowid, _page etc. are passed properly with underscores.
How to use sidx,sord,filters as column names in jqgrid ?
jQuery.extend(jQuery.jgrid.defaults, {
prmNames: { id: "_rowid", oper: "_oper", page: "_page",
sidx: "_sidx", sord: "_sord", page: "_page", rows: "_rows", filters: "_filters"
}
});
I don't understand what you mean under "If column names are sidx,sord,filters , jqGrid getting data is broken". Nevertheless if you need you can rename or remove the jqGrid parameters with two ways: prmNames and serializeGridData.
You should carefully examine the list of default values of the prmNames. There are no possibility to rename filters in the way, but to rename the name of other parameters you should use
$.extend(jQuery.jgrid.defaults, {
prmNames: {
id: "_rowid", page: "_page", rows: "_rows",
oper: "_oper", sort: "_sidx", order: "_sord"
}
});
(sort and order instead of sidx and sord). To rename filters to _filters and to remove sending of empty searchField, searchString and searchOper you can do almost the same what I described here:
serializeGridData: function (postData) {
var myPostData = $.extend({}, postData); // make a copy of the input parameter
myPostData._filters = myPostData.filters;
delete myPostData.filters;
delete myPostData.searchField;
delete myPostData.searchString;
delete myPostData.searchOper;
return myPostData;
}
Using Fiddler or Firebug you can verify that in the URL of the demo are used the following parameters
_search=true&nd=1313235583212&_rows=10&_page=1&_sidx=invdate&_sord=desc&_filters=...
like you as need.