Ace Editor - Autocomplete to Fire When I Press White-Space - javascript

Auto-complete is not getting fired when pressing white-space in the editor, Is there an option to fire Autocomplete when white space is pressed?
Please have a look at this demo:
[jsfiddle] https://jsfiddle.net/xbaha/cbfe6tx4/53/
I want the auto complete to be fired when i type "my name is " (note there is a space after "is"), then using onchange event i added the suggestions that should pop up, but it does not work, i must type a letter character so that autocomplete is getting fired.
is there a solution for this?

Instead of using enableLiveAutocomplete option you can use a custom handler for afterExec event https://github.com/ajaxorg/ace/blob/v1.4.7/lib/ace/ext/language_tools.js#L149
var editor;
var fieldsList = [];
function initAceEditor() {
editor = ace.edit("aceEditor", {
theme: "ace/theme/solarized_light",
mode: "ace/mode/text",
showPrintMargin: false,
fontSize: "24px",
minLines: 3,
maxLines: 8,
wrap: true,
// do not use live autocomplete since we want to invoke more often
// enableLiveAutocompletion: true,
enableBasicAutocompletion: true,
});
var langTools = ace.require("ace/ext/language_tools");
var stepLineCompleter = {
getCompletions: function(editor, session, pos, prefix, callback) {
var completions = [];
console.log('before foreach....', this.fields, fieldsList);
var cursor = session.selection.cursor
var line = session.getLine(cursor.row).slice(0, cursor.column - prefix.length)
var fieldsList
if (line.endsWith("name is ")) {
fieldsList = ["bob", "james", "alex", "jimmy"];
} else {
fieldsList = ["my name is", "completion2", "completion3", "one more"]
}
fieldsList.forEach(function(w) {
completions.push({
value: w,
});
});
callback(null, completions);
}
}
langTools.setCompleters([stepLineCompleter]);
langTools.addCompleter(stepLineCompleter);
var Autocomplete = ace.require("ace/autocomplete").Autocomplete
var doLiveAutocomplete = function(e) {
var editor = e.editor;
var hasCompleter = editor.completer && editor.completer.activated;
var session = editor.session
var cursor = session.selection.cursor
var line = session.getLine(cursor.row).slice(0, cursor.column)
// We don't want to autocomplete with no prefix
if (e.command.name === "backspace") {
// do not hide after backspace
} else if (e.command.name === "insertstring") {
if (!hasCompleter) {
// always start completer
var completer = Autocomplete.for(editor);
// Disable autoInsert
completer.autoInsert = false;
completer.showPopup(editor);
}
}
};
editor.commands.on('afterExec', doLiveAutocomplete);
}
initAceEditor()
#aceEditor {
position: absolute;
top: 10%;
right: 0;
bottom: 30%;
left: 0;
}
<script src="https://rawgithub.com/ajaxorg/ace-builds/master/src/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="https://rawgithub.com/ajaxorg/ace-builds/master/src/ext-language_tools.js" type="text/javascript" charset="utf-8"></script>
<div id="aceEditor"></div>

Related

interact.js prevent resizable elements from overlapping

I am using the interact.js library for drag-and-dropping elements inside a grid. Once it is inside my grid I want to be able to resize them which is working, but what is the recommend way for preventing two resizable elements from overlapping. I basically want to stop the resizable move listener when it hits another resizable element. I already know when one resizable elements hits another, But how do I prevent the user from being able to overlap them?
full function for resizing elements:
function resizeZone(target, parentContainer, minHeight, width) {
if (interact.isSet(target) == false) {
interact(target)
.resizable({
edges: { top: true, left: false, bottom: true, right: false },
listeners: {
start: function (event) {
startDataSet = event.target.dataset;
startDeltaRect = event.deltaRect;
startRect = event.rect;
},
move: function (event) {
var elementsAtDragLocation = document.elementsFromPoint(event.x0, event.client.y);
for (let elementId in elementsAtDragLocation) {
var result = elementsAtDragLocation[elementId].getAttribute('free-schedule');
var isFalseSet = (result === 'false');
if (isFalseSet) {
let dragLocationRoutineId = elementsAtDragLocation[elementId].id;
let routineId = event.target.id;
// if user drags element past other element they will overlap, because the isFalseSet check won't work =(
if (dragLocationRoutineId !== routineId) {
return;
}
}
}
let { x, y } = event.target.dataset
x = (parseFloat(x) || 0) + event.deltaRect.left
y = (parseFloat(y) || 0) + event.deltaRect.top
Object.assign(event.target.style, {
width: `${event.rect.width}px`,
height: `${event.rect.height}px`,
transform: `translate(${x}px, ${y}px)`
});
Object.assign(event.target.dataset, { x, y });
},
end: async function (event) {
let routineId = event.target.id;
ResizeTaskTrigger(routineId, event.rect.height, event.deltaRect);
},
},
modifiers: [
interact.modifiers.restrictSize({
min: { width: width, height: minHeight },
}),
interact.modifiers.restrictRect({
restriction: parentContainer
}),
],
});
}
}

