How can I implement dynamic styling for ion-list elements with AngularJS?


Tags: javascript,html,css,angularjs,ionic-framework

Problem :

I have an Ionic-framework app that has a list of messages. There are 4 types of messages, and depending on the type the message should be displayed on the list with a particular color in the left border.

The question is, how do I indicate the CSS color depending on the type of message?

The HTML looks like this:

<ion-content class="ionc">
  <ion-list class="list">
    <ion-item ng-repeat="mensaje in mensajes" class="listitem" ng-click="abrirMensaje($index)" 
    on-hold="mostrarMenu(mensaje, $index)">
      <h2><b>{{ mensaje.hid }}</b></h2>
      <h3>{{ mensaje.alert }}</h3>
      <p class="cont">{{ mensaje.mens }}</p>
      <p class="fecha">{{ mensaje.fecha }}</p>
  </ion-item>
</ion-list>

The CSS looks like this if I fix every message to have the same color (red):

.buzon-page .item-complex .item-content, .listitem {
  border: 4px;
  border-left-style: solid !important;
  border-left-color: red !important;
}

How can I change CSS coloring dynamically with AngularJS?

UPDATE

After modifying the code with the help of the first answer the color borders appear but they do not move with the items, that should as they have an ion-option-button applied to them.

This is the new HTML:

<ion-content class="ionc">
<ion-list class="list">
    <ion-item ng-repeat="mensaje in mensajes" 
    ng-class="mensaje.tipo == 'Promocion' ? 'clasePromocion': 
              mensaje.tipo == 'Aprobado'  ? 'claseAprobado' : 
              mensaje.tipo == 'Alerta'    ? 'claseAlerta'   : 
              mensaje.tipo == 'ATM'       ? 'claseATM'      : 'default'" 
    ng-click="abrirMensaje($index)" 
    on-hold="mostrarMenu(mensaje, $index)"
    item="item"
    class="item-remove-animate">

    <h2><b>{{ mensaje.hid }}</b></h2>
    <h3>{{ mensaje.alert }}</h3>
    <p class="cont">{{ mensaje.mens }}</p>
    <p class="fecha">{{ mensaje.fecha }}</p>

    <ion-option-button class="button-positive" ng-click="mostrarMenuComp($index)">
      Compartir
    </ion-option-button>
    <ion-option-button class="button-assertive" ng-click="mostrarMenuElim($index)">
      Eliminar
    </ion-option-button>

  </ion-item>
</ion-list>

And this is the new CSS:

.clasePromocion {
  border-left: solid 6px #0078ff !important; /* azul */
}

.claseAprobado {
  border-left: solid 6px #faaf40 !important; /* amarillo */
}

.claseAlerta {
  border-left: solid 6px #ee4036 !important; /* rojo */
}

.claseATM {
  border-left: solid 6px #00a551 !important; /* verde */  
}

.default {
  border-left: solid 6px white !important; /* blanco por defecto */
}

So, the issue now is how to make the color borders move with the list items? Here is a capture of the problem: http://i57.tinypic.com/2r71o5c.jpg



Solution :

If you have 4 types of messages, you can leverage ngClass to craft something similar to the following, where you'll map a class to the particular message you are interested in. In this case, I have a made up property called type, with values of A B C D and an extra E for demo purposes. Of course, this is a simplistic example - but the foundation here can be easily absorbed into your project specifics

<span  
    ng-repeat="msg in messages" 
    ng-class="msg.type == 'A' ? 'classA' : 
              msg.type == 'B' ? 'classB' : 
              msg.type == 'C' ? 'classC' : 
              msg.type == 'D' ? 'classD' : 'default'">{{ msg.text }}</span>

$scope.messages = [
    { 'type': 'A', 'text': 'message' },
    { 'type': 'B', 'text': 'message' },
    { 'type': 'C', 'text': 'message' },
    { 'type': 'D', 'text': 'message' },
    { 'type': 'E', 'text': 'message' } // -- will be .default
];

.classA { border-color: dodgerblue; }

.classB { border-color: tomato; }

.classC { border-color: limegreen; }

.classD { border-color: orange; }

.default { border-color: purple; }

JSFiddle Example


For a more complete example that targets ion-item elements directly, the suggestion above just needs slight CSS modification. Since you expressed you wish to have the border move with the ion-item, apply the style rule to the child <a> tag. Here is a possible solution

.classA a { border-left: solid 4px dodgerblue !important; }

.classB a { border-left: solid 4px tomato !important; }

.classC a { border-left: solid 4px limegreen !important; }

.classD a { border-left: solid 4px orange !important; }

.default a { border-left: solid 4px purple !important; }

CodePen link - working example with <ion-item> elements

Image Sample - target <a> tags to "move" with entry


Upon further investigation, In certain emulation environments, an <a> tag does not get rendered as a child element of <ion-item>. However, the immediate child element will have a class of .item-content e.g. <div class="item-content">. In this case, let's change our CSS to target this class instead of a specific child element.

.classA .item-content { border-left: solid 4px dodgerblue !important; }

    CSS Howto..

    How can I get text to be vertically-aligned to the bottom and fill the empty space above it as needed?

    How to use css method of rotation in jquery

    How do I show my existing rails app differently on Facebook canvas

    How can I make use of `::selection` for in chrome browsers?

    How to get different class selectors using nth-child in css

    how to select last-child or first-child elements just in parent? (css - html)

    how to stop css hover out with a conditional

    How to calculate the multiplication factor for scroll speed on another element so that they both reach end at the same time (top of view)

    How to have a hidable paragraph in an HTML email template

    How can i position a background image to the top left and bottom right of a html element?

    How to remove extra space in navigation bar? [duplicate]

    How to center div while keeping inside divs on same line in css?

    How to create a drop down menu like the one in this picture

    how to put links in one line [CSS]

    How can I push the first row of images down?

    How to manually apply styles from particular style sheet to an element?

    Angular.js: How to change div width based on user input

    How can I make it so the first element in a DIV has a different CSS to others?

    How to remove width with center DIV

    How to shorten this placeholder-transitioning CSS selector using sass/compass?

    how to make multiple inline dropdown lists cross platform compatible?

    CSS: How to make an image-border

    How to add CSS tag to ruby on rail loop?

    How to index star rating in google?

    How can I make the BODY element take up 100% height of the HTML element?

    how to render tilted images in html or css or javascript ..?

    How is padding-top as a percentage related to the parent's width?

    How to collapse div same like facebook chat

    How to write two CSS files: with and without sourcemap

    Css positioning: how to position a block/paragraph under another