load new view after the loginin extjs 4 mvc - extjs

I have a login view created in extjs 4 and the data is fetched from mysql.
What my issue is that i am not able to redirect my page after the sucessfull login.
My code to redirect is.
onLoginSuccess : function(response, opts)
{
//Received response from the server
response = Ext.decode(response.responseText);
if(response.success)
{
var redirect = 'index';
window.location = redirect;
}
else
{
Ext.MessageBox.alert('Login failed', response.message);
}
}

There are two ways to approach this:
Login as a separate page
This is the recommended way, for being faster and more secure.
Have an index.php page, that checks whether the user has logged in or not.
If the user is logged in, you should simply require your actual system index file, which includes the ExtJs headers.
If the user is not logged in, you should require a login.php file that shows the actual login screen. This page may, or may not load the ExtJs library (since there's very little on this page, I'd assume you won't need the ExtJs files here).
So for example, this is my index.php:
<?php
require_once('common/include/User.php');
if ( SessionUser()->IsLoggedIn() )
{
// chdir is simply to keep the correct paths when compiling the app.
// It works for php, but for html/css links you should use the base tag
// in your php/html file: <base href="app/"/>
chdir('app');
require_once('app/index.php');
} else {
require_once('login.php');
}
?>
Then app/index.php is the actual index file that loads your app scripts and ExtJs lib.
login.php is just a rather simple login form:
<?php
// Index file for logged out users (guests)
$iUserName = isset( $_POST['username'] ) ? $_POST['username'] : '';
$iLoginErrorTxt = '';
if ( isset( $_POST['username'] ) )
{
require_once('common/include/User.php');
$iLoginError = SessionUser()->Authenticate( $_POST['username'], $_POST['password'] );
if ( $iLoginError['success'] )
{
// Login successful - reload the page.
header( "Location: " . $_SERVER['PHP_SELF'] );
exit();
} else {
// Login failed - present an error.
$iLoginErrorTxt = $iLoginError['error'];
}
}
?>
<html>
<head>
<title>My System</title>
</head>
<body>
<form class="login-form" action="<?=$_SERVER['PHP_SELF']?>" enctype="application/x-www-form-urlencoded" method="post">
<input name="username" size="25" type="text" value="<?=$iUserName?>" value spellcheck="false" placeholder="User Name"/>
<input name="password" size="25" type="password" value spellcheck="false" placeholder="Password"/>
<div class="error-message"><?=$iLoginErrorTxt?></div>
<input name="submit" type="submit" value="Login" />
</form>
</body>
</html>
Login from within the ExtJs app
This method is not highly recommended as you need the load the whole ExtJs framework and very possibly your application scripts, before the user even authenticated.
A possible implementation will involve having a container panel, which only displays a panel at a time, being either the login page, or the actual application page.
The app.js might include this code:
refs:
[{
ref: 'contentPanel',
selector: 'viewport > #contentPanel'
}],
controllers: [
'MainMenu'
],
launch: function() {
// Enable quicktips
Ext.QuickTips.init();
// Create the viewport
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
xtype: 'panel',
id: 'contentPanel',
layout: 'card',
dockedItems: [{
xtype: 'mainmenu',
dock: 'top'
}]
}
]
});
},
Then you can do:
var iContentPanel = this.getContentPanel();
iContentPanel.getLayout().setActiveItem( iPage );
Where iPage is whatever page (panel) you wish to display.
There are obviously ways to improve how this works, for example, by dynamically loading controllers; but that's a story for a different question I believe.
Regardless, I would strongly suggest you consider the first method.

You could handle logging in by simply overlaying the whole app with a login window, like here:
http://blogapp.banchaproject.org/app.html
The code can be found here, especially the this controller will be of interest for you:
https://github.com/Bancha/BanchaBlogApp/blob/master/webroot/app/controller/Authentification.js

Related

Using Semantic UI Search with CakePHP 3

I'm not sure what I'm doing wrong exactly but I've been on this for hours, when it's supposed to be relatively straightforward. Here's my html;
<div class="ui search focus">
<div class="ui left icon input">
<input class="prompt" type="text" placeholder="Search GitHub" autocomplete="off">
<i class="github icon"></i>
</div>
<div class="results"></div>
</div>
And here's my script
$(document).ready(function () {
$('.ui.search')
.search({
apiSettings: {
url: '//api.github.com/search/repositories?q={query}'
},
fields: {
results : 'items',
title : 'name',
url : 'html_url'
},
minCharacters : 3
});
});
This is exactly from the examples page: https://semantic-ui.com/modules/search.html#/examples
When I try to load local data in the form of
var content = [
{ title: 'Andorra' },
{ title: 'United Arab Emirates' },
{ title: 'Afghanistan' },
{ title: 'Antigua' },
{ title: 'Anguilla' },
// etc
];
$('.ui.search')
.search({
source: content
});
It works, no problems, however loading external content like in the first snippet shows No results found and when I check the network tab in Network in Browser Dev tool, I see a 307 Internal Redirect on the request and another with a 200 Ok request which apparently gets the data from Github. Obviously I'm missing something here and will really appreciate some guidelines please. Thanks
you can try this using Url helper
url: "<?= $this->Url->build('https://api.github.com/search/repositories?q={query}', true); ?>"

