November 2017

css

Introduction

CSS allows you to apply styles to elements when their state changes, when the documents changes or when certains patterns are found in the document. We call them pseudo-classes. They are always preceded by a colon (:). They always refer to the element they are attached to, not their descendants. This is an important point to remember moving forward.

Most of the pseudo-classes are structural. They work with the structure of your markup. I want to target the third paragraph, the first link, the last list item …

Continue reading CSS 101: Structural pseudo-classes

Read more

css

Introduction

CSS ( Cascading Style Sheets ) is a language that allows you to describe the styles your markup should have. For a long time, I took CSS for a very simple thing that turns your text to a certain color, adds a little border here, maybe a cute animation here.

Then, I started to meet developers who were really good at CSS, and well, it’s a lot more than that… So, I’m spending some time becoming better at it, and we start with the basics.

Selectors

We could style our markup by adding a style attribute to each element:

<p style="color:red;">Paragraph</p>
<span style="color: red; font-size=14px;">Span element</span>

I let you imagine how many different rules you would have to write this way… let alone apply any kind of changes…

In CSS, we can use differents selectors. They allow us to group different elements and apply the same style rules to this group. We will explore:

  • Element selectors
  • Class and ID selectors
  • Attribute selectors

Element selectors

For markup, I will use HTML throughout this article. We can group our styles by elements. Give each *

* element a certain style for example.

The h1 and p tags are grouped and share the same rules. Instead of creating three different rules to style the paragraphs and two rules for my headers, I only make one for each.

You can also group different elements together by separating them with commas in CSS:

Do not forget the commas in this case! If you do, it won’t group the elements, but select the descendents elements.

Class and ID selectors

Classes

To allow more flexibility while selecting your elements, you can specify one or more classes to an element. Each class is space-separated. We use the class attribute.

<p class="danger"></p>
<h1 class="danger title"></h1>

In CSS, you use a period ( . ) to indicate that you are targetting a specific class name. You can chain several classes one after another.

.danger {
 /* Will style the paragraph */
}

.danger.title{
 /* Will style the h1*/
}

Note that the order is not important. If you specify .title.danger, the effect will be the same. It also doesn’t need to be an exact match. If you add a third class to your header, it will still follow the rules in the .danger.title block.

ID

ID are very similar to classes. The main differences are that an ID can only be used for one element. An element can only have one ID, because ID can’t have space-separated values. ID have more weight than classes. If you have an element with an ID and a class that change the same thing ( the color for example ), the style describe in the ID rules. Finally, ID are targetted by a pound sign ( # ) in a CSS declaration.

Attribute selectors

Class and ID are special attributes that CSS is able to handle in a special way. But in our markup, there are a LOT more attributes we can use. CSS allows us to target those in different ways to suit your needs

  • Simple attribute selector

You write CSS rules to check if an element has a special attribute specified. We don’t even care about the value. For example, I want to target all p element who have a key attribute:

p[key] {
  color: red;
}

/* OR, all elements with a key attribute, not just p */
[key]{
  color: red;
}

As you can see, we use [] in CSS to target attributes. So this is the first one, very general.

  • Exact attribute values

This time, we are looking for the exact attribute value.

  /* If the href is https://google.com, it won't match */
  a[href="google.com"] {
    color: purple;
  }

  /* The following are NOT equal */
  [class="danger warning"] {
    color: red;
  }

  .danger.warning {
    color: orange;
  }

Again, we are looking for an exact match. So, if we use the bracket notation, the element needs to have the classes danger and warning, in this order AND only those two. Quite different from the dot notation…

  • Partial attribute values

Finally, if you really want to have great control over the attributes you are using, you’ll need to use the following attribute selectors.

[attribute~="val"]{
  /* Attribute contains val in a space-separated list of words */
  /* Would match "friend" in "my friend Joe" */
}

[attribute*="val"] {
  /* Select any element with an attribute whose value CONTAINS val */
}

[attribute^="val"] {
  /* Select any element with an attribute whose value BEGINS with val */
}

[attribute$="val"] {
  /* Select any element with an attribute whose value ENDS with val*/
}

[attribute|="val"]{
  /* 
  Select any element with an attribute whose value starts with val followed by a dash (val-) 
  OR whose value is exactly equal to val.
  */
}

[attribute="val"i] {
  /* Add a i after the value to make it case insensitive ( The value will be case insensitive, NOT the attribute name. */
}

Examples:

Conclusion

There you have it. A quick overview of the different ways you can select elements with CSS. There are of course a lot of different things possible with these tools. But it should give you enough to play around.

Read more

Introduction

In the last few weeks, I was very intrigued by React native. I kept seeing more and more articles like this one, so I decided to take a deeper dive into React Native and actually use it, for real.

Meteor is the framework I use at work, and I now have some experience with it. I thought about connecting the React Native application with a Meteor back-end. This article will show you how to get things started.

Creating the Meteor app

First things first, we will create a Meteor application.

meteor create serverMeteor

For now, that is all we need. We’ll come back to that.

Creating our React Native app

I’ll use the very useful create-react-native-app tool. You can get more info on this, check this link. It will also explain how to use the Expo client app to see your work, very useful!

So, we run a command like this:

create-react-native-app reactFront

Now, you’ll have two folders. One named meteorServer that contains your Meteor application, and an other named reactFront where you will find your react-native application.

React-Native: Creating a simple PhoneBook

For the sake of brevity, we will create something simple. The user will have a form with two inputs. The first will take a name, the second a phone number.

After modifications, here is how App.js looks like:

import React from 'react';
import { StyleSheet, Text, View, TextInput, Button } from 'react-native';

export default class App extends React.Component {
  constructor(){
    super()
    this.state = {
      name: '',
      number: ''
    }
  }

  addPhoneNumber = () => {
    console.log(this.state)
    this.setState({
      number: '',
      name: ''
    })
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          style={styles.input}
          placeholder='Enter a name'
          onChangeText={name => this.setState( {name} )}
          value={this.state.name}/>
        <TextInput
          style={styles.input}
          keyboardType='numeric'
          placeholder='Enter a phone number'
          onChangeText={number => this.setState( {number} )}
          value={this.state.number}/>

        <Button
          onPress={this.addPhoneNumber}
          title='Save Phone Number'/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    marginTop: 20
  },
  input: {
    borderWidth: 2,
    borderColor: 'gray',
    height: 50,
    margin: 10
  }
});

