Navigation from one form to another using Alpacajs - alpacajs

I have one form with one button next. On clicking this next button,it should navigate to other form.
I have created two forms but I am not able to link them.
$("#field1").alpaca({
"schema": {
"title": "Name Info",
"type": "object",
"properties": {
"firstName": {
"title": "First Name",
"type": "string"
},
"lastName": {
"title": "Last Name",
"type": "string"
}
}
},
"options": {
"form": {
"buttons": {
"next": {
"click": function() {}
}
}
}
}
});

Have you tried using the Wizards, I think that might help you. Tell me If this is not what you're looking for, I'll try to help you.

#smileisbest and #Shabbir-Dhangot, I've implemented two forms in the same page. Use the JSON library to serialize the data and send to the next form:
"click" : function() {
var editJsonData = JSON.stringify(this.getValue(), null, " ");
doNext(editJsonData);
}
Then add the call to the next form as a function:
// If JSON data is not null, the next form will display.
var doNext = function(jsonData) {
$("#NextForm").empty();
if (null != jsonData) {
// Validate user or data...
// This starts the Editor form
$("#NextForm").alpaca({
"data" : jsonData,
"schema" : {
"type" : "object",
"properties" : { ...
Use show/hide appropriately to hide the prior form:
$("#field1").hide();
$("#NextForm").show();

Related

ElasticSearch reindexing with selected fields result into addition of non selected empty field

Scenario:
We are using AWS ElasticSearch 6.8. We got an index (index-A) with a mapping structure consist of multiple nested objects and JSON hierarchy. We need to create new index (index-B) and move all documents from index-A to index-B.
We need to create index-B with only specific fields.
We need to rename field names while reindexing
e.g.
index-A mapping:
{
"userdata": {
"properties": {
"payload": {
"type": "object",
"properties": {
"Alldata": {
"Username": {
"type": "keyword"
},
"Designation": {
"type": "keyword"
},
"Company": {
"type": "keyword"
},
"Region": {
"type": "keyword"
}
}
}
}
}
}}
Expected structure of index-B mapping after reindexing with rename (Company-cnm, Region-rg) :-
{
"userdata": {
"properties": {
"cnm": {
"type": "keyword"
},
"rg": {
"type": "keyword"
}
}
}}
Steps we are Following:
First we are using Create index API to create index-B with above mapping structure
Once index is created we are creating an ingest pipeline.
PUT ElasticSearch domain endpoint/_ingest/pipeline/my_rename_pipeline
{
"description": "rename field pipeline",
"processors": [{
"rename": {
"field": "payload.Company",
"target_field": "cnm",
"ignore_missing": true
}
},
{
"rename": {
"field": "payload.Region",
"target_field": "rg",
"ignore_missing": true
}
}
]
}
Perform reindexing operation, payload for the same below
let reindexParams = {
wait_for_completion: false,
slices: "auto",
body: {
"conflicts": "proceed",
"source": {
"size": 8000,
"index": "index-A",
"_source": ["payload.Company", "payload.Region"]
},
"dest": {
"index": "index-B",
"pipeline": "my_rename_pipeline",
"version_type": "external"
}
}
};
Problem:
Once the reindexing is complete as expected all documents transferred to new index with renamed fields but there is one additional field which is not selected. As you can see below the "payload" object with metadata is also added to the new index after reindexing. This field is empty and consist of no data.
index-B looks like below after reindexing:
{
"userdata": {
"properties": {
"cnm": {
"type": "keyword"
},
"rg": {
"type": "keyword"
},
"payload": {
"properties": {
"Alldata": {
"type": "object"
}
}
}
}
}}
We are unable to find the workaround and need help how to stop this field from creating. Any help will be appreciated.
Great job!! You're almost there, you simply need to remove the payload field within your pipeline using the remove processor and you're good:
{
"description": "rename field pipeline",
"processors": [
{
"rename": {
"field": "payload.Company",
"target_field": "cnm",
"ignore_missing": true
}
},
{
"rename": {
"field": "payload.Region",
"target_field": "rg",
"ignore_missing": true
}
},
{
"remove": { <--- add this processor
"field": "payload"
}
}
]
}

Kentico Kontent runtime resolution

I am having issue with kentico kontent a bit. Basically when I call _deliveryClient.GetItemsAsync<object> I am getting null even though the json below is being brought back.
{
"item": {
"system": {
"id": "0b9e6cf0-a9aa-422b-9e14-1576adfb6324",
"name": "Home",
"codename": "home",
"language": "default",
"type": "home",
"sitemap_locations": [],
"last_modified": "2020-04-30T17:16:48.706142Z"
},
"elements": {
"header": {
"type": "text",
"name": "Header",
"value": "This is my name"
},
"description": {
"type": "text",
"name": "Description",
"value": ".net specialist"
},
"background": {
"type": "modular_content",
"name": "Background",
"value": [
"universe"
]
}
}
},
"modular_content": {
"universe": {
"system": {
"id": "a8898eef-0f4b-4646-af72-c0a1e41ab165",
"name": "Universe",
"codename": "universe",
"language": "default",
"type": "background",
"sitemap_locations": [],
"last_modified": "2020-04-30T17:19:02.9586245Z"
},
"elements": {
"user_vid_or_imag": {
"type": "multiple_choice",
"name": "User Vid or Imag",
"value": [
{
"name": "Video",
"codename": "video"
}
]
},
"background_item": {
"type": "asset",
"name": "Background Item",
"value": [
{
"name": "Time Lapse Video Of Night Sky.mp4",
"description": null,
"type": "video/mp4",
"size": 2076845,
"url": "https://preview-assets-us-01.kc-usercontent.com:443/..."
}
]
}
}
}
}
}
However, if I use the concretion I get the Model back as expected. This is an issue even for members of a class e.g. linked items. The problem is that we have lots of models so we have opted to use the ModelGenerator kentico provides. The thing is we cannot tell the the Generator not to generate some of the objects so it will overwrite everything even though we only want to update one model. So this means I cannot go into every model and change the to some concretion because that will be overwritten.
The documentation says that should always work so is this a bug? or am I making a mistake somewhere.
You should always use the model generator in combination with partial classes. To enable customization via partial classes use the --generatepartials true switch. This will output something like:
Article.Generated.cs (will be always regenerated)
public partial class Article
{
public const string Codename = "article";
public const string TitleCodename = "title";
public const string BodyCopyCodename = "body_copy";
public const string RelatedArticlesCodename = "related_articles";
public string Title { get; set; }
public IRichTextContent BodyCopy { get; set; }
public IEnumerable<object> RelatedArticles { get; set; }
}
Article.cs (will be generated when it doesn't already exist, it will never be overwritten by the generator)
public partial class Article
{
// Space for your customizations
public IEnumerable<Article> ArticlesTyped => RelatedArticles.Cast<Article>();
}
Feel free to suggest improvements for the code generator at https://github.com/Kentico/kontent-generators-net/issues/new/choose
The most probable reason why your code doesn't work at the moment is that you haven't registered the implementation of the ITypeProvider interface. You can do so by adding it to the DI container (IServiceCollection):
services
.AddSingleton<ITypeProvider, CustomTypeProvider>();
.AddDeliveryClient(Configuration);
or by passing it to the DeliveryClientBuilder
CustomTypeProvider customTypeProvider = new CustomTypeProvider();
IDeliveryClient client = DeliveryClientBuilder
.WithProjectId("975bf280-fd91-488c-994c-2f04416e5ee3")
.WithTypeProvider(customTypeProvider)
.Build();
as described in the docs. You can either generate the CustomTypeProvider by the model generator utility or implement it by hand. It should look similar to this:
public class CustomTypeProvider : ITypeProvider
{
private static readonly Dictionary<Type, string> _codenames = new Dictionary<Type, string>
{
// <CLI type, model codename in Kontent>
{typeof(Article), "article"}
};
public Type GetType(string contentType)
{
return _codenames.Keys.FirstOrDefault(type => GetCodename(type).Equals(contentType));
}
public string GetCodename(Type contentType)
{
return _codenames.TryGetValue(contentType, out var codename) ? codename : null;
}
}
Alternatively, you can specify the type when calling GetItemsAsync() in the following way: _deliveryClient.GetItemsAsync<Article>() but this will resolve only the 1st level type. Any nested models will be null because the SDK won't know how to resolve them (that's what the ITypeProvider is for). So I'd avoid this.

Send a function along with the scheme from backend in Alpacajs

I am having an API in backend to return the full json (schema and options) for a AlpacaJS form. The content-type of the response is application/json. Following is a sample response,
{
"options": {
"fields": {
"students": {
"items": {
"type": "tablerow"
},
"type": "table"
}
},
"form": {
"buttons": {
"submit": {
"click": "function(){alert(\"sample\");}"
}
}
}
},
"schema": {
"properties": {
"students": {
"items": {
"properties": {
"name": {
"required": true,
"title": "Name",
"type": "string"
},
"contact-number": {
"title": "Age",
"type": "string"
}
},
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
}
When I click on the Submit button, I get the following error in browser console,
Uncaught TypeError: t.call is not a function
I think the issue is that the function is considered as a string in the following section of the response.
"form": {
"buttons": {
"submit": {
"click": "function(){alert(\"sample\");}"
}
}
}
Is there a way in AlpacaJS to send a javascript function from backend, or is there a way to convert the function string to a javascript function in frontend?
In order to get that, you should transform the stringified function to a function by doing new Function('return ' + val)(); (beware this is a form of eval and eval is evil).
Here's a working fiddle for that.
Tell me if it didn't work for you.

Extract specific users comments from a list using Wikipedia API and Python 2.7

I am using the wikipedia API - wikitools package to extract some data from Wikipedia. I get the output of the format shown below and now I want to extract the timestamp and the comment for revisions made of specific user for several pages. Let's say I just want the comments made by TechBot, then I figured that I can do something like:
for revision in res["query"]["pages"]["7940378"]["revisions"]:
if revision["user"] = "Techbot":
do.something()
But the problem is ["7940378"] because this is a unique page id and will change for every page and I dont know how to get the pageid. Is there another way of doing this?
[{
"query": {
"pages": {
"7940378": {
"ns": 0,
"pageid": 7940378,
"revisions": [
{
"comment": "robot Modifying: [[az:T\u00fcrk Tarixi]]",
"timestamp": "2009-01-03T19:47:11Z",
"user": "TechBot"
},
{
"comment": "",
"timestamp": "2009-02-14T02:07:49Z",
"anon": "",
"user": "88.231.237.130"
},
{
"comment": "fixing recent deletion by merging it with the next paragraph",
"timestamp": "2009-04-03T14:49:27Z",
"user": "Soap"
},
{
"comment": "robot Modifying: [[az:T\u00fcrk tarixi]]",
"timestamp": "2009-04-09T14:35:19Z",
"user": "RibotBOT"
},
{
"comment": "Repairing link to disambiguation page - [[Wikipedia:Disambiguation pages with links|You can help!]]",
"timestamp": "2009-06-12T23:55:55Z",
"user": "J04n"
}
],
"title": "History of the Turkic peoples"
}
}
},
"continue": {
"rvcontinue": "20090807172715|306635892",
"continue": "||"
},
"warnings": {
"main": {
"*": "Unrecognized parameter: 'user'"
}
}
}]
Instead of using a single for loop. you can split up into two loops, where the outer loop gets the pages, and with the inner loop you can get to the revisions.
for pageid, pagedetails in res["query"]["pages"].iteritems():
for revision in pagedetails["revisions"]:
if revision["user"] == "TechBot":
do.something()

AlpacaJS: programmatically change value of TextField after selecting Select

I'm new to AlpacaJS and getting crazy trying to figure out how to do a simple stuff like changing dinamically the content of a text field with the value of a "Select".
The code looks like
$("#form1").alpaca({
"data": {
"name": "Default"
},
"schema": {
"title": "What do you think of Alpaca?",
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Name"
},
"flavour":{
"type": "select",
"title": "Flavour",
"enum": ["vanilla", "chocolate", "coffee", "strawberry", "mint"]
}
}
},
"options": {
"helper": "Tell us what you think about Alpaca!",
"flavour": {
"type": "select",
"helper": "Select your flavour.",
"optionLabels": ["Vanilla", "Chocolate", "Coffee", "Strawberry", "Mint"]
}
}
},
"postRender": function(control) {
var flavour = control.childrenByPropertyId["flavour"];
var name = control.childrenByPropertyId["name"];
name.subscribe(flavour, function(val) {
alert("Val = " + val);
this.schema.data = val;
this.refresh();
});
}
});
I can see that the function in postRenderer is called (as I can see the alert with relevant value) but (maybe I'm brain dead at this stage) I cannot refresh the text field with that value.
Cheers
I was probably looking at the wrong attribute to be set... After I changed to
this.schema.data = val;
it worked fine :)