Saturday, November 19, 2016

Meteor + React => Adding and deleting rows and better CSS!

There's a default way to add and delete rows in react-bootstrap-table, though I'll have to tweak it for my use-case eventually. Looks like I'll have to add my own "add columns" code too (as well as the ability to specify where the new rows/columns will be inserted). For now though, my app looks like this, which I think is pretty cute!
What I learned:

First off, in order to add/delete a row in react-bootstrap-table, you do this:
<BootstrapTable data={this.state.cellData}
    striped={true}
    insertRow={true}
    deleteRow={true}
    selectRow={{ mode: 'checkbox' }}
    options={{
        onAddRow: this.props.onAddRow,
        onDeleteRow: this.props.onDeleteRow
    }}>
    <TableHeaderColumn width='150px' dataField='id' isKey={true}>Product ID</TableHeaderColumn>
    <TableHeaderColumn width='150px' dataField='name'>Product Name</TableHeaderColumn>
    <TableHeaderColumn width='150px' dataField='price'>Product Price</TableHeaderColumn>
</BootstrapTable>

However, that landed me on multiple warnings that I couldn't figure out... These are the warnings in case you landed here from Google:
Failed to decode downloaded font: http://localhost:3000/fonts/glyphicons-halflings-regular.woff2
(index):1 OTS parsing error: invalid version tag
(index):1 Failed to decode downloaded font: http://localhost:3000/fonts/glyphicons-halflings-regular.woff
(index):1 OTS parsing error: invalid version tag
(index):1 Failed to decode downloaded font: http://localhost:3000/fonts/glyphicons-halflings-regular.ttf
(index):1 OTS parsing error: invalid version tag
(index):1 Failed to decode downloaded font: http://localhost:3000/packages/bootswatch_readable/bootswatch/fonts/glyphicons-halflings-regular.woff2
(index):1 OTS parsing error: invalid version tag
(index):1 Failed to decode downloaded font: http://localhost:3000/packages/bootswatch_readable/bootswatch/fonts/glyphicons-halflings-regular.woff
(index):1 OTS parsing error: invalid version tag
(index):1 Failed to decode downloaded font: http://localhost:3000/packages/bootswatch_readable/bootswatch/fonts/glyphicons-halflings-regular.ttf
(index):1 OTS parsing error: invalid version tag

