ExtJS 6: Validator on a textfield not working properly - javascript

I got a signup-form with a textfield for the username.
For this textfield I added a custom validator function to check the availability for the selected username:
xtype: 'textfield',
name: 'username',
msgTarget: 'under',
bind: {
fieldLabel: '{texts.username}'
},
allowBlank: false,
minLength: 3,
checkChangeBuffer: 300,
validator: function (value) {
if (value.length < 3) {
return null;
}
Ext.Ajax.request({
method: 'POST',
url: '/rest/availability',
params: {
name: value
}
}).then(
function (result) {
return Ext.JSON.decode(result.responseText) ? true : 'Username already exists';
},
function (response) {
return 'Server issue.';
}
)
}
This should probably do it. But it doesnt.
I get a broken error, the validator shows always invalid and the message is not displayed:
When I check the response I get the correct value from the server.
What am I missing here?
Thanks in advance.

In order for the validation to pass you need to return true.
validator: function(value) {
if(!valid) {
return 'error message';
}
return true; // successfully passed
}

Related

Ext js 7 modern, form.submit vs ajax.request

I have a Ext.form.Panel with multiple textareafield and fileinput like this
// https://requestbin.com/r/en0ej96odon2sm/1n6r1tb49KK6eObGMPHlYa1hh4C
Ext.create({
xtype: 'formpanel',
renderTo: document.body,
buttons: {
submit: 'onSubmit',
},
controller: {
onSubmit: function () {
var form = this.getView();
form.submit({
method: 'POST',
url: 'https://en0ej96odon2sm.x.pipedream.net/test1',
success: function () {}
});
},
onSubmitTest: function () {
var form = this.getView();
Ext.Ajax.request({
url: 'https://en0ej96odon2sm.x.pipedream.net/test2',
method: 'POST',
params: {
data: form.getValues(),
},
success: function () {}
});
},
},
items: [{
xtype: 'textareafield',
name: 'testfield',
label: 'testfield',
value: 'test\nasd',
}, {
xtype: 'filefield',
label: 'Upload Test',
name: 'basedata-test',
}, {
xtype: 'button',
text: 'Ajax.request(), linebreaks but no files',
handler: 'onSubmitTest',
}]
});
Post Results:
https://requestbin.com/r/en0ej96odon2sm/1n6mtu8QtyreaisCAmV3csO724Q
Fiddle:
https://fiddle.sencha.com/#view/editor&fiddle/3b9j
So, cause i need fileinput/multipart, I have to use form.submit({}).
But when I do so, I don't get the linebreaks on Server side in my $_POST Var.
When I do a ajax.request({}) everything looks good, but $_FILES are missing, so this is not really an option. (but this is documented).
I also tried adding jsonSubmit to the form (then I get no $_POST at all).
When I add enableSubmissionForm: false I get the newline, but after submit the form disappears (and I don't know why).
Is there a solution for this or am I doing something wrong?
You can use the following override. Hope it will not make the framework unstable ;)
// https://requestbin.com/r/en0ej96odon2sm/1n6r1tb49KK6eObGMPHlYa1hh4C
// Override
Ext.define('overrides.form.Panel', {
override: 'Ext.form.Panel',
privates: {
createSubmissionForm: function (form, values) {
var fields = this.getFields(),
name, input, field, fileTrigger, inputDom;
if (form.nodeType === 1) {
form = form.cloneNode(false);
for (name in values) {
input = document.createElement('textarea');
input.setAttribute('type', 'string');
input.setAttribute('name', name);
input.innerHTML = values[name];
form.appendChild(input);
}
}
for (name in fields) {
if (fields.hasOwnProperty(name)) {
field = fields[name];
if (field.isFile) {
// The <input type="file"> of a FileField is its "file" trigger button.
fileTrigger = field.getTriggers().file;
inputDom = fileTrigger && fileTrigger.getComponent().buttonElement.dom;
if (inputDom) {
if (!form.$fileswap) {
form.$fileswap = [];
}
input = inputDom.cloneNode(true);
inputDom.parentNode.insertBefore(input, inputDom.nextSibling);
form.appendChild(inputDom);
form.$fileswap.push({
original: inputDom,
placeholder: input
});
}
} else if (field.isPassword) {
if (field.getInputType() !== 'password') {
field.setRevealed(false);
}
}
}
}
return form;
}
}
});
Ext.create({
xtype: 'formpanel',
renderTo: document.body,
buttons: {
submit: 'onSubmit',
},
controller: {
onSubmit: function () {
var form = this.getView();
form.submit({
method: 'POST',
url: 'https://en0ej96odon2sm.x.pipedream.net/test1',
success: function () {}
});
},
onSubmitTest: function () {
var form = this.getView();
Ext.Ajax.request({
url: 'https://en0ej96odon2sm.x.pipedream.net/test2',
method: 'POST',
params: {
data: form.getValues(),
},
success: function () {}
});
},
},
items: [{
xtype: 'textareafield',
name: 'testfield',
label: 'testfield',
value: 'test\nasd',
}, {
xtype: 'filefield',
label: 'Upload Test',
name: 'basedata-test',
}, {
xtype: 'button',
text: 'Ajax.request(), linebreaks but no files',
handler: 'onSubmitTest',
}]
});
Not ideal, but you also can do this:
form.submit({
method: 'POST',
//just like the ajax
params: {
data: form.getValues(),
},
url: 'https://en0ej96odon2sm.x.pipedream.net/test1',
success: function () {}
});
Here is a simple workaround for using Ajax.request instead of form.submit
I needed that because I have to set an Authorization header, which can't be done with IFRAME used by the framework
So preventing Ext.data.request.Ajax from setting Content-Type header seems to do the job.
multipart/form-data will be automatically set.
Warning : neither options.headers nor defaultHeaders should already have the 'Content-Type' header
Ext.define('Override.data.request.Ajax', {
override: 'Ext.data.request.Ajax',
setupHeaders: function(xhr, options, data, params) {
if (data instanceof FormData) {
if (Ext.apply({}, options.headers || {}, this.defaultHeaders).hasOwnProperty('Content-Type')) {
console.warn('The Content-Type header must not be set before request if you need to use FormData with this override');
}
/* prevent Ext.data.request.Ajax from setting Content-Type header */
return this.callParent([xhr, options, null, null]);
} else {
return this.callParent(arguments);
}
}
});
And call Ajax.request with a FormData as rawData
var formData = new FormData();
var files = myView.down('filefield').getFiles();
if (files.length > 0) {
formData.append('file', files[0], files[0].name);
}
Ext.Ajax.request({
url: 'your_url',
rawData: formData,
success: function(response) {
// handle success
},
failure: function(response) {
// handle failure
}
});

