Angular ngModel, 3 arrays are affected - javascript

I am creating a form builder in Angular, I used Lam Phuoc ThinhI work for reference, check his work here
<https://codepen.io/thinhlam/pen/BowEPp>
Now the problem is I have this 3 arrays, Current Field, Form Fields and Draggable Fields. Everytime I dragged a field, like for example the Header Field and then I changed the text or value of that field, the Draggable Fields is also affected. So if i dragged another Header field the value is the same with the first header field that i drag. Please check the image below.
image
app.component.html
<div *ngFor="let set of CurrentField.Settings; let i = index; trackBy:trackByIdx" [ngSwitch]="set.Type">
<div *ngSwitchCase="'textarea'" class="form-group">
<label for="textarea-{{i}}">{{set.Name}}</label>
<input [name]="'textarea' + i" type="text" class="form-control" [(ngModel)]="set.Value">
</div>
</div>
app.component.ts
FormFields: any;
CurrentField: any;
guid: number;
DragElements = [{
'Name': "Header",
"Type": "textLabel",
'Icon': "fa fa-header",
'Settings': [{
'Name': 'Field Label',
'Value': 'Header',
'Type': 'textarea'
}]
}, {
'Name': "Columns",
"Type": "columns",
'Icon': "fa fa-columns",
'Settings': [{
'Name': 'Number of Columns',
'Value': 0,
'PossibleValue': [2,3,4]
}, {
'Name': 'Column',
'Columns': []
}],
}, {
'Name': "Image",
"Type": "image",
'Icon': "fa fa-image",
'Settings': [{
'Name': 'Field Label',
'Value': 'Image',
'Type': 'textarea'
}]
}, {
'Name': "Single Text",
'Type': "text",
'Icon': "fa fa-font",
'Settings': [{
'Name': 'Field Label',
'Value': 'Single Text',
'Type': 'text'
}]
}, {
'Name': "Number",
'Type': "number",
'Icon': "fa fa-th-large",
'Settings': [{
'Name': 'Field Label',
'Value': 'Number',
'Type': 'text'
}]
}, {
'Name': "Date",
'Type': "date",
'Icon': "fa fa-calendar",
'Settings': [{
'Name': 'Field Label',
'Value': 'Date',
'Type': 'text'
}]
}, {
'Name': "Single Selection",
"Type": "dropdown",
'Icon': "fa fa-dot-circle-o",
'Settings': [{
'Name': 'Field Label',
'Value': 'Single Selection',
'Type': 'text'
}]
}, {
'Name': "Pagaraph Text",
"Type": "textarea",
'Icon': "fa fa-align-left",
'Settings': [{
'Name': 'Field Label',
'Value': 'Paragraph Text',
'Type': 'text'
}]
}];
constructor(
private cd: ChangeDetectorRef,
private zone: NgZone,
) {}
ngOnInit() {
this.CurrentField = {};
this.FormFields = [];
this.guid = 1;
}
createNewField = function() {
return {
'id': ++this.guid,
'Name': '',
'Settings': [],
'Active': true,
'ChangeFieldSetting': function(Value, SettingName) {
switch (SettingName) {
// case 'Field Label':
// this.Settings[0].Value = Value;
// // console.log(Value);
// break;
case 'Image Alignment':
this.Settings[2].DefaultAlignment = Value;
break;
case 'Columns':
let columns : any = {};
this.Settings[0].Value = Value;
for(let i = 0; i < Value; i++) {
columns = {
'ID': i + "-" + this.id,
'Title': 'Column '+i,
'Items': []
}
this.Settings[1].Columns.push(columns);
}
console.log(this);
break;
default:
break;
}
},
'GetFieldSetting': function(settingName) {
let result = {};
let settings = this.Settings;
settings.forEach((index, set) => {
if (index.Name == settingName) {
result = index;
return;
}
});
if (!Object.keys(result).length) {
settings[settings.length - 1].Options.forEach((index, set) => {
if (index.Name == settingName) {
result = index;
return;
}
});
}
return result;
}
};
}
changeFieldName = function(Value) {
this.CurrentField.Name = Value;
this.CurrentField.Settings[0].Value = this.CurrentField.Name;
}
removeElement = function(idx){
if(this.FormFields[idx].Active) {
this.CurrentField = {};
}
this.FormFields.splice(idx, 1);
};
addElement(ele, idx) {
// this.zone.run(() => {
this.CurrentField.Active = false;
this.CurrentField = this.createNewField();
Object.assign(this.CurrentField, ele);
if (idx == null) {
this.FormFields.push(this.CurrentField);
} else {
this.FormFields.splice(idx, 0, this.CurrentField);
}
// });
};
activeField = function(f) {
this.CurrentField.Active = false;
this.CurrentField = f;
f.Active = true;
};