After a bunch of Googling and trying various solutions there, I ended up looking at the react-bootstrap package, which includes a stylesheet from a link as opposed to a package install. So, I ended up removing bootstrap and adding a link-rel to my app header, like this (in App.jsx)
render() {
    console.log('rendering app');
    return (
        <div className="container">
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" />
            <header>
                <h1>CompareApp Draft</h1>
            </header>
            <br />
//...etc.

I also removed the style imports from client/main.jsx. Please note! Do not remove the import 'react-bootstrap-table/css/react-bootstrap-table.css'; line!

I removed it, and that caused me to realize that all styles imported using <link rel> have higher precedence than the styles in main.css, which is not something we want (probably)...

There are multiple ways to import CSS files in a React app.

  • Previously, we talked about adding it in App.jsx as an import. 
  • Above, we talked about <link rel> in the HTML. 
  • The other way is using @import in main.css.
It seems like I couldn't get @import to work with CSS files from the node_modules/ folder, although it seems like that should be possible (see the link I referenced in my previous post).

@imports go to the top of main.css, and everything defined below them takes higher precedence (as long as they have the same specificity). So, I removed the <link rel> from App.jsx, and now my main.css looks like:
@import "https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css";

That's kind of it for this post.

Friday, November 18, 2016

Meteor + React => react-bootstrap-table

I have this idea to build an app that would help people make decisions by allowing them to move away from making Excel lists and figuring what matters most to them in their heads (or am I the only one who does that?). Anyway, I have a project started here and the readme explains it better than I will now.

After much deliberation I decided to build the app in Meteor, and, since React seems to be so hot right now, make my UI in React. Please note that I have zero experience building web apps from scratch, though I've contributed code to some at work. Still, getting it somewhere where I can just write code is simply not as straight-forward as it should be, especially if you've never used npm before for example.

Meteor version: 1.4.2.3

The versions of the other stuff I'm using:

  • react: 15.4.0
  • react-bootstrap-table: 2.5.8
  • bootstrap: 3.3.7
  • react-dom: 15.4.0
  • react-widgets: 3.4.4


My OS is MacOs Sierra and I'm using iTerm2 because it can do split screen (among other things).

I already did the Meteor tutorial for React, and created my new app. Basically I'm currently between steps 2 and 3 in that tutorial with my new app. Note: console.log works just fine in react, although some of the tutorials were installing other packages for logging (don't do that for now!).

Since my whole app is built on tables, I decided to install react-bootstrap-table. And, since that depends on bootstrap, I also installed that. So you can do:
meteor npm install --save bootstrap react-bootstrap-table
And now, to use it!
The example on the npm packages page was pretty useless for me. Do not install boostrap (yet). We may end up wanting react-bootstrap, but not right now.

It took me a while to find some code that worked, and I found this in an answer, so I'll just paste below. I've put this in a ui/components/App.jsx file instead of the imports/ui/App.jsx file the tutorial suggested. I'll also replace the imports/ui/Task.jsx with a ui/components/Cells.jsx or something of the sort later.

My ui/components/App.jsx file looks like this:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';

var products = [];

function addProducts(quantity) {
  const startId = products.length;
  for (let i = 0; i < quantity; i++) {
    const id = startId + i;
    products.push({
      id: id,
      name: 'Item name ' + id,
      price: 2100 + i
    });
  }
}

addProducts(5);


// App component - represents the whole app
export default class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      ecsData: []
    };
  }

  componentDidMount() {
    this.setState({
      ecsData: products
    });
  }

  render() {
    console.log('rendering app');
    return (
      <div classname="container">
        <header>
          <h1>CompareApp Draft</h1>
        </header>
        <BootstrapTable data="{this.state.ecsData}">
          <TableHeaderColumn datafield="id" iskey="{true}" width="150px">Product ID</TableHeaderColumn>
          <TableHeaderColumn datafield="name" width="220px">Product Name</TableHeaderColumn>
          <TableHeaderColumn datafield="price" width="180px">Product Price</TableHeaderColumn>
        </BootstrapTable>
      </div>
    );
  }
}

Not completely what I want, but baby steps. Remember, I have absolutely zero experience with this.

Apparently, the only way to get css files from the node_modules folder into your app currently, is to do one of the things enumerated here. The only one that actually worked for me though, was the import. And the import seems to have to be done in client/main.jsx.

My client/main.jsx file looks like this:
import 'react-bootstrap-table/css/react-bootstrap-table.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';

import App from '../ui/components/App.jsx';
 
Meteor.startup(() => {
  render(<App />, document.getElementById('render-target'));
});

And the app, running at http://localhost:3000/, looks like this:


Monday, May 16, 2016

Automatically kill the process running on port $PORT in shell

Write this in a file and save it as filename.sh
Now, you can kill whatever process is running on the port you enter.
Note: this only works on *nix systems (lsof doesn't work in girt bash either).

     # kill the process using the desired port
     if [ -z "$1" ]
     then
       printf "Please select a port number to kill by, ie 8263:"
       read PORT
     else
       PORT=$1
     fi
     
     printf "\nThings running on port:$PORT\n==========================\n"
     STR=$(lsof -i:$PORT)
     if [ -z "$STR" ]
     then
       printf "Nothing was running\n"
     else
       printf "Killing process on port: $PORT\n==========================\n"
       kill -9 $(lsof -t -i:$PORT)
       lsof -i:$PORT
     fi
     
     read -p "Done. Press enter to continue..."

Tuesday, March 17, 2015

Spotify won't minimize to tray: Solution (or well, workaround)

Edit: Seems like they've added it back!

The people at Spotify decided to listen to people complaining about the "X" button doing something counter-intuitive (minimizing to tray instead of closing) by removing that functionality completely, to many other users' frustration.
Personally, I would have added an option so that the "-" button could either minimize to tray or to taskbar... but they decided to not do that. Which meant that I haven't used the app in a week, because I kept closing it and it kept distracting me from actual work by just being in the taskbar (I have it set to "never combine" and it fills up quickly!).
Today, I learned that this was intentional and not a weird quirk of my system, so I decided to go look for a solution online, another way of making an app minimize to tray. And I found this post!

So, download RBTray from here, unzip it, find the version of Windows you're running and run the executable. Then you can right-click on the "-" in Spotify, and it'll go where it SHOULD BE. Phew!

And it works for most other apps too, so you could clean your taskbar even more! :)

