Autodesk Forge Adding Input Element to Forge Button - autodesk-forge

I would like to dynamically add an input element to a button and based on Angular Binding, bind the input to the selected object in the viewer. What I tried so far you find below. The input element is shown without any problem. However, I cannot access the generated input element, no input possible.
Any suggestions to solve that?
public loadMobileToolbar() {
/////////////////////// Facade ///////////////////////
// #ts-ignore
var button1 = new Autodesk.Viewing.UI.Button('mobile-text-button-facade');
var button2 = new Autodesk.Viewing.UI.Button('mobile-coloring');
button1.onClick = (event) => {
console.log(this.input);
$('#mobile-text-button-facade').attr('data-before', '');
$('#mobile-text-button-facade').html('<input style="z-index: 100000" class="custom-input" type="text" [(ngModel)]="input.facade" (change)="onChange($event)" spellcheck="false">');
};
button2.onClick = (event) => {
this.showValuesOfParameter('facade');
};
button2.addClass('mobile-coloring');
// #ts-ignore
button2.container.children[0].classList.add('fas', 'fa-palette');
// Button 4 Textfeld
button1.addClass('mobile-text-button-facade');
// SubToolbar
var controlGroupMobile = new Autodesk.Viewing.UI.ControlGroup('mobile-custom-toolbar');
// controlGroupERP.addControl(button3);
controlGroupMobile.addControl(button1);
controlGroupMobile.addControl(button2);
this.toolbarMobile = new Autodesk.Viewing.UI.ToolBar('my-custom-view-toolbar-mobile-facade', {
collapsible: false,
alignVertically: false
});
this.toolbarMobile.addControl(controlGroupMobile);
$(this.viewerComponent.viewer.container)[0].append(this.toolbarMobile.container);
$('#mobile-text-button-facade').attr('data-before', 'Facade');
}

Adding the <input> without Angular bindings seems to be working fine:
You might need to ask around in the Angular community about the bindings.