Wherever you are using
Object.assign(this.CurrentField,ele);
like operations
deep clone before pushing.
Object.assign(this.CurrentField, JSON.parse(JSON.stringify(ele)));
This is one way of deep cloning which has its pros and cons. But your solution will be to deep clone using any suitable method.

Related

JS: Do I override or add in fields when use _.extend() in express?

When I have an object and I put it as an extension of another object in which I put value for some of the extended fields - is it going to be rewritten or the value will be added to the old one?
For example if I have:
const PATCH_REQUEST_SCHEMA = {
'type': 'object',
'title': 'Some object',
'description': 'Some object Representation',
'properties': {
'name': {
'type': 'string',
'minLength': 1,
'maxLength': 256,
'title': 'Name'
}
};
const POST_REQUEST_SCHEMA = _.extend({}, PATCH_REQUEST_SCHEMA, {
'properties': {
'surname': {
'type': 'string',
'minLength': 1,
'maxLength': 256,
'title': 'Surname'
}
}
});
What would be the result for POST_REQUEST_SCHEMA.properties ?
Will it be:
{
'name': {
'type': 'string',
'minLength': 1,
'maxLength': 256,
'title': 'Name'
},
'surname': {
'type': 'string',
'minLength': 1,
'maxLength': 256,
'title': 'Surname'
}
}
or:
{
'surname': {
'type': 'string',
'minLength': 1,
'maxLength': 256,
'title': 'Surname'
}
}
I tested it manually - it rewrites/overrides the field "properties". So the answer is:
{
'surname': {
'type': 'string',
'minLength': 1,
'maxLength': 256,
'title': 'Surname'
}
}

Bootstrap-table Toggle Column with colspan=1

When a grouped header (aka nested) has 1 nested level (like "Price" and "Total" in the example) there is a strange behaviour: I would expect a way to hide the whole column, yet when I hide "Total", "Price" remains visible. Is there a way to hide that?
You can see it works fine in case the 2nd level header has more than 1 element: I hide "Id" and "Name" and "Key" is automatically hidden.
https://live.bootstrap-table.com/code/antonioaltamura/6940
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table#1.19.1/dist/bootstrap-table.min.css">
<script src="https://unpkg.com/bootstrap-table#1.19.1/dist/bootstrap-table.min.js"></script>
<table id="table" border=1>
</table>
<button onclick="togglePrice()">
togglePrice
</button>
<button onclick="toggleKey()">
toggleKey
</button>
<script>
var $table = $('#table')
var priceVisible = true;
var keyVisible = true;
$(function() {
var data = [
{
'id': 0,
'name': 'Item 0',
'price': '$0'
},
{
'id': 1,
'name': 'Item 1',
'price': '$1'
},
{
'id': 2,
'name': 'Item 2',
'price': '$2'
},
{
'id': 3,
'name': 'Item 3',
'price': '$3'
},
{
'id': 4,
'name': 'Item 4',
'price': '$4'
},
{
'id': 5,
'name': 'Item 5',
'price': '$5'
}
]
$table.bootstrapTable({
data: data,
columns: [
[
{
title: "Key",
colspan:2
},
{
title: "Price",
field: "h_price"
},
],
[
{title: "Id", field:"id"},
{title: "Name", field:"name"},
{title: "Total", field:"price"}
]
]})
})
function togglePrice() {
$table.bootstrapTable(priceVisible ? "hideColumn" : "showColumn", "price")
priceVisible = !priceVisible
}
function toggleKey() {
$table.bootstrapTable(keyVisible ? "hideColumn" : "showColumn", "id")
$table.bootstrapTable(keyVisible ? "hideColumn" : "showColumn", "name")
keyVisible = !keyVisible
}
</script>

How to display api data on children column in ag grid angular

How to call the fieldName in children or how to display.
here's the code.
list.component.ts
monthNames = new Array(
['January'], ['February'], ['March'],
['April'], ['May'], ['June'],
['July'], ['August'], ['September'],
['October'], ['November'], ['December'],
);
ngOnInit() {
this.setColumnHeader();
}
setColumnHeader() {
this.globals.getData('/users').pipe(take(1)).subscribe((data: any) => {
const record = data['data'];
record.map((x: any) => {
this.rowData.push({
'fieldName': x.firstName,
'lastName': x.lastName
});
});
});
for (let i = 0; i <= 11; i++) {
this.columnDefs.push({
'headerName': this.monthNames[i],
'field': this.monthNames[i],
'width': 100,
///child
'children': [
{
'headerName': 'Total', 'columnGroupShow': 'closed', 'field': 'total',
'valueGetter': function (params: any) {
return params.data.sample + params.data.sampleb;
}
},
{
'headerName': 'a', 'editable': true, 'columnGroupShow': 'open', 'field': 'sample',
'valueParser': this.numberParser
},
////////call the fieldName
{
///here
///the 'headerName' should be the fieldName
}
});
}
}
}
numberParser(params: any) {
return Number(params.newValue);
}
thanks in advance.
Not clear what you really want, but here you can try this.
for (let i = 0; i <= 11; i++) {
const data = {
'headerName': this.monthNames[i],
'field': this.monthNames[i],
'width': 100,
///child
'children': [
{
'headerName': 'Total', 'columnGroupShow': 'closed', 'field': 'total',
'valueGetter': function (params: any) {
return params.data.sample + params.data.sampleb;
}
},
{
'headerName': 'a', 'editable': true, 'columnGroupShow': 'open', 'field': 'sample',
'valueParser': this.numberParser
},
]
}
for (let j = 0; j < this.rowData.length; j++) {
data.children.push(
{
'headerName': this.rowData[j].fieldName, 'editable': true, 'columnGroupShow': 'open', 'field': 'sample',
'valueParser': this.rowData[j].lastName
}
)
}
this.columnDefs.push(data)
}
you can comment if this not what you expect, hope that help.

JSTree context menu not displaying

I am trying to set up a context menu in my javascript project. Here is the code I have for the json data of the tree and the creation of the tree.
let json_data = {
'core': {
'data': [
{
'text': 'First',
'state': {
'opened': false,
'selected': false
},
'children': [
{
'text': 'First'
},
{
'text': 'Second'
},
{
'text': 'Third'
}
]
},
{
'text': 'Second',
'state': {
'opened': false,
'selected': false
},
'children': [
{
'text': 'First'
},
{
'text': 'Second'
},
{
'text': 'Third'
}
]
},
{
'text': 'Third',
'state': {
'opened': false,
'selected': false
},
'children': [
{
'text': 'First'
},
]
}
]
},
'plugins': ['contextmenu'],
'contextmenu' : {
'items': this.customMenuOptions
}
};
tree.jstree(json_data).bind("select_node.jstree", function(e, data){});
console.log(tree[0]);
}
And here is the code I have for customMenuOptions:
customMenuOptions(node) {
console.log(node);
let items = {
'item1': {
'label': 'item1',
'action': function(){}
},
'item2': {
'label': 'item2',
'action': function(){}
}
};
return items;
}
I know the right click functionality is working because whenever I right click on the any node on the tree, the print statement at the top of customMenuOptions appears in the console; however, the menu does not show up. Any help would be appreciated. Thanks.
Fixed the issue by increasing the z-index of the context menu element, so that it is not hidden behind the rest of the elements.

Angular.Copy does not allow me to create unique objects in a separate array

I'm building a configurator in AngularJS that uses the object $scope.data to allow users to edit the object via the front-end. The user can then save this object to a separate array in $scope.builds, allowing them to have multiple configurations. Here is the function that adds another configuration to $scope.builds.
$scope.addition = function(){
var newData = angular.copy($scope.data);
$scope.builds.push(newData);
}
Unfortunately, despite using the angular.copy function, all of the objects in the array of $scope.builds seem to be the same $scope.data object duplicated over and over.
EDIT:
Here is an abridged version of what $scope.data looks like:
$scope.data = [
{
'title': 'Select your configuration',
'required': true,
'options': [
{
'name': 'Option 1',
'select': true,
'filter': true
}, {
'name': 'Option 2',
'select': false,
'filter': true
}, {
'name': 'Option 3',
'select': false,
'filter': true
}
]
}, {
'title': 'Select your configuration',
'required': true,
'options': [
{
'name': 'Option 1',
'select': true,
'filter': true
}, {
'name': 'Option 2',
'select': false,
'filter': true
}, {
'name': 'Option 3',
'select': false,
'filter': true
}
]
}
];

Categories

Resources