6

I have a list which sometimes has true or false value. When I'm using ng-repeat to show the list with the value inside an <input type="text"> , I'd like to have <input type="checkbox"> if the value matches a boolean.

<table class="table table-hover table-striped table-bordered">
    <tbody>
        <tr ng-repeat="parameter in parameter_list">
            <th class="text-left">
                {{parameter.title | uppercase}}
            </th>
            <td class="text-left">
              <div class="form-group">
                <input type="text" ng-model="parameter_list[$index].value" class="form-control">
              </div>
            </td>
        </tr>
    </tbody>
</table>

Any ideas, how can I achieve this ?

Fiddle

Edit : It's not a duplicate since I don't have the input type in a $scope variable.

Community
  • 1
  • 1
AshBringer
  • 2,614
  • 2
  • 20
  • 42
  • You may need to convey this "The problem with this is that I don't have the input type in a $scope variable." some where in your post which saves from Duplicates issue for sure – Prasad Mar 08 '16 at 09:18

5 Answers5

16

Just keep it simple:

<input type="{{typeInput}}" />

And in your controller:

$scope.typeInput = 'number';

Works like a charm, without all that extra code

Oscar Bout
  • 690
  • 5
  • 19
  • The problem with this is that I don't have the input type in a $scope variable. – AshBringer Mar 08 '16 at 08:32
  • this wont work with ng-model i guess, after type and input data change the model will get undefined – Mohammed Aslam Dec 30 '16 at 17:33
  • Works superbly - ` CHECK BOX to enable / disable - In Controller - $scope.$watch('vm.showPassword',function(newVal){ if(newVal) { vm.typeInput = 'text'; } else { vm.typeInput = 'password'; } }); ` – Kishor Jul 28 '17 at 04:50
  • I did the same method, in chrome inspector I am not seeing the input `type` change from `text` to `tel`. The controller console.log shows the type output changing from text to tel, but its not reflecting so in the DOM. – rolinger Feb 27 '19 at 04:25
3

I would recommend more generic approach. First of all if you want to differentiate your inputs by type you need to declare some type checking function in your controller:

$scope.getType = function(x){
    return Object.prototype.toString.call(x);
}

You need to do this because it's impossible to do this in the expression - see: How to get a type of scope variable in Angular expression?

Then in your view you can use ng-if directive to show different controls depending on the type of the field. This is example expression for booleans:

ng-if="getType(parameter_list[$index].value) == '[object Boolean]'"

You should also define your booleans correctly, not "true"/"false" but true/false:

{
        "title": "differed",
        "value": true
}

Finally the code of your example would look as follows.

View:

<div ng-controller="MainCtrl" class="container">
        <div>
          <table class="table table-hover table-striped table-bordered">
            <tbody>
                <tr ng-repeat="parameter in parameter_list">
                    <th class="text-left">
                        {{parameter.title | uppercase}}
                    </th>
                    <td class="text-left">
                      <div class="form-group" ng-if="getType(parameter_list[$index].value) != '[object Boolean]'">
                        <input type="text" ng-model="parameter_list[$index].value" class="form-control">
                      </div>
                      <div class="form-group checkbox" ng-if="getType(parameter_list[$index].value) == '[object Boolean]'">
                        <label><input type="checkbox" ng-model="parameter_list[$index].value">{{ parameter_list[$index].title }} </label>
                    </div>
                    </td>
                </tr>
            </tbody>
          </table>
        </div>
</div>

Controller:

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

mymodal.controller('MainCtrl', function ($scope) {
  $scope.getType = function(x){
    return Object.prototype.toString.call(x);
  }

    $scope.parameter_list = [
    {
        "title": "name",
        "value": "Product3"
    },
    {
        "title": "version",
        "value": "01.00.00"
    },
    {
        "title": "inventory_name",
        "value": "Product3"
    },
    {
        "title": "inventory_version",
        "value": "01.00.00"
    },
    {
        "title": "differed",
        "value": true
    },
    {
        "title": "differed_name",
        "value": "whatever"
    },
    {
        "title": "accept_error_while_reboot",
        "value": false
    },
    {
        "title": "setup",
        "value": ""
    },
    {
        "title": "ggg",
        "value": "setup.exe"
    },
    {
        "title": "fx",
        "value": "test"
    },
    {
        "title": "gx",
        "value": "setup.exe"
    },
    {
        "title": "tx",
        "value": "setup.exe"
    }
]
  });

