Tag Archives: CSS

React component with Media queries for Responsive

This is a very simple approach using matchMedia support. We store media queries and a listener function as an object in an array. When the media query returns true the listener function will set the relevant component state true.

In our actual project, this approach is used with Redux. The queries instead of setting component state, update the Store. Containers connected to this store send the breakPoint, orientation, and other props to each child component.

Just an experiment. If pursued further, would probably make it a HOC (Higher Order Component).

Gist available here.

Demo
If packed and loaded into a web page as we resize the browser we should see:

Change size of browser to test

state: { 
    "orientation": "landscape", 
    "breakPoint": "LG" 
}

Why?
While CSS media queries are very useful, sometimes being able to respond ‘behaviorally’ to media events is very powerful.

Tested on
Chrome, FireFox, IE, and Edge. I guess they all have JavaScript MediaQuery support.

How it works

In the life cycle method ‘componentDidMount’ we add a query to an array in the component:

this.mediaQueryFactory(obj, '(orientation: portrait)', this.onPortrait);

this.mediaQueryLists.push({
	mql: obj.mql,
	listener: this.onPortrait
});

the onPortrait is the listener function:

onPortrait : function(flag){
  if(flag){
	this.setState({orientation: 'portrait'});
  }
},

Full Code

Other MediaQuery React implementations

Addendum

{
  "name": "ReactMediaQuery",
  "version": "1.0.0",
  "description": "Attempt at using Media Queries in React",
  "main": "./index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack index.js dist/react-media-query-bundle.js"
  },
  "keywords": [
    "react"
  ],
  "author": "JosefBetancourt",
  "license": "SEE LICENSE IN COPYWRITE.TXT",
  "dependencies": {
    "babel-polyfill": "^6.9.1",
    "classnames": "^2.2.5",
    "react": "^15.3.0",
    "react-dom": "^15.3.0"
  },
  "devDependencies": {
    "babel-core": "^6.10.4",
    "babel-loader": "^6.2.4",
    "babel-plugin-add-module-exports": "^0.2.1",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-es2016": "^6.11.3",
    "babel-preset-react": "^6.3.13",
    "babel-preset-stage-2": "^6.11.0",
    "eslint": "^3.2.2",
    "webpack": "^1.13.1"
  }
}

package.json

var path = require('path');
const webpack = require('webpack');

module.exports = {
  /* entry point */
  entry: './index.js',
  /* output folder */
  output: {
    filename: 'dist/react-media-query-bundle.js'
  },
  devtool: 'source-map',
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ['es2015', 'react', 'stage-2']
        }
      },
    ]
  },
  eslint: {
    configFile: path.join(__dirname, 'eslint.js'),
    useEslintrc: false
  },  
  plugins: [
  ],
  resolve: {
    extensions: ['', '.js', '.json'] 
  },
  resolveLoader: {
      modulesDirectories: [
          'node_modules'
      ]
  }
};

webpack.config.js

<!DOCTYPE html>
<html>
  <head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">  
  	<title>React Media Queries</title>
  </head>
  <body class="body">
    <div id="root" class="">Loading page, please wait ....</div>
	<script src="dist/react-media-query-bundle.js"></script>
  </body>
</html>

index.html

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Nested CSS Grid Hello World!

CSS based grids are a powerful approach to creating HTML web interfaces. There are now hundreds of CSS Frameworks that support Grid layouts.

I’ve used the 1KB grid system before, but have yet to really understand how to use grid systems well. Recently I was taking another look at this topic. One thing is very obvious, the documentation and examples of many of these are not very good. What if there were an example that all framework would implement that would showcase their use? In programming we usually would do a “Hello World!” program and extend that to say the same thing using the technologies in question, like JMS, for example.

So a solution would have to exercise the core feature set or solution set of a generic grid, and be easy to implement. One should not have to be a high-order expert in CSS to understand the solution. Below I created a simple ‘Hello world!’ that shows nested columns in use. Of course, it would need expansion to show more features and difficulties in using a CSS Grid. It would also need a real designer to create something that also looks good.

Example of nested columns using BluCSS. I just took the demo page as an example and changed it to do what I wanted. The BluCSS stylesheet includes media queries to help toward a “responsive” design. Note that I changed the “container” to 100% width. Why have large monitors if pages won’t use the space?

