Froala Editor Custom Input Field - javascript

I've been looking around but have found no where that explains how to create a custom input field on the toolbar of froala editor. Something similar to how the url button works:
Froala url input
It has an input field and an insert, how can I add a button with similar functionality

You could use the Custom Popup example as a starting point and extend from there by changing the initPopup method like this:
// Popup buttons.
var popup_buttons = '';
// Create the list of buttons.
if (editor.opts.popupButtons.length > 1) {
popup_buttons += '<div class="fr-buttons">';
popup_buttons += editor.button.buildList(editor.opts.popupButtons);
popup_buttons += '</div>';
}
// Custom layer.
var custom_layer = '<div class="fr-my-layer fr-layer fr-active" id="fr-my-layer-' + editor.id + '"><div class="fr-input-line"><input id="fr-my-layer-text-' + editor.id + '" type="text" placeholder="' + editor.language.translate('Alternate Text') + '" tabIndex="1"></div><div class="fr-action-buttons"><button type="button" class="fr-command fr-submit" data-cmd="myButton" tabIndex="2" role="button">' + editor.language.translate('Insert') + '</button></div></div>';
// Load popup template.
var template = {
buttons: popup_buttons,
custom_layer: custom_layer
};
// Create popup.
var $popup = editor.popups.create('customPlugin.popup', template);
return $popup;

Here is my take on using Froala's example and st3fan's suggestion. I wasn't sure how to use st3fan's Insert button, so I repurposed the closePopup button. In this case, I am wrapping the user's text with pre tags and inserting it into the editor.
// Define popup template.
$.extend($.FroalaEditor.POPUP_TEMPLATES, {
'customPlugin.popup': '[_BUTTONS_][_CUSTOM_LAYER_]'
});
// Define popup buttons.
$.extend($.FroalaEditor.DEFAULTS, {
popupButtons: ['popupClose', '|', 'popupButton1', 'popupButton2'],
});
// The custom popup is defined inside a plugin (new or existing).
$.FroalaEditor.PLUGINS.customPlugin = function (editor) {
// Create custom popup.
function initPopup () {
// Load popup template.
var template = $.FroalaEditor.POPUP_TEMPLATES.customPopup;
if (typeof template == 'function') template = template.apply(editor);
// Popup buttons.
var popup_buttons = '';
// Create the list of buttons.
if (editor.opts.popupButtons.length > 1) {
popup_buttons += '<div class="fr-buttons">';
popup_buttons += editor.button.buildList(editor.opts.popupButtons);
popup_buttons += '</div>';
}
// Custom layer.
var custom_layer = '<div class="fr-my-layer fr-layer fr-active" id="fr-my-layer-' + editor.id + '"><div class="fr-input-line"><textarea id="fr-my-layer-text-' + editor.id + '" placeholder="' + editor.language.translate('Alternate Text') + '" tabIndex="1"></textarea></div></div>';
// Load popup template.
var template = {
buttons: popup_buttons,
custom_layer: custom_layer
};
// Create popup.
var $popup = editor.popups.create('customPlugin.popup', template);
return $popup;
}
// Show the popup
function showPopup () {
// Get the popup object defined above.
var $popup = editor.popups.get('customPlugin.popup');
// If popup doesn't exist then create it.
// To improve performance it is best to create the popup when it is first needed
// and not when the editor is initialized.
if (!$popup) $popup = initPopup();
// Set the editor toolbar as the popup's container.
editor.popups.setContainer('customPlugin.popup', editor.$tb);
// If the editor is not displayed when a toolbar button is pressed, then set BODY as the popup's container.
// editor.popups.setContainer('customPlugin.popup', $('body'));
// Trigger refresh for the popup.
// editor.popups.refresh('customPlugin.popup');
// This custom popup is opened by pressing a button from the editor's toolbar.
// Get the button's object in order to place the popup relative to it.
var $btn = editor.$tb.find('.fr-command[data-cmd="myButton"]');
// Compute the popup's position.
var left = $btn.offset().left + $btn.outerWidth() / 2;
var top = $btn.offset().top + (editor.opts.toolbarBottom ? 10 : $btn.outerHeight() - 10);
// Show the custom popup.
// The button's outerHeight is required in case the popup needs to be displayed above it.
editor.popups.show('customPlugin.popup', left, top, $btn.outerHeight());
}
// Hide the custom popup.
function hidePopup () {
var html = $("#fr-my-layer-text-" + editor.id).val();
html = '<br/><pre>' + html + '</pre><br/>';
editor.html.insert(html);
editor.popups.hide('customPlugin.popup');
}
// Methods visible outside the plugin.
return {
showPopup: showPopup,
hidePopup: hidePopup
}
}
// Define an icon and command for the button that opens the custom popup.
$.FroalaEditor.DefineIcon('buttonIcon', { NAME: 'star'})
$.FroalaEditor.RegisterCommand('myButton', {
title: 'Show Popup',
icon: 'buttonIcon',
undo: false,
focus: false,
popup: true,
// Buttons which are included in the editor toolbar should have the plugin property set.
plugin: 'customPlugin',
callback: function () {
if (!this.popups.isVisible('customPlugin.popup')) {
this.customPlugin.showPopup();
}
else {
if (this.$el.find('.fr-marker')) {
this.events.disableBlur();
this.selection.restore();
}
this.popups.hide('customPlugin.popup');
}
}
});
// Define custom popup close button icon and command.
$.FroalaEditor.DefineIcon('popupClose', { NAME: 'plus' });
$.FroalaEditor.RegisterCommand('popupClose', {
title: 'Insert',
undo: false,
focus: false,
refreshAfterCallback: true,
callback: function () {
this.customPlugin.hidePopup();
}
});
jQuery('#fro').froalaEditor({
codeMirror: window.codeMirror,
toolbarButtons: ['bold', 'italic', 'underline', '|', 'myButton', 'html'],
pluginsEnabled: ['customPlugin', 'codeView', 'codeBeautifier']
})

