Firstly I would like to say Angular Formly is a fantastic library for novices such as myself. I am not a web developer, however find this library to be intuitive and powerful.
However I do need assistance with use of Expression Properties.
I have a model library which contains library items, for example:
{
"itemId":"STX001",
"title":"Grey Wolf",
"category":"White", etc.
}
{
"itemId":"STX002",
"title":"Noble Black",
"category":"Black", etc.
}
etc.
I also have a formly form which uses ui-select in top field to lookup all values from Library, select one of these (I will call this Item), and then populate remaining fields in the form with Items properties, then submit form to Catalogue model.
The problem I am facing is I cannot reference the properties of Item from within other fields. I have tried using expressionProperties but can only extract the valueProp value (which is uniqueID), however I am after Item.title, Item.category, etc.
Code below:
{
//This is form fields for creating a new Catalogue entry
key: 'libraryId',
type: 'ui-select',
templateOptions: {
label: gettextCatalog.getString('Search Library'),
options: [],
valueProp: 'itemId',
itemTitle: 'title',
itemCategory: 'category',
labelProp: 'title',
focus: true,
placeholder: 'Start typing keywords..'
},
controller: function ($scope) {
getLibrary().then(function(data){
$scope.options.templateOptions.options = data;
return data;
});
}
}
{
key: 'title',
type: 'input',
templateOptions: {
label: gettextCatalog.getString('Name'),
required: true
},
expressionProperties : {
//This is what i'm trying to achieve but doesn't work
'templateOptions.placeholder' : 'model.libraryId.itemTitle'
}
},
Use the call back function provided
expressionPropertyObj = {
'templateOptions.required': (model, formState: any, field: FormlyFieldConfig) => {
console.log('model',model);
console.log('state',formState);
console.log('field',field);
},
Related
How I can use the kendo menu without typescript?
html
<kendo-menu [items]="menuItems" [vertical]="true" style="display:inline-block;" (select)="onMenuSelected($event)"></kendo-menu>
TS
menuItems: any[] = [
// {
// text: "Rename",
// },
{
text: "Delete",
},
{
text: "Copy",
},
];
I want to use only html to use of menu
Technically, you can enter the data in the template itself, like this:
<kendo-menu [items]="
[{
text: 'Rename'
},
{
text: 'Delete'
},
{
text: 'Copy'
}]">
</kendo-menu>
Now, while it is possible, it's not good practice. Even if the menu, in this case, is static and simple, it's better to have a const on the component containing the menu entries, or perhaps in a dedicated file if you have many such constants which you in several places.
Let me explain it a little bit. The idea is to have categories and each category can have a parent category and a subcategory as well, but we don't know how deep this tree can go. For Example:
->Clothes
-->Men
--->Kids
---->Newborns
----->Etc, etc
-->Women
-->Unisex
So I thought that my Category.js model could have these attributes:
module.exports = {
attributes: {
name: {
type: 'string',
required: true,
unique: true
},
products: {
collection: 'product',
via: 'category'
},
parentCategory: {
model: 'category'
},
subCategories: {
collection: 'category',
via: 'parentCategory'
}
}
};
And when I get all my categories:
Category.find({}).populate('subCategories').exec(........
I get a list of all categories and its subcategories, but I also want to have the subcategories of the subcategories, just like the tree hierarchy I wrote before, but instead I'm getting
Clothes { subCategories: [Men:{}, Women:{}, Unisex:{}] }
Men { .....
But inside of Clothes, I have Men, that's correct. But now inside of this Men object I don't have "Kids".
Am I being clear?
Populate method only works in one level (at the moment), so you can't populate and object and then populate other one inside. I had a similar feature and I found and wrote this code, maybe it can help you:
return Object.findOne({
id: id
}).populateAll().then(function (result) {
var otherObject= otherObject.find(result.id).then(function (otherResult) {
return otherResult;
});
return [result, otherResult];
}).spread(function (house, otherResult) {
result= result.toObject();
result.otherResult= otherResult;
return result;
});
We are using Backgrid which allows you to define grid columns with an array of Javascript objects which it converts to a collection. We are trying to take advantage of this to have configurable validation on a column by column basis, so we might have the following where we've added a "validator" function to a couple of the columns:
[
{
label: "Delete",
name: "delete",
cell: "boolean"
},
{
label: "Alias",
name: "alias",
cell: "string",
sortType: "toggle",
validator: function (value) {
return true;
}
},
{
label: "Assigned Server",
name: "assignedServer",
cell: "string",
sortType: "toggle",
validator: function (value) {
return new Error("Cannot Assign Server")
}
}
]
We are listening to edits to the grid in the following prescribed manner and for the purposes of this question we can ignore the model argument to the function but concentrate on the column (delete, alias or assignedServer from above) which is itself a model in a collection. So far I have a snippet of code leveraging underscore.js's _.filter that returns the validatableColumns but I want to take this further and end up with an object of the format {name: validator, etc...}. Bearing in mind my specific use case, what is a succinct way to create an object from a Backbone collection that maps model values to one another?
certificateGrid.listenTo(certificateCollection, "backgrid:edited", function (model, column) {
var validatableColumns = _.filter(column.collection.models, function (c) {
return c.get('validator');
});
//etc.
Using _.reduce seems to do the trick:
var validatorFns = _.reduce(column.collection.models, function (fns, model) {
var validator = model.get('validator');
if (model.get('validator')) {
fns[model.get('name')] = validator;
}
return fns;
}, {});
How do you add a property to an entity dynamically? I've been looking, but haven't found anything.
For example, I have this model definition (I'm using the WebSQL provider):
$data.Entity.extend('$db.Types.Person', {
id: { type: 'int', key: true, computed: true },
name: { type: 'string' }
});
$data.EntityContext.extend('$db.Types.DBContext', {
Persons: { type: $data.EntitySet, elementType: $db.Types.Person},
});
At some point I need to extend my model with new properties. Initially I don't know these properties' names.
The syntax is very simple for this, but the background info is more important, please read the whole answer before you reuse the snippet.
The YourType can be extended with new fields using the YourType.addMember() function. See this example snippet:
$data.Entity.extend('Product', {
id: { type: 'int', key: true, computed: true },
Name: { type: 'string' }
});
$data.EntityContext.extend('Northwind', {
Products: { type: $data.EntitySet, elementType: Product},
});
Product.addMember('Description', {
type:'string',
key: false,
computed: false,
required: false
});
var context = new Northwind({provider: 'webSql', databaseName: 'Northwind'});
context.onReady(function() {
var product1 = new Product({ Name: 'Beer', Description: 'tasty'});
context.Products.add(product1);
context.saveChanges(function(result) {
//check the content of WebSQL DB
console.log(product1);
});
});
You can user the addMember() only before creating an instance of the context.
Important info:
There is no data migration/merge by in the library, and the default behavior on schema modification for webSql is to drop&re-create the DB. As IndexedDB isn't bound to a schema, the existing records won't be dropped. Make a try by running this code and adding more fields, here is a working JSFiddle.
The real solution is to use Schema Evolution module of JayData Pro to manage the changes in your data model.
I have a Model that contains an association to another Model. I am able to display the nested data into a form by using the mapping attribute on the field. Example:
Ext.define('Example.model.Request', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
type: Ext.data.Types.NUMBER,
useNull: false
}
{
name: 'plan_surveyor',
mapping: 'plan.surveyor',
type: Ext.data.Types.STRING
}
],
associations: [
{type: 'hasOne', associationKey: 'plan', getterName:'getPlan', model: 'Specs.model.Plan'}
],
proxy: {
type: 'direct',
api: {
read: requestController.load,
update: requestController.update,
},
reader: {
type: 'json',
root: 'records'
},
writer: {
type: 'json',
writeAllFields: true,
nameProperty: 'mapping'
}
}
});
Using this method, I can display the plan.surveyor value in the form by reference plan_surveyor. I call Form.loadRecord(model) to pull the data from the model into the form.
However, now that I'm trying to send the data back to the server, I get the error:
Error performing action. Please report the following: "Unrecognized field "plan.surveyor"
I am attempting to save to the server by first calling Form.updateRecord(model), then model.save(). Is there a way to have the Writer understand that 'plan.surveyor' is not a property name but instead to properly handle nesting?
Am I doing this the right way to start with, or should I just be handling the setting of the form data and loading back into the model in a more manual fashion? It seems that nested data is not all that well supported in general - any recommendations?
Ext.define('Example.model.Request', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
type: Ext.data.Types.NUMBER,
useNull: false
}
{
name: 'plan_surveyor',
mapping: 'plan.surveyor',//change to 'plan_surveyor'
type: Ext.data.Types.STRING
}
],
change that show in comment ,because data index is given in above format because ur give ur format thata time that is not dataindex it's a column or extjs preparatory ,so please change that may it's work well
it's not work u will send hole code