Storing array data from angularjs Form using MEAN stack

I am using MEAN stack. while creating a new article i would like to save array data. below code has the section deal which needs to be an array of data, for which i am unable to store array data. how do i modify my html partial and angularJS Controller so that i can store data like below for deal
{
"_id": "565d8a3a0ede9823aca797e9",
"user": {
"_id": "564ef3eaebf280b0abcc4876",
"displayName": "Table 2"
},
"__v": 0,
"deal": ["Special","Holiday"],
"name": "Idli",
"created": "2015-12-01T11:53:30.759Z"
}
My NodeJS Server Model
var FoodSchema = new Schema({
created: {
type: Date,
default: Date.now
},
name: {
type: String,
default: '',
required: 'Please fill Food name',
trim: true
},
deal: [{
type: String,
default: '',
trim: true
}],
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
my AngularJS controller
$scope.create = function (isValid) {
$scope.error = null;
if (!isValid) {
$scope.$broadcast('show-errors-check-validity', 'foodForm');
return false;
}
// Create new Food object
var food = new Foods({
name: this.name,
deal: this.deal,
// Redirect after save
food.$save(function (response) {
$location.path('foods/' + response._id);
// Clear form fields
$scope.name = '';
$scope.deal = '';
}, function (errorResponse) {
$scope.error = errorResponse.data.message;
});
};
HTML Partial
<section ng-controller="FoodsController">
<div layout="row" layout-wrap class="create-food">
<form name="foodForm" ng-submit="create(foodForm.$valid)" novalidate>
<div class="col-md-12">
<md-input-container flex="">
<label >Food Name</label>
<input type="text" data-ng-model="name" id="name" required>
</md-input-container>
</div>
<div class="col-md-6">
<md-input-container class="">
<label class="" for="deal">Deal</label>
<input type="text" data-ng-model="deal" id="deal" required>
</md-input-container>
</div>
<md-button type="submit">Create Food</md-button>
</form>
</div>
</section>
if you want to store data on your browser you can use the new html5 feature localStorage(key,value) you put some key for getting and the json like value.
This is not just for the sesion !
Well, I see that you already updated your mongoose model schema and made some updates in the frontend but what's the current state of your server API? Do you have any endpoints defined for the requests?
In other words (using the articles example of MEAN.js):
var articlesPolicy = require('../policies/articles.server.policy'),
articles = require('../controllers/articles.server.controller');
module.exports = function (app) {
// Articles collection routes
app.route('/api/articles').all(articlesPolicy.isAllowed)
.get(articles.list)
.post(articles.create);
// Single article routes
app.route('/api/articles/:articleId').all(articlesPolicy.isAllowed)
.get(articles.read)
.put(articles.update)
.delete(articles.delete);
// Finish by binding the article middleware
app.param('articleId', articles.articleByID);
};
Do you already have a similar setup for Food?
Once you have your routes setup you should then verify the server controllers logic and see if the data is being handled correctly and save into mongodb.
Edit to explain the workflow of saving data to mongodb in MEAN.js:
The database is only accessible from the server for security reasons. You cant access mongodb directly from angularjs. The process is: angular passes the data to expressjs via a request (for example: GET, POST, PUT, DELETE). Then in the server you should be able to capture the requests by defining your route endpoints. In those route endpoints you can specify route middlewares (i.e., server controllers) that will then use mongoose to interact with mongodb.

Meteor mobile web app touch support

I have a Meteor app that's having problems on mobile browsers. I'm using the autocomplete package (meteor-autocomplete), but I can't select the autocomplete options that drop down using touch. It works fine on the desktop browser when I click on the options. What's the problem? Also, how can I modify the app for mobile browsers (presentation, etc.).
Thanks
Edit:
Here's the html template code:
<template name="form">
{{> inputAutocomplete settings=settings id="food" class="form-control" name="food" placeholder="e.g. Chicken Pot Pie"}}
</template>
And here's Template.form.helpers:
Template.form.helpers({
settings: function() {
return {
position: "bottom",
limit: 5,
rules:
[
{
collection: Records,
field: 'food',
matchAll: true,
template: Template.foodFill
}
]
};
},
records: function() {
return Records.find().fetch();
}
});
And the Records collection holds all the entries to be used by autocomplete.

angularJS -Change in variable visible between html links

I have this code:
<li ng-repeat="objekt in driversList" class="mix {{objekt.Objekt.Type}}">
<a href="objekttest.html" data-ajax="false"
ng-click="objekt.Objekt.Active='yes'">
<img ng-src="../images/thumbs/{{objekt.Objekt.Thumb}}.jpg"
style="margin-right:0;" >
<span id="list">{{objekt.Objekt.Name}}{{objekt.Objekt.Active}}</span>
<span id="listmala">{{objekt.Objekt.Type}}</span>
</a>
</li>
objekt.Objekt.Active changes when I click the corresponding <li> tag.
However, on the other HTML link, I have:
<div ng-repeat="objekt in driversList">
{{objekt.Objekt.Name}} {{objekt.Objekt.Active}}
</div>
This time, objekt.Objekt.Active keeps the default value (i.e. 'no').
Is it possible to change a scope variable permanently so that it is changed on some other HTML element?
Here's my controller code:
angular.module('aki', [
'aki.controllers'
]);
angular.module('aki.controllers', []).
controller('akicontroller', function($scope,$rootScope) {
//$scope.toggle = function(){
//$scope.driversList.
//}
$rootScope.active='da';
$scope.driversList = [
{
Objekt: {
Name: 'Saint & Sinner',
Type: 'nightclub',
Thumb: 'Sinner',
Active:'no'
}
},
{
Objekt: {
Name: 'Corner Cafe',
Type: 'cafe',
Thumb: 'corner caffe',
Active:'no'
}
},...
...
EDIT: I'm making multipage application without Ajax
Not without using some form of backend or storage.
Looking at your code, you appear to have hard coded the driversList into the .js file. You're also navigating to a new page, it appears. AngularJS doesn't edit that JS file, so that's not going to persist.
You'll need to either have a backend service that stores the state (in memory or database) via http request, have AngularJS not actually change location (putting all of this on the same page, and show/hiding it as you interact), or use something like HTMLStorage to save/load the data.
You can also use something like AngularJS's Firebase backend to serve as persistence for the data - https://www.firebase.com/quickstart/angularjs.html has a quick start guide.

AngularJS ngRepeat Not Updating Display Properly

I have have a page where I am using plupload to upload files and having a weird issue with a ng-repeat not updating properly. Here is the relevant code:
<div ng:app>
<div name="myForm" ng-controller="Ctrl">
<input ng-model="test" type="text" />{{test}}<div id="container" class="controls">
<div id="filelist">
<div ng-repeat="file in filesToUpload">{{file.name}} ({{file.size}}) <b>{{file.percent}}</b></div>
</div>
<br />
<a id="pickfiles" href="#">[Select files]</a>
</div>
</div>
</div>​
function Ctrl($scope) {
$scope.test = '';$scope.filesToUpload = [{id: 1, name: 'test', size: '123kb'}];
$scope.addItem = function(object) {
$scope.filesToUpload.push(object);
}
$scope.uploader = new plupload.Uploader({
runtimes : 'html5,flash,browserplus,gears',
browse_button : 'pickfiles',
container : 'container',
max_file_size : '10mb',
url : 'upload.php',
flash_swf_url : '/plupload/js/plupload.flash.swf'
});
$scope.uploader.init();
$scope.uploader.bind('FilesAdded', function(up, files) {
$scope.filesToUpload = [];
$.each(files, function(i, file) {
$scope.addItem({
id: file.id,
name: file.name,
size: plupload.formatSize(file.size)
});
});
console.log($scope.filesToUpload);
up.refresh(); // Reposition Flash/Silverlight
});
}​
Here is a trimmed down jsfiddle showing the issue happening:
http://jsfiddle.net/9HuUC/
To reproduce this issue do the following:
Click on [select files] and selects a few files (notice how you don't see the files displayed anywhere on the output)
Type any character into the input box (magically the files that you select know appear)
What would cause this type of behavior? I mean I know that the data is properly being set in $scope.filesToUpload because I have the console.log() there and even checked it in Batarang and it loods good there but for some reason something else needs to be updated for the display to be updated.
Interestingly enough, I have another ng-repeat that is working fine on the same page. I am wondering if it has anything to do with where the code is (being inside the FilesAdded event on the uploader).
The issue is due to the fact that the FilesAdded callback is executed outside the scope of AngularJS (it's called by the uploader), therefore the scope updates won't be triggered.
To solve this, just add the $scope.$apply call in the callback, encapsulating your existing code:
$scope.uploader.bind('FilesAdded', function(up, files) {
$scope.$apply( function() {
$scope.filesToUpload = [];
$.each(files, function(i, file) {
$scope.addItem({
id: file.id,
name: file.name,
size: plupload.formatSize(file.size)
});
});
console.log($scope.filesToUpload);
up.refresh(); // Reposition Flash/Silverlight
});
});
With this update, it's working in the fiddle. For reference see the AngularJS official documentation, $apply method of the scope object:
http://docs.angularjs.org/api/ng.$rootScope.Scope

Resources