node.js - blessed textarea give repeat text - javascript

i am trying to make a chatroom app with blessed, here is my code:
index.js
const blessed = require('blessed')
const EventEmitter = require('events')
// Create a eventemitter
var chatroom = new EventEmitter()
// Create a screen object.
var screen = blessed.screen({smartCSR: true, dockBorders: true})
screen.title = 'chatroom'
screen.key(['C-c', 'escape'], () => { // exit
return process.exit(0)
})
var chatarea = blessed.box({
parent: screen,
top: 0,
title: 'chatroom',
width: '100%',
height: '100%-2',
tags: true,
border: {
type: 'line'
},
style: {
fg: 'white',
}
})
var form = blessed.form({
parent: screen,
bottom: 0,
width: '100%',
height: 3,
keys: true,
border: {
type: 'line'
}
})
var input = blessed.textarea({
parent: screen,
bottom: 1,
left: 1,
width: '100%',
height: 1,
input: true,
focused: true,
inputOnFocus: true,
tags: true,
});
input.focus()
screen.append(chatarea)
screen.append(form)
screen.append(input)
screen.render()
but it always repeat all the key i am typing, for example: if i type 'hello', it will show hheelllloo like this:
it will repeat all the chars, how can i fix this? thx

You can just move input.focus() after screen.render()

Related

Multiple horizontal lines displayed between set of dynamically created tables