Screen capture of my example rendered in FireFox’s Responsive Design View. In this tool a 1200 x 800 viewport correctly allows rotate, however, on a real smartphone, Samsung Note, the vertical view is stacked. Hmm.

screen capture snippet

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; 
		charset=ISO-8859-1">
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">	
	<meta name="viewport" content="width=device-width, initial-scale=1.0">	
	<title>BluCSS - Nested Grid Demo</title>
	<!-- Author: Josef Betancourt; Date: 20121221T1840	 -->
	<link rel="stylesheet" href="css/blucss.css">
	<link rel="stylesheet" href="css/myStyle.css">
	<script 
		src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
	</script>
	<script 
		src="js/ndhw.js">
	</script>
	<script>
		$(document).ready(function(){  	});		  
	</script>		
</head>
<body style="margin:1em;">
  <div class="container">
	<div class="blu_8">
	
		<!-- ########################## -->	
		<div class="blu_10 header">
			<h2 class="">CSS Grid Hello World!</h2>
		</div>		
		<!-- ########################## -->	
	
		<!-- ########################## -->	
		<div class="blu_1 test">a</div><div class="blu_1 test">b</div>
		<div class="blu_1 test">c</div><div class="blu_1 test">d</div>
		<div class="blu_1 test">e</div><div class="blu_1 test">f</div>
		<div class="blu_1 test">g</div><div class="blu_1 test">h</div>
		<div class="blu_1 test">i</div><div class="blu_1 test">j</div>
		<!-- ########################## -->	
	
		<!-- ########################## -->	
		<div class="blu_1 test">k</div>	
		<div class="blu_1 test">l</div>
		<div class="blu_5 test ">
			<div class="blu_10 box">5</div>
			<div class="blu_10">nested columns</div>
			<div class="blu_2 color1">2</div>
			<div class="blu_3 color1">3</div>
			<div class="blu_3 color1">3</div>
			<div class="blu_2 color1">2</div>			
		</div>	
		<div class="blu_1 test">m</div>
		<div class="blu_1 test">n</div>
		<div class="blu_1 test">o</div>
		<!-- ########################## -->
		<div class="clear">
			<div class="blu_1 test">1</div><div class="blu_1 test">2</div>
			<div class="blu_1 test">3</div><div class="blu_1 test">4</div>
			<div class="blu_1 test">5</div><div class="blu_1 test">6</div>
			<div class="blu_1 test">7</div><div class="blu_1 test">8</div>
			<div class="blu_1 test">9</div><div class="blu_1 test">10</div>
		</div>	
		
		<div class="blu_10">
			<a id="showBT" href="#" class="buttonCls" onclick="getSource()">source</a>
			<a id="hideBT" href="#" class="buttonCls" style="display:none;">hide</a>		
		</div>
		<div class="blu_10 color2">
			<pre class="box" id="theSrc" style="display:none;"></pre>		
		</div>		
	</div>
	
	<div class="blu_2 omega color2">	
		<div id="rs">rs</div>
	</div>	
			
	<!-- ########################## -->	
	<div class="blu_8 test color2">8</div>
	<!-- ########################## -->
	<div class="blu_1 test color2">1</div>	
	<div class="blu_1 test color2">1</div>
	
	<div class="blu_8">&nbsp;</div>	
	<div class="blu_2" style="font-size:.5em;">
			20121221T1840, J.Betancourt	
  	</div>	
	<!-- ########################## -->	
  	
 </div>
</html>

Summary
Created an example ‘hello world’ CSS Grid use. The example also includes the use of AJAX with JQuery to show the HTML source. Not part of the topic but was an interesting thing to get to work. I wonder if that technique can be used to show other things like log files.

Question: Since CSS Grids rely on horizontal flow, how are they a grid? Maybe they should be called CSS sliding rows that sometimes align into columns. ūüôā

