I am using Ext.direct.RemotingProvider . At the server side I make some validation checks. The Respond is send back in JSON format.
If i find any errors when making validation checks, the field success = false, and errors will contain the error.
I am trying to figure out, how do i reflect errors i found in the server side in the form (client side).
In the link below there is an example of what i want to achieve. When the client press on "submit" an error message will occur in the form, how does it work ?
Example
In the code i post in the bottom the following happens:
in the browser there are 2 fields (Name,Email) and 2 buttons.
the fields are irrelevant for now. they are used as dummies.
Each time the user press on "Add" button, a new action is added into callBuffer of Ext.direct.RemotingProvider
When the user press on "Apply" button, all the actions are being sent to the router (MVC model) and from there to a specific controller. (the function sfw.Direct.getProvider('sfwProvider').combineAndSend() is triggered).
As for now, i intentionally fails the respond and create an error field, just like the example link i added in the beginning of the Thread.
i put in the errors field {email="Already exists"}.
but i see not effect in the form..
what am i doing wrong ?
Code:
appWiki.main_panel = new Ext.FormPanel({
renderTo: 'extjs_panels_container'
, id: 'appWiki_main_panel'
, name: 'appWiki_main_panel'
, defaultType: 'textfield'
, items: [
{
fieldLabel: 'Name',
name: 'name'
}
,{
fieldLabel: 'Email',
msgTarget: 'side',
name: 'email'
}]
,buttons:[
{xtype: 'sfw.Button'
, text: 'Add'
, handler: function(){sfw.rule.store.api.readByRowId({data: {_ROWID_: 1}});}
}
,{text: 'Submit'
, handler: function(){
appWiki.main_panel.getForm().submit({
});
}
}]
,api: {
// The server-side must mark the submit handler as a 'formHandler'
submit: sumbitAllRequests
}
, load: function()
{
setTimeout("hide_loading_mask()",2000);
}
});
In the JSON response you need the following structure
{ "result" : { "success": false, "errors": { "name of field" : "validation message" } }
Where "name of field" is the name config option in your field, and "validation message" is the message you want to display to the user.
When you send a response like that ExtJS will take care of the rest.
EDIT: You may also need to enable QuickTips:
Ext.QuickTips.init();
Add that line before you declare your form
EDIT 2: Also, make sure you're using the submit() method found on the BasicForm:
buttons:[{
text: 'Submit',
handler: function(){
basicInfo.getForm().submit({
params: {
foo: 'bar',
uid: 34
}
});
}
}],
Related
I've created a custom dialog with a dropzone in order to upload files and images to our server. By default the dropzone renders with 'Drop an image here' / 'Browse for an image'.
As part of the tinymce editor options file_picker_type allows setting of the default dropzone and I wondered how to access these options for a stand-alone dropzone?
My tinymce options include:
tinymce.init({
file_picker_types: 'file image'
});
My upload dialog config looks something like this:
const upload_config = {
title: 'Upload files',
size: 'medium',
body: {
type: 'panel',
{
type: 'dropzone',
name: 'file_drop',
types: 'file image' //// <----- something like this???
}
]
},
buttons: [
{
type: 'cancel',
name: 'closeButton',
text: 'Cancel',
},
{
type: 'submit',
name: 'submitButton',
text: 'Upload',
buttonType: 'primary'
}
],
onSubmit: (api) => {
// handle upload here
}
};
Anybody managed to fathom this? The tinymce docs are in no way comprehensive as they simply say "A dropzone is a composite component that catches drag and drops items or lets the user browse that can send a list of files for processing and receive the result." but give no details on how to actually do that with a stand alone dropzone.
I've managed to make it all work, but this is the last hurdle.
Thanks in advance
Are you trying to override the default image/file upload dialog with the custom one? I'm asking because I see the file_picker_types config option. To do so, you will need to use the file_picker_callback.
If it's something else and you are not trying to override the default dialog, use this interactive example as a base. You will need to:
a) Register the custom button with a setup function:
setup: function (editor) {
editor.ui.registry.addButton('custom-upload', {
icon: 'upload',
onAction: function () {
editor.windowManager.open(upload_config)
}
})
},
b) Add this button to the toolbar via toolbar: 'custom-upload'. This way, pressing the button will open the dialog based on the upload_config variable.
c) You've made a mistake in the panel config. I guess, you forgot to create the items array at the beginning. Instead of
type: 'panel',
{
type: 'dropzone',
name: 'file_drop',
types: 'file image' //// <----- something like this???
}
]
There should be:
type: 'panel',
items: [
{
type: 'dropzone',
name: 'file_drop',
label: 'Dropzone',
}
]
I've created this fiddle as a quick demo: https://fiddle.tiny.cloud/3iiaab
P.S. The dropzone component does not support file types. But you can check the file types after they are uploaded.
I'm using Ionic 4 with React and typescript.
I'm looking to create an alert with a email input and 2 buttons, "cancel" and "accept".
I want the "accept" button to only be available when the user is giving a valid email address. Therefore I want to use a regex in the input field handler, but the handler is never called, not when typing nor when pressing enter. How can I get it to get callled when the user is typing
async showAlert() {
var promise = await alertController.create({
header: "Recevez la photo dans votre boƮte mail",
inputs: [{
name: "email",
type: "email",
placeholder: "email",
handler: () => {
console.log("input Fild Hanlder Called");
}
}],
buttons: [{
text: "cancel",
role: "cancel",
handler: cancel => {
console.log("cancel");
}
},
{
text: "envoyer photo",
role: "send",
handler: (alertData) => {
console.log((/^[a-zA-Z0-9]+#[a-zA-Z0-9]+\.[A-Za-z]+$/.test((alertData.email))));
}
}
]
});
await promise.present();
let result = await promise.onDidDismiss();
}
tl;tr This feature is not implemented in ionic4: ionic/issues/19059
After comparing the ionic code for rendering a checkbox in an alert and any other input element I came to the sad conclusion that the feature you are looking for doesn't exist.
At the moment it looks like handler on input in alerts is only supported for checkboxes and radio-inputs
There was a PR for ionic3 that added the validators option to AlertInputs to provide angular form validation but its not there anymore in ionic4.
There is still an open issue for ionic3 requesting input validation for alert inputs but non for ionic4 as far as I can see.
Update: new feature request for ionic4
I have an ExtJS Formpanel and I have written a listener on a click for the form ( not on any fields of a form ) which is working fine.
Even after setting the Ext.FocusManager.Enable() to true, I am not able to get the even 'blur' working. What am I missing?
I am not able to access form fields from the event handlers for formpanel click event. When I do - this.up.('form').get.(fielname).value [which works fine in the event handlers on the form fields.] It says the element is undefined. How can I access the form elements here?
Adding the code snippet -
// Call it Object A
Ext.create.('Ext.form.Panel', {
id : xyz,
items: [
{
xtype : 'textfield',
name : 'test',
fieldLabel : 'Name'
}
listeners : { // listener on the formPanel; not on any of its element
click : {
console.log("this works" );
},
focus : {
console.log('this does not work');
}
}
]
}
I am doing this so that I can access a value of another object, say B.field.
Onload I am able to fetch the value of B.field. But when the user changes the value of B.field which is on a different tab, I am not able to fetch the changed value of B.field in A. I am just finding ways to avoid an Ajax call to the database, if possible.
Thanks in advance for your time.
Without any sample from your code to reference, it's hard to determine what you are trying to do.
It could be that you just need to fix how you are querying for the form elements. For example, elements in a toolbar are not children of the form, so up/down doesn't work.
I don't think you can listen for the events focus, blur, or click on a form. Even if you could, I am not sure you would want to do. Instead, it's more common to listen for focus on a field or click on a button.
Example 1 form with field using focus and button using click
http://codepen.io/anon/pen/qEPRge?editors=001
;(function(Ext) {
Ext.onReady(function() {
console.log("Ext.onReady")
var form = new Ext.create("Ext.form.Panel", {
title: "person"
,items: [
{itemId: "fld-id", fieldLabel: "id", name: "id", value: "1", xtype: "textfield", labelAlign: "top", labelSeparator: ""}
,{itemId: "fld-name", fieldLabel: "name", name: "name", value: "Emily", xtype: "textfield", labelAlign: "top", labelSeparator: ""}
,{itemId: "btn-submit", text: "submit", xtype: "button"}
]
})
form.on("afterrender", function(component) {
console.log("form.afterrender")
})
form.render(Ext.getBody())
form.queryById("fld-id").on("focus", function(component) {
console.log("fld-id.focus")
})
form.queryById("fld-name").on("focus", function(component) {
console.log("fld-name.focus")
})
form.queryById("btn-submit").on("click", function(component) {
console.log("btn-submit.click")
console.log("fld-id.value:")
console.log(component.up("form").queryById("fld-id").getValue())
console.log("fld-name.value:")
console.log(component.up("form").queryById("fld-name").getValue())
})
})
})(Ext)
I am using ExtJS version 4.1.1.
I try to create upload file form using filefield as follow:
{
xtype: 'filefield',
itemId : 'my-file',
name: 'my file',
emptyText : 'No file chosen',
fieldLabel: 'Upload File',
submitValue: true,
allowBlank : false,
buttonText: 'Browse',
listeners: {
change: function(fld, value) {
var newValue = value.replace(/C:\\fakepath\\/g, '');
fld.setRawValue(newValue);
}
}
}
When the form is submitted, the filefield is reset.
As I see in
http://www.sencha.com/forum/showthread.php?135109-File-upload-field-is-empty-by-re-submitting-of-the-form
I try to override the filefield to :
Ext.override(Ext.form.field.File, {
extractFileInput: function() {
var me = this,
fileInput = me.fileInputEl.dom,
clone = fileInput.cloneNode(true);
fileInput.parentNode.replaceChild(clone, fileInput);
me.fileInputEl = Ext.get(clone);
me.fileInputEl.on({
scope: me,
change: me.onFileChange
});
return fileInput;
}
It look OK when I submit the form.
The value that I see in the textfield is not reset to empty.
However, when I submit the form again without re-choose file, the data that be sent to the server is null.
The data that be sent to the server should be retained.
Additional Info:
This problem occur when I use Chrome and IE, It seem work fine on Firefox.
Is it related with C:\\fakepath that I see on textfield when choose file?
How can I fix this problem?
set clearOnSubmit to false on your filefield
EDIT
It turns out that a store cannot have duplicate IDs. When i remove this field, All records display - which means the grid is not respecting the pageSize
I'm having an issue getting all my store records to display in my grid. The data is returning appropriately from a JSON request, and the pagingtoolbar behaves correctly.
Here's my store:
var store = Ext.create('Ext.data.Store', {
storeId : 'resultsetstore',
autoLoad : false,
model : model,
pageSize : itemsPerPage, // 3
proxy: {
type : 'ajaxwithpayload', //custom ajax proxy to read 'jsonData'
url : 'MCApp',
jsonData: searchquery,
reader: {
type : 'json',
root : 'elements'
}
}
});
I load the store here, and all the correct results are returned:
store.load({
params: { start: 0, limit: itemsPerPage },
callback : function(records, operation, success) {
if(success) {
mainresponse = operation.response.responseText;
if( mainresponse.length == 0 ){
alert('No results returned');
return;
}
var jsonResponse = Ext.JSON.decode(mainresponse);
}
else {
alert('Search Failed: Could not reach the server');
}
And lastly, a simple grid with pagingtoolbar:
var grid = Ext.create('Ext.grid.Panel', {
title: 'Test Data',
store: store,
columns: [{
text: 'Technical Name',
dataIndex: 'tech'
}, {
text: 'ID',
dataIndex: 'element.id'
}, {
text: 'Name',
dataIndex: 'name',
mapping: 'element.name'
}, {
text: 'View',
dataIndex: 'view'
}, {
text: 'Description',
dataIndex: 'description'
}],
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
pageSize: itemsPerPage,
dock: 'bottom',
displayInfo: true
}],
renderTo: Ext.getBody()
});
The problem here is that not all of my results load into the grid. It seems that when a duplicate ID is encountered, it cuts the results short. That may not be the problem, just my guess
In my logs I see all the data I need returned. In the picture below, I should have 3 rows with the same Element ID 001, however only one is displayed:
Another thing to note is that when I click the Next Button on my pagingtoolbar, the results do not change, and it also reads as a POST on my console. I'm not sure if it's supposed to do that or be a GET?
I used lightning bolts to show how shocking it is that this isn't working
Any ideas?
A very important thing to note is that the server is responsible for paging not ExtJS. The server must not return all rows, but only the rows of the current page. You server side code must take in account the parameters page, start and limit for getting the client side to work.
I think that, beside the duplicated ids, is the main reason for your problems. It is especially the reason, why you see the same data on page one and on page two:
ExtJs asks the server for the data of page 1 and gets all rows. Later, ExtJs asks the server for the data of page 2 and gets again the same rows. This cannot work.
This might be the case when you are giving name property as "id" in the fields array of your Model. try to change that.