Can't use stream in onclick callback

const ToneStream = require('tone-stream')
const Speaker = require('speaker');
const blessed = require('blessed');
const format = {
sampleRate: 8000,
bitDepth: 16,
channels: 1
}
let stream = new ToneStream(format);
const speaker = new Speaker(format);
stream.pipe(speaker);
var screen = blessed.screen({
smartCSR: true
});
let boxarray = [];
for(let i = 0; i < 10; i++) {
let box = blessed.box({
top: "0%",
left: (i/10 *100).toString() + '%',
width: (1/11 *100).toString() + '%',
height: "100%",
tags: true,
style: {
bg: "white"
}
});
box.on('click', () => {
stream.add([4000, 440]);
console.log(i);
});
boxarray.push(box);
}
boxarray.forEach((box) => {
screen.append(box);
});
screen.key(['escape', 'q', 'C-c'], function(ch, key) {
return process.exit(0);
});
screen.render();
I'm trying to get a tone to play when each UI box is clicked. My onclick event added to the boxes isn't working. The console.log works but no tone is played. How can I get a tone to play when a ui box is clicked? The reference to stream still exists, I can console log it without receiving null. The stream is also still open.

trying to show chessboard js in odoo form widget, no error no pieces

Hi i´m trying to show chessboardjs on a form view in odoo backend, I finally make the widget to show the board, but the pieces are hidden, I don´t know why because seems to work fine, except for the pieces. If I use dragable : true in the options and move a hidden piece then the board is rendered with all the pieces. do I´m missing something, on my code that the chessboard its not rendered well??
here is mi widget code:
(function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
openerp.chess_base = function (instance, local) {
local.YourWidgetClassName = instance.web.form.FormWidget.extend({
start: function () {
this.$el.append('<div id="board" style="width: 300px">BOARD GOES HERE</div>'); // creating the board in the DOM
this.onBoard();
},
onBoard: function (position, orientation) {
if (!position) {
this.position = 'start'
} else {
this.position = position
}
if (!orientation) {
this.orientation = 'white'
} else {
this.orientation = orientation
}
this.el_board = this.$('#board');
this.cfg = {
position: this.position,
orientation: this.orientation,
draggable: false,
pieceTheme: '/chess_base/static/img/chesspieces/wikipedia/{piece}.png'
};
this.board = ChessBoard(this.el_board, this.cfg);
}
});
instance.web.form.custom_widgets.add('widget_tag_name', 'instance.chess_base.YourWidgetClassName');
}
})(openerp);
I don't know why but this solve the issue, if someone have an explanation to me please ...
(function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
openerp.chess_base = function (instance, local) {
local.ShowBoard = instance.web.form.FormWidget.extend({
start: function () {
this.$el.append('<div id="board" style="width: 300px">BOARD GOES HERE</div>');
this.show_board();
},
show_board: function () {
var Game = new instance.web.Model("chess.game"),
record_id = this.field_manager.datarecord.id,
record_name = this.field_manager.datarecord.name,
self = this;
self.el_board = self.$('#board');
Game.query(['pgn']).filter([['id', '=', record_id], ['name', '=', record_name]]).all().then(function (data) {
console.log(data);
self.cfg = {
position: data[0].pgn,
orientation: 'white',
pieceTheme: '/chess_base/static/img/chesspieces/wikipedia/{piece}.png'
};
ChessBoard(self.el_board, self.cfg);
});
}
});
instance.web.form.custom_widgets.add('board', 'instance.chess_base.ShowBoard');
}
})(openerp);

Adding search button and text box in ui-dialog-buttonpane