Related reading

  • CSSButtonGenerator
  • Responsive Design View
  • Responsive web design
  • Grids CSS, as bad as HTML markup abuse, or worse
  • BluCSS
  • The 1KB CSS Grid, http://www.1kbgrid.com/
  • The Semantic Grid System
  • My (current) take on CSS Preprocessors
  • 45+ CSS Grid Layout Generators
  • ” Which Is Right for Me? 22 Responsive CSS Frameworks and Boilerplates Explained “, http://designshack.net/articles/css/which-is-right-for-me-22-responsive-css-frameworks-and-boilerplates-explained/
  • ” Which CSS Grid Framework Should You Use for Web Design?”, http://net.tutsplus.com/tutorials/html-css-techniques/which-css-grid-framework-should-you-use-for-web-design/
  • “Grid System Generator”, gridsystemgenerator.com
  • “Designing With Grid-Based Approach”, http://www.smashingmagazine.com/2007/04/14/designing-with-grid-based-approach/
  • The Ultimate Collection of 50+ Resources for Grid Lovers, http://designshack.net/articles/layouts/the-ultimate-collection-of-50-resources-for-grid-lovers/
  • “Grids Are Good (Right?)”, M. Boulton, Khoi Vinh. http://www.subtraction.com/pics/0703/grids_are_good.pdf
  • “Rethinking CSS Grids”, http://www.markboulton.co.uk/journal/rethinking-css-grids
  • ” Rolling Your Own Grid Layouts on the Fly Without a Framework”, http://designshack.net/articles/css/rolling-your-own-grid-layouts-on-the-fly-without-a-framework/
  • “Design By Grid”, http://www.designbygrid.com/
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Cascading Configuration Pattern

Synopsis

Many existing systems load configuration in cascade to reduce the use of duplicate properties and allow fine grained customization. This post expresses this common usage into a design pattern.

Keywords:   SCM, CM, Properties, Groovy, Config, CSS

Content:  Context, Forces, Solution, Consequences, Implementation, Code Example, Related Patterns, Related Intellectual Property, Further Reading

Context

A business system uses property (configuration) files to configure particular environments or subsystems.   Many environments share the same properties and values, however, some are different and crucial.  To avoid missing any properties, all the properties are duplicated in each file, and required differences are changed appropriately. 

For example, if there are 100 properties required and there are 23 possible environments, that is 2300 lines of source to manage.¬† If there are any duplicated properties that do not vary between environments, then there is an opportunity to simplify the configuration system.¬† In this case, if we make only a “root” file have the full set of properties,¬† the total size is given by:¬†

T = L+npL; 
where 
    T is total size, 
    n is number of files, 
    p is percent of each file that is overridden.
    L is number of properties  

Here the value is 560=100+23*.2*100). The reduction over the duplicated data is 75%.

Forces

There are many issues with having the same properties in multiple locations.  One obvious disadvantage, is adding a new property would require changing multiple files.  Also the files are larger and not really cohesive.   Tracking errors is also complicated, especially run-time errors due to configuration settings.  Any solution should not add its own complexity.  Thus, we should not require new types of configuration files and requirements.

Even when configuration could be isolated or systems modularized, there may be a need to have duplicated properties or reassignment to satisfy software development life cycle (SDLC).  A system will be different in dev, test, and production environments.

Solution

A hierarchy of property sources and a system that can load each source and override properties at a prior level will provide a partial solution.  This is the approach already taken in many systems.  For example, in software applications and servers, the final properties used are composed of those taken from various standard locations in a particular Operating System host.  In Windows for example, the Environment Variables are composed of those found in System and User name space.  In software tools, such as Mercurial DVCS, there is a command to show the results of the final configuration after all configuration sources are loaded: showconfig   show combined config settings from all hgrc files. In Git, one executes: git config -l.

Many build systems such as Ant and Maven, allow and expect the cascading of property files.  Note that in Ant, the inverse policy is used, the first property assignment wins.

And, of course, this cascading is seen in the Cascading Style Sheet (CSS) technology.

Consequences

There is now the requirement that the cascade order is well known, non-variable, and robust.  Any intervening file must be loaded, else the system may destabilize.  Adding a new property or changing a property will require extra care since an environment or subsystem may be effected if the file contents are not properly designed beforehand.

To provide management and debugging support the implementation should provide traceability of configuration.  Thus, during use, the system must report (log) what was overridden, not changed, what is missing, etc.

