I'm trying to create a login form that mimics the call to a server and "authenticates" a users information.
Here's my Login.js code. this is the form I created:
Ext.define("ies.view.login.Login",{
extend: 'Ext.window.Window',
xtype: 'login',
requires: [
'ies.view.login.LoginController',
'Ext.form.Panel'
],
controller: 'login',
bodyPadding: 60,
draggable: false,
title: 'Login Window',
closable: false,
autoShow: true,
items: {
xtype: 'form',
reference: 'form',
itemId: 'LogInForm',
method: 'post',
items: [{
xtype: 'textfield',
name: 'username',
fieldLabel: 'Username',
itemId: 'username',
allowBlank: false
}, {
xtype: 'textfield',
name: 'password',
itemId: 'passwords',
inputType: 'password',
fieldLabel: 'Password',
allowBlank: false
}, {
xtype: 'displayfield',
hideEmptyLabel: false,
value: 'Enter any non-blank password'
}],
buttons: [{
text: 'Login',
formBind: true,
itemId: 'submit',
listeners: {
click: 'onLoginClick'
}
}],
}
});
This is my controller code:
Ext.define('ies.view.login.LoginController', {
extend: 'Ext.app.ViewController',
alias: 'controller.login',
onLoginClick: function(){
//var username = form.down('textfield[name=username]').getValue();
//var password = form.down('textfield[name=password]').getValue();
//get form field values
var username = this.lookupReference('username');
var password = this.lookupReference('password');
console.log(username + ' ' + password);
// This would be the ideal location to verify the user's credentials via
// a server-side lookup. We'll just move forward for the sake of this example.
/********************************************/
if ((username === 'carol' || username === 'denise' || username === 'coley' || username === 'yegappan' || username === 'julie' || username === 'dawn' || username === 'yvonne' || username === 'chuck' || username === 'belinda' || username === 'atlante' || username === 'blake' || username === 'ernie' || username === 'Patrick.Dwyer') && password === 'password1'){
/********************************************/
// Set the localStorage value to true
localStorage.setItem("TutorialLoggedIn", true);
console.log("Atuthenticated");
// Remove Login Window
this.getView().destroy();
// Add the main view to the viewport
Ext.widget('app-main');
} else {
document.getElementById("displayfield-1014-inputEl").innerHTML = "Authentication Failed";
console.log("Not authenticated");
}
}
});
I'm not sure how to pass the form fields and assign them to the username and password variables in the controller code. All help is really apreciated. Thanks!
I'm using EXTJS v 5.1
The name and itemId aren't relevant here. Instead, use the reference property in conjunction with lookupReference.
Related
I have a task to create simple plugin for shopware to extend article with new tab and few fields in it. I did it some way, code is below, but i have a big problem:
after entering data for article on click on save button action is triggered, ajax call made, in networks section in browser I can see fields key but there is no value.
Request params look like this:
name: bla bla
myfield: <--- problem
category: some category etc..
Things worked well when fields was in original tabs.
app.js:
// {block name="backend/article/application"}
// {$smarty.block.parent}
// {include file="backend/article/controller/controller.js"}
// {/block}
model:
// {block name="backend/article/model/article/fields"}
//{$smarty.block.parent}
{ name: 'madeby', type: 'string' },
{ name: 'columna', type: 'string' },
{ name: 'colona', type: 'string' },
{ name: 'blabla', type: 'string' },
// {/block}
and the main part window.js:
// {block name="backend/article/view/detail/window"}
// {$smarty.block.parent}
// {namespace name="backend/etsy_attribute/window"}
Ext.define('Shopware.apps.Article.view.detail.Window.etsy_connector.Window', {
override: 'Shopware.apps.Article.view.detail.Window',
/**
* Override creatMainTabPanel method and add your custom tab here.
* To extend the tab panel this function can be override.
*
* #return Ext.tab.Panel
*/
createMainTabPanel: function () {
var me = this, result;
result = me.callParent(arguments);
me.registerAdditionalTab({
title: 'Etsy Tab',
tabConfig: { disabled: false },
contentFn: function (article, stores, eOpts) {
eOpts.tab.add({
tab:
me.etsyTab = Ext.create('Ext.container.Container', {
region: 'center',
padding: 10,
title: 'Etsy Tab',
disabled: false,
name: 'additional-tab',
//cls: Ext.baseCSSPrefix + 'etsy-tab-container',
items: [
me.createEtsyPanel()
]
}),
xtype:
me.etsyTab,
config:
me.etsyTab
});
},
scope: me
});
//result.add(me.etsyTab);
return result;
},
createEtsyPanel: function () {
var me = this;
me.etsyFormPanel = Ext.create('Ext.form.Panel', {
name: 'etsy-panel',
bodyPadding: 10,
autoScroll: true,
defaults: {
labelWidth: 155
},
items: [
me.createEtsyFieldSet()
]
});
return me.detailContainer = Ext.create('Ext.container.Container', {
layout: 'fit',
name: 'main',
title: me.snippets.formTab,
items: [
me.etsyFormPanel
]
});
},
createEtsyFieldSet: function () {
//var me = this;
return Ext.create('Ext.form.FieldSet', {
layout: 'anchor',
cls: Ext.baseCSSPrefix + 'article-etsy-field-set',
defaults: {
labelWidth: 155,
anchor: '100%',
translatable: true,
xtype: 'textfield'
},
title: 'Etsy connection content',
items: [
{
xtype: 'textfield',
name: 'blabla',
height: 100,
fieldLabel: 'blabla'
},
{
xtype: 'textfield',
name: 'columna',
height: 100,
fieldLabel: 'columna'
},
{
xtype: 'textfield',
name: 'colona',
height: 100,
fieldLabel: 'colona'
},
{
xtype: 'textfield',
name: 'madeby',
height: 100,
fieldLabel: 'madeby'
}
]
});
}
});
// {/block}
My question is:
Why no value is sent in request for my added fields in new tab?
Thanks.
You need also add controller for handle your tab.
//{block name="backend/article/controller/detail" append}
Ext.define('Shopware.apps.Article.controller.detail.etsy_connector.Base', {
override: 'Shopware.apps.Article.controller.Detail',
onSaveArticle: function(win, article, options) {
var me = this;
me.callParent([win, article, options]);
console.log(me);
console.log(me.getMainWindow());
//You need to find your own form
console.log(me.getMainWindow().detailContainer);
console.log(me.getMainWindow().detailContainer.getForm().getValues());
var myVariables = me.getMainWindow().detailContainer.getForm().getValues();
//Or merge your data with article data
var params = Ext.merge({}, me.getMainWindow().detailForm.getForm().getValues(), myVariables);
//Send to your own controller to handle
Ext.Ajax.request({
method: 'POST',
url: '{url controller=EtsyConnector action=save}',
params: myVariables
});
}
});
//{/block}
I searched hours and hours for a solution but can't find one. I want to submit something to a php api function. it looks like this:
/*global Ext:false */
Ext.onReady(function ()
{
var i = 0;
var form = Ext.create('Ext.form.Panel', {
title: 'base_entity_id',
bodyPadding: 5,
width: 350,
defaultType: 'textfield',
items: [{
fieldLabel: 'base_entity_id',
name: 'first',
allowBlank: false
}],
buttons: [{
text: 'Reset',
handler: function() {
this.up('form').getForm().reset();
}
}, {
text: 'Submit',
formBind: true,
//only enabled once the form is valid
disabled: true,
handler: function() {
var form = this.up('form').getForm();
}
}],
})
var tabs = Ext.create('Ext.tab.Panel',
{
renderTo: 'tabs',
id: 'tabs',
itemId: 'tabs',
fullscreen: true,
renderTo: document.body,
items:
[
{
title: 'Home',
margin: 40,
items: [form],
},
{
title: 'Results',
itemId: 'Results',
listeners:
{
activate: function (tab)
{
if(i == 0)
{
var panel = Ext.create('Ext.tab.Panel',
{
id: 'tabs2',
width: window,
height: window,
renderTo: document.body,
items:
[
{
title: '1',
itemId: '1',
closable: true,
html: '10329u9iwsfoiahfahfosaofhasohflhsalkfhoihoi3riwoifhoiashfkhasofhosahfsahfahsfosafoisaiohfaoishfoihsaoifasoifsaifhsaoifasoihfoiahsfoihasfoihasoifoisfoihsafoihasfoiasoihasfoihaoifhaoihfoiahfoiaoaffoafoiafsaoafohaoh'
},
{
title: '2',
itemId: '2',
closable: true,
}
]
})
tab.add(panel);
tab.doLayout();
i = 1;
}
}
}
}]
})
});
But when i'm submitting i get no response, can someone help me with this? I dont know what the next steps are...
I have a simple application done with Ext JS/PHP and the following code worked for me:
myFormPanel.getForm().submit({
clientValidation: true,
url: 'updateConsignment.php',
params: {
id: myFormPanel.getForm().getValues().first
},
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
switch (action.failureType) {
case Ext.form.Action.CLIENT_INVALID:
Ext.Msg.alert('Failure', 'Form fields may not be submitted with invalid values');
break;
case Ext.form.Action.CONNECT_FAILURE:
Ext.Msg.alert('Failure', 'Ajax communication failed');
break;
case Ext.form.Action.SERVER_INVALID:
Ext.Msg.alert('Failure', action.result.msg);
}
}
});
Source:
http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.form.BasicForm-method-submit
Well, you have set no URL for your form, and the submit button doesn't have the submit method so I'm not really sure how this was supposed to work.
You will need to add the url config to your form:
Ext.create('Ext.form.Panel', {
title: 'base_entity_id',
method: 'POST',
url: 'myBackEnd.php' // Or whatever destination you are using for your backend.
...
});
Also, I saw that you are using formbind: true and later checking if the form was valid, one action renders the other unnecessary, so choose one, there is no need for both!
Add this your button handler:
form.submit({
params: {
id: form.getForm().getValues().first
},
success: function(form, action) {
Ext.Msg.alert('Success', 'Your form was submitted successfully');
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result ? action.result.message : 'No response');
}
});
Then you should check for $_POST['id']
For more information on form methods and configurations check this doc: http://docs.sencha.com/extjs/5.0/apidocs/#!/api/Ext.form.Basic
I am following a tutorial using Ext JS 4. I would like for a user to be able to login the application after being authenticated. I have already created the user name and password in the database.
The problem is my JSON response is coming back empty when I click my submit button.
I have an AJAX call in my Login.js controller that calls my login.php which establishes my database connection.
Login.js
Ext.define('Packt.controller.Login', {
extend: 'Ext.app.Controller',
requires: [
'Packt.util.MD5',
'Packt.util.Alert',
'Packt.view.MyViewport',
'Packt.util.Util',
'Packt.util.SessionMonitor'
],
views: [
'Login',
'Header',
'authentication.CapsLockTooltip'
],
refs: [
{
ref: 'capslockTooltip',
selector: 'capslocktooltip'
}
],
init: function(application) {
this.control({
"login form button#submit": {
click: this.onButtonClickSubmit
},
"login form button#cancel": {
click: this.onButtonClickCancel
},
"login form textfield": {
specialkey: this.onTextfielSpecialKey
},
"login form textfield[name=password]": {
keypress: this.onTextfielKeyPress
},
"appheader button#logout": {
click: this.onButtonClickLogout
}
});
Ext.apply(Ext.form.field.VTypes, {
// vtype validation function
customPass: function(val, field) {
return /^((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%]).{6,20})/.test(val);
},
// vtype Text property: The error text to display when the validation function returns false
customPassText: 'Not a valid password. Length must be at least 6 characters and maximum of 20Password must contain one digit, one letter lowercase, one letter uppercase, onse special symbol ##$% and between 6 and 20 characters.'
});
},
onButtonClickSubmit: function(button, e, options) {
var formPanel = button.up('form'),
login = button.up('login'),
user = formPanel.down('textfield[name=user]').getValue(),
pass = formPanel.down('textfield[name=password]').getValue();
if (formPanel.getForm().isValid()) {
pass = Packt.util.MD5.encode(pass);
Ext.get(login.getEl()).mask("Authenticating... Please wait...", 'loading');
Ext.Ajax.request({
url: 'php/login.php',
params: {
user: user,
password: pass
},
success: function(conn, response, options, eOpts) {
Ext.get(login.getEl()).unmask();
var result = Packt.util.Util.decodeJSON(conn.responseText);
if (result.success) {
//Packt.util.Alert.msg('Success!', 'User Authenticated.');
login.close();
Ext.create('Packt.view.MyViewport');
Packt.util.SessionMonitor.start();
} else {
Packt.util.Util.showErrorMsg(conn.responseText);
}
},
failure: function(conn, response, options, eOpts) {
Ext.get(login.getEl()).unmask();
Packt.util.Util.showErrorMsg(conn.responseText);
}
});
}
},
onButtonClickCancel: function(button, e, options) {
button.up('form').getForm().reset();
},
onTextfielSpecialKey: function(field, e, options) {
if (e.getKey() == e.ENTER){
var submitBtn = field.up('form').down('button#submit');
submitBtn.fireEvent('click', submitBtn, e, options);
}
},
onTextfielKeyPress: function(field, e, options) {
var charCode = e.getCharCode();
if((e.shiftKey && charCode >= 97 && charCode <= 122) ||
(!e.shiftKey && charCode >= 65 && charCode <= 90)){
if(this.getCapslockTooltip() === undefined){
Ext.widget('capslocktooltip');
}
this.getCapslockTooltip().show();
} else {
if(this.getCapslockTooltip() !== undefined){
this.getCapslockTooltip().hide();
}
}
},
onButtonClickLogout: function(button, e, options) {
Ext.Ajax.request({
url: 'php/logout.php',
success: function(conn, response, options, eOpts){
var result = Packt.util.Util.decodeJSON(conn.responseText);
if (result.success) {
button.up('mainviewport').destroy();
window.location.reload();
} else {
Packt.util.Util.showErrorMsg(conn.responseText);
}
},
failure: function(conn, response, options, eOpts) {
Packt.util.Util.showErrorMsg(conn.responseText);
}
});
}
});
login.php
<?php
require("db/db.php");
session_start();
// username and password sent from form
$userName = $_POST['user'];
$pass = $_POST['password'];
// To protect MySQL injection (more detail about MySQL injection)
$userName = stripslashes($userName);
$pass = stripslashes($pass);
$userName = $mysqli->real_escape_string($userName);
$pass = $mysqli->real_escape_string($pass);
$sql = "SELECT * FROM USER WHERE userName='$userName' and password='$pass'";
$result = array();
if ($resultdb = $mysqli->query($sql)) {
// determine number of rows result set
$count = $resultdb->num_rows;
// If result matched $userName and $pass, table row must be 1 row
if($count==1){
$_SESSION['authenticated'] = "yes";
$_SESSION['username'] = $userName;
$result['success'] = true;
$result['msg'] = 'User authenticated!';
} else {
$result['success'] = false;
$result['msg'] = 'Incorrect user or password.';
}
/* close result set */
$resultdb->close();
}
/* close connection */
$mysqli->close();
//JSON encoding
echo json_encode($result);
?>
db.php
<?php
//$server = "192.168.0.11";
$server = "127.0.0.1";
$user ="mark";
$pass = "dog";
$dbName = "sakila";
$mysqli = new mysqli($server, $user, $pass, $dbName);
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
?>
I have also created a Login.js view page to display the pop up panel for user to login in.
Login.js view
Ext.define('Packt.view.Login', {
extend: 'Ext.window.Window',
alias: 'widget.login',
requires: [
'Packt.view.Translation'
],
autoShow: true,
height: 170,
width: 360,
layout: {
type: 'fit'
},
iconCls: 'key',
title: translations.login,
closeAction: 'hide',
closable: false,
items: [
{
xtype: 'form',
frame: false,
bodyPadding: 15,
defaults: {
xtype: 'textfield',
anchor: '100%',
labelWidth: 60,
allowBlank: false,
vtype: 'alphanum',
minLength: 3,
msgTarget: 'under'
},
items: [
{
name: 'user',
fieldLabel: translations.user,
maxLength: 25,
value: 'mark'
},
{
inputType: 'password',
name: 'password',
fieldLabel: translations.password,
enableKeyEvents: true,
id: 'password',
maxLength: 15,
value: '123456',
//vtype: 'customPass',
msgTarget: 'side'
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
xtype: 'translation'
},
{
xtype: 'tbfill'
},
{
xtype: 'button',
itemId: 'cancel',
iconCls: 'cancel',
text: translations.cancel
},
{
xtype: 'button',
itemId: 'submit',
formBind: true,
iconCls: 'key-go',
text: translations.submit
}
]
}
]
}
]
});
I am not sure how to debug this. I seems like it is making the database connection. but i not returning anything back. How can I authenticate this pre existing user and login?
I know how to add a store record into a form.
But now I have an object which is not part of a store.
I loaded it using the helper function
var fields = someFormPanel.getForm().getFields();
Ext.each(fields.items,function(field, i) {
if('name' in field && field.name in obj) field.setValue(obj[field.name]);
});
but afterwards I asked myself whether there already is a predefined function?
You can use setValues method from Ext.form.Basic object. If you use for your form Ext.form.Panel class you can get its underlying Ext.form.Basic with getForm() method.
var data = {
firstName: 'Homer',
lastName: 'Simpson'
}
var form = Ext.create('Ext.form.Panel', {
title: 'Simple Form',
bodyPadding: 5,
width: 350,
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
name: 'firstName',
allowBlank: false
},{
fieldLabel: 'Last Name',
name: 'lastName',
allowBlank: false
}],
renderTo: Ext.getBody()
});
form.getForm().setValues(data);
Fiddle with example: https://fiddle.sencha.com/#fiddle/2op
I have a form. And lots of textfields in it. I use allowBlank property not to allow user to left the field blank and blankText to define custom "blank error" text.
{
xtype: 'textfield',
fieldLabel: 'Surname',
name: 'person_surname',
allowBlank: false,
blankText: 'Please fill "Surname" field',
},
My question is:
Is there a way to use Ext.form.field.Text's object property inside of another propery of the same object?
Something like:
{
xtype: 'textfield',
fieldLabel: 'Surname',
name: 'person_surname',
allowBlank: false,
blankText: 'Please fill "' + fieldLabel + '" field',
},
(doesn't work)
or:
{
xtype: 'textfield',
fieldLabel: 'Surname',
name: 'person_surname',
allowBlank: false,
blankText: 'Please fill "' + this.fieldLabel + '" field',
},
(doesn't work either)
Update:
For example in minLengthText property I can use template driven text like 'The minimum length for this field is {0}', which takes minLength property value of the same object.
I repeat: I use ExtJS's object initialization method whith object literal syntax like:
{
xtype: 'textfield',
fieldLabel: 'Surname',
name: 'person_surname',
allowBlank: false,
blankText: 'Please fill "Surname" field',
},
This syntax is very neat, using another syntax is not welcome here.
You would need to create the object, get a reference to it, and then augment it via its reference.
var obj = {
xtype: 'textfield',
fieldLabel: 'Surname',
name: 'person_surname',
allowBlank: false
};
obj.blankText = 'Please fill "' + obj.fieldLabel + '" field';
try adding listener to your form if you don't want to rewrite your code
example
listeners : {
render : function(){
Ext.each(form.items.items,function(fld,idx){
if(fld.getXType()=='textfield'){
fld.blankText = fld.fieldLabel;
}
});
}
}
A few alternatives:
1) This one is superior to the accepted answer because the render listener is a poor place to be modifying DOM related object properties. It has to do with the way the rendering cycle works, but it's much better to it before, average to do it after, bad to do it during. The one below is probably only applicable if you're dealing with a flat list of fields.
Ext.define('MyClass', {
initComponent: function(){
var fields = [{
xtype: 'textfield',
fieldLabel: 'Field 1'
}, {
xtype: 'textfield',
fieldLabel: 'Field 2'
}];
Ext.Array.forEach(fields, function(field){
field.blankText = 'Foo ' + field.fieldLabel
});
this.items = fields;
this.callParent();
}
});
2) This gives you the most control, again, no mucking about after the field is defined:
Ext.define('MyClass', {
initComponent: function(){
var wrap = this.wrap;
this.items = [wrap({
xtype: 'textfield',
fieldLabel: 'Field 1'
}), wrap({
xtype: 'textfield',
fieldLabel: 'Field 2'
})];
this.callParent();
},
wrap: function(config){
config.blankText = 'Foo ' + config.fieldLabel;
return config;
}
});
The only thing I can think of is
new function(){
this.xtype = 'textfield';
this.fieldLabel = 'Surname';
this.name = 'person_surname';
this.allowBlank = false;
this.blankText = 'Please fill "' + this.fieldLabel + '" field';
}
You've got three options when you try to do this stuff, really:
var Object_1 = {};
Object_1.property_1 = "Something";
Object_1.property_2 = "I'm Really " + Object_1.property_1 + "!";
var Object_2 = {
property_1 : "Something",
property_2 : "I'm Really"
};
Object_2.property_2 += Object_2.property_1 + "!";
var Object_3 = (function () {
var property1 = "Something",
property2 = "I'm Really " + property1 + "!";
return { property_1 : property1, property_2 : property2 };
}());
Each of these three objects ends up being equivalent, in terms of the user-defined properties.
Personally, I use #3 an awful lot in JavaScript, expressly to avoid the problem that you're having right now.
Define properties and methods as vars within a function, and then either return a function which then has access to those original vars, or return an object (which you can attach methods to -- as long as the methods were defined inside of the original function -- which will have access to the internal vars).
How about you write a simple parser?
{
xtype: 'textfield',
fieldLabel: 'Surname',
name: 'person_surname',
allowBlank: false,
blankText: 'Please fill [fieldlabel] field',
},
When you output your message, replace the macro [fieldlabel] with the object's .fieldLabel value. Add other macros for other things you might need.
If your code runs in a browser that supports the ECMAScript 5 Getters and Setters feature you could use a getter to achieve what you need:
{
xtype: 'textfield',
fieldLabel: 'Surname',
name: 'person_surname',
allowBlank: false,
get blankText(){ return 'Please fill "' + this.fieldLabel + '" field';}
},
You can do the following:
({
xtype: 'textfield',
fieldLabel: 'Surname',
name: 'person_surname',
allowBlank: false,
init: function() {
this.blankText = `Please fill ${this.fieldLabel} field`;
...
delete this.init;
return this;
}
}).init()