backbone.js view return false - backbone.js

can somebody explain me, for what is in a backbone.js view the return false statement. For example
search: function() {
var view = this;
$.post('/contacts/find',
this.$('form').serialize(), function(data) {
view.render(data);
}).error(function(){
$("#results").text('No contacts found.');
$("#results").slideDown();
});
return false;
},

To cancel default event behaviour.
In your example after clicking the submit button the form will not be submitted (page reload).
This is the same as:
event.preventDefault();
event.stopPropagation();

Related

Event not waiting for user answer inside dialog

I need the user to confirm leaving the page if a specific condition is fulfilled. The problem is the location change is not waiting for the dialog to get the user answer.
Here's my code:
angular module 1:
...
function confirmLeavePage(e, newUrl) {
if(form.cod.value) {
customDialog.confirmDialog('Title','Leave?').then(
function(){
console.log('go to selected page');
},function(){
e.preventDefault();
});
}
}
$scope.$on("$locationChangeStart", confirmLeavePage);
...
angular module 2 :
angular.module('dialog').service('customDialog', function($mdDialog, $q, $location) {
this.confirmDialog = function(title, content){
var deferred = $q.defer();
$mdDialog.show($mdDialog.confirm({
templateUrl:'confirmDialog.html',
title : title,
textContent : content,
ok : 'Confirm',
cancel: 'Cancel'
})).then(function() {
console.log('confirmed');
deferred.resolve();
}, function() {
console.log('abort');
deferred.reject();
});
return deferred.promise;
}
});
Any ideas?
try this
function confirmLeavePage(e, newUrl) {
if(form.cod.value) {
customDialog.confirmDialog('Title','Leave?').then(
function(){
console.log('go to selected page');
});
}
e.preventDefault();
return;
}

Ionic close IonicPopup when button makes an Ajax call

Am new to both angular and ionic. I have a popup in my page where i show user a input field to enter the OTP and a submit button. When i click on the submit button, I make an Ajax call to check if the OTP is valid.
But am not able to close the popup with .close method. Please help
var OTPPopup = $ionicPopup.show({
title: 'OTP VERIFICATION',
templateUrl: 'templates/login/otp.html',
scope: $scope,
buttons : [{
text: 'Confirm OTP',
type: 'button-assertive',
onTap : function(e) {
e.preventDefault();
var validateResponse = validateOTP();
validateResponse.then(function(response){
console.log('success', response);
return response;
});
}
}]
}).then(function(result){
console.log('Tapped', result);
OTPPopup.close();
});
And below is the function validateOTP
function validateOTP() {
var requestObj = {
authentication: {
email_id: $scope.loginForm.email,
security_code: $scope.OTP
}
};
return $q(function(resolve, reject) {
activateUser(requestObj, function(response){
if(response.error == null && response.data.isSuccess) {
console.log('validate correct');
resolve(response);
}
}, function(response){
return 'error';
});
});
}
activateUser is my service which makes the ajax call. Please let me know how can i acheive this.
console.log('success', response) is being printed inside the .then but after returning something from the onTap , the promise of the popup is not being called.
Ended up solving it myself.
This solution would work only if you have exactly one ionicPopup on your page. I just wrote this line of code to do the trick
$ionicPopup._popupStack[0].responseDeferred.resolve();
This automatically closes the popup. The whole code is more simpler now with normal Ajax without any q promises.
var OTPPopup = $ionicPopup.show({
title: 'OTP VERIFICATION',
templateUrl: 'templates/login/otp.html',
scope: $scope,
buttons : [{
text: 'Confirm OTP',
type: 'button-assertive',
onTap : function(e) {
// e.preventDefault() will stop the popup from closing when tapped.
e.preventDefault();
validateOTP();
}
}]
});
and in the next function
function validateOTP() {
var requestObj = {
authentication: {
email_id: $scope.loginForm.email,
security_code: $scope.loginForm.OTP
}
};
activateUser(requestObj, function(response){
if(response.error == null && response.data.isSuccess) {
localStorage.setLocalstorage = response.data.user[0];
$ionicPopup._popupStack[0].responseDeferred.resolve();
$state.go('dashboard.classified');
}
}, function(response){
});
}
you don't need call e.preventDefault();
you just only return the validateOTP promise
ionicPopup will waiting the promise then close popup
var OTPPopup = $ionicPopup.show({
title: 'OTP VERIFICATION',
template: 'templates/login/otp.html',
scope: $scope,
buttons : [{
text: 'Confirm OTP',
type: 'button-assertive',
onTap : function() {
return validateOTP();
}
}]
}).then(function(result){
console.log('closed', result); // result is the activateUser resolve response
});