var filterbox = new Autodesk.Viewing.UI.Filterbox('mobile-filterbox', { filterFunction: this.testing });
var controlGroupMobileInput = new Autodesk.Viewing.UI.ControlGroup('mobile-custom-toolbar-input');
controlGroupMobileInput.addControl(filterbox);
buttonFilter.onClick = (event) => {
if (!this.input.objectPath && this.viewerComponent.viewer.getSelectionCount() === 0) {
$('.filter-box.docking-panel-delimiter-shadow').val('');
button1.setState(1);
button7.setState(1);
// tslint:disable-next-line: no-use-before-declare
button3.setState(1);
// tslint:disable-next-line: no-use-before-declare
button9.setState(1);
// tslint:disable-next-line: no-use-before-declare
button5.setState(1);
$('#mobile-custom-toolbar-input').hide();
this.whichInput = '';
}
else if (this.viewerComponent.viewer.getSelectionCount() > 1 && this.redSelectedDbIDs.length === 0) {
this.multiSelectedMobileInput.forEach(input => {
if (this.whichInput === 'u' || this.whichInput === 'v') {
input[this.whichInput] = Number($('.filter-box.docking-panel-delimiter-shadow').val());
}
else if (this.whichInput === 'additionalParameter') {
input[this.whichInput][0].value = $('.filter-box.docking-panel-delimiter-shadow').val();
}
else {
input[this.whichInput] = $('.filter-box.docking-panel-delimiter-shadow').val();
}
});
this.api.saveMultipleInput(this.multiSelectedMobileInput).then(
res => {
if (res === null) {
this.messageService.add({ key: 'warning', severity: 'error', summary: 'Error', detail: 'Something went wrong with SAVING' });
}
else {
this.api.getAllInputs(this.platform.currentProject._id).then(
inputs => {
this.inputs = inputs;
// #ts-ignore
this.messageService.add({ key: 'warning', severity: 'success', summary: 'Success', detail: res.modified + ' INPUT was UPDATED', life: 5000 });
this.viewerComponent.viewer.clearThemingColors(this.viewerComponent.viewer.model);
this.editTable = false;
this.unsavedChanged = false;
}
);
}
}
);
this.multiSelectedMobileInput = new Array();
this.viewerComponent.viewer.clearSelection();
$('.filter-box.docking-panel-delimiter-shadow').val('');
button1.setState(1);
button7.setState(1);
// tslint:disable-next-line: no-use-before-declare
button3.setState(1);
// tslint:disable-next-line: no-use-before-declare
button9.setState(1);
// tslint:disable-next-line: no-use-before-declare
button5.setState(1);
$('#mobile-custom-toolbar-input').hide();
this.whichInput = '';
}
else if (this.redSelectedDbIDs.length !== 0) {
this.redSelectedDbIDs.forEach(dbId => {
this.viewerComponent.viewer.model.getProperties(dbId, (r) => {
var tempInput = this.inputs.find(ele => {
if (ele.objectPath.indexOf('/')) {
return ele.objectPath.split('/')[ele.objectPath.split('/').length - 1] === r.name;
}
else {
return ele.objectPath === r.name;
}
});
this.multiSelectedMobileInput.push(tempInput);
});
});
setTimeout(() => {
this.multiSelectedMobileInput.forEach(input => {
if (this.whichInput === 'u' || this.whichInput === 'v') {
input[this.whichInput] = Number($('.filter-box.docking-panel-delimiter-shadow').val());
}
else if (this.whichInput === 'additionalParameter') {
input[this.whichInput][0].value = $('.filter-box.docking-panel-delimiter-shadow').val();
}
else {
input[this.whichInput] = $('.filter-box.docking-panel-delimiter-shadow').val();
}
});
this.api.saveMultipleInput(this.multiSelectedMobileInput).then(
res => {
if (res === null) {
this.messageService.add({ key: 'warning', severity: 'error', summary: 'Error', detail: 'Something went wrong with SAVING' });
}
else {
this.api.getAllInputs(this.platform.currentProject._id).then(
inputs => {
this.inputs = inputs;
// #ts-ignore
this.messageService.add({ key: 'warning', severity: 'success', summary: 'Success', detail: res.modified + ' INPUT was UPDATED', life: 5000 });
this.viewerComponent.viewer.clearThemingColors(this.viewerComponent.viewer.model);
this.editTable = false;
this.unsavedChanged = false;
}
);
}
}
);

Related

Angular remove null values of JSON object

I need to remove the null values of JSON object before requesting a post. My below code doesn't work, could you please let me know where I'm going wrong?
publish() {
let resource = JSON.stringify(this.form.value)
const removeEmpty = (obj) => {
Object.keys(obj).forEach(key => {
if (obj[key] && typeof obj[key] === "object") {
removeEmpty(obj[key]);
} else if (obj[key] === null) {
delete obj[key];
}
});
return obj;
};
console.log("new obj :" + removeEmpty(resource));
}
Stackblitz for sample
Your resource is a string, since you stringify your object. Please remove the stringify.
publish() {
let resource = this.form.value;
const removeEmpty = (obj) => {
Object.keys(obj).forEach(key => {
if (obj[key] && typeof obj[key] === "object") {
removeEmpty(obj[key]);
} else if (obj[key] === null) {
delete obj[key];
}
});
return obj;
};
console.log("new obj :", removeEmpty(resource));
}

set state after submit form in react js

how do you change the state back to blank when the form has been submitted?
I tried to empty it again when the form was submitted, but the state still has value
when it is finished, submit the state back to the initial state
state = {
importExcel: '',
active: true
};
handlerChange = e => {
this.setState({
importExcel: e.target.files[0],
active: !this.state.active
});
};
handlerOnSubmit = e => {
e.preventDefault()
const formData = new FormData();
formData.append('importExcel', this.state.importExcel);
api.post('web/user/import', formData)
.then(res => {
const { message, success } = res.data;
const alert = swal({
title: success === false ? 'Gagal Upload' : 'Berhasil Upload',
text: message,
icon: success === false ? 'error' : 'success',
// timer: 5000,
button: true
})
if (success === false) {
return alert
} else {
return alert
}
})
this.setState({
importExcel: '',
active: true
})
}
if (success === false) {
return alert
} else {
return alert
}
You are returning function every time. So the code below this line doesn't execute.

VueJs Axios Post FormData Parameters

We are using Vue in our frontend application, and for one of our REST service our backend server(using spring and java) expects to have the below data structure:
public class MAProductsUploadRequest
{
public List<MAProductUploadRequest> products;
}
public class MAProductUploadRequest {
public String productName;
public String productDescription;
public double productPrice;
public int productOrder;
public MultipartFile productImage=null;
public double cropX;
public double cropY;
public double cropWidth;
public double cropHeight;
public int categoryId;
}
And in our Vuejs application we tried to post the data as in the below code:
addProducts: function () {
console.log("Add Products Working. Total Product Count:"+this.excelProducts.length);
let header = {
headers: auth.getAuthHeader()
};
let formData = new FormData();
for (let i=0;i<this.excelProducts.length;i++ ) {
console.log("Starting loop:"+i);
var prod = this.excelProducts[i];
console.log("Product Before:"+prod);
if (document.getElementById('photo-image-'+i) !== null) {
if(document.getElementById('photo-image-'+i).files.length !== 0) {
console.log("Getting Image For Prod");
prod.productImage = document.getElementById('photo-image-'+i).files[0] ;
}
}
prod.cropX = this.cropProp.x;
prod.cropY = this.cropProp.y;
prod.cropWidth = this.cropProp.width;
prod.cropHeight = this.cropProp.height;
prod.rotate = this.cropProp.rotate;
console.log("Product After:"+prod);
formData.append("products[]",prod);
}
for (var pair of formData.entries()) {
console.log(pair[0]+ ', ' + pair[1]);
}
//console.log("Form Data:"+formData.products);
if (formData.products !== null) {
axios.post(`${API_URL}/company/uploadProducts`, formData, header).then((response) => {
logForDevelopment(response);
this.getProducts();
this.product = {
id: '',
name: '',
description: '',
price: '',
photo: '',
isEdit: false
};
this.excelProducts = [];
this.isPhotoChosen = false;
this.isPhotosChosen = [];
this.cropImg = '';
document.getElementById('photo-image').value = null;
this.isLoading = false;
}).catch((error) => {
this.isLoading = false;
if(error.response) {
logForDevelopment(error);
document.getElementById('photo-image').value = null;
if(error.response.status === 401 || error.response.status === 403) {
auth.afterInvalidToken('login');
}
}
})
} else {
console.log("Form Data Is Empty");
}
},
But when we use this code (even if the photo-image was null) the backend server returns HTTP 500 error. Because the products array seems null.
I wasn't able to figure it out where the problem may be in the Vuejs code?
EDIT: (I'VE also tried the below code but the still same result)
addProducts: function () {
console.log("Add Products Working. Total Product Count:"+this.excelProducts.length);
let header = {
headers: auth.getAuthHeader()
};
let formData = new FormData();
let prods = [];
for (let i=0;i<this.excelProducts.length;i++ ) {
console.log("Starting loop:"+i);
let prod = this.excelProducts[i];
let subFormData = new FormData();
subFormData.append("productName",prod.productName);
subFormData.append("productDescription",prod.productDescription);
subFormData.append("productPrice",prod.price);
subFormData.append("categoryId",prod.categoryId);
subFormData.append("cropX",this.cropProp.x);
subFormData.append("cropY",this.cropProp.y);
subFormData.append("cropWidth",this.cropProp.width);
subFormData.append("cropHeight",this.cropProp.height);
prods.push(subFormData);
if (document.getElementById('photo-image-'+i) !== null) {
if(document.getElementById('photo-image-'+i).files.length !== 0) {
console.log("Getting Image For Prod");
subFormData.productImage = document.getElementById('photo-image-'+i).files[0] ;
}
}
}
formData.append("products",prods);
console.log("Form Data:"+formData);
if (formData.products !== null) {
axios.post(`${API_URL}/company/uploadProducts`, formData, header).then((response) => {
logForDevelopment(response);
this.getProducts();
this.product = {
id: '',
name: '',
description: '',
price: '',
photo: '',
isEdit: false
};
this.excelProducts = [];
this.isPhotoChosen = false;
this.isPhotosChosen = [];
this.cropImg = '';
document.getElementById('photo-image').value = null;
this.isLoading = false;
}).catch((error) => {
this.isLoading = false;
if(error.response) {
logForDevelopment(error);
//document.getElementById('photo-image').value = null;
if(error.response.status === 401 || error.response.status === 403) {
auth.afterInvalidToken('login');
}
}
})
} else {
console.log("Form Data Is Empty");
}
},
What I'm actually trying to achive is, our below code works fine when sending single product info to our backend service, but I want to make it an array so send multiple products at once:
addProduct: function () {
let header = {
headers: auth.getAuthHeader()
};
let formData = new FormData();
formData.append('productName', this.product.name);
formData.append('productDescription', this.product.description === '' ? "" : this.product.description);
formData.append('productPrice', this.product.price);
formData.append('categoryId', this.product.categoryId);
if(document.getElementById('photo-image').files.length !== 0) {
formData.append('productImage', document.getElementById('photo-image').files[0]);
}
formData.append('cropX', this.cropProp.x);
formData.append('cropY', this.cropProp.y);
formData.append('cropWidth', this.cropProp.width);
formData.append('cropHeight', this.cropProp.height);
formData.append('rotate', this.cropProp.rotate);
console.log(formData);
axios.post(`${API_URL}/company/products`, formData, header).then((response) => {
logForDevelopment(response);
this.getProducts();
this.product = {
id: '',
name: '',
description: '',
price: '',
photo: '',
isEdit: false
};
this.isPhotoChosen = false;
this.cropImg = '';
document.getElementById('photo-image').value = null;
this.isLoading = false;
}).catch((error) => {
this.isLoading = false;
if(error.response) {
logForDevelopment(error);
document.getElementById('photo-image').value = null;
if(error.response.status === 401 || error.response.status === 403) {
auth.afterInvalidToken('login');
}
}
})
},
Does anyone have any idea about that?
You can also look at the screenshot of my application in below(I want to send all the items in screenshot , at once )
Your issue is probably il the formData.append("products[]",prod) method of your FormData class, try changing formData.append("products[]",prod) with formData.products.push(prod).
Furthermore in your axios call the payload should be formData.products if you API endpoint expects the products right?
Try axios.post(${API_URL}/company/uploadProducts, formData.products, header).
I do not see any syntax issue relative to Vue, hope this helps. (And of course check what is sent by XHR in devtools as suggested in the comments)

JSON api works on local, but not on public deploy

I have a weather API using JSON that works on my local machine, but when I try to deploy it to GithubPages, it nulls out and the API doesn't pull. It was written in js for a reactjs page.
Here is the working site that is on localhost:3000
Not working website hosted on GitHub pages
Deployed Website
state = {
current: 'none'
}
fetchWeather = () => {
return fetch(`https://api.aerisapi.com/observations/75248client_id=${accessId}&client_secret=${APIkey}`)
.then((res) => res.json())
}
componentDidMount = () => {
this.fetchWeather()
.then((json) => {
json.success ? this.setState({ current: json.response.ob }) : null
})
}
formatCurrentWeather = (currentWeather) => {
let current = ''
if (currentWeather.toLowerCase().charAt(currentWeather.length-1) === 'y') {
current = currentWeather.toLowerCase() + ' '
} else if (currentWeather.toLowerCase() === 'clear') {
current = 'cloudless '
} else if (currentWeather.toLowerCase() === 'freezing fog') {
current = 'freezing '
} else if (currentWeather.toLowerCase().charAt(currentWeather.length-1) === 'g') {
current = currentWeather.toLowerCase() + 'gy '
} else {
current = currentWeather.toLowerCase() + 'y '
}
return current
}
importAll = (r) => {
let icons = {};
r.keys().map((item, index) => { icons[item.replace('./', '')] = r(item); });
return icons;
}
render() {
console.log(this.state.current)
const icons = this.importAll(require.context('../images/icons', false, /\.(png|jpe?g|svg)$/));
let currentWeather = '🌃'
this.state.current === 'none' ? null : currentWeather = this.formatCurrentWeather(this.state.current.weatherPrimary)

Uploading Files in angular 2

I am trying to upload a csv/xlxs file in angular 2 but whenever i submit the file, i get an exception file could not upload. please try again from my backend although it works fine on postman. What could be wrong in my code?
//service
constructor (private authenticate:AuthenticationService) {
this.filetrack = Observable.create(observer => {
this.progressObserver = observer
}).share();
}
SendRequest (url: string, params: string[], files: File[]) {
return Observable.create(observer => {
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();
for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
observer.next(JSON.parse(xhr.response));
observer.complete();
} else {
observer.error(xhr.response);
}
}
};
xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);
this.progressObserver.next(this.progress);
};
xhr.open('POST', url, true);
xhr.setRequestHeader('Authorization', 'Bearer ' + this.authenticate.user_token);
xhr.send(formData);
});
}
}
//component
export class FileUploadComponent {
constructor(private service:FileUploadService) {
this.service.filetrack.subscribe(
data => {
console.log('progress = '+data);
});
}
onChange(event) {
console.log('onChange');
let files = event.target.files;
console.log(files);
this.service.SendRequest('http://localhost:8000/register/v1/file/country', [], files).subscribe(() => {
console.log('sent');
});
}
}
You have to set another header to be able to upload a file:
xhr.setRequestHeader("Content-Type", "multipart/form-data");