Related

Is it possible to display a modal in javascript like a popover below?

I have tried to display the modal in bootstrap like in the popover below and does not work
Is it possible to have it fixed and work well?
.on('click', '.event', function () {
var $t = $(this),
index = +($t.attr('data-index')),
haspop = $t.data('popover'),
data, time;
if (haspop || isNaN(index)) { return true; }
data = options.data[index];
time = data.start.toTimeString();
if (time && data.end) { time = time + ' - ' + data.end.toTimeString(); }
$t.data('popover',true);
$t.popover({content: '<p><strong>' + time + '</strong></p>'+data.text, html: true, placement: 'auto left'}).popover('toggle');
return false;
});
A modal is compsited with two elements. One is the dialog and the other one is the backdrop. So you want the popover has a backdrop, right?
Write a function to create popover.
Implements the logic that creating and showing a backdrop first and then creating the popover element.

Show the attribute inspector without saving a new feature

The requirement is to add a new feature from template picker but without applying it, can i show the attribute inspector than save the feature.
selectedTemplate = templatePicker.getSelected();
This selectedTemplate is then selected to put the points on the map than opens the attribute inspector by selecting it.
selectedTemplate.featureLayer.applyEdits([newGraphic], null, null);
Sample Code Block :
dojo.connect(drawToolbar, "onDrawEnd", function(geometry) {
//display the editable info window for newly created features
if (map.infoWindow.isShowing) {
map.infoWindow.hide();
}
drawToolbar.deactivate();
var fieldAttributes = layerFieldToAttributes(selectedTemplate.featureLayer.fields);
var newAttributes = dojo.mixin(fieldAttributes, selectedTemplate.template.prototype.attributes);
var newGraphic = new esri.Graphic(geometry, null, newAttributes);
var layerInfos = [{
'featureLayer': selectedTemplate.featureLayer,
'isEditable': true
}];
var attInspector = new esri.dijit.AttributeInspector({
layerInfos: layerInfos
}, dojo.create("div"));
selectedTemplate.featureLayer.applyEdits([newGraphic], null, null, function() {
var screenPoint = map.toScreen(getInfoWindowPositionPoint(newGraphic));
map.infoWindow.setContent(attInspector.domNode);
map.infoWindow.resize(325, 185);
map.infoWindow.show(screenPoint, map.getInfoWindowAnchor(screenPoint));
templatePicker.clearSelection();
});
dojo.connect(attInspector, "onAttributeChange", function(feature, fieldName, newFieldValue) {
feature.attributes[fieldName] = newFieldValue;
feature.getLayer().applyEdits(null, [feature], null);
});
dojo.connect(attInspector, "onDelete", function(feature) {
feature.getLayer().applyEdits(null, null, [feature]);
map.infoWindow.hide();
});
});
}
I would like my client first add the attribute to feature and (save & apply) it.
Any help would be appreciated.
Here is the sample project : https://www.dropbox.com/s/fh71g1k9nsa70nq/index-2.html.zip?dl=0
I dont think you can do that with the AttributeInspector, try creating a custom popup that will have options to save and delete/cancel, when saving fire the applyEdits, when clicking delete, remove, ect.
Content:
var content = "<input id='text1'></input> </br>" +
"<input id='text1'></input> </br>" + "<button id='submit'>Submit</button>" + "<button id='delete'>Delete</button>"
/*
var attInspector = new AttributeInspector({
layerInfos: layerInfos
}, dojo.create("div"));
*/
map.infoWindow.setTitle(selectedTemplate.featureLayer.name);
map.infoWindow.setContent(content);
map.infoWindow.resize(350, 240);
map.infoWindow.show(evt.geometry, map.getInfoWindowAnchor(evt.geometry));
Listener:
on(map.infoWindow, "show", function () {
on(dom.byId("submit"), "click", function () {
alert("I should be saving");
});
on(dom.byId("delete"), "click", function () {
alert("I should be deleting");
});
})
Check out this fiddler: https://jsfiddle.net/kreza/jpLj5y4h/2/

