this.up() is not function EXTJS - javascript

I want to submit my data to server from controller.
Code is as follows:
renterForms: function() {
var items3 = [{
xtype:'foresto-renterdata',
scrollable: true,
scope: this,
renderTo: 'mainPart',
handler: function() {
this.action3.hide();
}
},{
text: 'Submit',
ui: 'confirm',
scope: this,
handler: function() {
var form = this.up('foresto-rentertype');
if (form.isValid()) {
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
}
});
} else { /
Ext.Msg.alert('Error', 'Please correct form errors.')
}
}
in chrome debugger, I see next error:
Uncaught TypeError: this.up is not a function.
What is wrong? Is this a good way to get and submit data?
P.S. url for POST request define in code of form

scope: this
this is the actual issue which is messing up with scope inside handler function. Remove it and it will resolve the up function.
You can see the behavior with scope with following example fiddle:
https://fiddle.sencha.com/#view/editor&fiddle/2nhv
When "scope: this" is defined, then scope while building the component will be used and injected inside the handler function. It is equivalent to explicitly writing handlerFn.bind(this) which simply binds the different scope and returns a new function.

Related

Having issues understanding flow - HTML form data handling by vue and axios

I am new to Vue and Axios and trying to use it in Salesforce Marketing Cloud - Cloud pages. Basically there are 3 parts,
HTML + vue page : this is a form page, where the user is asked to input the automation name and click on send button
App.js : this is build using axios and Vue.
Form-hander.js (backend) : SSJS code that runs the automation.
I referred this document to build this setup -https://ampscript.xyz/how-tos/how-to-start-status-of-automation-from-marketingcloud-form/. I understand the Form-hander.js (ssjs) code and this can be skipped.
What I am not able to understand is the flow of App.js, could anyone please explain me what is happening here.
I understand that on click of send button, the function in App.js - validateForm is called. Here after I don’t understand the flow of the code.
From App.js is the form-handler code called ? OR the post method used in the HTML page is directly called the form-handler page and staring the automation?
Here is the code of app.js. Can some explain to me in simple terms the flow of this code, would be really helpful.
new Vue({
el: '#app',
data: {
status: 100,
form: {
name: 'My Test Automation',
context: 'perform'
},
endpoint: '',
message: ''
},
watch: {
status: function () {
if(this.status == 201 || this.status == 102) {
this.form.context = 'check';
} else {
this.form.context = 'perform';
}
}
},
mounted: function() {
this.endpoint = this.$refs.form.getAttribute('action');
},
methods: {
sendFormData: function() {
this.status = 101;
var $this = this;
axios({
method: 'POST',
url: $this.endpoint,
data: $this.form,
validateStatus: function() { return true }
}).then(function(result) {
$this.status = result.data.Status;
$this.message = result.data.Message;
$this.checkStatus();
}).catch(function(error) {
console.error(error);
});
},
checkStatus: function() {
var $this = this;
var intervalID = setInterval(function() {
axios({
method: 'POST',
url: $this.endpoint,
data: $this.form,
validateStatus: function() { return true }
}).then(function(result) {
$this.status = result.data.Status;
$this.message = result.data.Message;
if($this.status == 200 || $this.status == 500) {
clearInterval(intervalID);
}
}).catch(function(error) {
console.error(error);
});
}, 10000);
},
validateForm: function() {
if (this.$refs.form.checkValidity() !== false) {
this.sendFormData();
}
this.$refs.form.classList.add('was-validated');
}
}
})
Let me explain you the flow of the code you posted :
Once component mounted, The first method which is getting called is mounted(). In this method you are fetching the endopint binded to the action attribute in your form html element and binding that in a data variable via this.endpoint.
Now, you are calling validateForm() method on click of submit button to validate the input fields. If validation pass, you are calling sendFormData() method to make an POST API call.
After getting the response, you added a watcher on status to update the form.context value based on the status code you received from an API response.
At the end, you are calling a checkStatus() method on success of axios call and in this checkStatus() method you are again making an POST API call after every 10 seconds and following step 3.
When the components is mounted, you run the form binded action on (submit?)
The action is probably binded to the sendFormData function(in methods)
Inside sendFormData, there is the setup of the axios request, followed be a then callback which handles the response from the request
The checkStatus function is called inside the "then" block
Sends the same data back to the server every 10 seconds if the previous response
doesn't have status code other than 200 or 500.
ValidateForm is may binded to some onInput or onChange event on the template
** The watcher is always looking for the status code and updates a form context

Handling Direct Update with navigation to native page in IBM Mobile first

