I created a simple login page using extjs MVC to understand MVC architecture of extjs. As you can see below, I am trying to get the json data into the store and then I will check each username and password in that data with the entered login credentials. The thing in which I am confused right now is that, how to check the username and password from the retrieved json data present in store folder into the view folder? (Below code is only the related code with the problem)
I aware that this could invoke security threats, as I am checking on client side.
'view' folder --> Code.js
function checkJson(username, password){
//if matched, return true.
//else, return false.
}
'model' folder --> Code.js
Ext.define('AM.model.User', {
extend: 'Ext.data.Model',
fields: ['name', 'email']
});
'store' folder --> Code.js
Ext.define('LoginPage.store.Code', {
extend: 'Ext.data.Store',
model: 'LoginPage.model.Code',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
read: 'data/loginResponse.json',
update: 'data/checkCredentials.json' //Contains: {"success": true}
},
reader: {
type: 'json',
root: 'loginResponse',
successProperty: 'success'
}
}
});
loginResponse.json
{
"form": {
"login": [
{
"username": "venkat",
"password": "123"
},
{
"username": "admin",
"password": "345"
}
]
}
You should put your checking part of the code to the Controller (views are for presentation). In view define some form with login and password fields. In Controller catch click event on form OK (Login) button, get form values (login + password), then use Ext.data.Store.query() method to find wether credentials fits or not like:
Look here for examples how to use controllers in MVC to catch events;
In your Controller put:
init: function() {
this.control({
'#form_ok_button': { // this is the `id` property of your form's Login button
click: function(button) {
var fValues = button.up('form').getValues(); // Assume your button is bound to the form
// Or you can use `Controller.refs` property (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.app.Controller-cfg-refs) to get form
var matched = store.query('username', fValues.username);
if(matched.length && matched[0].get('password') === fValues.password) {
// login OK!
}
}
}
});
},
How to use refs (in Controller):
refs: [
{ ref: 'usernameField', selector: '#username_field' }, // username field id is "username_field"
{ ref: 'passwordField', selector: '#password_field' }, // password field id is "password_field"
],
init: function() {
this.control({
'#form_ok_button': {
click: function() {
// with `refs` autogetters are created for every `ref`:
var username_field = this.getUsernameField();
var password_field = this.getPasswordField();
}
}
})
}
You can read about referencing here.
For every Store in Ext.app.Controller.stores array autogetters are created too (in your case for Code store use this.getCodeStore() inside controller).
Here is the flow:
You get username and password field values with this.getUsernameField() and this.getPasswordField();
You query() store for username
If username exist in store, you check if password fits.
Related
Following is the code:
Accounts.findOrCreate({
where: {
userName: request.payload.userName
},
attributes: { exclude: ['password','sessionToken'] },
defaults: request.payload
}).spread(function (account, created) {
if (created) {
var account = account.get({
plain: true
});
console.log(account); // has the password and sessionToken fields
return reply(account).code(201);
} else {
return reply("user name already exists").code(422);
}
});
I noticed that sequelize first fires a select query in which the password field is not present, then it fires an insert statement in which the password field is present, and that needs to be there.
I would just like the password and sessionToken not be present in the resulting account object. I could of course delete those properties from the object but I am looking for a more straightforward way.
It seems like you need to delete those fields manually. According to the source code, findOrCreate method first fires the findOne function and then it goes with create if instance was not found. The create method does not accept attributes parameter. In such a case all fields will be returned.
Good solution would be to create instance method in the Accounts model in order to return an instance with only the desired attributes.
{
instanceMethods: {
toJson: function() {
let account = {
id: this.get('id'),
userName: this.get('userName')
// and other fields you want to include
};
return account;
}
}
}
Then you could simply use the toJson method when returning raw representation of object:
Accounts.findOrCreate({ where: { userName: 'username' } }).spread((account, created) => {
return account ? account.toJson() : null;
});
As mentioned by piotrbienias you can follow his way otherwise just delete the unwanted elements like this:
Accounts.findOrCreate({
where: {
userName: request.payload.userName
},
defaults: request.payload
}).spread(function (account, created) {
if (created) {
var account = account.get({
plain: true
});
delete account.password;
delete account.sessionToken;
console.log(account); // now you don't have the password and sessionToken fields
return reply(account).code(201);
} else {
return reply("user name already exists").code(422);
}
});
I am using Json-server to test CURD operations in my extjs grid. I have put some dummy data on json-server and I am able to read, delete, update and edit that data.
But When I create data using my extjs app, I am not able to delete or edit that data cause auto generated Id is "nameOfMyModel + autoIncrementNumber".
My Store is:
Ext.define('ThemeApp.store.peopleStore', {
extend: 'Ext.data.Store',
model: 'ThemeApp.model.peopleModel',
storeId: 'peopleStore',
pageSize: 500,
autoLoad: true,
autoSync: true
});
Model is:
Ext.define('ThemeApp.model.peopleModel', {
extend: 'Ext.data.Model',
fields: [ 'id' ,'title','body'],
proxy: {
type: 'rest',
//format: 'json',
limitParam:"",
filterParam: "",
startParam:'',
pageParam:'',
url:'http://localhost:3000/posts',
api: {
read : 'http://localhost:3000/db',
create: 'http://localhost:3000/posts',
update : 'http://localhost:3000/posts' ,
destroy : 'http://localhost:3000/posts'
},
headers: {'Content-Type': "application/json" },
reader: {
type: 'json',
rootProperty:'posts'
},
writer: {
type: 'json'
}
}
});
And I am Adding user like:
var UserStore = Ext.getStore('peopleStore');
var user = Ext.create('ThemeApp.model.peopleModel',{title: "Test", body: "Testing" });
user.save(); //POST /users
UserStore.load();
And For Deletion:
var grid = button.up('gridpanel');
var selection = grid.getView().getSelectionModel().getSelection()[0];
if (selection) {
UserStore.remove(selection);
UserStore.load();
}
Can anyone tell me why I am not able to delete/update records which I generate via extjs app?
The Id of simple post is like
http://localhost:3000/posts/(number like 1 or 2)
and of app generated record is
http://localhost:3000/posts/ThemeApp.model.peopleModel-1
And I can see app generated record in database.json but browser is saying that this url doesn"t exist.
Kindly point out my mistake
Reason you can't delete them is because they are not created properly. First of all to generate sequential ids use
identifier: 'sequential' in your model, than it will generate numeric id's
You can read it in detail here Model identifier
After doing this generate new objects and see if you can handle them properly.
I have a problem. I created a simple model and tried to save new value by using it through ajax request. But parameters which must be empty sends default value. You can see it by link under. The code does not specifically set the correct way bacause of what the console(f12) can be seen fallen challenge. In it I pass a value through a query-string, as well as through the payload-request (not yet invented how to get rid of it, as I understand it-payload is used by default). In general, instead of an empty carId call transfers Car-1.
https://fiddle.sencha.com/#fiddle/dsj
How do I fix this behavior and do that if we do not share any meaning, it passed empty?
You can create your custom proxy class that extends Ext.data.proxy.Ajax and then override buildRequest method to check for all create actions and to assign desired value to idProperty
Ext.define('CarProxy', {
extend: 'Ext.data.proxy.Ajax',
alias: 'proxy.carproxy',
type: 'ajax',
idParam: 'carId',
reader: {
type: 'json',
rootProperty: 'data'
},
api: {
create: './createcar.json'
},
writer: {
type: 'form'
},
buildRequest: function(operation) {
var request = this.callParent(arguments);
if (request.getAction() === 'create') {
request.getRecords().forEach(function(record) {
record.set('carId', ''); //assing desired value to id
});
}
return request;
}
});
Thanks everyone who answered. I want to show my solution:
add to model definition parameter
identifier: 'custom' .
And then create appropriate identifier which will return undefined on generate method:
Ext.define('Custom', {
extend: 'Ext.data.identifier.Generator',
alias: 'data.identifier.custom',
generate: function() {
return;
}
});
This is default ExtJS behaviour. If you do not specify id, it is generated. To avoid that you can for add constructor to your model:
Ext.define("Car", {
[...],
constructor: function() {
this.callParent(arguments);
// check if it is new record
if (this.phantom) {
// delete generated id
delete this.data[this.idProperty];
}
}
});
I have the following code. When fetching the value selected, it works fine. But if I try put the selected value in any condition, it falters. the code crashes.
var onAcctMgrSelect = function (e) {
// access the selected item via e.item (jQuery object)
ddAMList = $("#ddAM").data("kendoDropDownList");
if (ddAMList.value() == "0")
$("#btnSearch").attr("class", "k-button k-state-disabled");
else
$("#btnSearch").attr("class", "k-button");
///alert(ddAMList.text());
checkValidData();
};
DropDownlist Code is as below:
function loadAccountManagers() {
$("#ddAM").kendoDropDownList({
change: onAcctMgrSelect,
dataTextField: "AcctMgrFullName",
dataValueField: "Id",
dataSource: {
schema: {
data: "d", // svc services return JSON in the following format { "d": <result> }. Specify how to get the result.
total: "count",
model: { // define the model of the data source. Required for validation and property types.
id: "Id",
fields: {
Id: { validation: { required: true }, type: "int" },
AcctMgrFullName: { type: "string", validation: { required: true} }
}
}
},
transport: {
read: {
url: "../services/Prospects.svc/GetAccountManagers", //specify the URL which data should return the records. This is the Read method of the Products.svc service.
contentType: "application/json; charset=utf-8", // tells the web service to serialize JSON
type: "GET" //use HTTP POST request as the default GET is not allowed for svc
}
}
}
});
I'm basically trying to disable the submit button if the first item is selected (which is a blank item in my case with a value of '0').
Am I going wrong anywhere? Please help!
I have a JsonStore configured like so:
var store = new Ext.data.JsonStore({
restful: true,
url: '/categories',
remoteSort: true,
idProperty: 'Id',
totalProperty: 'total',
root: 'results',
writer: new Ext.data.JsonWriter({
encode: false
}),
fields: [ 'Id', 'Name' ]
});
I grab some data from the server, then edit one of the records. When I tell the store to save, it sends this JSON back to the server:
{
"results":
{
"Name":"Trivial123",
"Id":2
}
}
The store is wrapping the JSON inside the results property (the root property configured on the store). However, the server expects this:
{
"Name":"Trivial123",
"Id":2
}
In other words, the serialized entity should be put directly in the response body, and not wrapped in a property. Does anyone know how I can configure the store to do this?
You need to override the data rendering function in the JsonWriter, like so:
var rootlessRenderFunction = function (params, baseParams, data) {
if (this.encode === true) {
Ext.apply(params, baseParams);
params = Ext.encode(data);
} else {
params.jsonData = data;
}
};
var myWriter = new Ext.data.JsonWriter({
encode: false,
writeAllFields: true
});
myWriter.render = rootlessRenderFunction;
var myStore = new Ext.data.JsonStore({
// ... various config values ...
writer: myWriter
});
This "rootlessRenderFunction" implementation is the same as the Ext JsonWriter's render code except it doesn't interpose a root in the request data.
This is a hack, of course.
I'm assuming you can't just not set the root value for the store for some reason? That's the way I normally do it.