AngularJS hide div after delay

While creating my app in AngularJS (awesome framework!) I stuck in one task: how to show and hide hidden div (ng-show) after some action.
Detailed description: using AngularUI $modal service I'm asking if user wants to perform action, if yes, I run service to POST request via $http to send which item I want to delete. After it finished I want to show hidden div with information, that process has accomplished successfully. I created a simple service with $timeout to set div's ng-show and hide after some time but it doesn't update variable assigned to ng-show directive. Here is some code:
Controller for listing and deleting items
$scope.deleteSuccessInfo = false; //variable attached to div ng-show
$scope.deleteCluster = function(modalType, clusterToDelete) {
modalDialogSrvc.displayDialog(modalType)
.then(function(confirmed) {
if(!confirmed) {
return;
}
clusterDeleteSrvc.performDelete(itemToDelete)
.then(function(value) {
//my attempt to show and hide div with ng-show
$scope.deleteSuccessInfo = showAlertSrvc(4000);
updateView(itemToDelete.itemIndex);
}, function(reason) {
console.log('Error 2', reason);
});
}, function() {
console.info('Modal dismissed at: ' + new Date());
});
};
function updateView(item) {
return $scope.listItems.items.splice(item, 1);
}
Part of service for deleting item
function performDelete(itemToDelete) {
var deferred = $q.defer(),
path = globals.itemsListAPI + '/' + itemToDelete.itemId;
getDataSrvc.makeDeleteRequest(path)
.then(function() {
console.log('Item removed successfully');
deferred.resolve({finishedDeleting: true});
}, function(reason) {
console.log('error ', reason);
deferred.reject(reason);
});
return deferred.promise;
}
return {
performDelete: performDelete
};
Simple service with $timeout to change Boolean value after some time
angular.module('myApp')
.service('showAlertSrvc', ['$timeout', function($timeout) {
return function(delay) {
$timeout(function() {
return false;
}, delay);
return true;
};
}]);
I tried $scope.$watch('deleteSuccessInfo', function(a, b) {...}) with no effect. How to apply false after some delay? Or maybe You would achieve this in other way?
Thank You in advance for any help!
Change the implementation of the showAlertSrvc service, like this:
angular.module('myApp')
.service('showAlertSrvc', ['$timeout', function($timeout) {
return function(delay) {
var result = {hidden:true};
$timeout(function() {
result.hidden=false;
}, delay);
return result;
};
}]);
And then change thes 2 lines:
The declaration of deleteSuccessInfo should be like this:
$scope.deleteSuccessInfo = {};
And then do this:
$scope.deleteSuccessInfo = showAlertSrvc(4000);
And finally in your view do this "ng-show=!deleteSuccessInfo.hidden"
Example

How can a Router talk to a View other than using a global variable?