Function returning true despite promise evaluating to false

I'm having a real hard time figuring out the behaviour of Promises. I'm using Vue and the vee-validate library, which allows for manual validation of a form via:
this.$validator.validate()
However, when I try to use it I get weird behaviour:
async isFormValid() {
return await this.$validator.validate();
},
Whenever I submit a form with errors, the form sends the AJAX request:
onApprove() {
if (!that.isFormValid) {
return false;
}
$.ajax({
...
});
return false; // Modal never closes unless AJAX is successful.
},
Additionally, I've tried the following construct:
onApprove() {
this.$validator.validate().then(result => {
if(result) {
$.ajax({
...
});
}
return false; // Modal never closes unless AJAX is successful.
});
},
But this doesn't work either. I've found a work-around by doing this:
isFormValid() {
this.$validator.validate();
return Object.keys(this.fields).every(key => this.fields[key].valid);
},
But if someone could explain what I'm misunderstanding about the `Promise, that would be great.
Edit
Full onApprove example (always returns true regardless of validation:
onApprove() {
that.$validator.validate().then(result => {
if (result) {
$.ajax({
url: '/settings/user_management_add_user', method: 'POST', data: {
csrfmiddlewaretoken: that.csrfToken, password: that.password, user: JSON.stringify(that.users[that.activeUserRow]),
}, success() {
$('#modify_user_modal').modal('hide');
that.showToast('check icon', gettext('User created'));
that.activeUserRow = undefined;
that.initialQuery();
}, error(data) {
that.showToast('remove icon', gettext('User could not be created'));
if (data.responseText && data.responseText.length < 20) {
that.showToast('remove icon', data.responseText);
}
},
});
}
return false; // Modal never closes unless AJAX is successful.
});
},
This method also doesn't work (return false first):
onApprove() {
that.$validator.validate().then(result => {
if (!result) {
return false
}
$.ajax({
url: '/settings/user_management_add_user', method: 'POST', data: {
csrfmiddlewaretoken: that.csrfToken, password: that.password, user: JSON.stringify(that.users[that.activeUserRow]),
}, success() {
$('#modify_user_modal').modal('hide');
that.showToast('check icon', gettext('User created'));
that.activeUserRow = undefined;
that.initialQuery();
}, error(data) {
that.showToast('remove icon', gettext('User could not be created'));
if (data.responseText && data.responseText.length < 20) {
that.showToast('remove icon', data.responseText);
}
},
});
return false; // Modal never closes unless AJAX is successful.
});
},
So #Axnyff found this semantic-ui beug report, which led me to the solution:
onApprove() {
that.$validator.validate().then((result) => {
if (result) {
$.ajax({
...
},
complete() {
$('#modify_user_modal').modal('hide'); // Manually hide.
},
});
}
});
return false; // Modal never closes.
},

