I'm wondering the best way to replace all my alert('error...') with kendo notifications, the easiest way.
so I can just do
myKendoAlert('my message', info); and I don't have to add a specific html div or span holder to each page.
currently I'm doing something like:
var popupNotification = $("#popupNotification").kendoNotification({
position: {
pinned: false,
bottom: 100,
right: 100
},
templates: [{
type: "info",
template: "<div>Test : #= myMessage #</div>"
}],
autoHideAfter: 0,
stacking: "up"
}).data("kendoNotification");
But I need to put this in a common javascript file with a function I can use on all pages. with, info, error, success... (and clear on success)
Just add a method to your namespace to do just that, and call it from where ever you need to.
Here is a sample that is similar to what I do, putting two methods, showSuccess and showError on the top level of the javascript namespace for my application (I use toastr, but same approach).
I have my app object on the window object, with two methods I can call from wherever.
http://jsbin.com/novena/1/edit
var notificationWidget = null;
function alert(message, type) {
if (notificationWidget == null) {
notificationWidget = $("#notification").kendoNotification({
button: true,
hideOnClick: true,
//appendTo: "#container",
//width: "30em",
position: {
pinned: true,
top: "5em",
left: null,
bottom: null,
right: 10
},
autoHideAfter: 8000
}).data("kendoNotification");
}
notificationWidget.show(message, type);
}
Related
I am new to Grapesjs, and i find the intro in Grapesjs doc website:
so if we have code like this:
editor.BlockManager.add('test-block', {
label: 'Test block',
attributes: {class: 'fa fa-text'},
content: {
script: "alert('Hi'); console.log('the element', this)",
// Add some style just to make the component visible
style: {
width: '100px',
height: '100px',
'background-color': 'red',
}
}
});
On the doc website it says:
If you check now the generated HTML coded by the editor (via Export button or editor.getHtml()), you might see something like this:
<div id="c764"></div>
<script>
var items = document.querySelectorAll('#c764');
for (var i = 0, len = items.length; i < len; i++) {
(function(){
// START component code
alert('Hi');
console.log('the element', this)
// END component code
}.bind(items[i]))();
}
</script>
It looks like all the stuff defined in script tag will be executed after the component mount, on the other way, considering Grapesjs provide view.init() and view.onRender() such life cycle methods, I was thinking we can probably achieve exactly the same effect using such life cycle methods.
So my question would be: what's difference between the script and component own life cycle methods?
BTW, I use React before, and i did most state initialization and data fetching in componentDidMount() such life cycle, so i personally could not get what could be the scenario for script in Grapesjs(Especially when i comparing those two libs.)?
As you should know Grapes uses backbone.js, which is pretty different to react.
Now, talking about how it works for grapesjs.
Lifecycle hooks will allow you to interact with model and editor instance during website building process.
Script will contain javascript your component needs to be useful in and outside the editor (Obviously, having limited (read-only) access to model properties).
Here you can see a very basic, and probably dummy example of both cases.
Setting listener on init: You'll probably won't need to alert changes in component attributes in resulting page...
Add animation class: script will run when render in editor, but also will run at published page, so you can see the animation out of grapes' editor.
const editor = grapesjs.init({
height: "100%",
container: "#gjs",
showOffsets: true,
fromElement: true,
noticeOnUnload: false,
storageManager: false,
canvas: {
styles: [
"https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.min.css"
]
}
});
editor.DomComponents.addType("MagicBox", {
model: {
defaults: {
tagName: "div",
attributes: {
alert: ""
},
traits: ["alert"]
},
init() {
this.listenTo(this, "change:attributes:alert", this.handleChange);
},
handleChange(a) {
alert(this.get("attributes").alert);
}
}
});
const blockManager = editor.BlockManager;
blockManager.add("magic-box", {
label: "MagicBox",
content: {
type: "MagicBox",
tagName: "div",
style: {
width: "100px",
height: "100px",
background: "blue"
},
script: 'this.className+="animate__animated animate__bounce"'
},
category: "Basic",
attributes: {
title: "Magic Box"
}
});
I did some research on this and still can't find a good solution for it. I wrote my app in ExtJS 4.1 and when I run it on an iPod the dragging functionality is disabled by default (which is what I want), but if I write the same app in ExtJS 6.2 all windows can be draggable which causes issues of visibility of the app. With that being said, Does anyone know how to disable window dragging when using Tablets (iPod, iPad, etc.)? I'm using ExtJS 6.2
Here's my working code that works great for a single window, but I want a general solution that will stop ALL windows from being dragged.
var win = Ext.create('Ext.Window', {
title: "My Window",
width: 500,
modal: true,
layout: 'fit',
items: form,
buttons: [{
text: 'Close',
handler: function() {
win.hide();
}
}]
});
win.show();
if(Ext.os.deviceType === 'Tablet') {
win.dd.disable();
}
A "global solution" sounds like you want to use an override to apply one of the other answers globally to your application:
Ext.define('MyAppName.override.Window', {
override: 'Ext.window.Window',
initComponent: function() {
this.callParent(arguments);
if(Ext.os.deviceType === 'Tablet') {
this.dd.disable();
}
}
})
or
Ext.define('MyAppName.override.Window', {
override: 'Ext.window.Window',
initComponent: function() {
if(Ext.os.deviceType === 'Tablet') {
this.draggable = false;
}
this.callParent(arguments);
}
})
To make the override work, put it into the file app/override/Window.js and add a reference to your requires array in Application.js:
requires: [
'MyAppName.override.Window'
],
You are looking for Ext.os class.
More precisely Ext.os.is method, according to the docs it has all the values you would need.
I am not sure why you want to block only iPads and not tables in general. If you wan tablets than you can use if(Ext.os.deviceType === 'Tablet') {...}
Otherwise if(Ext.os.is.iPad) {...}.
UPDATE Solution:
If you want to force anything across all classes in the ExtJS you would use Ext.override.
So the solution would be to put at the beginning of the app this code:
if (Ext.os.deviceType === 'Tablet') {
Ext.override('Ext.Window', {
privates: {
initDraggable: function(){}
}
})
}
FYI You can check the Ext.Window source code. I had to override this method, the default value draggable: false doesn't work.
https://fiddle.sencha.com/#view/editor&fiddle/2iqi
To test it, just press F12 switch to table mode.
But this solution has 1 drawback:
If the target is a class declared using Ext.define, the override
method of that class is called
Which means this solution don't work when you use Ext.create('Ext.Window',{})
Solution for that would be to define our own Ext.Window class and than inside the app when you are using Ext.create('Ext.Window' you would use Ext.create('Fiddle.view.MyWindow', and when we have our own function already we don't need to use override but can put if directly into the class definition like this:
Ext.define('Fiddle.view.MyWindow', {
extend: 'Ext.Window',
alias: 'widget.mywindow',
draggable: (function(){
if (Ext.os.deviceType === 'Tablet') {
return false;
} else {
return true;
}
})()
});
https://fiddle.sencha.com/#view/editor&fiddle/2iqj
I don't know how to override it for Ext.create('Ext.Window' if you still insists on using it. One solution would be to re-write Ext.create or simply edit the framework source itself but I highly discourage from that.
Why you are not using draggable: false in window config
Here is some code in FIDDLE
var win = Ext.create('Fiddle.view.MyWindow', {
title: "My Window",
width: 500,
draggable: false,
modal: true,
layout: 'fit',
buttons: [{
text: 'Close',
handler: function() {
win.hide();
}
}]
});
win.show();
So i have this function onDisplayError which is called each time if request fails. This means if user press save button and 3 request are failing i currently getting 3 popup messages. My goal is that this function checks if my popup window is already opened. If it is then i will append errors in my already opened window otherwise it should open this error popup
onDisplayError: function (response, message) {
var errorPanel = Ext.create('myApp.view.popup.error.Panel',{
shortMessage: message,
trace: response
});
if(errorPanel.rendered == true){
console.log('Do some other stuff');
}else{
errorPanel.show();
}
},
This is Panel.js
Ext.define('myApp.view.popup.error.Panel', {
extend: 'Ext.panel.Panel',
requires: [
'myApp.view.popup.error.PanelController'
],
controller: 'myApp_view_popup_error_PanelController',
title: 'Fail',
glyph: 'xf071#FontAwesome',
floating: true,
draggable: true,
modal: true,
closable: true,
buttonAlign: 'center',
layout: 'border',
shortMessage: false,
width: 800,
height: 200,
initComponent: function() {
this.items = [
this.getMessagePanel(),
this.getDetailsPanel()
];
this.callParent(arguments);
},
getMessagePanel: function() {
if(!this.messagePanel) {
var message = this.shortMessage;
this.messagePanel = Ext.create('Ext.panel.Panel', {
bodyPadding: 5,
height: 200,
region: 'center',
border: false,
html: message
});
}
return this.messagePanel;
},
getDetailsPanel: function() {
if(!this.detailsPanel) {
this.detailsPanel = Ext.create('Ext.panel.Panel', {
title: 'Details',
hidden: true,
region: 'south',
scrollable: true,
bodyPadding: 5,
height: 400,
html: '<pre>' + JSON.stringify(this.trace, null, 4) + '</pre>'
});
}
return this.detailsPanel;
}
The problem is that i'm still getting multiple popups displayed. I think that the problem is that var errorPanel loses reference so it can't check if this popup (panel) is already opened. How to achieve desired effect? I'm working with extjs 6. If you need any additional information's please let me know and i will provide.
You could provide to your component definition a special xtype.
Ext.define('myApp.view.popup.error.Panel', {
extend: 'Ext.panel.Panel',
xtype:'myxtype'
and then you could have a very condensed onDisplayError function:
onDisplayError: function (response, message) {
var errorPanel = Ext.ComponentQuery.query('myxtype')[0] || Ext.widget('myxtype');
errorPanel.appendError(message, response)
errorPanel.show();
},
The panel's initComponent function should initialize an empty window, and appendError should contain your logic to append an error (which may be the first error as well as the second or the third) to the list of errors in the panel.
Using Ext.create will always create a new instance of that class.
You can use the reference config to create a unique reference to the panel.
Then, use this.lookupReference('referenceName') in the controller to check if the panel already exists, and show().
You also have to set closeAction: 'hide' in the panel, to avoid panel destruction on close.
Otherwise, you can save a reference to the panel in the controller
this.errorPanel = Ext.create('myApp.view.popup.error.Panel' ....
Then, if (this.errorPanel) this.errorPanel.show();
else this.errorPanel = Ext.create...
I need to fix the problem with body element and the css overflow attribute discussed in this post:
When a fancybox 2 is activated, a scrollbar flashes on the parent page causing the content to shift left and then back
Using the helper option helpers: {overlay: {locked: false}} fixes my problem, but I need a solution to set this option for all Fancybox calls, this way I do not need to spend this setting on each call.
I tried with different forms, but doesn't works:
$.fancybox.open([{
helpers: {
overlay: {
locked: false
}
}
}]);
$.extend($.fn.fancybox.helpers, {
overlay: {
locked: false
}
});
$.fn.fancybox.defaults.overlay.locked = false;
I do not want to change the css component, because currently use the same via Bower.
You could setup an object with this setting that you use in all of your fancyBox calls:
var fancyBoxDefaults =
{
helpers: {
overlay: {
locked: false
}
}
};
$(".fancybox1").fancybox(fancyBoxDefaults);
$(".fancybox2").fancybox(fancyBoxDefaults);
If you need to set settings for any specific fancyBox, you could extend the object:
$(".fancybox3").fancybox($.extend(fancyBoxDefaults,{
maxWidth: 800,
maxHeight: 600
}));
My callback code (js file) is something like
function addcontent(Title, tUrl, bURL, Id,purl){
alert(Id)
var runcontent = new Ext.Panel({
id: 'tt' + Id,
region: 'center',
autoLoad: {
url: tUrl,
callback: function(el){
addwindow(el, Id, bURL,purl);
},
scripts: true,
nocache: true
},
width: 600,
collapsible: false
});
}
function addwindow(el, Id, bURL,purl) {
//alert(el);
alert("add buttons " +{Id);
}
My problem is the call function is not going to addwindow. When I alert “Id” in addcontent it is displaying but not addwindow as the control is not moving to addwindow.
How can I trace/track what is the exception which is preventing the control to move onto addwindow.?
The proper approach to creating the callback with params is to use createCallback or createDelegate. Your functions are (apparently) executing in global scope so it wouldn't make much practical difference, but createDelegate allows your callback to execute within the same scope as the original function, which makes it the best default choice usually. So it would be something like:
autoLoad: {
url: tUrl,
callback: addwindow.createDelegate(this, [Id, bURL,purl]),
scripts: true,
nocache: true
},
Again, note that the this in your case will be the global Window object, but this is still a good practice to get into so that doing the same thing in the future within a class method will work as expected.
function addcontent(Title, tUrl, bURL, Id,purl){
alert(Id)
var runcontent = new Ext.Panel({
id: 'tt' + Id,
region: 'center',
autoLoad: {
url: tUrl,
callback: addwindow(Id, bURL,purl),
scripts: true,
nocache: true
},
width: 600,
collapsible: false
});
}
function addwindow(Id, bURL,purl) {
//alert(el);
alert("add buttons " +Id);
}