2

I am trying style location two in my array of locations to to have a deleted look, red background, white text that is crossed out. If the user selects this option, the selected option when the dropdown is closed should display the same prior red crossed out label.

This is my desired selected look with the dropdown closed.

Desired Look

Two problems with my sample code, first the option that is to look deleted is not showing the text-decoration:line-through styling... although the red background and white text are being applied by the isDeleted CSS class.

Second, when the deleted option is selected the dropdown in a closed state does not reflect any of the option styling, the text is black with a white background whereas what I want is shown above, red background with white crossed out text.

This below image shows the dropdown open with my cursor over the first option hovering in blue with the deleted option shown in red. But the deleted option is not crossed out even though the class is applied, why?

dropdown open

Also tried adding class styling the select element rather than to the option element but that changes all of the options once the deleted style is applied.

A Plunker Demo

$scope.locations = [
    {"label":"123 Main St","locno":1,"deleted":false},
    {"label":"456 Main St","locno":2,"deleted":true},
    {"label":"789 Main St","locno":3,"deleted":false}
];

$scope.oItem = {"itemName":"Strawberry","locno":2};
.isDeleted{
    background-color:red;
    color:white;
    text-decoration: line-through !important;
}
.isNotDeleted{
    background-color:white;
    color:black;
    text-decoration: none;
}
<select  ng-model="oItem.locno">
    <option disabled value="">select location</option>
    <option ng-repeat="opt in locations" 
            ng-value="{{opt.locno}}" value="{{opt.locno}}" 
            ng-class="{'isDeleted':opt.deleted, 'isNotDeleted':!opt.deleted}">{{opt.label}} -- {{opt.deleted}}</option>
</select>
Harvey Mushman
  • 615
  • 1
  • 11
  • 23

1 Answers1

3

For the first problem, I've got some bad news for you. Styling the element select is a nightmare, because of the element itself.

The element is considered impossible to style consistently cross-platform. However, some styles are workable

Source: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Advanced_styling_for_HTML_forms

Probably the CSS property text-decoration is one of those that are not supported in the styling of the html element option. However you can consider to do your own directive in angularjs that would work like the select/option html or using something from bootstrap.

For the second problem I've changed your code like below and it works.

HTML:

<select  ng-model="oItem.locno" ng-class="styleOItem" class="selectedValueDeleted" ng-change="styleSelectOnChange()">
        <option disabled value="">select location</option>
        <option ng-repeat="opt in locations" 
                ng-value="{{opt.locno}}" value="{{opt.locno}}" 
                ng-class="{'isDeleted':opt.deleted, 'isNotDeleted':!opt.deleted}">{{opt.label}} -- {{opt.deleted}}</option>
      </select>

JS:

$scope.styleSelectOnChange = function() {
    angular.forEach($scope.locations, function(loopedObject) {
      if (loopedObject.locno === $scope.oItem.locno) {
        if (loopedObject.deleted) {
          $scope.styleOItem = "isDeleted";
        } else {
          $scope.styleOItem = "isNotDeleted";
        }
      }

    });
  };

Plunker: https://next.plnkr.co/edit/kge3Uhw5iMPl1jXB?preview

I've added ng-class to determine what class to apply based. For determine the class to apply it's used a function inside the 'ng-change' on the 'select' element.

Let me know if I've misunderstood your problem or if you need further explanation.

Ray Soy
  • 371
  • 5
  • 9
  • I have a couple of questions, where is the function selectedItem(opt) and how does AngularJs know which item was selected since the only thing in common between the two objects (oItem and opt or locations[n].opt) is the locno property? Thanks for your post it has been very helpful so far. – Harvey Mushman Nov 02 '19 at 21:04
  • I've edited the post and I've deleted the 'selectedItem(opt)' function as was useless. For example, in AngularJs when you write something in the "input" the value you've wrote is stored in the 'ng-model' you've associated to the input. It's same for the "select" , when you select an option angularjs puts the selected item to the "ng-model" ("oItem" in our example). How angular js knows the item to put? In this case he took the object in the "ng-value" ("opt" in our example) and put it in "ng-model" on the "select" element. – Ray Soy Nov 02 '19 at 22:24
  • Yea, ok then I think I was following you.... the problem I'm having oItem and opt are different objects and although my example does not show it, there are a lot more properties that get overwritten when opt becomes the value of the select element. In my original post, I use the common property between the two object "locno" so when oItem taken on the value of the user selected option, the rest of the properties of oItem stay in tact. Does that make sense...? – Harvey Mushman Nov 02 '19 at 23:03
  • Yes, you're right. I've updated the answer and plunker for change the style without overwriting the entire 'oItem' object. In the plunker there is another commented solution. – Ray Soy Nov 03 '19 at 08:18
  • 1
    Your answer is works! I had to fiddle with the $scope a bit before I could get this to work in my production environment and added an ng-init to apply the correct style for the default value to display correctly. But all good now, thank you!! – Harvey Mushman Nov 03 '19 at 14:59