Validate x-editable using Ajax

I am using http://vitalets.github.io/x-editable/ and wish to validate an input using Ajax. For testing, I created the following script https://jsfiddle.net/m698gxgj/1/.
My Ajax request is asynchronous so the validate callback returns I believe undefined, and therefore it doesn't result in the input failing validation.
I "could" change my Ajax request to be synchronous, but everything I read (https://stackoverflow.com/a/14220323/1032531) indicates that is not a good idea.
How is this accomplished?
<p>Name</p>
$('#name').editable({
type: 'text',
title: 'Name',
url: '/echo/json/',
pk: 123,
validate: function (value) {
if (value == 'bob') {
return 'bob is not allowed';
} else {
$.post('/echo/html/', {
html: 'false',
delay: .5
}, function (result) {
if (result == 'false') {
console.log('remote error');
return 'remote error';
}
});
}
}
});
The validate option is only to be used for client side validation, so the if (value == 'bob') bit is alright, but you shouldn't fire the ajax post in the else block.
You should make the url option do the ajax post, then you can leverage the success and error options to handle async callback properly.
For example:
$('#name').editable({
type: 'text',
title: 'Name',
url: function () {
return $.post('/echo/json/', {
json: 'false',
delay: .5
});
},
pk: 123,
validate: function (value) {
if (value == 'bob') {
return 'bob is not allowed';
}
},
success: function (response) {
if(response === false) {
console.log('remote error from success');
return 'remote error';
}
},
error: function (response) {
console.log('remote error from fail');
return 'remote error';
}
});
jsfiddle:
https://jsfiddle.net/x0bdavn7/

How to get value from textfield to variables

Im using Mvc in C#.net and extjs. My question is
how to get value from textfield then set it to a variable and send email to multiple recipient.
This is my code for sending an email, and i want to get the values from the Extjs textfield id and set the id to a variable in sending. Then i want to send email to multiple recipient.
{
xtype: 'toolbar',
flex: 1,
dock: 'bottom',
ui: 'footer',
layout: {
pack: 'end',
type: 'hbox'
},
items: [{
xtype: 'button',
text: 'Send Email',
itemId: 'sen',
//iconCls: 'cancel'
handler: function() {
var rec = Ext.getCmp("activityGrid").getSelectionModel().selected()[0]
Ext.Ajax.request({
url: '/tblt_UAT_hr/generatePreview',
method: 'POST',
params: {
// id: Ext.get("Uath_Id").getValue(),
desc: rec.get("pc_desc"),
uat_date: rec.get("UAT_date"),
pcno: rec.get("pc_no"),
name: rec.get("name"),
stkid: rec.get("Stkhid")
},
success: function(resp) {
var result = Ext.decode(resp.responseText);
if (result.success) {
Ext.Ajax.request({
url: '/tblt_UAT_hr/SendEmailsTo',
method: 'POST',
params: {
from: null,
to: Ext.getCmp('to').getValue(),
subject: Ext.getCmp('subject').getValue(),
body: Ext.getCmp('bod').getValue(),
file: result.file
},
success: function(resp) {},
failure: function() {}
});
} else
mask.hide();
},
failure: function() {
mask.hide();
}
});
}
}, {
xtype: 'button',
text: 'Cancel',
itemId: 'can',
//iconCls: 'save'
}]
}]
public JsonResult SendEmailsTo(string from, string to, string subject, string body, string file) {
if (file != "" && file != null) {
MailMessage mail = new MailMessage();
SmtpClient smtpServer = new SmtpClient("smtp.gmail.com");
smtpServer.Credentials = new System.Net.NetworkCredential("ga.ojt.sunga#gmail.com", "1993doris");
smtpServer.Port = 587; // Gmail works on this port
string newfile = Server.MapPath("~/Content/pdf") + "\\" + file;
Attachment attachment = new Attachment(newfile);
mail.From = new MailAddress("ga.ojt.sunga#gmail.com");
//mail.To.Add(emailAdd);
foreach(var address in to.Split(new [] {
";"
}, StringSplitOptions.RemoveEmptyEntries)) {
mail.To.Add(address);
}
mail.Subject = subject;
mail.Body = body;
mail.Attachments.Add(attachment);
smtpServer.EnableSsl = true;
smtpServer.Send(e);
// return Content("email sent", "text/plain");
}
return Json(new {
success = true, msg = "success"
}, JsonRequestBehavior.AllowGet);
}
Find the text field, with ComponentQuery or otherwise, call getValue on it and add it to params of a request call. Pseudo code:
var field = Ext.ComponentQuery.query('#fieldItemId')[0];
params:{
yourField:field.getValue();
}

