AngularJS Sortable Table

Using angular-sortable table directive is an easy way to add sorting to you table.

For more documentation check out the Github page.

Example code:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Angular sortable table example</title>
		<link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css">
		<script src="bower_components/angular/angular.js"></script>
		<script src="bower_components/angular-sortable-table/angular-sortable-table.js"></script>
		<style>
			th.sortable { cursor: pointer; }
			th.sortable:after { content: "\f0dc"; padding-left: 5px; font-family: FontAwesome; font-size: 12px; }
			th.sortable.asc:after { content: "\f0de"; }
			th.sortable.desc:after { content: "\f0dd"; }
		</style>
		<script>
			angular.module('angular-sortable-table-example', [ 'shagstrom.angular-sortable-table' ])
				.controller('MainCtrl', function ($scope) {
					$scope.countryMappings = {
						"GH": "Ghana",
						"GQ": "Equatorial Guinea",
						"GR": "Greece"
					};
					$scope.people = [
						{ name: "John", age: 34, countryCode: "GQ" },
						{ name: "Sahra", age: 36, countryCode: "GH" },
						{ name: "Desmond", age: 19, countryCode: "GR" },
						{ name: "Carole", age: 25, countryCode: "GH" },
						{ name: "Annie", age: 25, countryCode: "GQ" }
					];
				});
		</script>
	</head>
	<body ng-app="angular-sortable-table-example" ng-controller="MainCtrl">
		<h1>Angular sortable table example</h1>
		<table sortable-table="personSortObject" sortable-table-options="{ multipleColumns: true }">
			<thead>
				<tr>
					<th sortable-column="name">Name</th>
					<th sortable-column="age">Age</th>
					<th sortable-column="countryCode:countryMappings[value]">Country</th>
				</tr>
			</thead>
			<tbody>
				<tr ng-repeat="person in people | sortTable: personSortObject">
					<td>{{person.name}}</td>
					<td>{{person.age}}</td>
					<td>{{countryMappings[person.countryCode]}}</td>
				</tr>
			</tbody>
		</table>
	</body>
</html>

angular-split-pane v1.3.0 released

angular-split-pane v1.3.0 has been released released.

New in this version:

  • npm package added
  • Feature to get and set component sizes

Check out original post and Github repo for more information.

