I am new to extjs, and I try to integrate extjs 5 with django 1.7 on my localhost. I have set the backend and got the rest api work (at /api/), as at https://github.com/MaZderMind/django-vs-extjs , but when the index.html runs app.js, which displays the login page, it seems that:
The controller file (Login.js) isn't loaded,
the launch function is not executed.
In firebug I can see that it reads the function definition and then returns without executing it automatically (also, when defining controller it steps over like it is simple command, but on the require statement steps into the function that fetches them), hence the login page is not displayed. But the other js files (for authentication) are loaded, as I see in console. Do you have any ideas what is happening? The codes are:
app.js
Ext.Loader.setConfig({enabled:true});
Ext.application({
// base-package of all classes
name: 'MyApp',
// url to load js-files from - adapted to django project
appFolder : 'static/static',
// required controllers
controllers: ['Login'],
// other required components
requires: [
'MyApp.helper.CrsfTokenHelper',
'MyApp.helper.PhantomStoreInserter'
],
// application launch method
launch: function () {
// save the scope
var app = this;
console.log('launched');
// ensure the user is logged in before showing her the main navigation with all our application goodies
app.getController('Login').ensureLoggedIn(function(userinfo) {
console.log('Login-Controller ensured that user', userinfo.username, 'is is currently loggeg in. Proceeding to navigation.')
// upate display of the navigation conteoller and show it
//app.getController('Navigation')
//.updateUserinfo(userinfo)
//.view.show();
console.log('Here should be loaded the view after the login page');
});
}
});
Login.js (controller)
Ext.define('MyApp.controller.Login', {
extend: 'Ext.app.Controller',
mixins: ['Ext.mixin.Observable'],
views: ['Login'],
// pointers into the view
refs: [
{ 'ref': 'userField', selector: '#user' },
{ 'ref': 'passField', selector: '#pass' },
{ 'ref': 'submitButton', selector: '#submit' }
],
// stored user information as received from the server
userinfo: null,
// controller initialisation
init: function() {
// save the scope
var loginController = this;
// create an instance of the view
var win = loginController.loginWindow = loginController.getView('Login').create();
this.control({
// register for the login-click
'#submit': {
click: function() {
// retrieve username & password from view
var username = this.getUserField().getValue(), password = this.getPassField().getValue();
// mask the form out
win.mask('Verifying…');
// process the login with the backend
loginController.performLogin(username, password, function(success) {
// the user was successfully authorized
if(success) {
// now request additional information on the user (name and such)
loginController.fetchLoginStatus(function(userinfo) {
// test if the server responded with data as expected
if(userinfo) {
// hide the login-window
win.hide();
// store received information locally
loginController.userinfo = userinfo;
// raise a event on the controller when finished
loginController.fireEvent('login', userinfo);
loginController.fireEvent('ready', userinfo);
}
// we did not receive valid data from the server
// this sould not fail, but if it does, just handle it like a failed login
else {
// disable the login on the form
win.unmask();
// set error-message on password-field
loginController.clearPasswordAndFocus().setPasswordError('Invalid Username or Password!');
}
})
}
// authorization was not successful
// unmask the form, show an error message and restart login process
else {
win.unmask();
loginController.clearPasswordAndFocus().showError('Invalid Username or Password!');
}
})
}
}
});
// register keyboard handler
this.nav = new Ext.KeyNav(win.getEl(), {
// enter key -> login-button click
enter: function() {
loginController.getSubmitButton().fireEvent('click')
}
});
},
// test if the user is logged in.
// if she is, call back immediatly. if she is not, show a login form
// delay the callback until she logged in successfully
ensureLoggedIn: function(callback) {
// save the scope
var loginController = this;
// test if the backend knows us
loginController.fetchLoginStatus(function(userinfo) {
// analyze if a user is logged in
if(userinfo) {
// callback, if she is
loginController.userinfo = userinfo;
loginController.fireEvent('ready', userinfo);
return callback(userinfo);
}
// no, we're not. show the login-window
console.log('no user logged in, showing login-window');
// login-testing and re-trying is handled by the handler set in the init-method
// it raises an event on the controller once it is finished
// we listen on this event and relay it to our callback - but only once
// -> the callback shouldn't be called multiple times
loginController.on('login', callback, {single: true});
// initiate login procedure by showing the login window
loginController.loginWindow.show();
loginController.clearForm();
});
},
// ask the backend if and which user is currently logged in
fetchLoginStatus: function(callback) {
console.info('requesting current userinfo from backend');
Ext.Ajax.request({
url: '/api/auth/user/',
success: function(response) {
// decode json-response
var userinfo = Ext.util.JSON.decode(response.responseText);
// request user permission list
Ext.Ajax.request({
url: '/api/auth/permissions/',
success: function(response) {
// decode json-response
userinfo.permissions = Ext.util.JSON.decode(response.responseText);
// callback with the decoded response
console.log('received userinfo:', userinfo);
callback(userinfo);
},
failure: function(response) {
// callback without info
console.log('received no permission list - nobody logged in');
callback();
}
});
},
failure: function(response) {
// callback without info
console.log('received no userinfo - nobody logged in');
callback();
}
});
},
// submit username & password to the backend
performLogin: function(username, password, callback) {
console.info('trying to log into backend with username=', username, 'password=', password.length, 'Chars');
// send login data via ajax to the server and callback with result
Ext.Ajax.request({
url: '/api/auth/login/',
method: 'POST',
params: {
'username': username,
'password': password
},
success: function(){
callback(true);
},
failure: function() {
callback(false);
}
});
},
// ask the backend to throw away our session which makes us logged out
performLogout: function(callback) {
console.info('trying to log out from backend');
// ensure userinfo is unset
this.userinfo = null;
Ext.Ajax.request({
url: '/api/auth/logout/',
method: 'GET',
success: function(){
callback(true);
},
failure: function() {
callback(false);
}
});
},
// shorthand to test iff userinfo is available
isLoggedIn: function() {
// null -> false, string -> true
return !!this.userinfo;
},
// shorthand to get the current username
getUserinfo: function() {
return this.userinfo;
},
// shorthand to get the current username
getUsername: function() {
return this.isLoggedIn() ? this.getUserinfo().username : null;
},
// shorthand to get the current username
getPermissions: function() {
return this.isLoggedIn() ? this.userinfo.permissions.user_permissions : [];
},
// shorthand to get the current username
isSuperuser: function() {
return this.isLoggedIn() ? this.userinfo.permissions.is_superuser : [];
},
hasPermission: function(permission) {
return this.isLoggedIn() && (this.isSuperuser() || this.getPermissions().indexOf(permission) !== -1)
},
// clears all form elements in the view
clearForm: function() {
this.loginWindow.unmask();
this.getPassField().setValue('').unsetActiveError();
this.getUserField().setValue('').unsetActiveError();
this.getUserField().focus();
return this;
},
// clears the password-field in the view and sets the typing-focus to it
clearPasswordAndFocus: function() {
this.getPassField().setValue('').focus();
return this;
},
// set an error-message on the password-fieldy
setPasswordError: function(msg) {
this.getPassField().setActiveErrors([msg]);
return this;
}
});
Login.js (view)
Ext.define('MyApp.view.Login', {
extend: 'Ext.window.Window',
renderTo: Ext.getBody(),
id: "loginBox",
title: 'Login',
width: 400,
layout: 'form',
bodyPadding: 5,
closable: false,
resizable: false,
draggable: false,
defaultFocus: 'user',
defaultType: 'textfield',
items: [{
itemId: 'user',
fieldLabel: 'Username',
allowBlank: false
},{
inputType: 'password',
fieldLabel: 'Password',
itemId: 'pass',
allowBlank: false
}],
buttons: [{
text: 'Login',
itemId: 'submit'
}]
});
console output:
GET localhost /static/static/helper/CrsfTokenHelper.js?_dc=1414444486439 200 OK 3ms ext-all-debug.js (line 1010)
GET localhost /static/static/helper/PhantomStoreInserter.js?_dc=1414444486439 200 OK 2ms ext-all-debug.js (line 1010)
Thanks anyway!
Well, apparently you are getting errors with your required files. If you comment the requires line inside your Ext.application:
Ext.application({
// base-package of all classes
name: 'MyApp',
// url to load js-files from - adapted to django project
appFolder : 'static/static',
// required controllers
controllers: ['Login'],
// other required components
//requires: [
// 'MyApp.helper.CrsfTokenHelper',
// 'MyApp.helper.PhantomStoreInserter'
//],
...
});
You will see that your Login window will show up. Assuming of course that you have your folder structure setup correctly
index.html
app.js
static/
static/static/
static/static/controller/Login.js
static/static/view/Login.js
Related
So I've got to create a calendar in html that gets events from Outlook and then deploy that as a custom page to Sharepoint, so it can be included as a webpart/iframe in site collections.
The problem is that I've tried adding ADAL security because you need to be logged in & send a token to Microsoft Exchange Online API in order to get calendar events etc. To display the calendar part, I'm using FullCalendar.io .
Now I've been keep getting a login/redirect loop that never ends. Does anyone see the fault in code? Here it is:
var $this = this;
$(document).ready(function() {
debugger;
window.config = {
tenantId: {tenant},
clientId: {clientid},
popUp: true,
callback: callbackFunction,
redirectUri: {custom aspx page URL on our Sharepoint},
cacheLocation: 'localStorage'
};
var authenticationContext = new AuthenticationContext(config);
authenticationContext.handleWindowCallback();
function callbackFunction(errorDesc, token, error, tokenType) {
alert('callbackFunction reached!');
}
var items = null;
if (authenticationContext.TokenCache) {
items = authenticationContext.TokenCache.ReadItems();
}
if (authenticationContext['_user']) {
authenticationContext.acquireToken(config.clientId, function (errorDesc, token, error) {
if (error) { //acquire token failure
if (config.popUp) {
// If using popup flows
authenticationContext.acquireTokenPopup(config.clientId, null, null, function (errorDesc, token, error)
{});
}
else {
// In this case the callback passed in the Authentication request constructor will be called.
authenticationContext.acquireTokenRedirect(config.clientId, null, null);
}
}
else {
//acquired token successfully
// alert('token success');
$this.DisplayEvents(token);
}
});
}
else {
// Initiate login
authenticationContext.login();
}
});
function DisplayEvents(adalToken) {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay,listWeek'
},
navLinks: true, // can click day/week names to navigate views
editable: true,
eventLimit: true, // allow "more" link when too many events
events: function(start, end, timezone, callback) {
var headers = new Headers();
var bearerToken = "Bearer " + adalToken;
headers.append('Authorization', bearer);
var options = {
method: 'GET',
headers: headers
};
var exchangeEndpoint = 'https://outlook.office.com/api/v2.0/me/events';
fetch(exchangeEndpoint, options).then(function (response) {
alert('Response data from successful call: ' + response);
});
}
});
}
So the code does get to "acquire token" and then the last "else", so "$this.DisplayEvents(token)" does get called! However, after acquire token, the app just keeps redirecting forever and ever... The Reply URL in my Azure AD App registration is also the window.config redirectURL value, or else I'd get an error stating the reply URL's don't match between request and Azure.
Does anyone know where it's going wrong?
I can reproduce your issue on my side by using your code. If you use authContext.getCachedUser() to check login status, redirect issue will disappear.
if (authContext.getCachedUser()) {
authContext.acquireToken(config.clientId, function (error, token) {
if (error) { //acquire token failure
if (config.popUp) {
// If using popup flows
authContext.acquireTokenPopup(config.clientId, null, null, function (errorDesc, token, error) { });
}
else {
// In this case the callback passed in the Authentication request constructor will be called.
authContext.acquireTokenRedirect(config.clientId, null, null);
}
}
else {
//acquired token successfully
// alert('token success');
alert(token);
}
});
}
else {
// Initiate login
authContext.login();
}
I'm working on a pair of Angular functions that should change a value from false to true when the user clicks a button. The app tracks a user's favorite books; when a user creates a favorite, the default values for 'tracking' and 'finished' are set to false. When the user goes to update them to true using an ng-click, the new 'true' values are not patched to the database, and are logged in the console as still false. Any thoughts on what's missing from my functions?
$scope.trackFavorite = function(favorite) {
var favoriteParams = {
id: favorite.id,
tracking: favorite.tracking,
finished: favorite.finished
};
favorite.tracking = !favorite.tracking;
$http.patch("/api/v1/favorites/"+favorite.id+".json", favoriteParams).success(function(response) {
console.log("READING NOW");
console.log(response);
});
};
$scope.markFinished = function(favorite) {
var favoriteParams2 = {
id: favorite.id,
finished: favorite.finished,
};
favorite.finished = !favorite.finished;
console.log(favorite);
$http.patch("/api/v1/favorites/"+favorite.id+".json", favoriteParams2).success(function(response){
console.log("IS IT FINISHED");
console.log(response);
});
};
Here's the ng-click snippets from the view, just in case:
<div>
<button ng-class="{tracking: favorite.tracking}" ng-click="trackFavorite(favorite)">Reading Now</button>
</div>
<div>
<button ng-class="{finished: favorite.finished}" ng-click="markFinished(favorite)">Finished</button>
</div>
Thanks a lot!
There could be a chance that you miss some http configuration. As it has been noticed here: patch request using angularjs.
It would also be a good idea to implement the error function in your controller and for example update the form according to the response, that you get back.
$scope.trackFavorite = function(favorite) {
var favoriteParams = {
id: favorite.id,
tracking: favorite.tracking,
finished: favorite.finished
};
$http.patch("/api/v1/favorites/"+favorite.id+".json", favoriteParams)
.then(
function(response) {
console.log("READING NOW");
console.log(response);
//update the UI according to the response
favorite.tracking = !favorite.tracking;
},function(error){
//clean up when an error occurs
});
};
I am currently building an Ionic hybrid application.
Unfortunately, I am having difficulties accessing the response data of the request during the Facebook sign-up process.
We want to retrieve data from an inappbrowser and are using Cordova's inappbrowser for a callback. Unfortunately we can't. What is the best way of accomplishing this?
function InAppBrowser($scope, $cordovaInAppBrowser, $rootScope, $http, $window) {
var durr;
$scope.facebook = facebook;
$scope.foobar = foobar;
function facebook() {
var options = {
location: 'no',
clearcache: 'yes',
toolbar: 'no'
};
durr = $cordovaInAppBrowser.open('https://www.facebook.com/dialog/oauth?scope=email,public_profile,user_friends,user_likes,user_photos,user_posts&client_id={client_id}&redirect_uri={callback_url}', '_blank', options)
.then(function(e) {
console.log(e);
})
.catch(function(e) {
console.log(e);
});
$rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event) {
$cordovaInAppBrowser.executeScript(
{ code: "localStorage.setItem('hurr', document.body.innerHTML)" },
function(data) {
console.log(data);
});
});
}
function foobar() {
console.log(durr);
// console.log(durr.localStorage.getItem('hurr'));
}
}
I don't use this for Facebook but the plugin Oauth. This plugin uses InAppBrowser : " https://github.com/nraboy/ng-cordova-oauth/blob/master/README.md ". It's very simple to use.
$cordovaOauth.facebook("Your client id", "scope", "options").then(function (result) {
Console.log(JSON.stringify(result);
// Get the information about the user's account
// See more at https://developers.facebook.com/docs/graph-api/reference/v2.2/user
$http.get("https://graph.facebook.com/v2.2/me", {
params: {
access_token: "your token",
fields: "id,last_name,first_name,gender,picture,birthday,location,email",
format: "json"
}
}).then(function (result) {
/** your code **/
}
I have store and I add a new record with this code. First it adds the new record and then it synchronizes to the back-end.
Ext.getStore('ilhan').add(Ext.getCmp('contacForm').getValues());
Ext.getStore('ilhan').sync({
success: function(){
Ext.getStore('ilhan').load();
Ext.getCmp('customerWindow').close();
}
});
I can also delete a record with this code below.
Ext.getStore('ilhan').remove(Ext.getCmp('theGrid').getSelectionModel().getSelection()[0]);
Ext.getStore('ilhan').sync({
success: function(){
Ext.getStore('ilhan').load();
}
});
But I don't know how to update a record. I can only fill up the form with the data from the row of the grid.
Ext.getCmp('contacEditForm').getForm().setValues(Ext.getCmp('theGrid').getSelectionModel().getSelection()[0].data);
So, I have add and remove methods for store but I don't have any update method? How I'm supposed to update the store?
I suggest using Model.
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'email'],
proxy: {
type: 'rest',
url : '/users'
}
});
Create:
var user = Ext.create('User', {name: 'Ed Spencer', email: 'ed#sencha.com'});
user.save(); //POST /users
Load:
//Uses the configured RestProxy to make a GET request to /users/123
User.load(123, {
success: function(user) {
console.log(user.getId()); //logs 123
}
});
Update:
//the user Model we loaded in the last snippet:
user.set('name', 'Edward Spencer');
//tells the Proxy to save the Model. In this case it will perform a PUT request to /users/123 as this Model already has an id
user.save({
success: function() {
console.log('The User was updated');
}
});
Delete:
//tells the Proxy to destroy the Model. Performs a DELETE request to /users/123
user.erase({
success: function() {
console.log('The User was destroyed!');
}
});
To update.
var form = Ext.getCmp('contacForm'),
record = form.getRecord(),
values = form.getValues(),
store = Ext.getStore('ilhan');
record.set(values);
store.sync({
success:function() {
store.load()
}
});
Look at your record. See if the 'dirty' property is true. That's what the proxies use to determine if a record is a post or a put.
I've been trying to utilize the Trello API via JSFiddle and haven't been able to get it to work (I have very limited JS/JSON knowledge). I need to create a card under a specific list, using the API.
function PostStuff()
{
$(document).ready(function(){
Trello.authorize({
interactive: true,
type: "popup",
expiration: "never",
name: "surveyrequest",
persist: "true",
success: function() { onAuthorizeSuccessful(); },
error: function() { onFailedAuthorization(); },
scope: { read: true, write: true}
});
function onAuthorizeSuccessful() {
Trello.post("cards", { name: "Card created for test", desc: "this is a test", idList: "........", due: null, urlSource: null});
}
});
}
I have JQuery and the Trello API included. I blanked out the idList in the code for security purposes. I confirmed that the code does execute the onAuthorizeSuccessful() function.
How can I modify this to create a Trello card?
function Auth() {
Trello.authorize({
type: 'popup',
name: 'your app name',
scope: {
read: true,
write: true },
expiration: '30days',
success: authenticationSuccess,
error: authenticationFailure
});
var authenticationSuccess = function(data){ /*your function stuff*/};
var authenticationFailure = function(data){ /*your function stuff*/};
}
this code works for me. i get function Auth() triggered on button click.
Also, you might have some issues with tokens which are expired, so Trello.deauthorize(); could be used on create new card failure function (it all depends on create new card error message).
regarding the create a new card...
var newCard =
{name: jQuery('input#tc_title').val(),
desc: jQuery('textarea#tc_desc').val(),
pos: "top",
idList: trello_list_id_var
};
Trello.post('/cards/', newCard, success, error);
var success = function(data){ /*..............*/}
var error= function(data){ /*..............*/}
in success/error functions you are able to check the error data
EDIT:
also i think that Trello.post("cards" ... should be replaced with Trello.post("/cards/" ... that might be the problem...