I am developing a project, in which i need to call a native page in wlCommonInit()
function wlCommonInit(){
WL.NativePage.show(nativePageClassName, backFromNativePage, params);
}
I want my project to receive the direct update with persession mode. So to connect with the Mobile First Server, I have called WL.Client.connect()
function wlCommonInit(){
busyind = new WL.BusyIndicator;
busyind.show();
WL.Client.connect({onSuccess: connectSuccess, onFailure: connectFail});
WL.NativePage.show(nativePageClassName, backFromNativePage, params);
}
More over I want to handle the direct update so I have added the required code.
wl_directUpdateChallengeHandler.handleDirectUpdate = function(directUpdateData,
directUpdateContext) {
// custom WL.SimpleDialog for Direct Update
var customDialogTitle = 'Custom Title Text';
var customDialogMessage = 'Custom Message Text';
var customButtonText1 = 'Update Application';
var customButtonText2 = 'Not Now';
WL.SimpleDialog.show(customDialogTitle, customDialogMessage, [{
text: customButtonText1,
handler: function() {
directUpdateContext.start(directUpdateCustomListener);
}
}, {
text: customButtonText2,
handler: function() {
wl_directUpdateChallengeHandler.submitFailure();
}
}]);
};
var directUpdateCustomListener = {
onStart: function(totalSize) {},
onProgress: function(status, totalSize, completeSize) {},
onFinish: function(status) {
WL.SimpleDialog.show('New Update Available', 'Press reload button to update to new version', [{
text: WL.ClientMessages.reload,
handler: WL.Client.reloadApp
}]);
}
};
Here the problem is, the application is navigating to the native page
before it can go to the direct update handler function when the direct
update is available.
Is there any way to resolve it?
I think what you should do instead if use the API [WL.Client.checkForDirectUpdate.
This way you will have the ability to first check for direct update - handle it if there is an update and then execute the function for opening the native page.
The code that is running is async, so you can't control it if you're not following the above suggestion.

Providing a template for $confirm dialogs

I'm using angular-confirm to display confirmation messages in a lot of places in my app. For example:
$confirm({
text: 'content',
title: 'title text',
ok: 'Yes',
cancel: 'No'})
.then(function() {
doSomething();
});
I want to globally change the layout in which these dialogs appear in the app. I know that angular-confirm allows you to make a global change like this:
$confirmModalDefaults.templateUrl = 'path/to/your/template';
However, this also overrides the template for all $modal.open() calls, which is not what I want.
I think that the way to do this is by a using a provider to append a template url to every $confirm call in the app but I'm not sure exactly how to do that.
How do I create a provider for $confirm and append a templateUrl parameter to every call?
Figured it out:
function config($provide) {
$provide.decorator('$confirm', confirmProvider);
}
/* #ngInject */
function confirmProvider($delegate) {
return function (data, settings) {
if (settings && !settings.template && !settings.templateUrl) {
settings.template = '<div>my confirm content</div>';
} else {
settings = {
template: '<div>my confirm content</div>'
}
}
return $delegate(data, settings);
};
So now, when $confirm() gets called with data and/or settings, it will apply my custom template unless it's been specified by the caller

Validate function is not working in backbone

I'm trying to log an error when an attribute of a variable is changed, but the validate is never being triggered, this is my code:
Person = Backbone.Model.extend({
initialize: function() {
console.log("hello world");
this.bind('change:name', function() {
console.log(this.get('name') + ' is now the value for the name');
});
this.bind('error', function(model, error) {
console.log(error);
});
},
defaults: {
name: 'Bob Hope',
height: 'unknown'
},
validate: function(attributes) {
if(attributes.name == 'blank'){
return 'no';
}
}
});
var person = new Person();
person.set({name: 'blank'});
I have even tried called set like this:
person.set({name: 'blank'}, {validate: true});
but that doesn't work either, I'm using version 1.0.0.
As per the documentation:
By default validate is called before save, but can also be called
before set if {validate:true} is passed.
Also, the event that is triggered is invalid, not error, so try this:
this.bind('invalid', function(model, error) {
console.log(error);
});

Extjs 3.3 IE8 chained events is breaking

This one is wired.
This fires from a grid toolbar button click:
// fires when the client hits the add attachment button.
onAddAttachmentClick: function () {
var uploadAttachmentsWindow = new Nipendo.ProformaInvoice.Attachment.UploadWindow({
invoice: this.invoice,
maxFileSizeInMB: this.maxFileSizeInMB
});
uploadAttachmentsWindow.on('uploadcomplete', function (win, message) {
if (message.msg !== 'success') {
return;
}
win.close();
var store = this.getStore();
store.setBaseParam('useCache', false);
store.load();
this.fireEvent(
'attachmentuploaded',
this.invoice.ProformaInvoiceNumber,
this.invoice.VendorSiteID,
this.invoice.CustomerSiteID);
}, this);
uploadAttachmentsWindow.show();
} // eo onAddAttachmentClick
This is what happens on the uploadcomplete event:
this.uploadBtn.on('click', function () {
var form = this.uploadForm.getForm();
if (!form.isValid()) {
return;
}
form.submit({
url: 'XXX.ashx',
waitMsg: Nipendo.Localization.UploadingAttachment,
scope: this,
success: function (form, action) {
this.fireEvent('uploadcomplete', this, {
msg: 'success',
response: action.response
});
},
failure: function (form, action) {
switch (action.failureType) {
case Ext.form.Action.CLIENT_INVALID:
this.fireEvent('uploadcomplete', this, {
msg: 'Form fields may not be submitted with invalid values'
});
break;
case Ext.form.Action.CONNECT_FAILURE:
this.fireEvent('uploadcomplete', this, {
msg: 'Ajax communication failed'
});
break;
case Ext.form.Action.SERVER_INVALID:
Ext.Msg.alert(action.result.title, action.result.message);
this.fireEvent('uploadcomplete', this, {
msg: action.result.message
});
break;
}
}
});
}, this);
On IE 8 I am getting this error in the debugger:
I have no idea what object is missing... from my check they are all defined.
Any idea anyone?
Notice that I have an event firing from a listener (I am suspecting it to be the root of the problem).
It is hard to see but the error occuers in ext-all.js in the fire method.
I have found the answer in : https://stackoverflow.com/a/3584887/395890
Problem was I was listing to events is 2 different windows, that is not possible in Ext.
What I have done to solv it was to call the opner window from the pop up window to notify about changes.

Categories

Resources