Generating nested streamblocks content programmatically in Wagtail - wagtail

Currently struggling to generate content programmatically for the following StreamBlock:
class SpecialistStreamBlock(blocks.StreamBlock):
accordion = SpecialistAccordionBlock()
class SpecialistAccordionBlock(BaseBlock):
content = StreamBlock([
('accordion_item', StructBlock([
('title', blocks.CharBlock(label=_(u"Title"), max_length=255)),
('content', LeanRichTextBlock()),
])),
], label=_(u"Accordion"))
In the case the structure is not nested is done using tuples like ("variablename for block definition", {dict with key value for defined fields}) but this approach doesn't seems to work in case of nested structures.
What I have tried so far without success:
accordion_block = ("accordion", {"title": "Some title",
"content": ("accordion_item",
{"title": "Another title",
"content": RichText(education_block_str)})})

Related

Angular // ng-select Use interpolation within a textarea on a text pulled from an array

Still in my very first days with Angular and ran into a problem i can't get my head around.
What I am trying to accomplish is sort of creating a way to have a persons name added to a message template.
The templates are loaded from a file like this
this.http.get('../../assets/templatefiles/customtemplates.json').subscribe(data => {this.templateArray = data as any [];
The structure of the JSON file is as follows
[{
"Id": 1,
"Type": "SR Templates",
"Name": "Message 1",
"Body": "Some meaningful text here"
},
{
"Id": 2,
"Type": "SR Templates",
"Name": "Message 2",
"Body": "Some more meaningful text here"
},
{
"Id": 3,
"Type": "GTFO Templates",
"Name": "Message 3",
"Body": "Guess what? Exactly, some even more..blahhh"
}]
All good so far. Then, in my template I use ng-select to create the dropdown list to display the options grouped by Type
<ng-select [items]="templateArray"
bindLabel="Name"
bindValue="Body"
groupBy="Type"
[(ngModel)]="selectedTemplate"
>
<ng-template ng-optgroup-tmp let-item="item">
<strong>{{item.Id}}</strong>
</ng-template>
</ng-select>
So far...working it seems. Templates are grouped by Type and show up in the drop down just fine.
Below the selection is a textarea in which the "Body" value is supposed to be displayed. Works fine as well, when selecting a template from the drop down the text shows fine in the textarea.
The problem I am facing is that there is an input field for the persons name the message will be send to.
I get the name as follows:
<input type="text" [(ngModel)]="srcName" class="form-control" placeholder="Name">
The bit confusing me is how to get/add the persons name to the message using interpolation?
I was hoping for something like just having to change the text in the JSON and adding the interpolation to it but apparently that does not work hehe.
{
"Id": 1,
"Type": "SR Templates",
"Name": "Message 1",
"Body": "Dear {{srcName}, Some meaningful text here"
}
I've been searching up and down, but am ultimately stuck and am desperate for a nudge in the direction I would have to go to actually get that name inserted in the textarea together with the template from the array...
You can make a function that concatenates your selected template and the name in you input, like so:
onSubmit() {
this.message = `Dear ${this.srcName}, ${this.selectedTemplate}`;
}
And then you can add a button that executes this function:
<button (click)="onSubmit()">Submit</button>
Now whenever you select the template you want and add the name you want to the input and click on submit button, you will get a concatenated message with the info you want.
Here is a live demo if you want more explanation.
In the live demo a used a normal HTML select, but it should work the same with angular material select.
##EDIT
If you need to put your srcName inside of your templates body, you will have to create a place holder in your template's body, something like:
"Guess what? Exactly {srcName}, some even more..blahhh"
instead of:
"Guess what? Exactly, some even more..blahhh"
Then you will have to change the onSubmit function:
onSubmit() {
this.message = this.selectedTemplate.replace('{srcName}', this.srcName)
}
I also added the changes to to the live demo.

angular-schema-form: Add custom html to form fields

I have just started to look into angular-schema-form, so this might be something I've missed in the docs or description.
What I am trying to do is to add an icon next to the label of generated form fields and next to the field itself. Like so:
But out of the box angular-schema-form will generate:
I know I can make my own custom field types, but is that the way to go? That would require me to redefine all field types in a custom variant, because I need these two icons and their functionality on all my form fields.
I was hoping there were an easier way to add this functionality to generated html, and an easy way to add functionality (ng-click function) on them.
Edit: After reading through the docs again, I've figured out that I need to define my own custom field type (https://github.com/Textalk/angular-schema-form/blob/development/docs/extending.md)
From what I gather, I need to add the following to my modules config block:
schemaFormDecoratorsProvider.addMapping(
'bootstrapDecorator',
'custominput',
'shared/templates/customInput.tpl.html',
sfBuilderProvider.builders.sfField
);
I have also added the contents of shared/templates/customInput.tpl.html to $templatesCache.
But when I try to render a form, with a schema like
"schema": {
"type": "object",
"properties": {
"firstName": {
"title": "First name",
"type": "string"
},
"lastName": {
"title": "Last name",
"type": "custominput"
},
"age": {
"title": "Age",
"type": "number"
}
}
}
I only see the first field (firstName) and age. The custom type is just ignored.
I have tried to debug my way to the problem, but as far as I can see, the custom field is correctly added to the decorator. I've tried to console.log the schemaFormDecoratorsProvider.decorator() and there I can see my custom field type.
I've also tried to fire off a $scope.$broadcast('schemaFormRedraw') in my controller, but I still only see the built in field types.
As a test, I've tried to define my own decorator, overwriting the default Bootstrap decorator:
schemaFormDecoratorsProvider.defineDecorator('bootstrapDecorator', {
'customType': {template: 'shared/templates/customInput.tpl.html', builder: sfBuilderProvider.stdBuilders},
// The default is special, if the builder can't find a match it uses the default template.
'default': {template: 'shared/templates/customInput.tpl.html', builder: sfBuilderProvider.stdBuilders},
}, []);
I would expect to see all fields to be rendered the same, since I only define a default type and my own custom type. But still, I only see built in types rendered, my custominput is till just ignored.
What am I missing?
I've had this same problem, the problem is that you should not confuse the JSON schema with the form definition.
To render a custom component you have to change the form definition. I.e in your controller your standard form defintion might look something like:
$scope.form = [
"*",
{
type: "submit",
title: "Save"
}
];
You'll have to change this to:
$scope.form = [
"firstName",
"age",
{
key:"lastName",
type:"customInput"
},
{
type: "submit",
title: "Save"
}
];

Observable array from another JSON object with child arrays

I am trying to initialize an observable array from a json object which is rendered from the server as Javascript/Json;
Basically I have a simple model (from the server) that looks like this
var BaseModel = { "changeRequestLocations":
[{ "location": "New Zealand", "devices":
[
{ "id": "5", "deviceName": "Server 1" },
{ "id": "6", "deviceName": "Server 2" }
],
"id": 1 }] };
I then initialize an observable array from the baseModel
this.changeRequestLocations = ko.observableArray(BaseModel.changeRequestLocations);
This basically does what I want but the "devices" element is an array not an observable array.
I really need to have it as an observable array - is there a way to tell Knockout to do this automatically or do I need to do it manually?
See a fiddle here that shows the case
In itself Knockout does not do this for you automatically, so
you do it manually like your jsfiddle
you use the Knockout.Mapping plugin which is designed for this scenario: convert plain JavaScript objects to objects with observable properties.
So in your example you just need to write:
this.changeRequestLocations = ko.mapping.fromJS(BaseModel.changeRequestLocations);
and the mapping plugin will convert your location array into an observable array.
Demo JSFiddle.

Association ExtJs MVC 4.2

ExtJS 4.2 MVC: I have two models ServiceM and CommentsM. ServiceM has association(hasmany) with CommentsM. I DIDNOT forget to add the requires section ServiceM. Proxy is an ajax type defined in the model itself. I also created stores for each. Coming to the view, I have a grid for viewing all the services which are derived on loading the application. itemdblclick event is used to provide a detailed view about the service which is a window extending a form. The form is popullated by the below code:
var ServiceDetailV = Ext.widget('alias name of the service detail view');
ServiceDetailV.down('form').getForm().loadRecord(record);
I have two questions here.
When using developer tools in google chrome, in the above code I place debugger; at the end. I have highlighted the record, right clicked and evaluated that part. I see the data part and raw part. what is this raw part. It has all the data which the server is giving me(payload), even the nested comments section which is associated with the Service data.
I am able to popullate the fields in the form, but not the list of comments. the list of comments goes into a panel present in the form. How can I popullate the comments section.
JSON data:
{
"data": [
{
"id": 1,
"x": "some text",
"q": "some text",
"a": "some text",
"r":"some text",
"comments": [
{
"id": 87,
"commentDate": "date",
"description": "some text"
},
{
"id": 86,
"commentDate": "date",
"description": "some text"
}
]
} "total": 1,
"success": true}
Now, how can i access the comments field and poppulate the form with this data?
Please shed some knowledge on Associations ExtJs MVC.
Cheers!
Well, I took a step and got the solution for this. the raw parameter actually has the raw JSON payload. In the controller part I have handled it via a select event.
onSelectIssueShowComments : function(selection,record, index, eOpts) {
this.getComments().setRecord(record.raw);
}
I the view part
tpl : [ '<p>Previous Comments: ', '<tpl for="comments">',
'<p>{#}. {description} {commentDate}</p>', '</tpl></p>' ],
setRecord : function(record) {//this record here is record.raw
this.record = record;
if (record) {
this.update(record);
} else {
this.update(' ');
}
}
So it displays the array of comments in a Panel.

Adding a view that displays user data using store Sencha touch2

My store JSON looks like this:
"content" : {
"RecId" : "123",
"CustNo" : "123",
"Attn" : "",
"AcctManagFirst": "Sample ",
"AcctManagLast": "Sample2",
"Name": "Works",
"Terms": "1234",
"Freight":0,
"Taxable":1,
"TaxTable": "EXEMPT",
"TaxTableRate": "0.000000",
"BillToAddr": "GGGGGGGGG",
"BCity": "New Iberia",
"BState": "LA",
"BZip": "70560",
"WHAddr": "Perry",
"WHCity": "New Iberia",
"WHState": "LA",
"WHZip": "70560"
}
Using the above I want create a view that displays user information like:
Name {Name from the store}
AccountManager Last NAme {AcctManagLast from the store}
I am new to Sencha . Plese help me how to write form that displays the label followed by value from store.
A simple panel with template and data will work for you, check out : http://www.senchafiddle.com/#KmNX8#yqVQt

Resources