jquery validation error while checking department name

I have used the jquery validation for checking the department name is already exist in the specific organization. But its not returning the correct result. Please someone help me.
Here is my Jquery:
$(document).ready(function(){
var validator = $("#frmAddDepartment").validate({
errorElement:'div',
rules: {
organization:{
required:true
},
department: {
required: true,
allowChars:true,
//remote:$('#site_url').val()+"admin/department/check_department/"+$('#department').val()+"/"+$('#Organization').val(),
checkdeptname:true
}
},
messages: {
organization:{
required:languageArray['select_organization']
},
department:{
required:languageArray['enter_department'],
//remote:jQuery.format(languageArray['dept_exist'])
}
}
});
jQuery.validator.addMethod("allowChars", function(value, element) {
var filter = new RegExp(/[^a-zA-Z0-9\-& ]/);
if(!(filter.test(value)))
{
return true;
}else
return false;
},languageArray['please_enter_valid_chars']);
jQuery.validator.addMethod("checkdeptname", function(value, element) {
returnResult = false;
$.ajax({
url: $('#site_url').val()+"admin/department/check_department",
type: "GET",
data:{department:value,organization:$('#Organization').val()},
success: function (result)
{
returnResult = result;
alert(returnResult);
}
});
//$.get( $('#site_url').val()+"admin/department/check_department", { department:value,organization:$('#Organization').val() }, function(data){alert(data);returnResult = result;} );
return returnResult;
},languageArray['dept_exist']);});
PHP controller's function:
public function check_department()
{
$sql_query=$this->department_model->check_department();
if($sql_query>0)
{
echo "false";
}else
{
echo "true";
}
}
I think , in your php controller function you are returning ture/flase as String and on ajax success call back function your are comparing it with boolean ture/flase.

Categories

Resources