Change style programmatically ionic toast - javascript

I have the following ionicToast into my popup:
onTap: function(e) {
var nombre = scope.data.nombre;
var telefono = scope.data.telefono;
if (nombre.length > 0 && telefono.toString().length > 0) {
scope.data.nombre = nombre;
scope.data.telefono = telefono;
return scope.data;
} else {
ionicToast.show('Debe completar todos los campos.', 'bottom', true, 2500);
e.preventDefault();
}
}
The toast works perfect. But I wanna differentiate when the toast is an error or a success message.
The question is: ¿How can I change the style of the toast programmatically?
Because Sometimes I need the background red (for error message) and sometimes i need it green (for success message).
Also I don't have this toast in my .HTML file, so I can't set a specific style
This is my style that I defined:
.toast-container-error{
background-color: red;
}
.toast-container-success{
background-color: green;
}
Thanks for helping me!
//EDIT//
Using toastr for my custom toast, it not showing on Android devices
index.html
<link href="bower_components/toastr/toastr.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js" ></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet" />
Agenda.service (where I wanna use it)
agendaService.$inject = ['remoteDataService','$q', '$ionicPopup', '$rootScope', 'ionicDatePicker'];
/* #ngInject */
function agendaService(remoteDataService,$q, $ionicPopup, $rootScope, ionicDatePicker){
var agendaComplejo = [];
var service = {
obtenerAgenda: obtenerAgenda,
cargarNuevoTurno: cargarNuevoTurno,
abrirAgenda: abrirAgenda
};
toastr.options = {
"closeButton": true,
"debug": true,
"newestOnTop": false,
"progressBar": false,
"positionClass": "toast-bottom-full-width",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000",
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
}
return service;
function cargarNuevoTurnoPopup() {
var scope = $rootScope.$new();
scope.data = {
nombre: '',
telefono: ''
};
return {
templateUrl: 'scripts/complejo/agenda/nuevo-turno.html',
title: "Nuevo Turno",
scope: scope,
buttons: [{
text: 'Cancelar',
onTap: function(e) {
scope.data.canceled = true;
return scope.data;
}
}, {
text: '<b>Guardar</b>',
type: 'button-positive',
onTap: function(e) {
var nombre = scope.data.nombre;
var telefono = scope.data.telefono;
if (nombre.length > 0 && telefono.toString().length > 0) {
scope.data.nombre = nombre;
scope.data.telefono = telefono;
return scope.data;
} else {
toastr["error"]("Debe completar todos los campos.")
e.preventDefault();
}
}
}]
};
}
Also, I generate the apk with the following command:
ionic build android --debug

It is possible but you have to overide the native style of the component to do this. In our project we use Toastr that give you standard method to display an error or an info and that can be overide more easily.
To include it in your project only include the js and the css
<script src="toastr.js"></script>
<link href="toastr.css" rel="stylesheet"/>
Then the api allow you to raise an info or an error
toastr.info('yourmessage')
toastr.error('your message')
toastr.success('your message')
You can found a demo here:
http://codeseven.github.io/toastr/demo.html

Related

Toastr is not defined, javascript error

In my php project i'm trying to implement toastr notifications.
When i just use the toastr setup with the hardcoded cdn resources it works fine.
But now i'm using bower etc to included toastr into my bundles.
I am using the latest version of toastr that has a fix to use with Jquery 3+
At this point all the needed resources are included in my bundle.js and bundle.css
In my head:
<link defer="defer" src="http://localhost:8080/GiveaDay/design/css/gad.bundle.css"></script>
<script defer="defer" src="http://localhost:8080/GiveaDay/design/js/gad.bundle.js"></script>
Part of my bundle.js where toast is included:
(not pasting the entire toast code)
/*
* Toastr
* Copyright 2012-2015
* Authors: John Papa, Hans Fjällemark, and Tim Ferrell.
* All Rights Reserved.
* Use, reproduction, distribution, and modification of this code is subject to the terms and
* conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
*
* ARIA Support: Greta Krafsig
*
* Project: https://github.com/CodeSeven/toastr
*/
/* global define */
(function (define) {
define(['jquery'], function ($) {
return (function () {
var $container;
var listener;
var toastId = 0;
var toastType = {
error: 'error',
info: 'info',
success: 'success',
warning: 'warning'
};
var toastr = {
clear: clear,
remove: remove,
error: error,
getContainer: getContainer,
info: info,
options: {},
subscribe: subscribe,
success: success,
version: '2.1.3',
warning: warning
};
var previousToast;
return toastr;
But now I get the error "toastr is not defined" on following code:
<script>
window.addEventListener('DOMContentLoaded', function() {
(function($) {
$(document).ready(function() {
toastr.options = {
"closeButton": false,
"debug": false,
"newestOnTop": false,
"progressBar": true,
"positionClass": "toast-top-center",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000",
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
}
});
})(jQuery);
});
<?php if($feedback['type'] == "alert-success"){ ?>
toastr.success("<?php echo $feedback['text']; ?>");
<?php }else if($feedback['type'] == "alert-danger"){ ?>
toastr.error("<?php echo $feedback['text']; ?>");
<?php } ?>
</script>
What am i missing here?
Thanks in advance

Can I use a JavaScript inline edit library in my Angular 2 project?

This is the library:
http://www.jqueryscript.net/demo/jQuery-jQuery-UI-Based-Content-editable-Widget-contenteditable-js/
This is used for inline editing on html pages. My code on HTML page is shown below -
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<script src="http://sco7.com/del/jquery-contenteditable.js"></script>
<script>
$("#basic").editable();
$("#paragraph").editable({
multiline: true,
autoselect: true
});
$("#alert").editable({
multiline: true,
saveDelay: 800,
save: function(e, ui) {
alert("Saving actual content: " + ui.content);
}
});
$("#scalable").editable({
multiline: true
});
$("#nonempty").editable({
multiline: true,
saveDelay: 600,
autoselect: true,
save: function(e, ui) {
alert("Saving actual content: " + ui.content);
},
validate: function(e, ui) {
return ui.content !== "";
}
});
$("#complex").editable({
content: "a", //only link <a> is editable
autoselect: true,
save: function(e, ui) {
alert("New link: " + ui.content);
},
validate: function(e, ui) {
return ui.content !== ""
}
});
</script>
<p id="alert">
This sample fires alert each time changed content is supposed to be saved (e.g. sent to server).
It is currently set up to fire after 800ms delay of not typing anything.
</p>
I want to use this in my Angular project. Can I use this as it is? Like the <p id="alert">, do I need to do this in a similar way?
You can use contenteditable attribute or set designmode on html elements to make it editable. For more information you can refer Mozilla Developer Network
$(document).ready(function(){
$("#alert").keyup(function(){
console.info($(this).html()); // prints edited text
console.info("Inner Html---->"+$("#container").html()); // prints html of edited text
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<p id="alert" contenteditable="true">
EDIT ME
</p>
</div>
Example Code
<div #container>
<p #alert contenteditable="true">EDIT ME</p>
</div>
Script File
import {ElementRef,Renderer2} from '#angular/core';
#ViewChild('container') el:ElementRef;
constructor(private rd: Renderer2) {}
ngAfterViewInit() {
this.el.nativeElement.innerHtml;
}
Option 1: Add scripts directly
You can add that scrips directly in your page using $("selector")
index.html
<h2 id="basic">
Basic examples. Click on me to edit. Press 'ESC' or 'Tab' or click anywhere else to finish editing.
</h2>
<!--do not forget add scripts-->
<!--basic scripts-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<script src="http://www.jqueryscript.net/demo/jQuery-jQuery-UI-Based-Content-editable-Widget-contenteditable-js/src/jquery-contenteditable.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.3/angular.js"></script>
<!--your scripts-->
<script src="app.js"></script>
<script src="your-editable.js"></script>
app.js
var app = angular.module("app", []);
your-editable.js
$("#basic").editable();
Options 2: convert to directive
There you can convert the editable to directive to have more access on elements
index.html
<!--options: basic, paragraph, alert, scalable, nonempty, complex-->
<h2 content="basic">
Basic examples. Click on me to edit. Press 'ESC' or 'Tab' or click anywhere else to finish editing.
</h2>
<!--do not forget add scripts-->
<!--basic scripts-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<script src="http://www.jqueryscript.net/demo/jQuery-jQuery-UI-Based-Content-editable-Widget-contenteditable-js/src/jquery-contenteditable.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.3/angular.js"></script>
<!--your scripts-->
<script src="app.js"></script>
<script src="directive.js"></script>
app.js
var app = angular.module("app", []);
directive.js
Also you can improve this directive to get more options from developers
app.directive("content", function () {
return {
restrict: "A",
scope: {
content: "#"
},
link: function ($scope, $element) {
switch ($scope.content) {
case "basic":
$element.editable();
break;
case "paragraph":
$element.editable({
multiline: true,
autoselect: true
});
break;
case "alert":
$element.editable({
multiline: true,
saveDelay: 800,
save: function (content) {
alert("Saving actual content: " + content);
}
});
break;
case "scalable":
$element.editable({
multiline: true
});
break;
case "nonempty":
$element.editable({
multiline: true,
saveDelay: 600,
autoselect: true,
save: function (content) {
alert("Saving actual content: " + content);
},
validate: function (content) {
return content !== "";
}});
break;
case "complex":
$element.editable({
content: "a",
autoselect: true,
save: function (content) {
alert("New link: " + content);
},
validate: function (content) {
return content !== "";
}});
break;
default:
$element.editable();
}}}});

Element not found

I'm having a problem with an element not being found. I have this Ui-State from ui-router called AuthDesc, And for the templateURL I have this:
<head>
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
</head>
<body>
<textarea id="SimpleMDE">
# This one autosaves!
By default, it saves every 10 seconds, but this can be changed. When this textarea is included
in a form, it will automatically forget the saved value when the form is submitted.
</textarea>
</body>
And for the Controller I have this:
(function(angular) {
var app = angular.module('ForumApp');
app.controller('authDescCtrl', ["$scope", "$mdDialog", "$state", "$firebaseObject","refService","currentAuth",authDescCtrl])
function authDescCtrl($scope, $mdDialog, $state, $firebaseObject,refService,currentAuth){
$scope.topic = $firebaseObject(refService.ref().child("Topics"))
$scope.goToPerson = function(person, event) {
$mdDialog.show(
$mdDialog.alert()
.title('Navigating')
.textContent('Inspect ' + person)
.ariaLabel('Person inspect demo')
.ok('Neat!')
.targetEvent(event)
);
};
$scope.goToTopic = function(avatar, date, email, title, uid, username, value) {
$state.go("authHome.topic", {
"AVATAR": avatar,
"DATE": date,
"EMAIL": email,
"TITLE": title,
"UID": uid,
"USERNAME": username,
"VALUE": value
})
}
}
new SimpleMDE({
element: document.getElementById("SimpleMDE"),
spellChecker: true,
autosave: {
enabled: true,
unique_id: "SimpleMDE",
},
});
})(angular);
You can see in the last couple lines of controller that there is a new MDE Generator, however the console states that the element cannot be found:
SimpleMDE: Error. No element was found.
I am confused. There is a textarea named SimpleMDE, but I do not know how is it not finding it. Here is a link to the code in the wild: https://ide.c9.io/amanuel2/fourm2
I am afraid that the Javascript loads before the HTML, so it doesn't recognize the texarea with ID SimpleMDE.
Wrap your widget initialization in window.onload event handler
For angular controller use:
angular.element(document).ready(function () {
new SimpleMDE({
element: document.getElementById("SimpleMDE"),
spellChecker: true,
autosave: {
enabled: true,
unique_id: "SimpleMDE",
},
});
});
you can do it also with this code :
$timeout(function() {
new SimpleMDE({
element: document.querySelector("#SimpleMDE"),
spellChecker: true,
autosave: {
enabled: true,
unique_id: "SimpleMDE",
}
});
});

MathJax not Rendering With Angular

The issue I have is this:
On my website, I pull my blog content from an external source which, the first time it's called upon to display, has to use a HTTP request to get. Also, the blog posts are written in Markdown, and I have to parse this to HTML.
I have this controller that goes out and gets the posts from github, decodes them, and parses them into HTML:
app.controller('content', function ($scope, github, html) {
github.getAllContent().then(function (res) {
var files = [];
res.data.forEach(function (obj) {
github.getFile(obj.path).then(function (res) {
res.data.content = marked(window.atob(res.data.content));
res.data.name = res.data.name.slice(0, res.data.name.indexOf('.'));
files.push(res.data);
})
});
$scope.files = files;
});
$scope.renderHtml = html.renderHtml;
});
html is this service
app.service('html', function ($sce) {
this.renderHtml = function (string) {
return $sce.trustAsHtml(string);
}
});
that allows me to insert the HTML into each HTML element like this: <elem>ng-bind-html="renderHtml(info) </elem>".
Whenever I do this, however, LaTeX content isn't rendered. I have configured MathJax to recognize $ ... $ as delimiters, but no matter what happens, I can't seem to get anything to render. I have even called the MathJax.Hub.Typeset() function or set the typeset callback in the MathJax.Hub.Queue function and it doesn't work. Is this because of the markdown parser I use or how the data is encoded? Or is it just a matter of typesetting the MathJax at the right time?
In this project, I use Angular ui-router, if that has anything to do with it.
I have used this (mathjaxBind.directive.js) directive in my project for MathJax and its working for me:
Plunker
mathjaxBind.directive.js
'use strict';
MathJax.HTML.Cookie.Set("menu", {});
MathJax.Hub.Config({
skipStartupTypeset: true,
messageStyle: "none",
extensions: ["tex2jax.js", "mml2jax.js", "MathML/content-mathml.js", "MathML/mml3.js"],
jax: ["input/MathML", "input/TeX", "output/SVG", "output/HTML-CSS", "output/NativeMML", "output/CommonHTML"],
"HTML-CSS": {
availableFonts: [],
styles: {".MathJax_Preview": {visibility: "hidden"}},
showMathMenu: false
},
"SVG": {
availableFonts: [],
styles: {".MathJax_Preview": {visibility: "hidden"}},
showMathMenu: false
},
"NativeMML": {
availableFonts: [],
styles: {".MathJax_Preview": {visibility: "hidden"}},
showMathMenu: false
},
"CommonHTML": {
availableFonts: [],
styles: {".MathJax_Preview": {visibility: "hidden"}},
showMathMenu: false
}
});
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready", function () {
var FONT = MathJax.OutputJax["HTML-CSS"].Font;
FONT.loadError = function (font) {
MathJax.Message.Set("Can't load web font TeX/" + font.directory, null, 2000);
document.getElementById("noWebFont").style.display = "";
};
FONT.firefoxFontError = function (font) {
MathJax.Message.Set("Firefox can't load web fonts from a remote host", null, 3000);
document.getElementById("ffWebFont").style.display = "";
};
});
(function (HUB) {
var MINVERSION = {
Firefox: 3.0,
Opera: 9.52,
MSIE: 6.0,
Chrome: 0.3,
Safari: 2.0,
Konqueror: 4.0,
Unknown: 10000.0 // always disable unknown browsers
};
if (!HUB.Browser.versionAtLeast(MINVERSION[HUB.Browser] || 0.0)) {
HUB.Config({
jax: [], // don't load any Jax
extensions: [], // don't load any extensions
"v1.0-compatible": false // skip warning message due to no jax
});
setTimeout('document.getElementById("badBrowser").style.display = ""', 0);
}
})(MathJax.Hub);
MathJax.Hub.Register.StartupHook("End", function () {
var HTMLCSS = MathJax.OutputJax["HTML-CSS"];
if (HTMLCSS && HTMLCSS.imgFonts) {
document.getElementById("imageFonts").style.display = ""
}
});
angular.module('fsaApp')
.directive('mathjaxBind', function () {
return {
restrict: "A",
controller: ["$scope", "$element", "$attrs", function ($scope, $element, $attrs) {
$scope.$watch($attrs.mathjaxBind, function (value) {
//$($element).parent().find('math').wrap("<script type='math/mml'></script>");
$element.html(value);
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
});
}]
};
});
Controller:
app.controller('MainCtrl', function($scope) {
$scope.info='<script type=\"math/mml\"><math>\n<mstyle displaystyle=\"true\">\n<mtext> N </mtext>\n<msub>\n<mrow>\n<mtext> O </mtext>\n</mrow>\n<mrow>\n<mn> 2 </mn>\n</mrow>\n</msub>\n</mstyle>\n</math></script>';
$scope.info2='<script type=\"math/mml\"><math>\n<mstyle displaystyle=\"true\">\n<mtext> C </mtext>\n<msub>\n<mrow>\n<mtext> H </mtext>\n</mrow>\n<mrow>\n<mn> 4 </mn>\n</mrow>\n</msub>\n</mstyle>\n</math></script>';
});
Library:
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
in HTML:
<div mathjax-bind="info"></div>
<div mathjax-bind="info2"></div>

Cannot read property 'grid' of undefined in modal?

I have a modal that I want to display pre-selected rows in. However, I keep getting a 'cannot read 'grid' of undefined' error. The UI Grids are defined within the modal, and I declare two Grid Apis with two different names. Here is my code:
This launches the modal:
//edit user group
$scope.editSelectedGroup = function(){
//get the selected row
var row = $scope.gridApiInfo.selection.getSelectedRows();
var modalInstance = $modal.open({
animation: true,
templateUrl: 'userGroupModal.html',
controller: 'UserGroupModalController',
resolve: {
modalTitle: function () {
return "Edit User Group"
},
allDepartments: function () {
return $scope.allDepartments;
},
allRegions: function() {
return $scope.allRegions;
},
isEdit: function(){
return true;
},
row: function(){
return row[0];
}
}
});
This is the modal controller:
.controller('UserGroupModalController',function($scope,$modalInstance,$modal,$window,modalTitle,allDepartments,allRegions,isEdit,row,referenceDataService){
$scope.modalTitle = modalTitle;
$scope.isEdit = isEdit;
$scope.allDepartments= allDepartments;
$scope.allRegions = allRegions;
$scope.form= {
value: "",
description: "",
departments: [],
regions: []
};
$scope.departmentsGrid = {
enableRowSelection: true,
multiSelect: true,
enableRowHeaderSelection: false,
onRegisterApi: function(gridApi) {
$scope.deptGridApi= gridApi;
},
columnDefs: [
{name: 'Name', field: 'name'}
],
data: $scope.allDepartments
};
$scope.regionsGrid = {
enableRowSelection: true,
multiSelect: true,
enableRowHeaderSelection: false,
onRegisterApi: function(gridApi) {
$scope.gridApiRegions = gridApi;
},
columnDefs: [
{name: 'Name', field: 'name'}
],
data: $scope.allRegions
};
if ($scope.isEdit){
$scope.form.value = row.value;
$scope.form.description = row.description;
//pushing selected depts
angular.forEach(row.departments, function(department) {
var deptElementPos=angular.findIndexOf($scope.allDepartments, department.id);
$scope.form.departments.push($scope.allDepartments[deptElementPos]);
});
//pushing selected regions
angular.forEach(row.regions, function(region) {
var regionElementPos=angular.findIndexOf($scope.allRegions, region.id);
$scope.form.regions.push($scope.allRegions[regionElementPos]);
});
//setting pre-selected rows
angular.forEach($scope.form.departments, function(department) {
$scope.deptGridApi.grid.rows.map(function (row) {
if (row.entity.id == department.id) {
row.setSelected(true);
$log.log("row selected: " + row.entity.id);
}
});
});
angular.forEach($scope.form.regions, function(region) {
$scope.gridApiRegions.grid.rows.map(function (row) {
if (row.entity.id == region.id) {
row.setSelected(true);
$log.log("row selected region: " + row.entity.id);
}
});
});
$scope.form.id = row.id;
}
$scope.close = function () {
$modalInstance.dismiss();
};
})
When I click the button to launch the modal, no modal shows up - instead I get a console error saying that it 'Cannot read property 'grid' of undefined' at the line with $scope.deptGridApi.grid.rows.map. Anyone have any suggestions for how to fix this? Thanks in advance!
EDIT: Getting selected rows using deptGridApi and gridApiRegions work - I wrote a test function activated by clicking a button in the modal, shown below:
$scope.getDeptandRegions= function(form){
$log.log($scope.gridApiRegions.selection.getSelectedRows());
$log.log($scope.deptGridApi.selection.getSelectedRows())
};
These log the selected rows fine, even though this also uses the grid APIs. Is it this is only fired after I press a button?
Cannot read property 'grid' of undefined' at the line with $scope.deptGridApi.grid.rows.map
means that :
$scope.deptGridApi === undefined
Looking at your code it is because onRegisterApi is either
Never called
Called with "undefined" as paramener
If you can provide a working code snippet I may be able to help you better

Categories