How to show confirmation pop up when changing page in DataTable

I am landing on the first page of DataTable, make some changes.
Then I move to the second page.
Actually, confirmation popup is shown but it navigate to the second page.
Expected: confirm pop is shown but it still landing on the first.
Here is my code:
$('#dataTable-id').on( 'page.dt', function (event) {
if( change ){
bootbox.dialog({
title: "Confirmation",
message : "Discard changes?",
buttons :{
main: {
label : "Leave",
className : "btn-primary",
callback: function (){
// To avoid broking page/length controller
// move to other pages
return true; // cancel draw
}
},
cancel: {
label : "Stay",
className : "btn-default",
callback : function() {
// stay at current page.
return true;
}
}
},onEscape: function () {return true;}
});
}
});
How to show confirmation popup before page change?
The page.dt event is only informational, it can not be canceled.
You can workaround that restriction by writing a custom preDrawCallback like discussed here: https://datatables.net/forums/discussion/25507
EDIT: You have to cancel the redraw generally and do the paging manually in the bootbox callback (as it does not work as a real modal dialog like the native javascript confirm()). I modified the above example to incorporate a bootbox confirm dialog on paging: https://jsfiddle.net/bk4nvds5/
$(document).ready(function () {
var pageLen = 10;
var originalPage = 0;
var originalPageLen = pageLen;
var gotoPage = 0;
var gotoPageLen = originalPageLen;
var fromBootbox = false;
var table = $('#example').DataTable({
"pageLength": pageLen,
"preDrawCallback": function (settings) {
if(table){ // ignore first draw
if (!fromBootbox) {
// To avoid broking page/length controller, we have to reset the paging information
gotoPage = settings._iDisplayStart;
gotoPageLen = settings._iDisplayLength;
bootbox.confirm("Are you sure?", function(result) {
console.log("goto page" + gotoPage + " (result: " + result + ")");
if (result) {
fromBootbox = true;
table.page.len(gotoPageLen);
table.page(gotoPage / gotoPageLen).draw(false);
fromBootbox = false;
}
});
settings._iDisplayStart = originalPage;
settings._iDisplayLength = originalPageLen;
$('[name="example_length"]').val(originalPageLen);
return false; // cancel draw
}else{
originalPage = settings._iDisplayStart;
originalPageLen = settings._iDisplayLength;
}
}
}
});
});

How do I create my own confirm Dialog?