Implementation

Using this pattern is very easy.  One just has to determine how the system handles reassignment in the configuration loader subsystem.  If it allows resetting then the file hierarchy is from global to specific.

Where complexity may come is when one wants to satisfy more sophisticated requirements.  For example, a property may need to be appended.  In OS paths, for instance, paths are combined to create the final path.  Thus, the operations on properties could be a combination of:

  • create: initial assignment of a property
  • update:¬† a new value is assigned
  • delete:¬† the property is removed
  • append: append to existing value
  • merge:¬† use a pattern to merge a new value
  • locked: allow no change
  • fail on replace:¬† if a value already assigned throw an exception.

Code Example

In Java the java.util.Properties class will overwrite an existing property with the same key value.¬† Thus, to cascade properties, one just reuses the same instantiated Properties Object via the various load(…) methods.

Note that in some frameworks, like Ant, the reverse is true, properties do not get overwritten. So, the “root” properties must be loaded last in a cascade sequence.

Shown in listing one is a simple implementation written in Groovy, a dynamic language on the JVM.¬† The PropCascade class extends Properties and adds methods to load a list of sources.¬† The first source in the list is the root of the “cascade”.¬† In addition, a few methods explicitly specify the root source. From a traceability point of view, reusing java.util.Properties class may not be optimal. It gives no access to low level capture of the actual “put” action. Even with the use of Aspect Oriented Programming, with for example the AspectJ language, there is no joinpoint available to add it.

listing 1

/**
 * File: CascadedProperties.groovy
 * Date: 23OCT10T18:13-05
 * Author: JBetancourt
 */

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

/**
 * An extension of Properties that adds Convenience
 * methods to load lists of sources.
 *
 * @author jbetancourt
 */
class CascadedProperties extends Properties {
	//private Properties rootProperties = new Properties();
	//private boolean firstWins = true;
	//private boolean failOnDuplicate = false;
	//private boolean isTrace = false;

	/**
	 * Load a list of properties sources.
	 * @param list
	 */
	public void load(List list) throws IOException, IllegalArgumentException {
		list.each {
			load(it)
		}
	}

	/**
	 * Explicit file path is specified.
	 * @param path
	 */
	public void load(String path) throws IOException, IllegalArgumentException {
		load(new File(path).newInputStream());
	}

	/**
	 * A load method that explicitly specifies the &quot;default&quot; source in
	 * the cascade order.
	 *
	 * @param inStream
	 * @param list
	 */
	public void load(InputStream inStream, List list) throws IOException, IllegalArgumentException {
		load inStream
		load list
	}

	/**
	 * A load method that explicitly specifies the &quot;default&quot; source in
	 * the cascade order.
	 *
	 * @param reader
	 * @param list
	 */
	public void load(Reader reader, List list) throws IOException, IllegalArgumentException {
		load reader
		load list
	}

	/**
	 * A load method that explicitly specifies the &quot;default&quot; source in
	 * the cascade order.
	 *
	 * @param path
	 * @param list
	 */
	public void load(String path, List list) throws IOException, IllegalArgumentException {
		load path
		load list
	}

} // end of CascadedProperties

In listing two, the JUnit test class is shown.
listing 2

/**
 * File: CascadedPropertiesTest.groovy
 * Date: 23OCT10T18:13-05
 * Author: JBetancourt
 */

import java.io.File;
import java.io.FileInputStream;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import groovy.util.GroovyTestCase;

/**
 * Test the {@link CascadedProperties} class.
 */
class CascadedPropertiesTest extends GroovyTestCase{
	private CascadedProperties cp;

	/** excuted before each test method run */
	public void setUp() throws Exception {
		cp = new CascadedProperties();
	}

	public void testloadListPaths() throws Exception {
		List list = new ArrayList();
		list.add path1
		list.add path2

		cp.load(list);

		assertEquals("v2",cp.get("k1"));
	}

	public void testloadListReaders() throws Exception {
		List list = new ArrayList();
		list.add reader1
		list.add reader2

		cp.load(list);

		assertEquals("v2",cp.get("k1"));
	}