I added two TextInput elements and a Button element. I also added some styles for the input. In React Native, we use StyleSheet.create({}) to control styles. Or you could style use the inline objects as in React.

On my iOS simulator it looks like this:

Ok, for now, when we click ( or tap ) on the button. Nothing happens. It logs the values in the console and reset them. Let’s move on to the back-end.

Meteor: Preparing the method and publication

Go to the folder where your Meteor application is located. Mine was called serverMeteor.

Let’s create a /imports folder, and inside this /imports, we’ll add an /api folder. Just to follow the proper Meteor conventions.

Here is the plan: we will create a Meteor method that our React Native app will call when we click on the Save Phone Number button. This method will save the name and the number to the Meteor mongo database.

Then, we will create a publication that our React Native application will subscribe to. It will simply return all the entries we have. Let’s go!

In /imports/api/, let’s create a PhoneNumbers.js file that will hold our small back-end logic.

export const PhoneNumbers = new Mongo.Collection( 'phoneNumbers' )

Meteor.methods({
  addPhoneNumber( data ){
    PhoneNumbers.insert({
      name: data.name,
      number: data.number
    }, err => {
      if (err){
        return err
      } else {
        return null
      }
    })
  }
})

Meteor.publish( 'getAllNumbers', () => {
  return PhoneNumbers.find({})
})

Nothing fancy here. We create our collection, our method addPhoneNumber and our publication getAllNumbers. And that’s it for Meteor. Let’s make the two applications talk to one another.

React Native: Adding react-native-meteor

Go back to the React Native folder. We will use the react-native-meteor package to connect both applications.

npm install --save react-native-meteor

Here are the changes we need to make:

  • Call the addPhoneNumber method when we click our button.
  • Subscribe to our getAllNumbers publication
  • Display the numbers in a list
  • Make sure our React Native app is aware of our Meteor application.

Let’s start with the method call. If you’ve work with Meteor/React before, this will look very familiar:

// In our App component
addPhoneNumber = () => {
    const data = {
      number: this.state.number,
      name: this.state.name
    }

    Meteor.call('addPhoneNumber', data, err => {
      if( err ){
        console.log( err )
      } else {
        this.setState({
          number: '',
          name: ''
        })
      }
    })
  }

Next, let’s subscribe to our publication. For this, we will wrap our App component in createContainer provided by react-native-meteor. Let’s import it at the top of our file:

import Meteor, { createContainer } from 'react-native-meteor'

Good, now we will NOT export our App component, but the createContainer wrapper. Like so:

// The App Component will be defined above like so:
// class App extends React.Component{ ... } 

export default createContainer( () => {
  Meteor.subscribe('getAllNumbers')
  return {
    phoneNumbers: Meteor.collection('phoneNumbers').find({})
  }
}, App) // Need to specify which component we are wrapping

Ok, that’s done. So we will get the phone numbers in a nice array. We will display them in a list. Nothing fancy, we will use the FlatList component. Don’t forget to import FlatList from react-native. Our render function will look like so:

// Still in the App component my friend
  render() {
    return (
      <View style={styles.container}>
        <TextInput
          style={styles.input}
          placeholder='Enter a name'
          onChangeText={name => this.setState( {name} )}
          value={this.state.name}/>
        <TextInput
          style={styles.input}
          keyboardType='numeric'
          placeholder='Enter a phone number'
          onChangeText={number => this.setState( {number} )}
          value={this.state.number}/>

        <Button
          onPress={this.addPhoneNumber}
          title='Save Phone Number'/>

        <FlatList
          data={this.props.phoneNumbers}
          keyExtractor={(item, index) => item._id}
          renderItem={({item}) => (
            <View>
              <Text>{item.name} || {item.number}</Text>
            </View>
          )} />
      </View>
    );
  }

FlatList takes the array of data and loops through it in the renderItem function. I’m just displaying the name and the phone number. keyExtractor is used to create keys for each element we render in this list, just like React needs in the web. Each key will be the ObjectID returned from MongoDB.

Finally, let’s make sure our React Native application knows where to get those informations:

//I have only one component anyway...
  componentWillMount(){
    Meteor.connect('ws://localhost:3000/websocket')
  }

We use the connect method from react-native-meteor.

Note: Because I am only using the iOS simulator here, I can use localhost. If you use the android simulator, you will need to use the IP address of your machine ( 192.168.xx.xx:3000/websocket for example).

Clicking on the Save Phone Number button will populate the database in our Meteor application. Our subscription to the publication will retrieve the informations and display them!

Just a final picture to show you how it looks on my iOS simulator:

Well, there you have it. You can now connect a React Native application to a Meteor application without a problem. Have fun!

Warning: It seems that using npm5 with create-react-native-app is buggy and doesn’t work properly. You should probably use npm4 or yarn to make sure you don’t encounter any problems for now.

Read more