I am facing one issue while inserting horizontal line on the fly (i.e. at the time of creating dynamic tables).
As you can see from the code snippet below:
1) If you click on any row of the first table/grid, a horizontal line is shown below it and a new table is shown
2) If I click on any row of second grid/table ,everything looks good and a horizontal line is shown and a 3rd grid/table is shown
3) Click on 3rd grid , 4th grid is shown and a horizontal line. But when you click on 4th grid, you will notice an additional horizontal line getting added just above the grid as shown in the screenshot
(highlighted) below:
Could anyone tell me why this is happening?
I am trying to accomplish this using an additional variable hll in the code. Not sure if it's redundant to use hll or I could use hl for the same purpose?
var hll = document.createElement('div');
hll.id = 'newhorizLine';
hll.style.margin = "25px 0";
hll.style.height = "1px";
hll.style.background = "black";
hll.style.background = "-webkit-gradient(linear, 0 0, 100% 0, from(white), to(white), color-stop(50%, black))";
Please consider the code snippet below :
var source = {
localdata: [
["Test1", "2018-08-29 14:19:07", "2020-08-29 14:19:07", "Path1"],
["Test2", "2018-09-05 11:26:39", "2020-09-05 11:26:39", "Path2"],
["Test3", "2018-08-30 07:32:23", "2020-08-30 07:32:23", "Path3"],
["Test4", "2018-09-11 09:01:42", "2020-09-11 09:01:42", "Path4"],
["Test5", "2018-08-01 15:28:22", "2020-08-01 15:28:22", "Path5"],
["Test6", "2018-08-01 15:28:22", "2020-08-01 15:28:22", "Path6"],
["Test7", "2018-09-13 07:34:57", "2020-09-13 07:34:57", "Path7"]
],
datafields: [{
name: 'dataSetName',
type: 'string',
map: '0'
},
{
name: 'accessStartDate',
type: 'date',
map: '1'
},
{
name: 'accessEndDate',
type: 'date',
map: '2'
},
{
name: 'conceptPath',
type: 'string',
map: '3'
}
],
datatype: "array"
};
var dataAdapter = new $.jqx.dataAdapter(source, {
loadComplete: function(data) {},
loadError: function(xhr, status, error) {}
});
$("#main_downloader_grid").jqxGrid({
source: dataAdapter,
width: 381,
height: '200',
pageable: true,
sortable: true,
autoheight: true,
columnsResize: true,
theme: 'classic',
columns: [{
text: 'Data Set',
datafield: 'dataSetName',
width: 140
},
{
text: 'Start Date',
datafield: 'accessStartDate',
width: 120,
cellsformat:'MM/dd/yyyy'
},
{
text: 'End Date',
datafield: 'accessEndDate',
width: 120,
cellsformat:'MM/dd/yyyy'
},
{
text: 'Concept Path',
datafield: 'conceptPath',
width: 50,
hidden: true
}
]
});
// Row Select Logic Starts Here
$("#main_downloader_grid").on("rowselect", function(e) {
let data_set_name = $("#main_downloader_grid").jqxGrid('getcell', e.args.rowindex, 'dataSetName');
console.log("Cell Value Test");
console.log(data_set_name.value);
let conceptPath = $("#main_downloader_grid").jqxGrid('getcell', e.args.rowindex, 'conceptPath');
console.log("Concept Path Test");
console.log(conceptPath.value);
$('#commonWindow').remove();
//$('.clickable').remove();
$('.clickable').next('#testbutton').remove();
$('.clickable').slice(1).remove();
var elem = document.createElement('div');
elem.id = 'commonWindow';
//elem.setAttribute('style', 'margin:500px 10px 20px 20px;');
console.log(elem);
let data = [{
letter: '<b>People</b>'
},
{
letter: '1) Detailed demographics data of all people'
},
{
letter: '2) Attributes associated with all people'
},
{
letter: '<b>Technology</b>'
},
{
letter: '1) Computer details'
},
{
letter: '2) Hardware Details'
},
{
letter: '3) Software Details'
},
{
letter: '<b>Company Details</b>'
}
/* {conceptpath: conceptPath.value } */
];
let source = {
localdata: data,
datatype: "array",
datafields: [{
name: 'letter',
type: 'string'
} /* ,{ name: 'conceptpath', type: 'string' } */ ]
};
let newDataAdapter = new $.jqx.dataAdapter(source);
$(elem).jqxGrid({
source: newDataAdapter,
width: 395,
height:310,
columns: [{
text: 'Data set <b>' + data_set_name.value + '</b> selected, what data do you want to see?',
datafield: 'letter'
//width: 450
}
]
});
$(elem).insertAfter('#main_downloader_grid');
elem.style.margin = "50px 10px 20px 50px";
var hl = document.createElement('div');
hl.id = 'horizLine';
hl.style.margin = "25px 0";
hl.style.height = "1px";
hl.style.background = "black";
hl.style.background = "-webkit-gradient(linear, 0 0, 100% 0, from(white), to(white), color-stop(50%, black))";
$(hl).insertAfter('#main_downloader_grid');
var hll = document.createElement('div');
hll.id = 'newhorizLine';
hll.style.margin = "25px 0";
hll.style.height = "1px";
hll.style.background = "black";
hll.style.background = "-webkit-gradient(linear, 0 0, 100% 0, from(white), to(white), color-stop(50%, black))";
$("#commonWindow").on("rowselect", handleClick);
function handleClick(e) {
var $el = $("<div />", {
class: "clickable",
style: "margin:100px 10px 20px 20px ",
})
.on('click', handleClick)
$el.jqxGrid({
height: 270,width:520, pageable: true,source: dataAdapter, columns: [
{ text: 'Data Set Name', datafield: 'dataSetName', width: 200 },
{ text: 'Access Start Date', datafield: 'accessStartDate', width: 150,cellsformat:'MM/dd/yyyy' },
{ text: 'Access End Date', datafield: 'accessEndDate', width: 150,cellsformat:'MM/dd/yyyy' },
{ text: 'Concept Path', datafield: 'conceptPath', width: 100,hidden:true }
]
});
$(hll).insertAfter(".clickable");
var $this = $(this), $parent = $(this).parent();
if (e.type == 'rowselect') {
$('.clickable').next('#testbutton').remove();
$('.clickable').next('#newhorizline').remove();
$('.clickable').slice(1).remove();
}
var $button = $("<div id = 'testbutton'></div>").on('click', function (e) {
$(".clickable").jqxGrid('exportdata', 'csv', 'jqxGrid');
});
console.log($button);
$button.jqxButton({ width: 100, height: 20});
$button.html('Download Data');
$el.after($button);
$parent.append($el);
$(this).off('click');
}
});
<link href="https://jqwidgets.com/public/jqwidgets/styles/jqx.base.css" rel="stylesheet"/>
<script src="https://jqwidgets.com/public/jqwidgets/jqx-all.js"></script>
<div class="wrapper">
<div id="main_downloader_grid" style="margin:50px 10px 20px 50px"></div>
<div class="clickable" style="margin:50px 10px 20px 20px;"></div>
</div>
While, I am not exactly sure what you are try to accomplish, you can get horizontal lines without css using the tag in html!
<h2>Hello!</h2>
<hr>
<h3>Hi, Tim!</h3>

How to Create an animation tool from the following prototype