Here you can find JSFiddle: http://jsfiddle.net/57qhsqwf/2/

Community
  • 1
  • 1
Arkadiusz Kałkus
  • 17,101
  • 19
  • 69
  • 108
2

Simply you can define ngShow and ngHide.

FIDDLE

EDIT FIDDLE

If you want to use show;

<div class="form-group">
    <input type="checkbox" ng-show="parameter_list[$index].value==false || parameter_list[$index].value==true " ng-model="parameter_list[$index].value" class="form-control">
    <input type="text" ng-show="parameter_list[$index].value!=false && parameter_list[$index].value!=true " ng-model="parameter_list[$index].value" class="form-control">
</div>

Or you can send object with isChecked value.

<div class="form-group">
    <input type="checkbox" ng-show="parameter_list[$index].isChecked" ng-model="parameter_list[$index].value" class="form-control">
    <input type="text" ng-show="!parameter_list[$index].isChecked" ng-model="parameter_list[$index].value" class="form-control">
</div>
hurricane
  • 6,521
  • 2
  • 34
  • 44
  • @BipBip if you don't want to set other input you can use ngInıt to. – hurricane Mar 08 '16 at 08:21
  • 1
    @BipBip "value": "true" is a string :) – hurricane Mar 08 '16 at 08:28
  • I just noticed actually when I click the checkbox, it's getting back to `text`, which is normal http://jsfiddle.net/eynvqnL6/. How can we solve it ? – AshBringer Mar 08 '16 at 08:42
  • @BipBip You have two option. 1. Send data with boolean not string. Or 2. filter data with string or boolean like value=='false' OR value=='false' OR value=='true' OR value==false OR value==true – hurricane Mar 08 '16 at 08:46
  • Can you make a fiddle please ? – AshBringer Mar 08 '16 at 08:50
  • As far as I remember `ng-show`/`ng-hide` could be trouble maker because angular will only hide those fields so there will be two inputs with the same name if you'd set name property, and bound to the same scope variable. I'd recommend using `ng-if` instead. – Arkadiusz Kałkus Mar 08 '16 at 09:13
  • @Landeeyo You are right. NgInıt or NgIf very usefull. It is a simple example for 'BipBip' . Now he/she can use any directive. – hurricane Mar 08 '16 at 09:16
2

I updated your jsfiddle : http://jsfiddle.net/tornado1979/jp5rcm8j/2/

I use ng-show directive to check when the value is tru or false and create dynamically checkbox that could be checked or not.

<input ng-show="parameter_list[$index].value !=true && parameter_list[$index].value !=false" type="text" ng-model="parameter_list[$index].value" class="form-control">

<input ng-show="parameter_list[$index].value==true || parameter_list[$index].value==false" type="checkbox" ng-model="parameter_list[$index].value" class="form-control"> 

1. There is a problem though with the 'setup' property, you left it empty so the angular reads it as false and creates a checkbox. Could you just add a value different than null? That would solve the problem completely.

2. i changed your 'true' and 'false' values to true and false without the ' symbol , for the angular to understand that is boolean and not string value.

Hope helps ,good luck.

Theo Itzaris
  • 4,321
  • 3
  • 37
  • 68
1

You can use ng-switch to achieve your goal according to the value of the property that is either true or false!

<table class="table table-hover table-striped table-bordered">
<tbody>
    <tr ng-repeat="parameter in parameter_list">
        <th class="text-left">
            {{parameter.title | uppercase}}
        </th>
        <td class="text-left">
          <div class="form-group" ng-switch="parameter_list[$index].value">
            <input type="text" ng-model="parameter_list[$index].value" class="form-control" ng-switch-when="true">

Cheers! :)

Cowwando
  • 450
  • 5
  • 11