2

A form has 2 fields, a selector and a (sometimes) non editable input field. When the user selects something in the selector both fields are filled. The selector shows a date-time and a related label goes to the non editable field. To make the selection more user friendly I need to display in the selector dropdown the data-time concatenated with the label to allow the user to chose the rigth option if two options have the same date but different label. The problem is that after the user chooses an option then the selected value in the selector should have just the date and not the label (this is just shown in its own field). I have added two images to make it clear.

This is the Session Group dropdown with the concatenated date-time and label: enter image description here

When a value is selected the label should be removed from the display value, since it is shown in the Thermal Profile field:

enter image description here

The ng-options code of the selector looks like this:

ng-options="opt.id as ((opt.sessions_datetime | date:'short') + ' (' + (opt.thermal_profiles_label || '') + ')') for opt in selectors.sessions_groups"

How can the label be added only when the dropdown is displayed, but not when the selector shows the selected value?

I have created a simplified Plunker here:

https://plnkr.co/edit/aDVOFuojDhFSV15BdPU0?p=preview

Note: AngularJS 1.5.0

3
  • 1
    The ng-options you posted is too complicated. Please post relevant code and demo in Fiddle/Plunker to help us to solve your problem Commented Nov 11, 2017 at 20:06
  • Added a Plunker to question. plnkr.co/edit/aDVOFuojDhFSV15BdPU0?p=preview Commented Nov 13, 2017 at 23:59
  • @DavidCasillas please have a look at my answer. Let me know if you're still need any help. Thanks Commented Nov 18, 2017 at 0:10

2 Answers 2

3
+50

I think the best solution for your problem is add "group by thermal_profiles_label" in ng-options.

<select ng-model="selected"
        ng-options="opt.id as (opt.sessions_datetime | date:'short') group by opt.thermal_profiles_label for opt in selectors.sessions_groups">
</select>

An alternative solution (not recommended ) could be to hide thermal_profiles_label if selected:

<select ng-model="selected"
        ng-options="opt.id as ((opt.sessions_datetime | date:'short') + (selected != opt.id ? ( '(' + (opt.thermal_profiles_label || '') + ')' ) : '') ) for opt in selectors.sessions_groups">
</select>

Check here an example in plunker: https://embed.plnkr.co/kmgCLaXw9Ixo4nADOzlV/

Sign up to request clarification or add additional context in comments.

1 Comment

It's a nice idea the use of "group by" but not sure if it will it my use case.
1

Ternary conditions are really helpful getting workaround for these kind of issues. To get a workaround for your requirement, I've used the same approach (ternary conditions). What is happening here is whenever a value is selected, you can save the id of that selected value and then make a decision on the base of that id whether to hide or show the labels.

here is the full code.

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

  $scope.session = {
    sessions_groups_id: null,
    thermal_profiles_id: null
  }
  $scope.sessions_groups = [{
    id: 0,
    sessions_datetime: '2017-11-17',
    thermal_profiles_id: 0,
    thermal_profiles_label: 'Baseline'
  }, {
    id: 1,
    sessions_datetime: '2017-11-17',
    thermal_profiles_id: 1,
    thermal_profiles_label: '+24h'

  }];
  $scope.thermal_profiles = [{
    id: 0,
    label: 'Baseline'
  }, {
    id: 1,
    label: '+24h'
  }, {
    id: 2,
    label: '+36h'
  }];
  $scope.sessionsGroupsChange = function(thermal_profiles_id) {
     $scope.sessions_groups.map((e)=>{ 
     if(e.id == thermal_profiles_id)
      $scope.session.thermal_profiles_id = e.thermal_profiles_id
   });
  }

});
<script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<!DOCTYPE html>
<html ng-cloak ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    
     
  </head>

  <body ng-controller="MainCtrl">
    
    <p><b>Sessions Groups selector</b>
    <br/>
    The dropdown displays the date concatenated with the thermal profile label
    <br/>
    But after selecting a value it should only display the date. The thermal profile label will be visible in the thermal profiles selector 
    </p>
		<select id="sessions_groups_id"
				name="sessions_groups_id"
				ng-model="session.sessions_groups_id"
				ng-change="sessionsGroupsChange(session.sessions_groups_id)">
		 <option ng-repeat="r in sessions_groups" value="{{r.id}}" >
		   {{r.sessions_datetime }} {{session.sessions_groups_id == r.id ? '' : '(' + r.thermal_profiles_label +')'  }} 
   </option> 
			</select>
			
		<br/>
		
    <p><b>Thermal Profile selector</b>
    <br/>
    Displays the thermal profile label asociated with the value selected in the previuos selector.
    <br/>
    Here it is always disabled but in real app can be enabled under some conditions.
    </p>
		<select id="thermal_profiles_id"
			name="thermal_profiles_id"
			ng-model="session.thermal_profiles_id"
			ng-disabled="true"
			ng-options="opt.id as opt.label for opt in thermal_profiles">
			<option value></option>
		</select>	
  </body>

</html>

Ps. It's always confusing for me to use ng-options angular directive, that's why I prefer to use ng-repeat on <option>. This just makes things more easy to understand.

There was another problem of page/template loading in your application. Please have a look at ngCloak. I've used this app to smoothen up the template loading. What ngCloak does is

The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display.

Hope this was helpful.

1 Comment

I like your approach and it gives me some ideas but there is a minor feature. The thermal profiles label is always hidden for the selected value, both in the selector and in the drop down. The idea was have it hidden only in the input selector, but show it in the drop down no matter if it is the selected value or not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.