I was recently asked this question: How to approach this problem? Create a tool that will allow designers to configure animations. In order to facilitate this, implement an AnimationSequence in JavaScript that can render these animations.
For example, if a designer wanted to configure the filling of a bar element, the usage of AnimationSequence would look something like this
var barSequence = new AnimationSequence(bar, [
[100, { width: '10%' }],
[200, { width: '20%' }],
[200, { width: '50%' }],
[200, { width: '80%' }],
[300, { width: '90%' }],
[100, { width: '100%' }]
]);
barSequence.animate();
where the first element of each step in the sequence is the number of milliseconds until the step occurs and the second element is an object containing any number of CSS properties.
How would you implement an AnimationSequence?
You need to build a queue system then call each animation frame based on the first value. So something like this...
var AnimationSequence = function(elem, opts) {
this.element = (typeof elem == "object") ? elem : $(elem); //jQuery
this.options = opts;
this.queue = [];
this.timer = 0;
this.init(opts);
}
AnimationSequence.prototype = {
init: function(opts) {
var that = this;
for(var i = 0, l = opts.length; i < l; i++) {
this.queue.push({delay: opts[i][0], command: opts[i][1]});
}
this.deQueue();
},
deQueue: function() {
if(this.queue.length) {
var animation = this.queue.shift(),
that = this;
this.timer = setTimeout(function() {
that.element.animate(animation.command, function() {
that.deQueue();
});
}, animation.delay);
}
}
};
$(function() {
var barSequence = new AnimationSequence(".bar", [
[100, { width: '10%' }],
[200, { width: '20%' }],
[200, { width: '50%' }],
[200, { width: '80%' }],
[300, { width: '90%' }],
[100, { width: '100%' }]
]);
});
Obviously you would have the html...
<div id="bar-holder">
<div class="bar"></div>
</div>
And Css...
#bar-holder {
width: 100%;
padding: 5px;
background: #ccc;
}
.bar {
height: 25px;
background: red;
}
Working jsfiddle example... https://jsfiddle.net/kprxcos4/
Obviously you might want to beef it up a bit, but that is the start of an animation queue system that can handle arguments and custom fields.

Creating a set of views takes a long time (Appcelerator) and blocks user interactions on iOS only