I am writing a greasemonkey script to manipulates the DOM, queries a server and displays the result on a separate jquery dialog.
I want to add following two functionalities to it:
Provide a search box which acts like a simple search on a browser (i.e. searches through the content of the jquery dialog only and highlights the text).
Provide a text-box, the content of which should be stored permanently for all future use of the userscript unless the user changes it specifically.
The problem I am facing is that I want to include both of these in the ui-dialog-buttonpane area of the dialog, to the left of the close button, but I am not able to figure out how to do that.
What I do know is that I can use window.find() (as used here http://www.javascripter.net/faq/searchin.htm) to enable the browser find functionality.
Can someone help me with this ? Following is the code for my existing greasemonkey script:
// ==UserScript==
// #name Query for each URL Asynchronously
// #namespace SupportScript
// #include *
// #require https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
// #require https://ajax.googleapis.com/ajax/libs/jquery/ui/1.11.0/jquery-ui.min.js
// #resource jqUI_CSS https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/redmond/jquery-ui.css
// #grant GM_addStyle
// #grant GM_getResourceText
// #grant GM_getResourceURL
// #run-at document-end
// allow pasting
// ==/UserScript==
var snapshotResults = document.evaluate('//a[contains(#href,"http")]/#href', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var windowWidth = $(window).width()-800;
var windowHeight = $(window).height();
var zNode = document.createElement ('input');
zNode.setAttribute ('id', 'SSButton');
zNode.setAttribute( 'type', 'image' );
zNode.setAttribute( 'src', 'http://www.veryicon.com/icon/64/System/Longhorn%20R2/Back%20Button.png');
//zNode.setAttribute( 'src', 'https://dperkins.org/2013/2013-07-24.Icon.2.png');
//zNode.setAttribute( 'src','http://i1043.photobucket.com/albums/b433/suzuki800/Button-Info-icon.png');
document.body.appendChild (zNode);
var batchSize = 10;
var urlsToUpsert = [];
var uniqueHostnameSet = new Set();
var uniqueURLArray = [];
uniqueHostnameSet.add(window.location.hostname);
var finalUrl = window.location.protocol + '//' + window.location.hostname;
uniqueURLArray.push(finalUrl);
for (var iterate = 0; iterate < snapshotResults.snapshotLength; iterate++)
{
var hrefContent = snapshotResults.snapshotItem(iterate).textContent;
var regex = /http.*/;
var href = regex.exec(hrefContent);
var a = document.createElement('a');
a.href = href;
if (!uniqueHostnameSet.has(a.hostname))
{
uniqueHostnameSet.add(a.hostname);
finalUrl = a.protocol + '//' + a.hostname;
uniqueURLArray.push(finalUrl);
}
}
var divMain = '<div id="SSOverlayDialog"></div>';
$('body').append(divMain);
$.Coral = function (options) {
$.extend(options, {
url: "my URL",
data: JSON.stringify(options.data),
dataType: 'json',
crossDomain: true,
type: 'POST',
contentType: 'application/json',
processData: false,
headers: {
'Content-Encoding': 'abc',
'X-Target': options.operation
},
dataFilter: function(data, type) {
return data || "{}";
}
});
return $.ajax(options);
};
$.GetOperation = function (options) {
$.extend(options, {
async: true,
success: function(data) {
handleData(data);
},
operation: 'opeartion1'
});
return $.Coral(options);
};
$.UpsertOperation = function (options) {
$.extend(options, {
async: true,
operation: 'Operation2'
});
return $.Coral(options);
};
for (var iterateUniqueURLArray=0; iterateUniqueURLArray<uniqueURLArray.length; iterateUniqueURLArray+=batchSize) {
var urlList = uniqueURLArray.slice(iterateUniqueURLArray,iterateUniqueURLArray+batchSize);
try {
var listOfURLs = {
storeUrlList: urlList
};
var dataGetAttributes = {data: listOfURLs};
$.GetOperation(dataGetAttributes);
} catch(e) {
console.log(e);
}
}
function handleData (data) {
var div = '<div id="SSOverlayDialog">';
var response = JSON.stringify(data);
var subString = "";
var startIndex = response.indexOf('{',1);
var endIndex = response.lastIndexOf('}');
var responseText = response.substring(startIndex,endIndex);
var subString = JSON.parse(responseText);
$.each( subString, function( key, value ) {
key = JSON.stringify(key);
div+='<b><i><a style="color:#0645AD" href="'+key.substring(1,key.length-1)+'"><u>' + key.substring(1,key.length-1) + '</u></a></i></b><br><br>';
if(JSON.stringify(value)==='{}') {
console.log("Value for URL "+key+" is null.");
div+='<p>This URL does not exist with Mobius.<span style="color:red" class="urlNotPresent" id ="'+key.substring(1,key.length-1)+'"><u>Click Here</u></span> to submit to Mobius.</p>';
}
$.each( value, function( ky, val ) {
ky = JSON.stringify(ky);
if (val==null) {
div += '<p><b>'+ky.substring(1,ky.length-1)+': </b><i>'+val+'</i></p>';
}
else{
val = JSON.stringify(val);
div += '<p><b>'+ky.substring(1,ky.length-1)+': </b><i>'+val.substring(1,val.length-1)+'</i></p>';
};
});
div+='<br>';
});
div += '</div>';
$('#SSOverlayDialog').append(div);
$(".urlNotPresent").off('click');
$(".urlNotPresent").one('click', urlNotPresentFn);
$(".urlNotPresent").hover(pointerToClick, pointerToDefault);
}
var urlNotPresentFn = function() {
var url = jQuery(this).attr("id");
if (urlsToUpsert.length == batchSize-1) {
urlsToUpsert.push(url);
var listOfURLs = {
storeUrlList: urlsToUpsert
};
var myOptions = {data: listOfURLs};
$.UpsertOperation(myOptions);
urlsToUpsert.length = 0;
} else {
urlsToUpsert.push(url);
};
console.log(urlsToUpsert);
}
var pointerToClick = function() {
$(".urlNotPresent").css("cursor", "pointer");
}
var pointerToDefault = function(){
$(".urlNotPresent").css("cursor", "default");
}
$(window).bind('beforeunload', function() {
if(urlsToUpsert.length>0) {
var listOfURLs = {
storeUrlList: urlsToUpsert
};
var myOptions = {data: listOfURLs};
$.UpsertOperation(myOptions);
urlsToUpsert.length = 0;
};
return ;
});
$('#SSOverlayDialog').dialog({
autoOpen: false,
modal: false,
title: 'Discovered URLs (press "Esc" button to close)',
position: {
at: 'right top'
},
resizable: false,
width: windowWidth,
height: windowHeight,
open: function(event, ui) { $(".ui-dialog-titlebar-close").hide(); },
zIndex: 11111111,
buttons: [
{
text: 'Close',
click: function () {
$(this).dialog('close');
}
}
]
});
$("#SSButton").click(function() {
($("#SSOverlayDialog").dialog("isOpen") == false) ? $("#SSOverlayDialog").dialog("open") : $("#SSOverlayDialog").dialog("close") ;
/* if ($("#SSOverlayDialog").dialog("isOpen") == false) {
$("#SSOverlayDialog").dialog("open"),
$('#SSButton').css({
'transform': 'rotate(180deg)',
'transform': 'translate(-windowWidth)'
});
} else{
$("#SSOverlayDialog").dialog("close"),
$('#SSButton').css({
'transform': 'initial'
});
};*/
});
var jqUI_CssSrc = GM_getResourceText('jqUI_CSS');
jqUI_CssSrc = jqUI_CssSrc.replace(/\.ui-front \{[\s]*z-index:\s100\;[\s]*\}/g,".ui-front \{\n z-index: 20000000 \; \n\}");
GM_addStyle(jqUI_CssSrc);
GM_addStyle ( multilineStr ( function () {/*!
#SSButton {
background: none repeat scroll 0% 0% ;
background-image: none;
background-repeat: repeat;
background-attachment: scroll;
background-position: 0% 0%;
background-size: auto auto;
overflow: hidden;
position: absolute;
top: 0;
right: 0;
z-index: 22222222;
width: 40px;
height: 40px;
}
*/} ) );
function multilineStr (multiLineStringFn) {
var str = multiLineStringFn.toString ();
str = str.replace (/^[^\/]+\/\*!?/, '') // Strip function () { /*!
.replace (/\s*\*\/\s*\}\s*$/, '') // Strip */ }
.replace (/\/\/.+$/gm, '') // Double-slash comments wreck CSS. Strip them.
;
return str;
}
To include controls to the left of the "Close" button in a ui-dialog-buttonpane, you can use the .prepend() function on the .ui-dialog-buttonset class like this:
$('.ui-dialog .ui-dialog-buttonset').prepend('<input type="text"/><button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">Search</span></button>');
You'll most likely want to add a selector for the specific dialog you're using to avoid adding this control to any dialog on the page. Based on your example, it would be something like this:
$('div[aria-describedby=SSOverlayDialog]').find('.ui-dialog-buttonset').prepend('<input type="text"/><button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">Search</span></button>');
Hope that helps answer the main problem.
Best of luck!

Titanium Mobile Controller troubles

Ok so Im working on a mobile app and I wanna make sure my structure is right so I can continue to add more complex things.
Basicaly I am asking if this is the best way to do this.
this is my controller:
app.controller.newItem = function(object) {
var item = app.view.newItem();
item.cancel.addEventListener("click", function(){
item.win.close();
});
item.save.addEventListener('click', function(e) {
if ( String(name.value).length > 0){
var lastInsert = app.model.addItem({
title: item.name.value,
todo: item.todo.value,
section: 1,
placement: 1,
matrix_id: object.id
});
Ti.App.fireEvent('item_updated', { title: item.name.value, todo: item.todo.value, id: lastInsert, section: '1' });
item.close();
}
});
}
then this is my view:
app.view.newItem = function() {
// create new item window
var win = Titanium.UI.createWindow({
title:'Add a New Item',
backgroundColor:'stripped',
navBarHidden: false
});
// navbar buttons
var cancel = Titanium.UI.createButton( {title:'Cancel'} );
var save = Titanium.UI.createButton( {title:'Save', style:Titanium.UI.iPhone.SystemButton.SAVE,} );
// labels and text areas
var name_label = app.ui.label({
text: "Item Name:",
top: 35,
left: 30
});
var name = app.ui.textArea({
height: name_label.height,
top: name_label.top + 35
});
var todo_label = app.ui.label({
text: "Todo:",
top: name.top + 40,
left: name_label.left
});
var todo = app.ui.textArea({
height: 70,
top: todo_label.top +35
});
//set items
var setItems = function() {
win.setLeftNavButton(cancel);
win.setRightNavButton(save);
win.add(name);
win.add(name_label);
win.add(todo);
win.add(todo_label);
win.open({modal: true, animation: true});
}();
return {
win: win,
cancel: cancel,
save: save
}
}
Should I be adding my event listener in my controller? I really don't want to use the
item = app.view.newItem(); then item.save.addEventListener().. sintax can't I just call them save.addEventListener instead of having the item in front. I can't cause that would make save a global variable right?
I generally put event listeners on buttons when I create the button. Especially when the functions they're executing pertain to information on the view.
app.view.newItem = function() {
// create new item window
var win = Titanium.UI.createWindow({
title:'Add a New Item',
backgroundColor:'stripped',
navBarHidden: false
});
// navbar buttons
var cancel = Titanium.UI.createButton({title:'Cancel'});
cancel.addEventListener('click', function(e) {
win.close();
});
var save = Titanium.UI.createButton({title:'Save', style:Titanium.UI.iPhone.SystemButton.SAVE});
save.addEventListener('click', function(e) {
if (String(name.value).length > 0){
var lastInsert = app.model.addItem({
title: item.name.value,
todo: item.todo.value,
section: 1,
placement: 1,
matrix_id: object.id
});
Ti.App.fireEvent('item_updated', { title: item.name.value, todo: item.todo.value, id: lastInsert, section: '1' });
win.close();
}
});
// labels and text areas
var name_label = app.ui.label({
text: "Item Name:",
top: 35,
left: 30
});
var name = app.ui.textArea({
height: name_label.height,
top: name_label.top + 35
});
var todo_label = app.ui.label({
text: "Todo:",
top: name.top + 40,
left: name_label.left
});
var todo = app.ui.textArea({
height: 70,
top: todo_label.top +35
});
//set items
var setItems = function() {
win.setLeftNavButton(cancel);
win.setRightNavButton(save);
win.add(name);
win.add(name_label);
win.add(todo);
win.add(todo_label);
win.open({modal: true, animation: true});
}();
return {
win: win,
cancel: cancel,
save: save
}
}

Categories

Resources