Wednesday, April 30, 2014

Paste unformatted text in Word on Mac OS

This will be short and not very computer science-y, but I was making a list by pasting a bunch of items from various places on the web and Word kept formatting it according to the HTML (which I went around by first pasting the text in the Chrome bar and then copying that, because otherwise my lists would turn out wrong even if I did "match formatting"). Anyway, here's the smart way to do it.

Say we want to use Command+Shift+V to paste unformatted text (I think that's what it does in Windows by default-- well replace Command by Control obviously).

  • copy some internet formatted text (this bullet point works just fine)
  • go to Tools->Macro->Record New Macro...
  • type a name for the macro (can leave the default), eg: "PastePlainText"
  • click (on the exact center of) the "Keyboard" in "Assign macro to"
  • press "command" "shift" "v" on your keyboard in sequence
  • click "Assign" first
  • click "OK"
  • Go to Edit->Paste Special and select "Unformatted Text", click OK
  • Go to Tools->Macro->Stop recording
  • Go to Tools->Macro->Macros and highlight your "PastePlainText" macro, and click Edit
  • Replace "wdPasteDefault" with "wdFormatPlainText", save and return to Word (there's a blue W Word symbol in the toolbar there, click on that)
  • And, you're done!

P.S.: I thought there was a way to assign this by using System Preferences -> Keyboard shortcuts but I just tried and that only works for actual Menu items, so the best that could do is open the "Paste Special" menu, so this is a far better solution.
P.P.S.: I learned this by watching this video. Not sure what that person gains if you click on the link, so do so, but I never got exactly why I'd watch a video instead of reading 5 bullet points (with images if something is very complicated). So, click on the video and then close it I guess. But thanks to the author anyway!
P.P.P.S.: I ended up using Ctrl+Shift+V because the other combination was already assigned to something (not sure what, didn't want to dig into it)

Tuesday, April 29, 2014

Mac OS Finder Sidebar - Want the bookmark icons colored? Read on!

I just restarted my computer and was stuck again in no-color land for my Finder Bookmarks. I do not get their choice of making them all, well, basically the same. I know they wanted to be slick and all, but I find it just so confusing (and I miss previous Finder versions where the color of your icon could tell you automatically what you needed to click on). But enough of the editorial: if you're here you probably feel the same!

To get your wonderful color-coded icons back, you need to install a small program. You could download SIMBL, but I remember having problems with it, so download EasySIMBL.
Then download ColorfulSidebar and follow their instructions (basically open EasySIMBL and drag-and drop the ColorfulSidebar bundle there or in the SIMBL plugins folder). Make sure the bundle file is checked in the list, and also check "use SIMBL" at the top.

I think you may have to restart Finder (Either login and logout of Mac OS X, or just kill the Finder through the Terminal to relaunch it: killall Finder) though it worked automatically for me this time (I didn't go through the install process again, I just had to check "use SIMBL" after restarting my Mac).

Enjoy the colors!

Tuesday, February 25, 2014

SyntaxHighlighter

I mentioned in my previous post that I'm using  SyntaxHighlighter. Well, it took some configuring!
First off, I followed this tutorial. But then nothing would happen. Turns out, at least for me, the SyntaxHighlighter.config.clipboardSwf link got converted to the HTML encoding of the quotes, no matter what I did. Then I eventually found out that you need to write like this to prevent encoding (with the CDATA)

And then, all of my links kept getting forwarded to https://alekgorbatchev... (instead of http://) which meant that nothing worked when I tried to preview the page. Turns out this is because of the new browser "feature" that looks for secure webpages if viewed from a secure webpage. And if I previewed the page, blogger (or is it Google Chrome) automatically makes it secure (since the new post page is secure). So if you want to preview it, you should manually remove the https. It has no effect on people viewing the page, since they are viewing the non-secure version when they look at your blog. In any case, this is the final version of what I have before my </head> tag (notice the lack of http: and the agorbatchev.typepad.com/pub/sh/3_0_83 instead of alexgorbatchev.com/pub/sh/current/):