I am creating a list (ScrollView) with some custom "rows" (The image contains a single "row"). I show 5 rows and have added an event listener so that when the user scrolls to the end, 5 more elements are loaded and displayed. I made this using Alloy but I noticed it was taking too long so I tried writing the views manually.
// created the views programmatically to see if there was any difference from Alloy
function createRow(args) {
var container = Ti.UI.createView({
layout: "vertical",
width: Ti.UI.FILL,
height: "42dp"
});
var rowContent = Ti.UI.createView({
width: Titanium.UI.FILL,
height: "41dp", //Titanium.UI.FILL,
layout: "horizontal",
left: "16dp",
right: "16dp"
});
var border = Ti.UI.createView({
left: "16dp",
right: "16dp",
height: "1dp",
backgroundColor: Colors.darkGrey
});
var titleScroll = Ti.UI.createScrollView({
scrollType: "horizontal",
width: "49%",
horizontalWrap: false
});
var scrollContainer = Ti.UI.createScrollView({
scrollType: "horizontal",
horizontalWrap: false,
width: "50%"
});
var scroll = Ti.UI.createView({
layout: "horizontal",
horizontalWrap: false,
right: 0,
width: Ti.UI.SIZE,
height: Titanium.UI.SIZE
});
var title = Ti.UI.createLabel({
text: args.title,
font: args.isTitle ? {font: "Lato-Regular", fontSize: "22dp"} : {fontFamily: "Lato-Regular", fontSize: "15"},
horizontalWrap: false,
wordWrap: false,
left: 0,
color: Colors.grey,
minimumFontSize: "15dp"
});
if(args.value) {
var t = args.value.join();
scroll.add(Ti.UI.createLabel({
text: t,
color: args.action ? Colors.blue : Colors.black,
font: {fontSize: "15dp", fontFamily: "Lato-Regular"},
right: "5dp",
width: Ti.UI.SIZE,
horizontalWrap: false,
wordWrap: false,
minimumFontSize: "15dp"
}));
}
if(args.data)
scrollContainer.data = args.data; //just a dump of the data used by the click handler
if(args.action)
scrollContainer.addEventListener("click",args.action);
scrollContainer.add(scroll);
titleScroll.add(title);
rowContent.add(titleScroll);
rowContent.add(scrollContainer);
container.add(rowContent);
container.add(border);
return container; //Ti.UI.View
}
function createHeader(args) {
var header = Ti.UI.createView({
layout: "horizontal",
height: "44dp",
backgroundColor: "#fff"
});
var leftView = Ti.UI.createView({
width: "25%",
height: Ti.UI.FILL
});
var rightView = Ti.UI.createView({
width: "25%",
height: Ti.UI.FILL
});
var centerView = Ti.UI.createView({
width: "49%",
height: Ti.UI.FILL
});
var verticalAligner = Ti.UI.createView({
height: Ti.UI.SIZE,
width: Ti.UI.SIZE,
layout: "vertical"
});
var headerTitle = Ti.UI.createLabel({
color: Colors.green,
font: {fontSize: "16.5dp", fontFamily: "Lato-Regular"},
textAlign: "center",
horizontalWrap: false,
wordWrap: false
});
var headerSubtitle = Ti.UI.createLabel({
font: {fontSize: "14dp", fontFamily: "Lato-Regular"},
textAlign: "center",
color: Colors.grey,
horizontalWrap: false,
wordWrap: false
});
if(args.rightView)
rightView.add(args.rightView);
if(args.leftView)
leftView.add(args.leftView);
verticalAligner.add(headerTitle);
verticalAligner.add(headerSubtitle);
centerView.add(verticalAligner);
header.add(leftView);
header.add(centerView);
header.add(rightView);
headerTitle.text = args.title;
headerSubtitle.text = args.subTitle;
return header;
}
function createBlock(args) {
var container = Ti.UI.createView({
layout: "vertical",
width: "100%",
height: Ti.UI.SIZE
});
var covers = Ti.UI.createView({ //
height: "119dp"
});
var content = Ti.UI.createView({
height: Ti.UI.SIZE,
layout: "vertical"
});
function goToEvent() {
Storage.event.id = args.event;
Alloy.Globals.openWin("event");
}
var data = new D.data();
var w = Android ? Ti.Platform.displayCaps.platformWidth : Measure.dpToPX(Ti.Platform.displayCaps.platformWidth);
var h = Measure.dpToPX(119); //Android ? Alloy.Globals.dpToPX(119) : Measure.dpToPX(119);
if(args.images) {
//setTimeout(function() { //timeout didn't make any difference
var image = null;
//for(var i = 0; i < args.images.length; i++) {
image = Ti.UI.createImageView({
image: data.getBlobResized({ //returns a URL for the picture
id: args.images[0], //i
width: w,
height: h
}),
width: iOS ? Measure.pxToDP(w) : Alloy.Globals.pxToDP(w),
height: iOS ? Measure.pxToDP(h): Alloy.Globals.pxToDP(h)
});
image.addEventListener("click",goToEvent);
covers.add(image); //addView
//}
//},0);
}
var row = null;
if(args.rows) {
for(var j=0; j < args.rows.length; j++) {
//row = Alloy.createController("index/events/block/row",args.rows[j]).getView();
content.add(createRow(args.rows[j]));
}
}
container.add(createHeader(args));
container.add(covers);
container.add(content);
return container;
}
In particular, in the code provided, I call 4 times the function createRow() which creates a row inside the element (as seen in the picture). This function takes 7ms to 10ms to run for some reason. So calling it 4 times means it slows the whole process 28-40ms.
On Android the app doesn't lag at all. On iOS it stops user interaction completely until these operations are done
Using latest Titanium SDK (5.2.2GA) on Appcelerator Studio
Testing on iPhone 5, iOS simulator (4s,5,6,6s)
Thank you for your help

How do I programmatically hide Tab in the TabPanel (ExtJS 3)