	public void testloadListStreams() throws Exception {
		List list = new ArrayList();
		list.add iStream1
		list.add iStream2

		cp.load(list);

		assertEquals("v2",cp.get("k1"));
	}

	public void testloadStreamAndListStreams() throws Exception {
		List list = new ArrayList();
		list.add iStream2
		list.add iStream3

		cp.load(iStream1,list);

		assertEquals("v3",cp.get("k1"));
	}

	public void testloadPathAndListStreams() throws Exception {
		List list = new ArrayList();
		list.add iStream2
		list.add iStream3

		cp.load("datafile1.properties",list);

		assertEquals("v3",cp.get("k1"));
	}

	public void testloadReaderAndListStreams() throws Exception {
		List list = new ArrayList();
		list.add reader2
		list.add reader3

		cp.load(reader1,list);

		assertEquals("v3",cp.get("k1"));
	}

	public void testPutAgain() {
		cp.put("k1", "v1")
		cp.put("k1", "v2")
		assertEquals(cp.get("k1"), "v2");
	}

	public void testLoadOneFilePath() throws Exception {
		cp.load("datafile1.properties");
		assertEquals("v1",cp.get("k1"));
	}

	public void testLoadTwoFiles() throws Exception {
		cp.load(iStream1)
		cp.load(iStream2)

		assertEquals("v2",cp.get("k1"));
	}

	//
	// class fields
	//
	String path1 = "datafile1.properties"
	String path2 = "datafile2.properties"
	String path3 = "datafile3.properties"
	File file1 = new File(path1)
	File file2 = new File(path2)
	File file3 = new File(path3)

	InputStream iStream1 = file1.newInputStream()
	InputStream iStream2 = file2.newInputStream()
	InputStream iStream3 = file3.newInputStream()
	Reader reader1 = file1.newReader()
	Reader reader2 = file2.newReader()
	Reader reader3 = file3.newReader()

}

Property Files Analysis

It is very difficult to eyeball a set of property files to see if there are many duplicates. I guess one could do some magic one line script that concatenates, sorts, prunes, etc. Here is an alternative using the Groovy language.
listing 3

/*
 * Script: AnalyizePropertyFiles.groovy
 * Author: J. Betancourt
 */
import java.util.Hashtable;
import java.util.Map.Entry;

/**
 * @author jbetancourt
 */
class AnalyizePropertyFiles {
	// these could have been created dynamically by reading the target folder.  But, that may pick up non-used files.
	static fileNames = []

	// where are the files?
	static basePath = ""

	// run analysis....
	static main(args) {
		def propList = [] // each property file will be load into a cell which contains a properties object.

		// put each file into properties object in propList.
		fileNames.each {
			def p = new Properties()
			p.load(new File(basePath + "" + it).newInputStream())
			propList.add(p)
		}

		// put all properties in one allProps object.
		Properties allProps = new Properties();
		propList.each {
			allProps.putAll(it)
		}// each propList
		
		def result = []
		
		int totalCount = 0
		
		// get how many times each property is used in all properties object
		allProps.each { prop ->
			String key = prop.key
			String value = prop.value
			def values = []
			int count = 0
			propList.each { p ->
				if(p.containsKey(key)){
					count++
					def curValue = p.get(key)
					if(!values.contains(curValue)){
						values.add(curValue)
					}								
				}
			} // each property file
				
			StringBuilder vb = new StringBuilder()
			values.each{ s ->
				vb.append("[" + s + "], ")
			}
			
			int numberValues = values.size()

			StringBuilder sb = new StringBuilder()			
			sb.append(count).append(",").append(values.size).append(", ").append(key).append(", ").append(vb.toString())
			result.add(sb.toString())	
			
			totalCount += count				
			
		} // each allProps property
		
		
		result.each{
			println(it)
		}
		
		println("Total number of times properties are repeated: " + totalCount)
		
	} // end main

} // end class

Related Patterns

Related Intellectual Property

Cascading configuration using one or more configuration trees“, U.S. Patent number 7760746, 30Nov2004, http://patft.uspto.gov/netacgi/nph-Parser?Sect2=PTO1&Sect2=HITOFF&p=1&u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&r=1&f=G&l=50&d=PALL&RefSrch=yes&Query=PN%2F7760746


Further Reading

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.