The confirm box only has two options: ok and cancel.
I'd like to make one myself, so I can add a third button: save and continue. But the issue I currently don't know how to solve, is that: once the custom confirm dialog is up, how do I block the previously running script (or navigation) from running? and then how do I make the buttons return values for the confirmation?
my understanding of the confirm dialog box is this:
it's a visual boolean, that has the power to block navigation and scripts on a page. So, how do I emulate that?
If you want a reliable proven solution... Use jQuery... it'll work on every browser without worrying about crappy IE etc. http://jqueryui.com/demos/dialog/
In javascript, you don't stop while you're waiting for a user action : you set a callback (a function) that your dialog will call on close.
Here's an example of a small dialog library, where you can see how callbacks can be passed.
dialog = {};
dialog.close = function() {
if (dialog.$div) dialog.$div.remove();
dialog.$div = null;
};
// args.title
// args.text
// args.style : "", "error" (optionnel)
// args.buttons : optional : map[label]->function the callback is called just after dialog closing
// args.doAfter : optional : a callback called after dialog closing
dialog.open = function(args) {
args = args || {};
if (this.$div) {
console.log("one dialog at a time");
return;
}
var html = '';
html += '<div id=dialog';
if (args.style) html += ' '+args.style;
html += '><div id=dialog-title>';
html += '</div>';
html += '<div id=dialog-content>';
html += '</div>';
html += '<div id=dialog-buttons>';
html += '</div>';
html += '</div>';
this.$div=$(html);
this.$div.prependTo('body');
$('#dialog-title').html(args.title);
$('#dialog-content').html(args.text);
var buttons = args.buttons || {'Close': function(){return true}};
for (var n in buttons) {
var $btn = $('<input type=button value="'+n+'">');
$btn.data('fun', buttons[n]);
$btn.click(function(){
if ($(this).data('fun')()) {
dialog.close();
if (args.doAfter) args.doAfter();
}
});
$btn.appendTo($('#dialog-buttons'));
}
this.$div.show('fast');
shortcuts.on('dialog', {
27: function(){ // 27 : escape
dialog.close();
}
});
}
Two call samples :
dialog.open({
title: 'ccccc Protection Error',
text: 'There was an error related to cccc Protection. Please consult <a href=../cccc.jsp>this page</a>.',
style: 'error'
});
var ok = false;
dialog.open({
title: sometitle,
text: someHtmlWithInputs,
buttons: {
'OK': function() {
if (// inputs are valid) ok = true;
return true;
},
'Cancel': function() {
return true;
}
},
doAfter: function() {
if (ok) {
if (newvg) {
cccmanager.add(vg);
} else {
cccmanager.store();
}
if (doAfter) doAfter();
}
}
});
As specified by others, you may not need your own library if you just want to make a dialog.

Native Javascript Alert - style override remove new line functionality

I am using a simple jQuery plugin to style my javascript alerts. The problem being the usual methods for adding new lines does not appear to work. Here is the javascript for the plugin, any ideas?
(function($) {
$.fn.customAlert = function(options) {
var settings = {
'alertTitle' : 'Notice!',
'alertOk' : 'OK',
'alertClose' : 'x',
'draggable' : false
};
if (options) $.extend(settings, options);
if(document.getElementById) {
window.defaultAlert = window.alert;
window.alert = function(msgTxt) {
if ($('#modalDiv').length > 0) return; // Only ever show one alert
// The modal div to block out the rest of the document whilst the alert is shown
var modalDiv = $('<div></div>');
modalDiv.attr('id', 'modalDiv');
modalDiv.height($(document).height()); // Make overlay cover the whole window
// The alert container
var alertDiv = $('<div></div>');
alertDiv.attr('id', 'alertDiv');
// The alert title
var titleH1 = $('<h1></h1>');
titleH1.addClass('titleH1');
titleH1.text(settings.alertTitle);
// The alert text to display
var msgP = $('<p></p>');
msgP.text(msgTxt);
// OK button - will remove/close the alert on click
var okBtn = $('<a></a>');
okBtn.addClass('okBtn');
okBtn.text(settings.alertOk);
okBtn.attr('href', '#');
// X button - will remove/close the alert on click
var closeBtn = $('<span></span>');
closeBtn.addClass('alert-close');
closeBtn.text(settings.alertClose);
// Append elements to document body
alertDiv.append(titleH1);
alertDiv.append(msgP);
alertDiv.append(okBtn);
alertDiv.append(closeBtn);
$('body').append(modalDiv);
$('body').append(alertDiv);
// Center alert on page
$('#alertDiv').css('top', ($(window).height()/2) - ($('#alertDiv').height()/2)+'px');
$('#alertDiv').css('left', ($(window).width()/2) - ($('#alertDiv').width()/2)+'px');
// Make draggable
if (settings.draggable && $('#alertDiv').draggable) {
$('#alertDiv').draggable({
handle: 'h1',
opacity: 0.4
});
$('#alertDiv h1').css('cursor', 'move');
}
// Bind OK button to remove/close alert
$('#alertDiv .okBtn, #alertDiv .alert-close').bind('click', function(e) {
$('#alertDiv').remove();
$('#modalDiv').remove();
e.preventDefault();
});
};
}
};
})(jQuery);
I am guessing its a case of in this above finding /n and adding a <br> or </p><p>. I am unsure how to do that if even possible though.
Change this line:
msgP.text(msgTxt);
to
msgP.html(msgTxt);
and I think then you can use <br /> and other html tags.

Categories

Resources