This my TabPanel code:
inside the code there is two tabs (tab1 and tab2) in the TabPanel (tabs_panel)
MyTabPanelUi = Ext.extend(Ext.TabPanel, {
activeTab: 0,
height: 210,
resizeTabs: true,
tabWidth: 266,
id: 'tabs_panel',
initComponent: function () {
this.items = [{
xtype: 'panel',
title: 'Project',
padding: 20,
height: 150,
id: 'tab1'
}, {
xtype: 'panel',
title: 'Service',
height: 150,
padding: 20,
id: 'tab2'
}]
}
});
I'm trying to hide tab2 using bellow code but this bellow code
var tabPanel = Ext.getCmp('tabs_panel');
var tabToHide = Ext.getCmp('tab2');
tabPanel.hideTabStripItem(tabToHide);
but somehow this above code does not work for me. How can I fix the problem?
You have two possibilities:
var tabPanel = Ext.getCmp('tabs_panel');
tabPanel.hideTabStripItem("tab2"); // with tab id
or
var tabPanel = Ext.getCmp('tabs_panel');
tabPanel.hideTabStripItem(1); // with tab index
try this one
Ext.getCmp("tab").child('#id').tab.hide()

Titanium mobile Javascript objects

Ok so I'm new to Titanium and I'm pretty much a noob at Javascript
I tried doing this:
app.view.newMatrix = function() {
return {
matrix = Titanium.UI.createWindow({
title:'Add a New Matrix',
backgroundColor:'stripped',
navBarHidden: false
}),
// navbar buttons
cancel = Titanium.UI.createButton({
title:'Cancel'
}),
save = Titanium.UI.createButton({
title:'Save',
style:Titanium.UI.iPhone.SystemButton.SAVE
}),
name_label = Titanium.UI.createLabel({
text: "Matrix Name:",
font: { fontsize: 12, fontstyle: 'italic', color: '#336699' },
height: 35,
top: 35,
left: 30,
width: 150,
color: "black"
}),
name = Titanium.UI.createTextArea({
color: '#336699',
height: this.name_label.height,
top: this.name_label.top + 35,
left: this.name_label.left - 10,
width: 275,
borderRadius:15
}),
setItems = function() {
this.win.add(this.name);
this.win.add(this.name_label);
this.win.add(this.desc);
this.win.add(this.desc_label);
Ti.API.info("label:"+ this.name_label.height);
return this.win.open({modal: true, animation: true});
}
}
}
then called it like this:
app.controller.home = function() {
var home = app.view.home();
home.setItems();
home.butn.addEventListener("click", function(e){
app.controller.newMatrix();
});
home.butn2.addEventListener("click", function (e) {
matrix_table(tab);
});
home.butn3.addEventListener("click", function(e){
newItem();
});
home.butn5.addEventListener("click", function (e) {
item_table();
});
}
I did this because I saw a Titanium MVC suggestion here but I don't get why it returns an anonymous object. I can't access properties like name_label from within the name object.
I figured out that I should do this instead:
app.view.newMatrix = function() {
this.matrix = Titanium.UI.createWindow({
title:'Add a New Matrix',
backgroundColor:'stripped',
navBarHidden: false
}),
// navbar buttons
this.cancel = Titanium.UI.createButton({
title:'Cancel'
}),
this.save = Titanium.UI.createButton({
title:'Save',
style:Titanium.UI.iPhone.SystemButton.SAVE
}),
this.name_label = Titanium.UI.createLabel({
text: "Matrix Name:",
font: { fontsize: 12, fontstyle: 'italic', color: '#336699' },
height: 35,
top: 35,
left: 30,
width: 150,
color: "black"
}),
this.name = Titanium.UI.createTextArea({
color: '#336699',
height: this.name_label.height,
top: this.name_label.top + 35,
left: this.name_label.left - 10,
width: 275,
borderRadius:15
}),
this.setItems = function() {
this.win.add(this.name);
this.win.add(this.name_label);
this.win.add(this.desc);
this.win.add(this.desc_label);
Ti.API.info("label:"+ this.name_label.height);
return this.win.open({modal: true, animation: true});
}
}
and call it like this:
app.controller.home = function() {
return {
getView: function() {
var home = app.view.home();
home.setItems();
home.butn.addEventListener("click", function(e){
app.controller.newMatrix();
});
home.butn2.addEventListener("click", function (e) {
matrix_table(tab);
});
home.butn3.addEventListener("click", function(e){
newItem();
});
home.butn5.addEventListener("click", function (e) {
item_table();
});
}
}
}
But I don't know why the first example doesn't work. I mean aren't properties the same as variables? Also I do know that the second example is an object too.. is that how I'm supposed to do them? Also with the second example is the new keyword optional? Should I use it? I kinda wanted to stay away from that cause I'm not sure when I should use it.
thanks I hope I made sense. I do have it working but I don't know if the second example is the right way to go....

Categories

Resources