I am trying to set my own image for the LoadMask.
I am using the LoadMask as an alert message that describes why a form has been disabled.
This form is within a modal that has opened from the window.
I want the alert message to be centered and confined to the form on scrolling, so when you scroll down out of sight of the form, the message stays over the form.
I have achieved this with the LoadMask, however, now I just want to remove the loading image in the mask, and set it as a single alert image.
I know its achievable with a grid panel by using the viewConfig, but it doesn't seem to work for form panels.
Here is the layout I am using, and after items, I just add a lot of forms.
I had also tried to use the wait message for forms, but I couldn't get it to remain on screen.
var layout = Ext.create( 'Ext.panel.Panel',
{
border : false,
// padding: '10 0 10 10',
autoScroll: true,
//defaults: {padding:'10 10 0 10'},
defaults: {
waitMsgTarget: true,
viewConfig:{
loadingCls: 'custom-loader'
},
listeners:{
afterlayout: function(form, layout, eOpts){
if(form && form.disabled){
var alert;
switch(form.name){
case 'Settings':
alert = 'Select a profile to edit this menu.'
break;
case 'activeswitchbox':
alert = 'Select a profile or profile group to edit this menu.'
break;
case 'enabledisable':
alert = 'Select a profile or profile group to edit this menu.'
break;
case 'roomassignment':
alert = 'Select a profile or profile group to edit this menu.'
break;
default:
alert = 'Select a profile to edit this menu.';
}
// var myMask = new Ext.LoadMask(form.getEl(),
// {
// msg:alert,
// });
// myMask.show();
form.getForm().load({waitMsg:'Wait'});
//form.view.loadMask.show();
}
}
}
},
items:
[
{
xtype: 'form',
Related
I have an event on one calendar, and I need to offer the user the ability to move that event to another month in the same calendar. It seems like the best way to do this is (1) remove the event from the current calendar, (2) create a draggable div outside the calendar, (3) allow the user to change the month/day/year, (4) allow the user to drag the div back onto the calendar, (5) hide the new div, (6) submit an ajax request to update the datasource, (7) delete the newly dropped event.
Attached are the code snippets used to do this.
My question: this seems very roundabout. Is there a better way?
// 1
reschedulingEvent = calendar.getEventById(....)
reschedulingEvent.remove()
// 2
rescheduledAppointment = new FullCalendar.Draggable(document.getElementById(
'rescheduled-appointment'), {
eventData: {
id: reschedulingEvent.id,
title: reschedulingEvent.title,
duration: "0:" + (reschedulingEvent.end - reschedulingEvent.start)/1000/60,
}
})
// 4
calendar = new FullCalendar.Calendar(document.getElementById('calendar'), {
editable: true,
droppable: true,
eventDrop: addEventToForm,
eventReceive: addEventToForm,
});
async function addEventToForm(info) {
if (!confirm("Would you like to reschedule this appointment")) return;
$(".rescheduled-appointment-div").hide() // 5
await axios.post(`/appointments/${info.event.id}`, {
start: info.event.start,
end: info.event.end,
}) // 6
calendar.refetchEvents()
calendar.getEventById(info.event.id).remove() // 7
I want to hide the Dev Tools menu item in Kibana, but according to their roadmap, that's not possible with their permission system nor will it be anytime soon. (see https://discuss.elastic.co/t/disable-hide-management-plugin-kibana-5/72763)
Kibana is inside an iFrame hosting a site on the container's domain.
I ended up using MutationObservers in JavaScript to watch for changes to the DOM inside the iFrame in order to hide the menus I didn't want non-admins to see. Solution written in AngularJS 1.2 and is known to work with Kibana 6.2 and 6.3. This will hide several "left side" menus as well as a bunch of Management sub-menus. You can use or modify the code to hide/show additional UI elements. Unfortunately, I had to rely on classes a lot since very few elements contained IDs I could reference.
I hope this at least helps you think of your own solution to managing Kibana display elements outside of their permission structure.
HTML:
<iframe id="AnalysisFrame" ng-src="{{kibanaUrl}}" ng-init="setupFrame()"></iframe>
JavaScript:
$scope.setupFrame = function() {
//iframes are excluded from mutation observation, so we will
// need to create an observer _inside_ the iframe content.
var theFrame = document.querySelector('#AnalysisFrame');
//once the frame is loaded, that is when we can now attach our
// observer to the frame's content.
theFrame.onload = function() {
//console.log('[TRACE] iframe is completely loaded');
var bIsKibanaAdmin = $scope.bIsKibanaAdmin;
//the above is TRUE|FALSE set by some outside logic
// which does not pertain to this exercise.
//create an observer instance for Management sub-menus
var observerMan = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
//console.log('[TRACE] ', mutation);
//sub-menus of the Management console area
var manArea = theFrame.contentDocument.body.querySelector('kbn-management-landing');
if ( manArea ) {
//Management area is divided up by panels of related subjects
var manPanels = manArea.querySelectorAll('div[class*="page-row"]');
if ( manPanels ) manPanels.forEach(function(aPanel) {
//console.log('[TRACE] panel=', aPanel);
//6.2.4 had <div> titles, 6.3.x has <h3> titles, select based on their class only
var panelTitle = aPanel.querySelector('.kuiPanelHeader__title');
//if a panel has a title (version panel does not have one), see if hide or not.
if ( panelTitle ) switch ( panelTitle.innerText ) {
case 'Kibana':
//only hide the Advanced Settings item off this panel
var panelItem = aPanel.querySelector('li > a[href*="#/management/kibana/settings"]');
if ( panelItem ) panelItem.parentElement.hidden = !bIsKibanaAdmin;
break;
default:
//most management panels are hidden from non-admins
aPanel.hidden = !bIsKibanaAdmin;
}//switch
});
}
});
});
//configuration of the left menu becomes active observer
var configMan = {
attributes: true, //for when Management becomes the Active menu
attributeFilter: ['class'],
//attributeOldValue: true,
childList: false,
characterData: false,
//characterDataOldValue: false,
//subtree: true,
};
//the Management menu item does not exist yet, cannot start observing until later.
//create an observer instance for left menu
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
//console.log('[TRACE] ', mutation);
var leftMenus = mutation.target.querySelectorAll('.global-nav-link');
//since the menus do not have IDs, we are searching for their outer
// DIV class unique to all left menu items. Their first element child
// will be the <a href> link we can use to filter out ones we
// wish to show or not.
if ( leftMenus ) leftMenus.forEach(function(aMenu) {
if ( aMenu.firstElementChild ) {
switch ( aMenu.firstElementChild.hash ) {
case "#/dev_tools":
aMenu.hidden = !bIsKibanaAdmin;
break;
case "#/account":
aMenu.hidden = true;
break;
case "":
if ( aMenu.innerText=='Logout' ) {
aMenu.hidden = true;
}
//else console.log('[TRACE] menu=', aMenu);
break;
case "#/management":
//we only want to hide certain sub-menus
// our menu item exists, attach observer for when
// user clicks it to make it "active"
observerMan.observe(aMenu, configMan);
break;
default:
//console.log('[TRACE] menu=', aMenu);
}//switch
}
});
});
});
//configuration of the left menu creation observer
var configLM = {
attributes: false,
//attributeFilter: ['src'],
//attributeOldValue: true,
childList: true,
characterData: false,
//characterDataOldValue: false,
//subtree: true,
};
//start observing the contents of the iframe changes
observer.observe(theFrame.contentDocument.body, configLM);
};
};
I'm facing an issue when trying to perform server side pagination using an enhanced datagrid (dojo v1.10).
The first page is correctly displayed, but the widget (store ? grid ? plugin ?) seems to ignore the 'Content-Range' header value in response and does not allow to get next page.
For example with response header containing 'Content-Range: items 0-9/17', pagination displays '1 to 10 of 10 items', and next page is not available.
After some debug I see that range value is correctly read from JsonRest store (query function)
results.total = results.then(function(){
var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
return range && (range = range.match(/\/(.*)/)) && +range[1];
});
...
But in fetch method from ObjectStore, totalCount value is undefined, results.length is then used:
var results = this.objectStore.query(query, args);
Deferred.when(results.total, function(totalCount){
Deferred.when(results, function(results){
if(args.onBegin){
args.onBegin.call(scope, totalCount || results.length, args);
...
Any idea ?
Thanks,
My code:
// get grid store
var restStore = new JsonRest(
{
target: "ks2/api/workflow/...",
});
var memoryStore = new Memory();
var store = Cache(restStore, memoryStore);
/*set up layout*/
var layout = [{
name: "id",
field: 'id',
width: '5%',
datatype:"string"
},
....
];
/*create a new grid*/
this.workflowGridWidget = new EnhancedGrid({
id: 'workflowGridWidget',
store: new ObjectStore({objectStore: store}),
structure: layout,
rowSelector: '20px',
plugins: {
pagination: {
pageSizes: ["10", "25", "50"],
defaultPageSize: 10,
description: true,
sizeSwitch: true,
pageStepper: true,
gotoButton: true,
maxPageStep: 4,//page step to be displayed
position: "bottom" //position of the pagination bar
}
}
});
/*append the new grid to the div*/
this.workflowGridWidget.placeAt("workflowDataGrid");
/*Call startup() to render the grid*/
this.workflowGridWidget.startup();
I found the issue: I was using a non dojo restful compliant API, and I needed to add JSON response post-processing using
aspect.after(store, "query", this.processResponse);
...
processResponse: function ks2ProcessMonitor_datagrid_WorkflowDataGrid_processResponse(deferred) {
return deferred.then(function(response) {
//process response content
return processedResponse;
});
},
This was working properly but for some reason, it has an impact on pagination. Removing this post-processing (using another API which is dojo compliant) fix the pagination issue.
Maybe I should try response post-processing using an Observable as suggested by Layke.
I am new to the tinymce. I have been trying to figure out all of the attributes I need to use to create decent looking dialog that the user fills out and create shortcode output. In the code example below the label and the textbox are butted against each other with no margin or padding and any trailing spaces in the label text are trimmed, this is just one change that I would like to make. I have looked at the documentation to tinymce and all I find are simple brief code examples.
My Question 1: Where can I find the formal full documentation of this windowManager.open method and all of the possible attributes and methods associated with it?
My Question 2&3: Are these attribute actually native javascript? If so where can I find the formal full documentation to it?
Thanks for any help you can give me to retrieve the documentation or possibly formatting with a css sytle sheet (w/.mce-widget or .mce-textbox) and where and how to register this style sheet in Wordpress.
(function() {
tinymce.create("tinymce.plugins.youtube_plugin", {
//url argument holds the absolute url of our plugin directory
init : function(ed, url) {
alert('in youtube');
//add new button
ed.addButton("youtube_button", {
title : "Youtube Video Responsive Embed",
cmd : "youtube_command",
image : "https://cdn0.iconfinder.com/data/icons/social-flat-rounded-rects/512/youtube_v2-32.png"
});
//button functionality.
ed.addCommand("youtube_command", function() {
//alert('hello youtube');
ed.windowManager.open({
title: "YouTube Video Settings", // The title of the dialog window.
//file : url + '/../html/youtube.html',
width : 800,
height : 300,
inline : 1,
body: [{
type: 'container',
//label : 'flow',
//layout: 'flow',
items: [
{type: 'label', text: 'Youtube ServerPath:'},
{type: 'textbox', size: '80', name: 'title', value: 'http://www.youtube.com/embed/'},
//{type: 'label', text: 'and two labels'}
]
}],
buttons: [{
text: 'Submit',
onclick: 'submit'
}, {
text: 'Cancel',
onclick: 'close'
}],
onsubmit: function(e) {
//form = $('#youtube_plugin_id iframe').contents().find('form');
alert('hello');
ed.insertContent('Title: ' + e.data.title);
}
});
//var selected_text = ed.selection.getContent();
// var return_text = "<span style='color: green'>" + selected_text + "</span>";
//ed.execCommand("mceInsertContent", 0, return_text);
});
} // end init
}); // end tinymce.create
tinymce.PluginManager.add("youtube_button_plugin", tinymce.plugins.youtube_plugin);
})();
Although I didn't find any formal documentation to create a nice looking mce dialog box specifically, I did figure out how to format the dialog title and then embed an external html file that you can add a link tag to a css style sheet and the sky is the limit.
Here is the JavaScript code for the mce, it's up to you to create the external html and css files.
(function($) {
/**
This tinymce plugin provides the editor button and the modal dialog used to embed.
*/
// Extract data stored in the global namespace in tinymce-dev-starter.php.
var passed_data = lgrriw_data;
var php_version = passed_data.php_version;
var valid_domains = passed_data.valid_domains;
var dialogTitle = 'My Dialog Title';
// Define the TinyMCE plugin and setup the button.
// The last property in the first tinymce.create paramenter below must be the same
// as the plugin you defined in tinymce-dev-starter.php. In this case, it is
// lgrriw_plugin. If we called it my_cool_plugin, the first parameter would change
// to 'tinymce.plugins.my_cool_plugin'.
tinymce.create('tinymce.plugins.lgrriw_plugin', {
init: function(editor, url) {
/**
* The editor parameter contains the TinyMCE editor instance. The url
* parameter contains the absolute url to the directory containing the
* TinyMCE plugin file (this file's directory).
*
* We will be using editor to talk to the TinyMCE instance. And we
* will be using url to tell TinyMCE where files are (e.g. button
* images).
*/
// Specify button properties and commands.
// The first parameter of editor.addButton must be the button ID
// given in tinymce-dev-starter.php. In this case, it is lgrriw_button.
editor.addButton('lgrriw_button', {
title: dialogTitle, // Tooltip when hovering over button.
image: url + '/../../assets/tinymce-button_32.png', // The image for the button.
cmd: 'lgrriw_command' // The editor command to execute on button click.
});
// Define the "command" executed on button click.
editor.addCommand('lgrriw_command', function() {
editor.windowManager.open(
{
title: dialogTitle, // The title of the dialog window.
file: url + '/../html/tinymce_dialog.html', // The HTML file with the dialog contents links to css style sheet(s).
width: 810, // The width of the dialog
height: 505, // The height of the dialog
inline: 1 // Whether to use modal dialog instead of separate browser window.
},
// Parameters and arguments we want available to the window.
{
editor: editor,
jquery: $,
valid_domains: valid_domains
}
);
$('.mce-title').each(function(index,item){
// Iterate through the mce titles until you find
// the dialog for this dialog before formatting, otherwise
// the formatting will change the Wordpress
// Theme globally. Be Careful!
if($(item).text() == dialogTitle){
// Format the dialog title using css
$(item).css('text-align', 'center');
$(item).css('color', '#336999');
$(item).css('background-color', '#add9ff');
}
});
});
}
});
// Add the plugin to TinyMCE
// Documentation: http://www.tinymce.com/wiki.php/api4:method.tinymce.AddOnManager.add
tinymce.PluginManager.add('lgrriw_plugin', tinymce.plugins.lgrriw_plugin);
})(jQuery);
I have a login screen which has an ExtJs form panel with two button Login and Reset.
Now, I'm trying to add another button below the lofin panel for a new user sign up.
But the button goes out to the bottom of the screen and a scroll bar appears making the page look ugly!
I have these in my login.jsp file:
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all-access.css">
<script type="text/javascript" src="extjs/ext-all.js"></script>
<script type="text/javascript" src="js/app.js"></script>
And this is my app.js file:
Ext.onReady(function(){
Ext.QuickTips.init();
var login = new Ext.FormPanel({
labelWidth:100,
frame:true,
title:'Member Login',
defaultType:'textfield',
monitorValid:true,
// Specific attributes for the text fields for username / password.
// The "name" attribute defines the name of variables sent to the server.
items:[{
fieldLabel:'Username',
name:'loginUsername',
allowBlank:false
},{
fieldLabel:'Password',
name:'loginPassword',
inputType:'password',
allowBlank:false
}],
buttons: [{
text: 'New User Register',
scale: 'medium',
handler: function()
{
login.getForm().doAction('standardsubmit',{
target : '_self',
method : 'POST',
standardSubmit:true,
formBind: false,
url: 'registration.jsp'
})
}
},{
text: 'Login',
scale: 'medium',
handler: function()
{
login.getForm().doAction('standardsubmit',{
target : '_self',
method : 'POST',
standardSubmit:true,
formBind: true,
url: 'index.jsp'
})
}
},{
text: 'Reset',
scale: 'medium',
handler: function(){
login.getForm().reset();
}
}]
});
// This just creates a window to wrap the login form.
// The login object is passed to the items collection.
var win = new Ext.Window({
layout:'fit',
width:325,
height:175,
closable: false,
resizable: false,
plain: true,
border: false,
items: [login]
});
win.show();
});
I tried adding a new button using the Ext.Createat the end of the above one but it wouldn't work.
I tried having the code in a separate js file and adding the script tag with src to the button file along with the panel file in a separate script tag and even that failed.
Can anybody help me out to create a separate button and my desired position?
Any kind of help is appreciated. Thanks.
I've looked everywhere and I've tried everything I could, but I'm not able to come up with the answer.
NOTE: The code makes the question seem very long and big, but my main query and issue is at the top and bottom of the question.
Im assuming you dont want to add the new button INSIDE the login panel because otherwise you could just add another button to your buttons list anyway. To add a button under your login panel and YET inside the window, do the following steps;
Put your form panel as an item inside a container
Add your button as a second item in the container after your form pannel
Add the container to your window as you did the panel to the window
Voilah! You could also try giving your window and 'id' such as 'id=loginWindow' and then calling the code
Ext.getCmp('loginWindow').add(
{
xtype:button,
text:'Yay!'
}
);
If you need more code specific help, feel free to message me. I know your feel bro <3