I can not understand why in my Backbone app (Todo app) after I reload a page (CTRL+F5) a filterTodos method does not get called. When I simply click on links to filter Todos ("Active", "Completed") - it does get called.
You can see this feature in links below. No matter how many times you click Refresh in Browser - correct filtered results are displayed:
http://todomvc.com/architecture-examples/backbone/#/completed
http://todomvc.com/architecture-examples/backbone/#/active
I have a theory that it's because I am triggering a filter event from Router too early - a TodosView is not initialized yet and therefore it does not listenTo filter event yet.
But how a Router can inform a View to re-render itself (based on filter) if this View does not exist yet? Can't it be achieved via triggering some event in Router as I do? One possible option is to have a global variable app.FilterState.
Is there any other methods of communications between a Router and a non-constructed yet View?
For app.FilterState I will set its state in Router and then check it in View and call filterTodos function manually like so and it will work:
views/todos.js
render: function() {
app.Todos.each(function(todo) {
this.renderTodo(todo);
}, this);
if (app.FilterState !== 'all') { // <--- ADDED CODE
this.filterTodos(app.FilterState);
}
return this;
}
Existing source code:
routers/router.js
var app = app || {};
var Router = Backbone.Router.extend({
routes: {
'all': 'all',
'active': 'active',
'completed': 'completed'
},
all: function() {
console.log('all');
app.Todos.trigger('filter', 'all');
},
active: function() {
console.log('active');
app.Todos.trigger('filter', 'active');
},
completed: function() {
console.log('completed');
app.Todos.trigger('filter', 'completed');
}
});
app.Router = new Router();
Backbone.history.start();
views/todos.js
var app = app || {};
app.TodosView = Backbone.View.extend({
el: '#todo-list',
initialize: function(todos) {
console.log('initialize begin');
app.Todos.reset(todos);
this.listenTo(app.Todos, 'add', this.addOneTodo);
this.listenTo(app.Todos, 'filter', this.filterTodos);
this.render();
console.log('initialize end');
},
render: function() {
app.Todos.each(function(todo) {
this.renderTodo(todo);
}, this);
return this;
},
renderTodo: function(todo) {
var todoView = new app.TodoView({model: todo});
this.$el.append(todoView.render().el);
},
addOneTodo: function(todo) {
this.renderTodo(todo);
},
filterTodos: function(filterType) {
console.log('filter'); // <--- CODE DOES NOT REACH THIS LINE WHEN CALLED ON BROWSER'S REFRESH (F5)
var active = app.Todos.active();
var completed = app.Todos.completed();
if (filterType === 'active') {
// hide remaining
_.each(completed, function(todo) {
todo.trigger('hide');
});
//show active
_.each(active, function(todo) {
todo.trigger('show');
});
}
else if (filterType === 'completed') {
_.each(completed, function(todo) {
todo.trigger('show');
});
//show active
_.each(active, function(todo) {
todo.trigger('hide');
});
}
else if (filterType === 'all') {
app.Todos.each(function(todo) {
todo.trigger('show');
});
}
}
});
Have you considered using Backbone Marionette? It comes with a built in pub sub communication system built in that makes it super easy to do this. Overall it gives you a great organization/modularization of your code by utilizing the pub sub system.

Backbone: Setting server response from one model to another

After login user gets redirected to another page. So the response Login model gets from server, it tries to set to another model.
Second model gets set properly from the first model.But when it reaches another page's view, it becomes empty.
Models
var LoginModel = Backbone.Model.extend({
url:'http://localhost:3000/login',
defaults: {
email:"",
password:""
},
parse: function(resp) {
console.log('Model: Got the response back');
return resp;
},
login: function() {
console.log('Model: Login function:'+JSON.stringify(this));
this.save(
{}, {
success: function(resp) {
console.log('success'+JSON.stringify(resp));
dashboardModel.set(resp.result);
window.location = 'templates/dashboard.html'
},
error: function(error) {
console.log('error: '+JSON.stringify(error));
}
});
},
redirect: function() {
console.log('inside redirect method');
}
});
var loginModel = new LoginModel();
var DashboardModel = Backbone.Model.extend({
defaults: {
campaignName:"",
orderedAndGoal:"",
status:"",
endDate:"",
},
parse: function(resp) {
console.log('Model: Got the response back');
return resp;
}
});
var dashboardModel = new DashboardModel();
View
var DashboardView = Backbone.View.extend({
template:_.template('<div>'+
'<h3><%= campaignName %></h3>'+
'<span><%= orderedAndGoal %>, </span>'+
'<span><%= status %>, </span>'+
'<span><%= endDate %>, </span>'+
'</div>'),
initialize: function() {
this.model.on('change', this.render, this);
},
render: function() {
console.log('what happens here')
var attributes = this.model.toJSON();
this.$el.html(this.template(attributes));
},
});
var dashboardView = new DashboardView({model: dashboardModel});
dashboardView.render();
$(".container").append(dashboardView.el);
You are literally navigating to another HTML page with window.location = .... That's not gonna work. When the browser navigates to another page, all your running code and any variables they set are blown away. Backbone is all about creating "single page applications (SPA)" where there is only 1 page loaded by the browser and then the DOM is dynamically changed at runtime. Take a look at Backbone.Router as a starting point for understanding this. You'll call methods on this router to move the user to another "view" rather than touching window.location
Fix that and your code should work :)

Resources