Example

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
		<title>Set component size</title>
		<link rel="stylesheet" href="../bower_components/split-pane/split-pane.css" />
		<script src="../bower_components/jquery/dist/jquery.min.js"></script>
		<script src="../bower_components/angular/angular.js"></script>
		<script src="../bower_components/split-pane/split-pane.js"></script>
		<script src="../angular-split-pane.js"></script>
		<style type="text/css">
			html, body { height: 100%; min-height: 100%; margin: 0; padding: 0; }
			/* The styling bolow is very simple. You can style things your own way. */
			body { box-sizing: border-box; background: #aaa; padding: 5px; }
			.split-pane-divider { background: #aaa; }
			.split-pane-component { background: #fff; }
		</style>
	</head>
	<body data-ng-app="example" ng-controller="MainCtrl">
		<div data-split-pane data-split-pane-properties="splitPaneProperties">
			<div data-split-pane-component data-width="20em">
				<p>Left</p>
				<p>
					<button data-ng-click="setLastComponent(0)">Collapse right component</button>
				</p>
				<p>Left component size {{splitPaneProperties.firstComponentSize}}px</p>
				<p>Right component size {{splitPaneProperties.lastComponentSize}}px</p>
			</div>
			<div data-split-pane-divider data-width="5px"></div>
			<div data-split-pane-component>
				<p>Right</p>
				<p>
					<button data-ng-click="setFirstComponent(0)">Collapse left component</button>
				</p>
				<p>Left component size {{splitPaneProperties.firstComponentSize}}px</p>
				<p>Right component size {{splitPaneProperties.lastComponentSize}}px</p>
			</div>
		</div>
		<script>
			angular.module('example', ['shagstrom.angular-split-pane'])
			.controller('MainCtrl', function ($scope) {
				$scope.splitPaneProperties = {};
				$scope.setFirstComponent = function (value) {
					$scope.splitPaneProperties.firstComponentSize = value;
				};
				$scope.setLastComponent = function (value) {
					$scope.splitPaneProperties.lastComponentSize = value;
				};
			});
		</script>
	</body>
</html>

AngularJS Split Pane directive version 1.0.0

Version 1.0.0 of the angular-split-pane directive now supports IE 8.

A bug with extra left margin appearing in fixed-top split-pane has also been fixed.

Remember to use attributes when setting up directives in IE 8!

Here is a complete example:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<title>Fixed left</title>
		<link rel="stylesheet" href="../bower_components/split-pane/split-pane.css" />
		<script src="../bower_components/jquery/dist/jquery.min.js"></script>
		<script src="../bower_components/angular/angular.js"></script>
		<script src="../bower_components/split-pane/split-pane.js"></script>
		<script src="../angular-split-pane.js"></script>
		<style type="text/css">
			html, body {
				height: 100%;
				min-height: 100%;
				margin: 0;
				padding: 0;
			}
			/* The styling bolow is very simple. You can style things your own way. */
			body {
				box-sizing: border-box;
				background: #aaa;
				padding: 5px;
			}
			.split-pane-divider {
				background: #aaa;
			}
			.split-pane-component {
				background: #fff;
			}
		</style>
	</head>
	<body data-ng-app="example">
		<div data-split-pane>
			<div data-split-pane-component data-width="20em">left</div>
			<div data-split-pane-divider data-width="5px"></div>
			<div data-split-pane-component>right</div>
		</div>
		<script>
			angular.module('example', ['shagstrom.angular-split-pane']);
		</script>
	</body>
</html>

AnglarJS Split Pane directive

I have created a AngularJS Split Pane directive. It’s built on top of the popular jQuery Split Pane plugin.

Try resizing the browser and dragging the dividers.

It’s a bit simpler to set up than the jQuery plugin, so I hope you all enjoy it!

Simply install with bower:

bower install angular-split-pane

The easiest way to get started is to study the examples folder at github.

Here are some examples:

Here is a complete example:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Basic Example</title>
        <link rel="stylesheet" href="bower_components/split-pane/split-pane.css" />
        <script src="bower_components/jquery/dist/jquery.min.js"></script>
        <script src="bower_components/angular/angular.js"></script>
        <script src="bower_components/split-pane/split-pane.js"></script>
        <script src="bower_components/angular-split-pane/angular-split-pane.js"></script>
        <style type="text/css">
            html, body {
                /* The split-pane needs a container with width and height. */
                height: 100%;
                min-height: 100%;
                margin: 0;
                padding: 0;
            }
            /* The styling below is very simple. You can style things your own way. */
            body {
                box-sizing: border-box;
                background: #aaa;
                padding: 5px;
            }
            .split-pane-divider {
                background: #aaa;
            }
            .split-pane-component {
                background: #fff;
            }
        </style>
    </head>
    <body ng-app="example">
        <split-pane>
            <split-pane-component width="20em">
                This is the left component
            </split-pane-component>
            <split-pane-divider width="5px"></split-pane-divider>
            <split-pane-component>
                This is the right component
            </split-pane-component>
        </split-pane>
    </body>
    <script>
        angular.module('example', ['shagstrom.angular-split-pane']);
    </script>
</html>

UTF-8, JSP and Spring MVC

If you are using UTF-8 with your Spring web app, then I would suggest using the following configurations.

In web.xml add:

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <page-encoding>UTF-8</page-encoding>
    </jsp-property-group>
</jsp-config>

(so that you don’t have to add <%@ page pageEncoding="utf-8" %> to every jsp file) and

<filter>
    <!-- This filter has to come before other filters. -->
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

And if you are using ResourceBundleMessageSource you need to set defaultEncoding in you Spring Servlet config:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="messages" />
    <property name="defaultEncoding" value="UTF-8" />
</bean>

Note that if you are not using JDK 1.6 or above you have to use ReloadableResourceBundleMessageSource instead of ResourceBundleMessageSource to be able to set defaultEncoding.

Now, if you remember to save all files using UTF-8, you should be fine.

box-sizing: border-box and IE7

Internet Explorer 7 doesn’t support box-sizing: border-box. You can, however, achieve the same thing with nested divs.

Replace

<div class="border-box">

    ... content ...

</div>
.border-box {
    box-sizing: border-box;
    width: 50%;
    font-size: 50%;
    margin-bottom: 0.5em;
    background: green;
    padding: 5em;
    border: 5px solid red;
    overflow: hidden;
}

with

<div class="border-boxish">
    <div class="border-boxish-inner">

        ... content ...

    </div>
</div>
.border-boxish {
    width: 50%;
    font-size: 50%;
    margin-bottom: 0.5em;
    background: green;
}

.border-boxish-inner {
    padding: 5em;
    border: 5px solid red;
    overflow: hidden;
}

You don’t need to use all css-rules from the example. I just included them to show what goes where.

Gradle Selenium (WebDriver) task

If you want to run your Selenium (WebDriver) tests from Gradle you can do it like this:

1. Add Jetty plugin to build.gradle:

apply plugin: 'jetty'

2. Create a src/selenium/java folder in you project root.

3. Add a SourceSet to build.gradle:

sourceSets {
    selenium
}

4. Add Selenium dependencies to build.gradle:

seleniumCompile 'junit:junit:4.11'
seleniumCompile 'org.seleniumhq.selenium:selenium-java:2.30.0'

Add jettyDaemon and selenium tasks to build.gradle:

task jettyDaemon(type: org.gradle.api.plugins.jetty.JettyRun) {
    daemon = true
}

task selenium(type: Test, dependsOn: jettyDaemon) {
    testClassesDir = sourceSets.selenium.output.classesDir
    classpath = sourceSets.selenium.runtimeClasspath
}

5. If you are using Eclipse, add Selenium dependencies to the Eclipse classpath in build.gradle:

eclipse {
    classpath {
        plusConfigurations += configurations.seleniumCompile
    }
}

You can now place you Selenium tests in src/selenium/java and run:

gradle clean selenium

JavaFX and Groovy Exception

You might have tried out the JavaFX Hello World example, from Oracle’s Getting Started with JavaFX guide, using Groovy.

You will then get the following exception:


Exception in thread "main" java.lang.RuntimeException: Error: class sun.reflect.NativeMethodAccessorImpl is not a subclass of javafx.application.Application

In order to fix this, change

launch(args);

to

launch(HelloWorld.class, args);

The example now runs fine with Groovy.

SQL and alpha-numeric sort order

Say you have this data set:

my_table
some_column
abc1
abc2
abc10
def1abc1
def2abc1
def10abc1
def10abc2
def10abc10

If you now do:

SELECT * FROM my_table ORDER BY some_column

you will get the following result:

some_column
abc1
abc10
abc2
def10abc1
def10abc10
def10abc2
def1abc1
def2abc1

which might not be what you want.

Now, if you create the following funtion:

CREATE FUNCTION pad_numbers(text) RETURNS text AS $$
  SELECT regexp_replace(regexp_replace(regexp_replace(regexp_replace($1,
    E'(^|\\D)(\\d{1,3}($|\\D))', E'\\1000\\2', 'g'),
      E'(^|\\D)(\\d{4,6}($|\\D))', E'\\1000\\2', 'g'),
        E'(^|\\D)(\\d{7}($|\\D))', E'\\100\\2', 'g'),
          E'(^|\\D)(\\d{8}($|\\D))', E'\\10\\2', 'g');
$$ LANGUAGE SQL;

you can use this query:

SELECT * FROM my_table ORDER BY pad_numbers(some_column)

with this result:

some_column
abc1
abc2
abc10
def1abc1
def2abc1
def10abc1
def10abc2
def10abc10

Now you got your data sorted alpha-numerically.

Note: I have used PostgreSQL 9.0.

Split Pane jQuery plugin

I have created a jQuery plugin for adding split panes to you web site or web application.

Split panes can be nested. Component min-widths and min-heights are supported. I have not implemented support for max-width and max-height, yet.

Component size can be set programmatically.

I’ve tested the code in the latest versions of Chrome, Firefox and Safari on OS X, and in IE8 on XP.

The source code can be found at github.

Please give me you feed back!

Check out the following pages for examples on how to use it:

N.B., not all markup in the examples are needed for setting up the split panes. <div class="pretty-split-pane-frame"> and <div class="pretty-split-pane-component-inner"> are used for styling purposes only. Feel free to use them, but you might want to style things your own way.