I have a table with two columns: name and code. I have created a simple custom editor for code column. The idea is, when user double clicks on the cell, the custom dialog with code editor opens. I have implemented it and posted the simplified example here:
Link to plunker
However, I have one issue with copy/paste functionality: if I use my editor, edit some code for the cell, press “Save”, the "code" column value seems to be correctly saved. But when I select this cell and press Ctrl+C, the value is not copied.
The question is: is it a bug in handsontable or I have just missed something, while implementing the custom editor? How should I change my custom editor to make the copy-paste functionality working properly.
The code of editor:
var ScriptEditor = Handsontable.editors.TextEditor.prototype.extend();
ScriptEditor.prototype.getValue = function () {
return this.TEXTAREA.value;
};
ScriptEditor.prototype.setValue = function (value) {
this.TEXTAREA.value = value;
};
ScriptEditor.prototype.open = function () {
var self = this;
this.instance.deselectCell();
var value = self.instance.getDataAtCell(self.row, self.col);
var decodedCode = decodeURI(value);
var success = function (resultCode) {
var encodedCode = encodeURI(resultCode);
self.instance.setDataAtCell(self.row, self.col, encodedCode, 'edit');
self.instance.selectCell(self.row, self.col);
};
openEditor(decodedCode)
.then(success);
};
ScriptEditor.prototype.focus = function () {
Handsontable.editors.TextEditor.prototype.focus.apply(this, arguments);
};
ScriptEditor.prototype.close = function () {
};
var openEditor = function (codeToEdit) {
var deferred = $q.defer();
var dialog = ngDialog.open({
template: 'editorTemplate.htm',
className: 'ngdialog-theme-default',
controllerAs: "editor",
controller: function () {
var vm = this;
vm.inputCode = codeToEdit;
vm.submitChanges = function () {
dialog.close();
deferred.resolve(vm.inputCode);
};
}
});
return deferred.promise;
};
Specs:
Angular version: 1.6.1
Handsontable version: 0.31.2
Chrome version: Version 58.0.3029.81
I have posted an issue on handsontable github repositiory and received there the answer. Link to issue: here
Solution:
Like the member of handsontable team has suggested, in open function before opening my dialog I call this.instance.deselectCell();. However, with this solution, the problem was, that if I press Enter my code editor dialog, not the new line is inserted, but the next cell in handsontable is selected. Then, I have wrappped the call in setTimeout() and it is worked.
Link to plunker:
here
The working code is:
ScriptEditor.prototype.open = function () {
var self = this;
setTimeout(function () {
self.instance.deselectCell();
});
var value = self.instance.getDataAtCell(self.row, self.col);
var decodedCode = decodeURI(value);
var success = function (resultCode) {
var encodedCode = encodeURI(resultCode);
self.instance.setDataAtCell(self.row, self.col, encodedCode, 'edit');
self.instance.selectCell(self.row, self.col);
};
openEditor(decodedCode)
.then(success);
};
Related
I'm trying to replace the HTML in an element on my main page.
This is the JS function I am calling:
var insertHtml = function(selector,html) {
var targetElem = document.querySelector(selector);
console.log(html);
targetElem.innerHtml = html;
};
The new HTML is displaying on the console, however, no changes are reflected on the browser.
If it helps, these are the calling functions:
dc.loadMenuCategories = function () {
showloading("#main-content");
$ajaxUtils.sendGetRequest(categoriesURL, buildAndShowCategoriesHTML);
};
function buildAndShowCategoriesHTML (categories) {
$ajaxUtils.sendGetRequest(
categoriesTitleHTML,
function (categoriesTitleHTML){
$ajaxUtils.sendGetRequest(
categoryHTML,
function (categoryHTML) {
var categoriesViewHTML =
buildCategoriesViewHtml(categories,
categoriesTitleHTML,
categoryHTML);
insertHtml("#main-content", categoriesViewHTML);
},
false);
},
false);
}
Does anyone know why these changes are not loading on the browser?
I'm trying to create a Widget with the function of auto populate commas or dots when the user enters values into the float field by js.
If the user enters 123456789 , it should automatically become 12,345,667.89 immediately.
But In my code, it just works after click a Button:
odoo.define('autofill.separate', function (require) {
"use strict";
var basic_fields = require('web.basic_fields');
var registry = require('web.field_registry');
var BoldWidget = basic_fields.FieldChar.extend({
_renderReadonly: function () {
this._super();
var old_html_render = this.$el.html();
var new_html_render = old_html_render.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
this.$el.html(new_html_render);
},
});
registry.add('autofill_separate', BoldWidget);
});
Please help!
Thank you!
you can use jquery mask plugin:
add this to your backend assets
https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.13.4/jquery.mask.min.js
update your widget:
var basic_fields = require('web.basic_fields');
var registry = require('web.field_registry');
var BoldWidget = basic_fields.FieldMonetary.extend({
_prepareInput: function ($input) {
this._super.apply(this, arguments);
this.$input.mask("#,##0.00", {reverse: true});
return this.$input;
},
});
registry.add('autofill_separate', BoldWidget);
I'm using Redactor II as text editor for a CMS I'm developing, the problem is that a little function isn't working and I don't know why, because everything was installed fine and was working on previous website that I used Redactor.
Even the Table plugin, and line button aren not working. This an example of a plugin I'm making.
var grid_items = {};
$.Redactor.prototype.grids = function()
{
return {
init: function()
{
grid_items.grid01 = { title: '20-80', func: this.grids.insertGrid };
grid_items.grid02 = { title: '20-20-60', func: this.grids.insertGrid };
var button = this.button.add('grids', '<i class="fa fa-table"></i>');
this.button.addDropdown(button, grid_items);
$redactor = this;
},
insertGrid: function(button)
{
var grid = grid_items[button].title;
var grids = grid.split('-');
var html = '';
$.each(grids, function(){
html += '<p>123</p>';
});
this.insert.html(html);
}
};
};
The problem is on the last line, this.insert.html() will not work, but this.insert.set() works. They do different things as stated in the api documentation.
This is not my plugin problem, since the official plugins that use this, are not working too...
Anyone faced this before ? What am I missing here?
Just started with knockout and need to implement page change warning. Following is the code snippet. I just need an alert pop up as warning if any change is made on the page.
function parseViewModel() {
var viewModel = JSON.parse(getState());
viewModel.checking = ko.observable(false);
viewModel.Slider = new ko.observable(100 - viewModel.Slider);
viewModel.CausalsList = buildHierarchy(viewModel.Causals);
viewModel.Causals["-1"] = "Total Marketing Budget";
viewModel.GeographiesList = ko.observableArray(gl);
viewModel.Geographies["0"] = "All Geographies";
viewModel.ProductsList = ko.observableArray(pl);
viewModel.Products["0"] = "All Products";
.
.
.
return viewModel;
}
function bindModel() {
model = parseViewModel();
ko.dirtyFlag = function (root, isInitiallyDirty) {
var result = function () { },
_initialState = ko.observable(ko.toJSON(root)),
_isInitiallyDirty = ko.observable(isInitiallyDirty);
result.isDirty = ko.computed(function () {
return _isInitiallyDirty() || _initialState() !== ko.toJSON(root);
});
result.reset = function () {
_initialState(ko.toJSON(root));
_isInitiallyDirty(false);
};
return result;
};
model.dirtyFlag = new ko.dirtyFlag(model);
model.isDirty.subscribe(function () {
alert("Page change warning!");
});
ko.applyBindings(model, $('#const').get(0));
ko.applyBindings(model, $('#buttonDiv').get(0));
}
Referred Ryan Niemeyer's blog. Unfortunately, it's not working anymore. Any insights please?
You would want to subscribe to model.dirtyFlag.isDirty in your case rather than model.isDirty.
One way to do is by using customBinding. I'm not that familiar with KO either but this might be something you're interested on.
Basically you would do is :-
ko.bindingHandlers.myFunction = {
update : function(){
//do something
}
}
http://knockoutjs.com/documentation/custom-bindings.html
And call it on your element using :-
<h1 data-bind="myFunction:{}"></h1>
Also, a jsfiddle to show how it works. (If you change the value of the First Name and focus out of it then the customBinding gets triggered. )
http://jsfiddle.net/3vuTk
Not sure if it's the best practice though.
when using the ckeditor link dialog, I have custom code for some extra options. I would also like to grab the selected text to use - so I have called:
selectedContents = CKEDITOR.instances['my_editor'].getSelection().getSelectedText();
I want this to happen when the dialog is loaded. So I wrote an "onShow()" handler function... but that messes up the customizations that I have made to the dialog. I'm guessing that my onShow is grabbing the normal process for that event - how can I continue with the normal processing at that point?
dialogDefinition.onShow = function(evt)
{
contents = CKEDITOR.instances['my_editor'].getSelection().getSelectedText();
// now here, continue as you were...
}
Ok, I still have some issues, but the answer to this question is to grab the existing "onShow" handler before overwriting it. Use a global, then it can be called within the new handler:
var dialogDefinition = ev.data.definition;
var oldOnShow = dialogDefinition.onShow;
dialogDefinition.onShow = function(evt) {
// do some stuff
// do some more stuff
// call old function
oldOnShow();
}
Depending on Andy Wallace code:
var oldOnShow = dialogDefinition.onShow;
var newOnShow = function () {
//your code
}
and then:
dialogDefinition.onShow = function(){
oldOnShow.call(this, arguments);
newOnShow.call(this, arguments);
}
It helps me!
Correct syntax is:
/* if new picture, then open the Upload tab */
CKEDITOR.on('dialogDefinition', function(ev) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
var dialog = dialogDefinition.dialog;
if (dialogName == 'image2') {
dialogDefinition.onShow = CKEDITOR.tools.override(dialogDefinition.onShow, function(original) {
return function() {
original.call(this);
CKEDITOR.tools.setTimeout( function() {
if (dialog.getContentElement('info', 'src').getValue() == '') {
dialog.selectPage('Upload');
}
}, 0);
}
});
}
});