Ionic open modal in app.js - angularjs

I am trying to implement Web intent and need to show popup when user shared something with my app and want to get some text.
if (window.plugins && window.plugins.webintent) {
var incomingURL;
window.plugins.webintent.getExtra(window.plugins.webintent.EXTRA_TEXT,function(url) {
incomingURL = url
var myPopup = messageAlert.saveData(url);
}, function() {
incomingURL = false;
}
);
Here messageAlert is a factory. I want to show a modal or popup where user can input some text and i can use furture.
.factory('messageAlert', function ($ionicPopup,$timeout,$ionicModal) {
return {
saveData : function(url) {
// here i tried different scenes. but nothing work out.
// i want a form where user can input some data and save
}
}
}
Can anybody give me idea

As far as I understand, your problem is not about getting the webintent to work, but simply to display the $ionicPopup.
So the main issue I see, is that you inject the $ionicPopup within a factory. Since you want to display the popup on a view, you need to inject it in your controller. There you can create a popup like this:
$ionicPopup.prompt({
title: 'Your title text',
template: 'Please enter your text here',
inputType: 'text',
inputPlaceholder: 'Your text here'
}).then(function(res) {
// after the user typed something, this result callback will be called
// res will contain the text which your user entered
});
You can find the corresponding docs with possible settings here.
Trying to merge this with your code above, I would suggest something like this:
.controller('YourCtrl', function($ionicPopup, messageAlert) {
this.someFunction = function() {
if (window.plugins && window.plugins.webintent) {
var incomingURL;
window.plugins.webintent.getExtra(window.plugins.webintent.EXTRA_TEXT,function(url) {
incomingURL = url;
// open the text input popup
var myPopup = $ionicPopup.prompt({
title: 'Your title text',
template: 'Please enter your text here',
inputType: 'text',
inputPlaceholder: 'Your text here'
});
// after the user typed something, this result callback will be called
myPopup.then(function(userText) {
// userText contains the text which your user entered
// now you can save the data with your factory
messageAlert.saveData(incomingURL, userText);
});
}, function() {
incomingURL = false;
});
}
};
});
Please note that I did not test the latter code, since I do not understand your exact use case.

Here are some ideas to debug the problem:
Does it work when you put a simple alert('YES THIS WORKS!') in the messageAlert.saveData() factory?
Are you sure that the app was invoked with the specified extra? See: https://github.com/Initsogar/cordova-webintent#hasextra

Related

Ionic 1 - Popup not working properly after state change

I have an $ionicPopup defined inside a particular controller say Controller-1. When I move to Controller-1 from any other different Controller-X by changing the state as $state.go('xxx.xx.xx'), the $ionicPopup is not working as expected. But at the same time, if I open Controller-1 for the first time, $ionicPopup works fine. State change is causing issue. How to solve it?
The code for $ionicPopup inside Controller-1 is:
$ionicPopup.show({
title: "Delivery Not Available",
subTitle: 'Selected area is beyond our delivering area. You can place only Take Away orders.',
scope: $scope,
buttons: [{
text: 'Cancel',
onTap: function(e) {
return true;
}
},
{
text: '<b>OK</b>',
type: 'button-balanced',
onTap: function(e) {
$state.go('home.app');
}
},
]});
If I directly launch it from Controller-1 for the first time, it works as expected:
Screenshot - Normal Case
But, if I move to Controller-1 from any other state through a state change using $state.go('xxx.xx.x'), it shows broken output:
Screenshot - Failing Case
Make a function like this for your popup and Call that Function in your success callback function and make sure you have this code in the same controller in which success callback is written
$scope.showConfirm = function() {
var confirmPopup = $ionicPopup.confirm({
title: 'Title',
template: 'Are you sure?'
});
confirmPopup.then(function(res) {
if(res) {
console.log('Sure!');
} else {
console.log('Not sure!');
}
});
};
Refer this link for more details on Ionic Popup

Should I test calls to my service inside BootstrapDialog prompt?

I am using BootstrapDialog to show a dialog box. If the user clicks delete it calls my service and deletes it from the database. If they click cancel it closes the dialog.
I am writing unit tests and this one is puzzling me. The call to my service is nested pretty deep and I wouldn't even know how to make the tests know which path I'm testing.
My code in the controller:
$scope.deleteInventoryEntry = function(id){
//launch dialog
BootstrapDialog.show({
title: 'CONFIRM DELETION',
message: 'Are you sure you want to delete this record?',
closable: false,
type: BootstrapDialog.TYPE_DANGER,
buttons: [{
label: 'Cancel',
action: function(dialog) {
dialog.close();
}
}, {
label: 'Delete',
icon: 'glyphicon glyphicon-remove',
cssClass: 'btn-danger',
action: function(dialog) {
//remove item from database
tankService.deleteInventoryEntry(id).success(function (response) {
//remove item from table if successful
if(response > 0){
//figure out which item to remove from table
var pos = $scope.invTable.filtered.map(function(item) { return item._id; }).indexOf(id);
//remove from table
$scope.invTable.filtered.splice(pos,1);
$scope.selectedItem.lineItems = [];
dialog.close();
//$scope.successGrowl(' QC Deleted Successfully');
}
});
}
}
]
});
};
My Test
it('prompts on delete inventory item', function(){
spyOn(BootstrapDialog, 'show').and.callThrough();
$scope.deleteInventoryEntry(1);
expect(BootstrapDialog.show).toHaveBeenCalled();
});
I can also test if say the ID was NAN or Null and the dialog shouldn't show. But I'm just curious if I should be somehow testing tankService.deleteInventoryEntry() was called. I feel like I should but does that mean I have to mock this entire dialog item?
Any help to point me in the right direction would be much appreciated.
Thanks!
Rule of thumb to any testing. Don't test the implementation, but the behavior. For instance you should test that when you filled a form and clicked a submit button it was sent to your API and something happened in response. Tests should be independent from the view part as much as possible (eg. was the form located in a modal or somewhere in the page).

Text Placeholders in CKEDITOR (angular context)

I am not very familiar with the CKEDITOR API yet and now I got stuck trying to find the way to create placeholders inside of the CKEDITOR editable area.The expected behaviour for the placeholder - to dissappear on user interaction with it, allowing to edit the content instead.
I know that there is already a placeholder plugin (http://ckeditor.com/addon/placeholder) but its behaviour is not what I am looking for.
To be more specific, the question is: is it possible to subscribe for some events on the particular element inside of the CKEDITOR?
Working in the angular context I am able to compile my html before it is passed to the CKEDITOR ng-model
$scope.html = $compile('<div><span text-placeholder >Placeholder</span></div>')($scope).html();
But then I fail trying to set click events inside of the directive:
.directive('textPlaceholder', [ function () {
return {
restrict: 'A',
link: function ($scope, $element) {
//THIS DOES NOT WORK UNFORTUNATELY
$element.on('click', function () {
console.log('clicked');
})
}
}
}])
Any thoughts?
UPDATE: For now I came up with the solution to implement simple plugin and then reference it in the CKEDITOR config:
(function () {
CKEDITOR.plugins.add('text-placeholder', {
init: function (editor) {
editor.on('key', function (evt) {
var el = $(CKEDITOR.instances.editor1.getSelection().getNative().baseNode.parentElement);
if (el.hasClass('text-placeholder')) {
el.remove();
}
});
}
});
})();
Looks ugly for me. Any feedback is appreciated.
This seems to be a final Solution:
CKEDITOR.plugins.add('text-placeholder', {
init: function (editor) {
editor.on('contentDom', function () {
var editable = editor.editable();
editable.attachListener(editable, 'click', function (event) {
var $placeholder = $(event.data.$.target).closest('.text-placeholder');
if ($placeholder.length > 0) {
var selection = editor.getSelection();
selection.selectElement(selection.getStartElement());
}
});
});
}
});
This applies the selection on the element with "text-placeholder" class when user focuses it inside of the editable area
Update:
See example
You inspired me to write one myself, using the above example as a starting point. In my use case I wanted to take placeholder text from an attribute on the editor -- data-placeholder -- and display it in the editor. When the editor gets focus, the placeholder text disappears. When the editor blurs -- if no user content has been entered -- the placeholder text is displayed again. Additionally, I set a data-placeholder-showing attribute so that I can, for example, use CSS to make the placeholder text gray. Here's my code:
CKEDITOR.plugins.add('text-placeholder', {
init: function (editor) {
var placeholder = editor.element.getAttribute('data-placeholder');
editor.on('contentDom', function () {
if (placeholder) {
editor.setData(placeholder);
editor.element.setAttribute('data-placeholder-showing', true);
}
});
editor.on('focus', function() {
if (editor.getData() === placeholder) {
editor.element.setAttribute('data-placeholder-showing', false);
editor.setData('');
}
});
editor.on('blur', function() {
if (placeholder && editor.getData().length === 0) {
editor.element.setAttribute('data-placeholder-showing', true);
editor.setData(placeholder);
}
});
}
});

WebSQL data into AngularJs DropDown

I have very simple question about getting data from WebSql
I have DropDown i.e
<select id="selectCatagoryFood" data-role="listview" data-native-menu="true"
ng-init="foodCatagory = foodCatagories.cast[0]"
ng-options="foodCatagory as foodCatagory.text for foodCatagory in foodCatagories.cast"
ng-model="foodCatagory"
ng-change="changeFoodCatagory()">
</select>
now i want to add data init from webSQL. I already get Data from webSql but i am confuse that how to add that data into DropDown
An example or hints maybe very helpful for me.
Update 1 :: Add Controller Code
myApp.controller('foodSelection',function($scope,foodCatagories){
$scope.foodCatagories = foodCatagories;
$scope.changeFoodCatagory = function(){
alert($scope.foodCatagory.value);
}
});
Update 2 webSQL and JayData
_context.onReady({
success: showData,
error: function (error){
console.log(error);
}
});
function showData(){
var option = '';
_context.FoodGroup.forEach(function(FG)
{
option += '<option value="'+FG.FoodGroupID+'">'+FG.Description+'</option>';
}).then(function(){
console.log(option);
});
}
Update 3
var myApp = angular.module('myApp',[]);
myApp.factory('foodCatagories',function(){
var foodCatagories = {};
foodCatagories.cast = [
{
value: "000",
text: "Select Any"
}
];
return foodCatagories;
});
Update 4
One thing that i didn't mention is that I am using JayData for getting data from webSQL to my App
I will try to explain how it works:
EDIT: Live demo
html
Here is your stripped down select.
<select ng-options="item as item.text for item in foodCategories"
ng-model="foodCategory"
ng-required="true"
ng-change="changeFoodCategory()">
</select>
The directive ng-options will fill automatically the option elements in your select. It will take the foodCategories variable from the $scope of your controller and foreach item in the collection, it will use the text property as the label shown (<option>{{item.text}}</option>') and it will select the whole objectitemas the value of the selectedoption. You could also refer to a property as the value like ({{item.text}}). Then yourng-modelwould be set to theid` value of the selected option.
The directive ng-model corresponds to the variable in the $scope of your controller that will hold the value of the selected option.
The directive ng-required allows you to check if a value has been selected. If you are using a form, you can check if the field is valid formName.ngModelName.$valid. See the docs for more details on form validation.
The directive ng-change allows you to execute a function whenever the selected option changes. You may want to pass the ng-model variable to this function as a parameter or call the variable through the $scope inside the controller.
If no default value is set, angular will add an empty option which will be removed when an option is selected.
You did use the ng-init directive to select the first option, but know that you could set the ng-model variable in your controller to the default value you would like or none.
js
Here I tried to simulate your database service by returning a promise in the case that you are doing an async request. I used the $q service to create a promise and $timeout to fake a call to the database.
myApp.factory('DbFoodCategories', function($q, $timeout) {
var foodCategories = [
{ id: 1, text: "Veggies", value: 100 },
{ id: 2, text: "Fruits", value: 50 },
{ id: 3, text: "Pasta", value: 200 },
{ id: 4, text: "Cereals", value: 250 },
{ id: 5, text: "Milk", value: 150 }
];
return {
get: function() {
var deferred = $q.defer();
// Your call to the database in place of the $timeout
$timeout(function() {
var chance = Math.random() > 0.25;
if (chance) {
// if the call is successfull, return data to controller
deferred.resolve(foodCategories);
}
else {
// if the call failed, return an error message
deferred.reject("Error");
}
}, 500);
/* // your code
_context.onReady({
success: function() {
deferred.resolve(_contect.FoodGroup);
},
error: function (error){
deferred.reject("Error");
}
});
*/
// return a promise that we will send a result soon back to the controller, but not now
return deferred.promise;
},
insert: function(item) {
/* ... */
},
update: function(item) {
/* ... */
},
remove: function(item) {
/* ... */
}
};
});
In your controller you set the variables that will be used in your view. So you can call your DbFoodCategories service to load the data into $scope.foodCategories, and set a default value in $scope.foodCategory that will be used to set the selected option.
myApp.controller('FoodSelection',function($scope, DbFoodCategories){
DbFoodCategories.get().then(
// the callback if the request was successfull
function (response) {
$scope.foodCategories = response; //response is the data we sent from the service
},
// the callback if an error occured
function (response) {
// response is the error message we set in the service
// do something like display the message
}
);
// $scope.foodCategory = defaultValue;
$scope.changeFoodCategory = function() {
alert($scope.foodCatagory.value);
}
});
I hope that this helped you understand more in detail what is happening!
See this example and how use $apply to update the data in scope.
in the new version we released a new module to support AngularJS. We've started to document how to use it, you can find the first blogpost here
With this you should be able to create your dropdown easily, no need to create the options manually. Something like this should do the trick:
myApp.controller('foodSelection',function($scope, $data) {
$scope.foodCatagories = [];
...
_context.onReady()
.then(function() {
$scope.foodCatagories = _context.FoodGroup.toLiveArray();
});
});
provided that FoodGroup has the right fields, of course

How to validate errors in Backbone.Form field:blur event?

I want to validate some form field in blur event. How can i do it with Backbone.Form?
I found it. May be useful to someone else.
var oldText= Backbone.Form.editors.Text;
var newText= oldText.extend({
initialize: function(options) {
oldText.prototype.initialize.call(this,options);
this.on("blur",function(){
this.form.fields[this.options.key].validate();
});
}
});
Backbone.Form.editors.Text=newText;
This code change basic text editor and all input[type="text"] and other extends fields will validate on blur event.
If you want create one "blur validate field". You can create new editor.
Backbone.Form.editors.BlurText= Backbone.Form.editors.Text.extend({
initialize: function(options) {
Backbone.Form.editors.Text.prototype.initialize.call(this,options);
this.on("blur",function(){
this.form.fields[this.options.key].validate();
});
}
});
Now you can use it in schema:
var User = Backbone.Model.extend({
schema: {
username: {
type:'BlurText',
validators: ['required']
}
}
});
You should be able to do this:
form.on('password:blur', function() {
form.fields.password.validate();
});

Resources