Bagaimana cara saya mengikat daftar nilai kotak centang dengan AngularJS?

670

Saya punya beberapa kotak centang:

<input type='checkbox' value="apple" checked>
<input type='checkbox' value="orange">
<input type='checkbox' value="pear" checked>
<input type='checkbox' value="naartjie">

Bahwa saya ingin mengikat ke daftar di controller saya sehingga setiap kali kotak centang diubah controller mempertahankan daftar semua nilai yang diperiksa, misalnya ['apple', 'pear'],.

ng-model tampaknya hanya dapat mengikat nilai satu kotak centang ke variabel di controller.

Apakah ada cara lain untuk melakukannya sehingga saya dapat mengikat empat kotak centang ke daftar di controller?

nickponline
sumber
23
Apakah harus daftar? Akankah sebuah objek bekerja ?: <input type='checkbox' ng-model="checkboxes.apple">, dll. Modelnya adalah: {"apple": true, "orange": false, "pear": true, "naartjie": true}
Mark Rajcok
2
Cobalah arahan dalam Repo
Vikas Gautam
1
Pastikan untuk melihat melewati jawaban yang diterima. Ada jawaban lain yang menurut saya jauh lebih elegan.
Jason Swett
3
naartjie!? Itu hanya memberi Anda kesempatan! : D
Piotr Kula
1
@pumkin hehe baru saja melihat ini. Anda benar: D
nickponline

Jawaban:

927

Ada dua cara untuk mendekati masalah ini. Baik menggunakan array sederhana atau array objek. Setiap solusi memilikinya pro dan kontra. Di bawah ini Anda akan menemukan satu untuk setiap kasing.


Dengan array sederhana sebagai input data

HTML bisa terlihat seperti:

<label ng-repeat="fruitName in fruits">
  <input
    type="checkbox"
    name="selectedFruits[]"
    value="{{fruitName}}"
    ng-checked="selection.indexOf(fruitName) > -1"
    ng-click="toggleSelection(fruitName)"
  > {{fruitName}}
</label>

Dan kode pengontrol yang sesuai adalah:

app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) {

  // Fruits
  $scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];

  // Selected fruits
  $scope.selection = ['apple', 'pear'];

  // Toggle selection for a given fruit by name
  $scope.toggleSelection = function toggleSelection(fruitName) {
    var idx = $scope.selection.indexOf(fruitName);

    // Is currently selected
    if (idx > -1) {
      $scope.selection.splice(idx, 1);
    }

    // Is newly selected
    else {
      $scope.selection.push(fruitName);
    }
  };
}]);

Kelebihan : Struktur data sederhana dan beralih berdasarkan nama mudah ditangani

Kekurangan : Tambah / hapus rumit karena dua daftar (input dan seleksi) harus dikelola


Dengan array objek sebagai input data

HTML bisa terlihat seperti:

<label ng-repeat="fruit in fruits">
  <!--
    - Use `value="{{fruit.name}}"` to give the input a real value, in case the form gets submitted
      traditionally

    - Use `ng-checked="fruit.selected"` to have the checkbox checked based on some angular expression
      (no two-way-data-binding)

    - Use `ng-model="fruit.selected"` to utilize two-way-data-binding. Note that `.selected`
      is arbitrary. The property name could be anything and will be created on the object if not present.
  -->
  <input
    type="checkbox"
    name="selectedFruits[]"
    value="{{fruit.name}}"
    ng-model="fruit.selected"
  > {{fruit.name}}
</label>

Dan kode pengontrol yang sesuai adalah:

app.controller('ObjectArrayCtrl', ['$scope', 'filterFilter', function ObjectArrayCtrl($scope, filterFilter) {

  // Fruits
  $scope.fruits = [
    { name: 'apple',    selected: true },
    { name: 'orange',   selected: false },
    { name: 'pear',     selected: true },
    { name: 'naartjie', selected: false }
  ];

  // Selected fruits
  $scope.selection = [];

  // Helper method to get selected fruits
  $scope.selectedFruits = function selectedFruits() {
    return filterFilter($scope.fruits, { selected: true });
  };

  // Watch fruits for changes
  $scope.$watch('fruits|filter:{selected:true}', function (nv) {
    $scope.selection = nv.map(function (fruit) {
      return fruit.name;
    });
  }, true);
}]);

Pro : Tambah / hapus sangat mudah

Cons : Agak struktur data yang lebih kompleks dan beralih dengan nama itu rumit atau memerlukan metode pembantu


Demo : http://jsbin.com/ImAqUC/1/

Yoshi
sumber
10
FYI, alih-alih menyuntikkan $ filter, Anda dapat menyuntikkan filterFilter, dan kemudian gunakan sebagai berikut: return filterFilter ($ scope.fruits, {checked: true}); Filter bawaan dan kustom terdaftar dengan $ injector dengan nama filterNameFilter ("filterName" harus dicetak miring) - $ filterProvider docs
Mark Rajcok
24
value="{{fruit.name}}"dan ng-checked="fruit.checked"berlebihan, karena ng-model digunakan.
Mark Rajcok
3
Saya perhatikan bahwa tidak perlu menentukan "dicentang" dalam model, Angular akan mengatur properti secara otomatis :)
daveoncode
3
Sebaiknya gunakan ng-ubah daripada ng-klik karena ini berhubungan dengan kasus tepi yang lebih baik.
amccausl
2
@ViktorMolokostov Itu hanya akan berguna, jika Anda mengirimkan formulir secara tradisional . Berarti mempostingnya ke penangan tindakan (beberapa skrip sisi server). Dengan php, elemen formulir dengan nama seperti itu (menggunakan tanda kurung siku) membuat array dalam data permintaan. Dengan cara ini Anda bisa dengan mudah menangani buah yang dipilih.
Yoshi
406

Solusi sederhana:

<div ng-controller="MainCtrl">
  <label ng-repeat="(color,enabled) in colors">
      <input type="checkbox" ng-model="colors[color]" /> {{color}} 
  </label>
  <p>colors: {{colors}}</p>
</div>

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

  app.controller('MainCtrl', function($scope){
      $scope.colors = {Blue: true, Orange: true};
  });
</script>

http://plnkr.co/edit/U4VD61?p=preview

kolypto
sumber
57
@ polypto - ini pasti jawabannya. Saya menulis ulang untuk orang-orang (seperti saya) yang bekerja dengan objek: plnkr.co/edit/cqsADe8lKegsBMgWMyB8?p=preview
Kyle
5
Saya melakukannya persis seperti yang Anda lakukan, tetapi apa yang diaktifkan di (color,enabled) in colorslakukan?
Sebastian
3
@ Sebastian, karena colorsmerupakan objek, ketika Anda mengulanginya - Anda mendapatkan pasangan (key,value).
kolypto
10
Meskipun saya sangat menyukai jawaban ini! Saya pikir, ada satu masalah utama dengan menggunakan objek sebagai sumber data. Yaitu, karena secara definisi urutan properti objek tidak terdefinisi, seseorang tidak dapat memberikan urutan yang pasti saat menampilkan kotak centang. Masih +1;)
Yoshi
2
colorsharus dinamai isSelected, lebih mudah dibaca isSelected[color]daripadacolors[color]
Dmitri Zaitsev
87
<input type='checkbox' ng-repeat="fruit in fruits"
  ng-checked="checkedFruits.indexOf(fruit) != -1" ng-click="toggleCheck(fruit)">

.

function SomeCtrl ($scope) {
    $scope.fruits = ["apple, orange, pear, naartjie"];
    $scope.checkedFruits = [];
    $scope.toggleCheck = function (fruit) {
        if ($scope.checkedFruits.indexOf(fruit) === -1) {
            $scope.checkedFruits.push(fruit);
        } else {
            $scope.checkedFruits.splice($scope.checkedFruits.indexOf(fruit), 1);
        }
    };
}
Umur Kontacı
sumber
2
Suka betapa sederhananya ini, persis apa yang saya cari (walaupun saya harus mengakui bahwa direktif @vitalet luar biasa). Saya telah memodifikasi sedikit kode Umur untuk membuat biola ini: jsfiddle.net/samurai_jane/9mwsbfuc
samurai_jane
Saya membuat kata-kata milik Samurai Jane! Betapa sederhananya untuk menunjukkan apa yang saya butuhkan! :)
Francis Rodrigues
81

Berikut ini adalah petunjuk singkat yang dapat digunakan kembali yang tampaknya melakukan apa yang Anda inginkan. Saya hanya menyebutnya checkList. Ini memperbarui array ketika kotak centang berubah, dan memperbarui kotak centang ketika array berubah.

app.directive('checkList', function() {
  return {
    scope: {
      list: '=checkList',
      value: '@'
    },
    link: function(scope, elem, attrs) {
      var handler = function(setup) {
        var checked = elem.prop('checked');
        var index = scope.list.indexOf(scope.value);

        if (checked && index == -1) {
          if (setup) elem.prop('checked', false);
          else scope.list.push(scope.value);
        } else if (!checked && index != -1) {
          if (setup) elem.prop('checked', true);
          else scope.list.splice(index, 1);
        }
      };

      var setupHandler = handler.bind(null, true);
      var changeHandler = handler.bind(null, false);

      elem.bind('change', function() {
        scope.$apply(changeHandler);
      });
      scope.$watch('list', setupHandler, true);
    }
  };
});

Berikut adalah pengontrol dan tampilan yang menunjukkan bagaimana Anda bisa menggunakannya.

<div ng-app="myApp" ng-controller='MainController'>
  <span ng-repeat="fruit in fruits">
    <input type='checkbox' value="{{fruit}}" check-list='checked_fruits'> {{fruit}}<br />
  </span>

  <div>The following fruits are checked: {{checked_fruits | json}}</div>

  <div>Add fruit to the array manually:
    <button ng-repeat="fruit in fruits" ng-click='addFruit(fruit)'>{{fruit}}</button>
  </div>
</div>
app.controller('MainController', function($scope) {
  $scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
  $scope.checked_fruits = ['apple', 'pear'];
  $scope.addFruit = function(fruit) {
    if ($scope.checked_fruits.indexOf(fruit) != -1) return;
    $scope.checked_fruits.push(fruit);
  };
});

(Tombol-tombol menunjukkan bahwa mengubah array juga akan memperbarui kotak centang.)

Akhirnya, berikut adalah contoh arahan dalam tindakan di Plunker: http://plnkr.co/edit/3YNLsyoG4PIBW6Kj7dRK?p=preview

Michelle Tilley
sumber
2
Terima kasih Brandon, ini melakukan persis apa yang saya inginkan (dan persis apa yang ditanyakan juga, tidak seperti jawaban lainnya). Satu-satunya penyesuaian yang saya lakukan adalah mengubah "elem.on ('change', function () ..." menjadi "elem.bind ('change', function () ..." untuk menghapus ketergantungan pada jQuery .
Jonathan Moffatt
Ini cukup rapi, tapi entah bagaimana menghancurkan kemampuan saya untuk menggunakan ng-disable :( Apakah ada cara saya bisa memperbaikinya?
Nikolaj Dam Larsen
Sangat berguna! Dan bahkan bekerja untuk saya dengan objek, bukan array untuk daftar sumber dan daftar data!
SteveShaffer
Saya setuju dengan semua orang. Ini adalah yang paling berguna dan tidak diragukan lagi dapat digunakan kembali !! Terima kasih atas kerja bagusnya. :)
maksbd19
2
Jika Anda mengalami masalah dengan AngularJS> = 1.4.4, periksa github.com/angular/angular.js/issues/13037 : ganti value: '@'denganvalue: '=ngValue'
tanguy_k
66

Berdasarkan jawaban di utas ini, saya telah membuat arahan daftar-model yang mencakup semua kasus:

  • sederetan primitif
  • array objek (pilih id atau seluruh objek)
  • iterasi properti objek

Untuk kasus topik-pemula adalah:

<label ng-repeat="fruit in ['apple', 'orange', 'pear', 'naartjie']">
    <input type="checkbox" checklist-model="selectedFruits" checklist-value="fruit"> {{fruit}}
</label>
vitalet
sumber
Itu seperti yang saya butuhkan. Apakah ada kemungkinan Anda bisa menjelaskan cara menggunakannya saat mendapatkan data secara tidak sinkron? Bagian itu membingungkan saya.
Dan Cancro
Setelah Anda mendapatkan data secara tidak sinkron, cukup modifikasi model checlist dalam cakupan, pada contoh di atas selectedFruits.
Adrian Ber
11

Menggunakan string $indexcan dapat membantu menggunakan hashmap dari nilai yang dipilih:

<ul>
    <li ng-repeat="someItem in someArray">
        <input type="checkbox" ng-model="someObject[$index.toString()]" />
    </li>
</ul>

Dengan cara ini objek ng-model akan diperbarui dengan kunci yang mewakili indeks.

$scope.someObject = {};

Setelah beberapa saat $scope.someObjectakan terlihat seperti:

$scope.someObject = {
     0: true,
     4: false,
     1: true
};

Metode ini tidak akan berfungsi untuk semua situasi, tetapi mudah diterapkan.

pengguna2479438
sumber
Ini adalah solusi yang sangat elegan dan sesuai dengan kasus saya (menggunakan AJAX)
Stephan Ryer
menggunakan metode ciuman
Geomorillo
8

Karena Anda menerima jawaban di mana daftar tidak digunakan, saya akan menganggap jawaban untuk pertanyaan komentar saya adalah "Tidak, itu tidak harus menjadi daftar". Saya juga mendapat kesan bahwa mungkin Anda sedang merender sisi server HTML, karena "diperiksa" ada dalam sampel HTML Anda (ini tidak akan diperlukan jika ng-model digunakan untuk memodelkan kotak centang Anda).

Bagaimanapun, inilah yang ada dalam pikiran saya ketika saya mengajukan pertanyaan, juga dengan asumsi Anda membuat sisi server HTML:

<div ng-controller="MyCtrl" 
 ng-init="checkboxes = {apple: true, orange: false, pear: true, naartjie: false}">
    <input type="checkbox" ng-model="checkboxes.apple">apple
    <input type="checkbox" ng-model="checkboxes.orange">orange
    <input type="checkbox" ng-model="checkboxes.pear">pear
    <input type="checkbox" ng-model="checkboxes.naartjie">naartjie
    <br>{{checkboxes}}
</div>

ng-init memungkinkan HTML yang dihasilkan sisi server untuk awalnya mengatur kotak centang tertentu.

Biola .

Mark Rajcok
sumber
8

Saya pikir solusi termudah adalah dengan menggunakan 'pilih' dengan 'beberapa' yang ditentukan:

<select ng-model="selectedfruit" multiple ng-options="v for v in fruit"></select>

Kalau tidak, saya pikir Anda harus memproses daftar untuk membangun daftar (dengan $watch()mengikat array model dengan kotak centang).

Omong kosong
sumber
3
Dia meminta daftar kotak centang, namun Anda memberitahunya tentang pilih dengan opsi. Yang benar-benar berbeda.
CrazySabbath
@CrazySabbath: namun Anda tidak mengerti bahwa ia menyarankan solusi alternatif dan jawaban ini membantu 6 orang lain sebagai "solusi alternatif"
curiousBoy
5

Saya telah mengadaptasi jawaban yang diterima Yoshi untuk berurusan dengan benda-benda kompleks (bukan string).

HTML

<div ng-controller="TestController">
    <p ng-repeat="permission in allPermissions">
        <input type="checkbox" ng-checked="selectedPermissions.containsObjectWithProperty('id', permission.id)" ng-click="toggleSelection(permission)" />
        {{permission.name}}
    </p>

    <hr />

    <p>allPermissions: | <span ng-repeat="permission in allPermissions">{{permission.name}} | </span></p>
    <p>selectedPermissions: | <span ng-repeat="permission in selectedPermissions">{{permission.name}} | </span></p>
</div>

JavaScript

Array.prototype.indexOfObjectWithProperty = function(propertyName, propertyValue)
{
    for (var i = 0, len = this.length; i < len; i++) {
        if (this[i][propertyName] === propertyValue) return i;
    }

    return -1;
};


Array.prototype.containsObjectWithProperty = function(propertyName, propertyValue)
{
    return this.indexOfObjectWithProperty(propertyName, propertyValue) != -1;
};


function TestController($scope)
{
    $scope.allPermissions = [
    { "id" : 1, "name" : "ROLE_USER" },
    { "id" : 2, "name" : "ROLE_ADMIN" },
    { "id" : 3, "name" : "ROLE_READ" },
    { "id" : 4, "name" : "ROLE_WRITE" } ];

    $scope.selectedPermissions = [
    { "id" : 1, "name" : "ROLE_USER" },
    { "id" : 3, "name" : "ROLE_READ" } ];

    $scope.toggleSelection = function toggleSelection(permission) {
        var index = $scope.selectedPermissions.indexOfObjectWithProperty('id', permission.id);

        if (index > -1) {
            $scope.selectedPermissions.splice(index, 1);
        } else {
            $scope.selectedPermissions.push(permission);
        }
    };
}

Contoh kerja: http://jsfiddle.net/tCU8v/

Adam
sumber
1
Anda seharusnya tidak pernah memiliki <input type="checkbox">tanpa pembungkus atau pencocokan <label>! Sekarang pengguna Anda harus mengklik pada kotak centang yang sebenarnya, bukan teks di sebelah kotak centang, yang jauh lebih sulit dan kegunaan yang buruk.
Scott
5

Arahan sederhana lain bisa seperti:

var appModule = angular.module("appModule", []);

appModule.directive("checkList", [function () {
return {
    restrict: "A",
    scope: {
        selectedItemsArray: "=",
        value: "@"
    },
    link: function (scope, elem) {
        scope.$watchCollection("selectedItemsArray", function (newValue) {
            if (_.contains(newValue, scope.value)) {
                elem.prop("checked", true);
            } else {
                elem.prop("checked", false);
            }
        });
        if (_.contains(scope.selectedItemsArray, scope.value)) {
            elem.prop("checked", true);
        }
        elem.on("change", function () {
            if (elem.prop("checked")) {
                if (!_.contains(scope.selectedItemsArray, scope.value)) {
                    scope.$apply(
                        function () {
                            scope.selectedItemsArray.push(scope.value);
                        }
                    );
                }
            } else {
                if (_.contains(scope.selectedItemsArray, scope.value)) {
                    var index = scope.selectedItemsArray.indexOf(scope.value);
                    scope.$apply(
                        function () {
                            scope.selectedItemsArray.splice(index, 1);
                        });
                }
            }
            console.log(scope.selectedItemsArray);
        });
    }
};
}]);

Pengontrol:

appModule.controller("sampleController", ["$scope",
  function ($scope) {
    //#region "Scope Members"
    $scope.sourceArray = [{ id: 1, text: "val1" }, { id: 2, text: "val2" }];
    $scope.selectedItems = ["1"];
    //#endregion
    $scope.selectAll = function () {
      $scope.selectedItems = ["1", "2"];
  };
    $scope.unCheckAll = function () {
      $scope.selectedItems = [];
    };
}]);

Dan HTML:

<ul class="list-unstyled filter-list">
<li data-ng-repeat="item in sourceArray">
    <div class="checkbox">
        <label>
            <input type="checkbox" check-list selected-items-array="selectedItems" value="{{item.id}}">
            {{item.text}}
        </label>
    </div>
</li>

Saya juga termasuk seorang Plunker: http://plnkr.co/edit/XnFtyij4ed6RyFwnFN6V?p=preview

Adrian Stanescu
sumber
5

Solusi berikut sepertinya pilihan yang baik,

<label ng-repeat="fruit in fruits">
  <input
    type="checkbox"
    ng-model="fruit.checked"
    ng-value="true"
  > {{fruit.fruitName}}
</label>

Dan dalam nilai model pengontrol fruitsakan seperti ini

$scope.fruits = [
  {
    "name": "apple",
    "checked": true
  },
  {
    "name": "orange"
  },
  {
    "name": "grapes",
    "checked": true
  }
];
Mohammed Safeer
sumber
semakin saya melihat contoh-contoh ini sepertinya saya harus memetakan array saya ke dalam array objek.
Winnemucca
4

Anda tidak harus menulis semua kode itu. AngularJS akan menjaga model dan kotak centang tetap sinkron hanya dengan menggunakan ngTrueValue dan ngFalseValue

Codepen di sini: http://codepen.io/paulbhartzog/pen/kBhzn

Cuplikan kode:

<p ng-repeat="item in list1" class="item" id="{{item.id}}">
  <strong>{{item.id}}</strong> <input name='obj1_data' type="checkbox" ng-model="list1[$index].data" ng-true-value="1" ng-false-value="0"> Click this to change data value below
</p>
<pre>{{list1 | json}}</pre>
Paul B. Hartzog
sumber
Ini bukan yang diminta OP.
bfontaine
Mengikat kotak centang ke daftar adalah apa yang ditanyakan, dan apa yang saya lakukan. Array dapat dimodifikasi agar sesuai dengan aplikasi. Intinya adalah bahwa kotak centang terikat. ngTrueValue dan ngFalseValue juga dapat digunakan untuk memetakan ke array kedua yang hanya mencantumkan atribut lainnya, seperti nama.
Paul B. Hartzog
OP menginginkan daftar nilai yang dicentang, bukan daftar semua nilai, dicentang dan tidak dicentang.
bfontaine
4

Lihat arahan ini yang mengelola daftar kotak centang secara efektif. Saya harap ini berhasil untuk Anda. Model Daftar Periksa

DSB
sumber
4

Ada cara untuk bekerja pada array secara langsung dan menggunakan ng-model sekaligus ng-model-options="{ getterSetter: true }".

Caranya adalah dengan menggunakan fungsi pengambil / penyetel dalam model-ng Anda. Dengan cara ini Anda dapat menggunakan array sebagai model asli Anda dan "memalsukan" boolean dalam model input:

<label ng-repeat="fruitName in ['apple', 'orange', 'pear', 'naartjie']">
  <input
    type="checkbox"
    ng-model="fruitsGetterSetterGenerator(fruitName)"
    ng-model-options="{ getterSetter: true }"
  > {{fruitName}}
</label>

$scope.fruits = ['apple', 'pear']; // pre checked

$scope.fruitsGetterSetterGenerator = function(fruitName){
    return function myGetterSetter(nowHasFruit){
        if (nowHasFruit !== undefined){

            // Setter
            fruitIndex = $scope.fruits.indexOf(fruit);
            didHaveFruit = (fruitIndex !== -1);
            mustAdd = (!didHaveFruit && nowHasFruit);
            mustDel = (didHaveFruit && !nowHasFruit);
            if (mustAdd){
                $scope.fruits.push(fruit);
            }
            if (mustDel){
                $scope.fruits.splice(fruitIndex, 1);
            }
        }
        else {
            // Getter
            return $scope.user.fruits.indexOf(fruit) !== -1;
        }
    }
}

CAVEAT Anda seharusnya tidak menggunakan metode ini jika array Anda besar karena myGetterSetterakan dipanggil berkali-kali.

Untuk lebih lanjut tentang itu, lihat https://docs.angularjs.org/api/ng/directive/ngModelOptions .

David
sumber
3

Saya suka jawaban Yoshi. Saya meningkatkannya sehingga Anda dapat menggunakan fungsi yang sama untuk beberapa daftar.

<label ng-repeat="fruitName in fruits">
<input
type="checkbox"
name="selectedFruits[]"
value="{{fruitName}}"
ng-checked="selection.indexOf(fruitName) > -1"
ng-click="toggleSelection(fruitName, selection)"> {{fruitName}}
</label>


<label ng-repeat="veggieName in veggies">
<input
type="checkbox"
name="selectedVeggies[]"
value="{{veggieName}}"
ng-checked="veggieSelection.indexOf(veggieName) > -1"
ng-click="toggleSelection(veggieName, veggieSelection)"> {{veggieName}}
</label>



app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) {
  // fruits
  $scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
  $scope.veggies = ['lettuce', 'cabbage', 'tomato']
  // selected fruits
  $scope.selection = ['apple', 'pear'];
  $scope.veggieSelection = ['lettuce']
  // toggle selection for a given fruit by name
  $scope.toggleSelection = function toggleSelection(selectionName, listSelection) {
    var idx = listSelection.indexOf(selectionName);

    // is currently selected
    if (idx > -1) {
      listSelection.splice(idx, 1);
    }

    // is newly selected
    else {
      listSelection.push(selectionName);
    }
  };
}]);

http://plnkr.co/edit/KcbtzEyNMA8s1X7Hja8p?p=preview

Bikey
sumber
3

Jika Anda memiliki beberapa kotak centang pada formulir yang sama

Kode pengontrol

vm.doYouHaveCheckBox = ['aaa', 'ccc', 'bbb'];
vm.desiredRoutesCheckBox = ['ddd', 'ccc', 'Default'];
vm.doYouHaveCBSelection = [];
vm.desiredRoutesCBSelection = [];

Lihat kode

<div ng-repeat="doYouHaveOption in vm.doYouHaveCheckBox">
    <div class="action-checkbox">
        <input id="{{doYouHaveOption}}" type="checkbox" value="{{doYouHaveOption}}" ng-checked="vm.doYouHaveCBSelection.indexOf(doYouHaveOption) > -1" ng-click="vm.toggleSelection(doYouHaveOption,vm.doYouHaveCBSelection)" />
        <label for="{{doYouHaveOption}}"></label>
        {{doYouHaveOption}}
    </div>
</div>

<div ng-repeat="desiredRoutesOption in vm.desiredRoutesCheckBox">
     <div class="action-checkbox">
          <input id="{{desiredRoutesOption}}" type="checkbox" value="{{desiredRoutesOption}}" ng-checked="vm.desiredRoutesCBSelection.indexOf(desiredRoutesOption) > -1" ng-click="vm.toggleSelection(desiredRoutesOption,vm.desiredRoutesCBSelection)" />
          <label for="{{desiredRoutesOption}}"></label>
          {{desiredRoutesOption}}
     </div>
</div>        
Rama Krshna Ila
sumber
3

Terinspirasi dari pos Yoshi di atas. Ini plnkr .

(function () {
   
   angular
      .module("APP", [])
      .controller("demoCtrl", ["$scope", function ($scope) {
         var dc = this
         
         dc.list = [
            "Selection1",
            "Selection2",
            "Selection3"
         ]

         dc.multipleSelections = []
         dc.individualSelections = []
         
         // Using splice and push methods to make use of 
         // the same "selections" object passed by reference to the 
         // addOrRemove function as using "selections = []" 
         // creates a new object within the scope of the 
         // function which doesn't help in two way binding.
         dc.addOrRemove = function (selectedItems, item, isMultiple) {
            var itemIndex = selectedItems.indexOf(item)
            var isPresent = (itemIndex > -1)
            if (isMultiple) {
               if (isPresent) {
                  selectedItems.splice(itemIndex, 1)
               } else {
                  selectedItems.push(item)
               }
            } else {
               if (isPresent) {
                  selectedItems.splice(0, 1)
               } else {
                  selectedItems.splice(0, 1, item)
               }
            }
         }
         
      }])
   
})()
label {
  display: block;  
}
<!DOCTYPE html>
<html>

   <head>
      <link rel="stylesheet" href="style.css" />
   </head>

   <body ng-app="APP" ng-controller="demoCtrl as dc">
      <h1>checkbox-select demo</h1>
      
      <h4>Multiple Selections</h4>
      <label ng-repeat="thing in dc.list">
         <input 
            type="checkbox" 
            ng-checked="dc.multipleSelections.indexOf(thing) > -1"
            ng-click="dc.addOrRemove(dc.multipleSelections, thing, true)"
         > {{thing}}
      </label>
      
      <p>
         dc.multipleSelections :- {{dc.multipleSelections}}
      </p>
      
      <hr>
      
      <h4>Individual Selections</h4>
      <label ng-repeat="thing in dc.list">
         <input 
            type="checkbox" 
            ng-checked="dc.individualSelections.indexOf(thing) > -1"
            ng-click="dc.addOrRemove(dc.individualSelections, thing, false)"
         > {{thing}}
      </label>
      
      <p>
         dc.invidualSelections :- {{dc.individualSelections}}
      </p>
      
      <script data-require="[email protected]" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
      <script data-require="[email protected]" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script>
      <script src="script.js"></script>
   </body>

</html>

Vikas Gautam
sumber
3

Berdasarkan posting saya yang lain di sini , saya telah membuat arahan yang dapat digunakan kembali.

Lihat repositori GitHub

(function () {
   
   angular
      .module("checkbox-select", [])
      .directive("checkboxModel", ["$compile", function ($compile) {
         return {
            restrict: "A",
            link: function (scope, ele, attrs) {
               // Defining updateSelection function on the parent scope
               if (!scope.$parent.updateSelections) {
                  // Using splice and push methods to make use of 
                  // the same "selections" object passed by reference to the 
                  // addOrRemove function as using "selections = []" 
                  // creates a new object within the scope of the 
                  // function which doesn't help in two way binding.
                  scope.$parent.updateSelections = function (selectedItems, item, isMultiple) {
                     var itemIndex = selectedItems.indexOf(item)
                     var isPresent = (itemIndex > -1)
                     if (isMultiple) {
                        if (isPresent) {
                           selectedItems.splice(itemIndex, 1)
                        } else {
                           selectedItems.push(item)
                        }
                     } else {
                        if (isPresent) {
                           selectedItems.splice(0, 1)
                        } else {
                           selectedItems.splice(0, 1, item)
                        }
                     }
                  }   
               }
               
               // Adding or removing attributes
               ele.attr("ng-checked", attrs.checkboxModel + ".indexOf(" + attrs.checkboxValue + ") > -1")
               var multiple = attrs.multiple ? "true" : "false"
               ele.attr("ng-click", "updateSelections(" + [attrs.checkboxModel, attrs.checkboxValue, multiple].join(",") + ")")
               
               // Removing the checkbox-model attribute, 
               // it will avoid recompiling the element infinitly
               ele.removeAttr("checkbox-model")
               ele.removeAttr("checkbox-value")
               ele.removeAttr("multiple")
               
               $compile(ele)(scope)
            }
         }
      }])
   
      // Defining app and controller
      angular
      .module("APP", ["checkbox-select"])
      .controller("demoCtrl", ["$scope", function ($scope) {
         var dc = this
         dc.list = [
            "selection1",
            "selection2",
            "selection3"
         ]
         
         // Define the selections containers here
         dc.multipleSelections = []
         dc.individualSelections = []
      }])
   
})()
label {
  display: block;  
}
<!DOCTYPE html>
<html>

   <head>
      <link rel="stylesheet" href="style.css" />
      
   </head>
   
   <body ng-app="APP" ng-controller="demoCtrl as dc">
      <h1>checkbox-select demo</h1>
      
      <h4>Multiple Selections</h4>
      <label ng-repeat="thing in dc.list">
         <input type="checkbox" checkbox-model="dc.multipleSelections" checkbox-value="thing" multiple>
         {{thing}}
      </label>
      <p>dc.multipleSelecitons:- {{dc.multipleSelections}}</p>
      
      <h4>Individual Selections</h4>
      <label ng-repeat="thing in dc.list">
         <input type="checkbox" checkbox-model="dc.individualSelections" checkbox-value="thing">
         {{thing}}
      </label>
      <p>dc.individualSelecitons:- {{dc.individualSelections}}</p>
      
      <script data-require="[email protected]" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
      <script data-require="[email protected]" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script>
      <script src="script.js"></script>
   </body>

</html>

Vikas Gautam
sumber
3

Dalam HTML (seandainya kotak centang berada di kolom pertama dari setiap baris dalam tabel).

<tr ng-repeat="item in fruits">
    <td><input type="checkbox" ng-model="item.checked" ng-click="getChecked(item)"></td>
    <td ng-bind="fruit.name"></td>
    <td ng-bind="fruit.color"></td>
    ...
</tr>

Dalam controllers.jsfile:

// The data initialization part...
$scope.fruits = [
    {
      name: ....,
      color:....
    },
    {
      name: ....,
      color:....
    }
     ...
    ];

// The checked or not data is stored in the object array elements themselves
$scope.fruits.forEach(function(item){
    item.checked = false;
});

// The array to store checked fruit items
$scope.checkedItems = [];

// Every click on any checkbox will trigger the filter to find checked items
$scope.getChecked = function(item){
    $scope.checkedItems = $filter("filter")($scope.fruits,{checked:true});
};
lqt0223
sumber
3

Inilah solusi lain. Kelebihan dari solusi saya:

  • Tidak memerlukan jam tangan tambahan (yang mungkin berdampak pada kinerja)
  • Itu tidak memerlukan kode apa pun di controller menjaganya tetap bersih
  • Kode ini masih agak pendek
  • Ini membutuhkan kode yang sangat sedikit untuk digunakan kembali di banyak tempat karena itu hanya sebuah arahan

Ini adalah arahannya:

function ensureArray(o) {
    var lAngular = angular;
    if (lAngular.isArray(o) || o === null || lAngular.isUndefined(o)) {
        return o;
    }
    return [o];
}

function checkboxArraySetDirective() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            var name = attrs.checkboxArraySet;

            ngModel.$formatters.push(function(value) {
                return (ensureArray(value) || []).indexOf(name) >= 0;
            });

            ngModel.$parsers.push(function(value) {
                var modelValue = ensureArray(ngModel.$modelValue) || [],
                    oldPos = modelValue.indexOf(name),
                    wasSet = oldPos >= 0;
                if (value) {
                    if (!wasSet) {
                        modelValue = angular.copy(modelValue);
                        modelValue.push(name);
                    }
                } else if (wasSet) {
                    modelValue = angular.copy(modelValue);
                    modelValue.splice(oldPos, 1);
                }
                return modelValue;
            });
        }
    }
}

Pada akhirnya gunakan saja seperti ini:

<input ng-repeat="fruit in ['apple', 'banana', '...']" type="checkbox" ng-model="fruits" checkbox-array-set="{{fruit}}" />

Dan hanya itu yang ada. Satu-satunya tambahan adalah checkbox-array-setatribut.

yankee
sumber
3

Anda dapat menggabungkan AngularJS dan jQuery. Misalnya, Anda perlu mendefinisikan array $scope.selected = [];,, di controller.

<label ng-repeat="item in items">
    <input type="checkbox" ng-model="selected[$index]" ng-true-value="'{{item}}'">{{item}}
</label>

Anda bisa mendapatkan array yang memiliki item yang dipilih. Dengan menggunakan metode alert(JSON.stringify($scope.selected)), Anda dapat memeriksa item yang dipilih.

Dahai
sumber
Sempurna! ... ini adalah solusi paling sederhana menggunakan array bukan objek
Mario Campa
3
Jangan gabungkan Jquery dan Angular
Jens Alenius
Ini akan menyebabkan lubang di Array yang dipilih. Lihat posting
Vikas Gautam
2
  <div ng-app='app' >
    <div ng-controller='MainCtrl' >
       <ul> 
       <li ng-repeat="tab in data">
         <input type='checkbox' ng-click='change($index,confirm)' ng-model='confirm' />
         {{tab.name}} 
         </li>
     </ul>
    {{val}}
   </div>
 </div>


var app = angular.module('app', []);
 app.controller('MainCtrl',function($scope){
 $scope.val=[];
  $scope.confirm=false;
  $scope.data=[
   {
     name:'vijay'
     },
    {
      name:'krishna'
    },{
      name:'Nikhil'
     }
    ];
    $scope.temp;
   $scope.change=function(index,confirm){
     console.log(confirm);
    if(!confirm){
     ($scope.val).push($scope.data[index]);   
    }
    else{
    $scope.temp=$scope.data[index];
        var d=($scope.val).indexOf($scope.temp);
        if(d!=undefined){
         ($scope.val).splice(d,1);
        }    
       }
     }   
   })
vijay007
sumber
1

Lihatlah ini: checklist-model .

Ini bekerja dengan array JavaScript, dan objek dan dapat menggunakan kotak centang HTML statis, tanpa ng-repeat

<label><input type="checkbox" checklist-model="roles" value="admin"> Administrator</label>
<label><input type="checkbox" checklist-model="roles" value="customer"> Customer</label>
<label><input type="checkbox" checklist-model="roles" value="guest"> Guest</label>
<label><input type="checkbox" checklist-model="roles" value="user"> User</label>

Dan sisi JavaScript:

var app = angular.module("app", ["checklist-model"]);
app.controller('Ctrl4a', function($scope) {
    $scope.roles = [];
});
sarkiroka
sumber
1

Satu-satunya cara sederhana HTML untuk melakukannya:

<input type="checkbox"
       ng-checked="fruits.indexOf('apple') > -1"
       ng-click="fruits.indexOf('apple') > -1 ? fruits.splice(fruits.indexOf('apple'), 1) : fruits.push('apple')">
<input type="checkbox"
       ng-checked="fruits.indexOf('orange') > -1"
       ng-click="fruits.indexOf('orange') > -1 ? fruits.splice(fruits.indexOf('orange'), 1) : fruits.push('orange')">
<input type="checkbox"
       ng-checked="fruits.indexOf('pear') > -1"
       ng-click="fruits.indexOf('pear') > -1 ? fruits.splice(fruits.indexOf('pear'), 1) : fruits.push('pear')">
<input type="checkbox"
       ng-checked="fruits.indexOf('naartjie') > -1"
       ng-click="fruits.indexOf('apple') > -1 ? fruits.splice(fruits.indexOf('apple'), 1) : fruits.push('naartjie')">

Matt Carroll
sumber
1

Menggunakan contoh ini dari @Umur Kontacı, saya pikir menggunakan untuk menangkap data yang dipilih di seluruh objek / array lain, seperti halaman edit.

Opsi tangkapan di basis data

masukkan deskripsi gambar di sini

Beralih beberapa opsi

masukkan deskripsi gambar di sini

Sebagai contoh, semua warna json di bawah ini:

{
    "colors": [
        {
            "id": 1,
            "title": "Preto - #000000"
        },
        {
            "id": 2,
            "title": "Azul - #005AB1"
        },
        {
            "id": 3,
            "title": "Azul Marinho - #001A66"
        },
        {
            "id": 4,
            "title": "Amarelo - #FFF100"
        },
        {
            "id": 5,
            "title": "Vermelho - #E92717"
        },
        {
            "id": 6,
            "title": "Verde - #008D2F"
        },
        {
            "id": 7,
            "title": "Cinza - #8A8A8A"
        },
        {
            "id": 8,
            "title": "Prata - #C8C9CF"
        },
        {
            "id": 9,
            "title": "Rosa - #EF586B"
        },
        {
            "id": 10,
            "title": "Nude - #E4CAA6"
        },
        {
            "id": 11,
            "title": "Laranja - #F68700"
        },
        {
            "id": 12,
            "title": "Branco - #FFFFFF"
        },
        {
            "id": 13,
            "title": "Marrom - #764715"
        },
        {
            "id": 14,
            "title": "Dourado - #D9A300"
        },
        {
            "id": 15,
            "title": "Bordo - #57001B"
        },
        {
            "id": 16,
            "title": "Roxo - #3A0858"
        },
        {
            "id": 18,
            "title": "Estampado "
        },
        {
            "id": 17,
            "title": "Bege - #E5CC9D"
        }
    ]
}

Dan 2 jenis objek data, arraydengan satu objek dan objectberisi dua / lebih objek data:

  • Dua item yang dipilih ditangkap di database:

    [{"id":12,"title":"Branco - #FFFFFF"},{"id":16,"title":"Roxo - #3A0858"}]
  • Satu item dipilih ditangkap di database:

    {"id":12,"title":"Branco - #FFFFFF"}

Dan di sini, kode javascript saya:

/**
 * Add this code after catch data of database.
 */

vm.checkedColors = [];
var _colorObj = vm.formData.color_ids;
var _color_ids = [];

if (angular.isObject(_colorObj)) {
    // vm.checkedColors.push(_colorObj);
    _color_ids.push(_colorObj);
} else if (angular.isArray(_colorObj)) {
    angular.forEach(_colorObj, function (value, key) {
        // vm.checkedColors.push(key + ':' + value);
        _color_ids.push(key + ':' + value);
    });
}

angular.forEach(vm.productColors, function (object) {
    angular.forEach(_color_ids, function (color) {
        if (color.id === object.id) {
            vm.checkedColors.push(object);
        }
    });
});

/**
 * Add this code in your js function initialized in this HTML page
 */
vm.toggleColor = function (color) {
    console.log('toggleColor is: ', color);

    if (vm.checkedColors.indexOf(color) === -1) {
        vm.checkedColors.push(color);
    } else {
        vm.checkedColors.splice(vm.checkedColors.indexOf(color), 1);
    }
    vm.formData.color_ids = vm.checkedColors;
};

Kode Html saya:

<div class="checkbox" ng-repeat="color in productColors">
    <label>
        <input type="checkbox"
               ng-checked="checkedColors.indexOf(color) != -1"
               ng-click="toggleColor(color)"/>
        <% color.title %>
    </label>
</div>

<p>checkedColors Output:</p>
<pre><% checkedColors %></pre>

[Sunting] Kode yang di-refactored di bawah ini:

function makeCheckedOptions(objectOptions, optionObj) {
    var checkedOptions = [];
    var savedOptions = [];

    if (angular.isObject(optionObj)) {
        savedOptions.push(optionObj);
    } else if (angular.isArray(optionObj)) {
        angular.forEach(optionObj, function (value, key) {
            savedOptions.push(key + ':' + value);
        });
    }

    angular.forEach(objectOptions, function (object) {
        angular.forEach(savedOptions, function (color) {
            if (color.id === object.id) {
                checkedOptions.push(object);
            }
        });
    });

    return checkedOptions;
}

Dan panggil metode baru seperti di bawah ini:

vm.checkedColors = makeCheckedOptions(productColors, vm.formData.color_ids);

Itu dia!

Francis Rodrigues
sumber
1

Saya sudah meletakkan array di controller.

$scope.statuses = [{ name: 'Shutdown - Reassessment Required' },
    { name: 'Under Construction' },
    { name: 'Administrative Cancellation' },
    { name: 'Initial' },
    { name: 'Shutdown - Temporary' },
    { name: 'Decommissioned' },
    { name: 'Active' },
    { name: 'SO Shutdown' }]

Pada markup saya telah memasukkan sesuatu seperti mengikuti

<div ng-repeat="status in $scope.statuses">
   <input type="checkbox" name="unit_status" ng-model="$scope.checkboxes[status.name]"> {{status.name}}
   <br>                        
</div>
{{$scope.checkboxes}}

Outputnya adalah sebagai berikut, pada controller saya hanya perlu memeriksa apakah benar atau salah; benar untuk diperiksa, tidak ada / salah untuk tidak dicentang.

{
"Administrative Cancellation":true,
"Under Construction":true,
"Shutdown - Reassessment Required":true,
"Decommissioned":true,
"Active":true
}

Semoga ini membantu.

Mahib
sumber
0

Saya pikir cara berikut ini lebih jelas dan berguna untuk ng-mengulangi bersarang. Lihatlah di Plunker .

Kutipan dari utas ini :

<html ng-app="plunker">
    <head>
        <title>Test</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
    </head>

    <body ng-controller="MainCtrl">
        <div ng-repeat="tab in mytabs">

            <h1>{{tab.name}}</h1>
            <div ng-repeat="val in tab.values">
                <input type="checkbox" ng-change="checkValues()" ng-model="val.checked"/>
            </div>
        </div>

        <br>
        <pre> {{selected}} </pre>

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

                app.controller('MainCtrl', function ($scope,$filter) {
                    $scope.mytabs = [
             {
                 name: "tab1",
                 values: [
                     { value: "value1",checked:false },
                     { value: "value2", checked: false },
                     { value: "value3", checked: false },
                     { value: "value4", checked: false }
                 ]
             },
             {
                 name: "tab2",
                 values: [
                     { value: "value1", checked: false },
                     { value: "value2", checked: false },
                     { value: "value3", checked: false },
                     { value: "value4", checked: false }
                 ]
             }
                    ]
                    $scope.selected = []
                    $scope.checkValues = function () {
                        angular.forEach($scope.mytabs, function (value, index) {
                         var selectedItems = $filter('filter')(value.values, { checked: true });
                         angular.forEach(selectedItems, function (value, index) {
                             $scope.selected.push(value);
                         });

                        });
                    console.log($scope.selected);
                    };
                });
        </script>
    </body>
</html>
Oğuz Can Sertel
sumber
0

Berikut adalah tautan jsFillde untuk hal yang sama, http://jsfiddle.net/techno2mahi/Lfw96ja6/ .

Ini menggunakan arahan yang tersedia untuk diunduh di http://vitalets.github.io/checklist-model/ .

Ini bagus untuk direktif karena aplikasi Anda akan sering membutuhkan fungsi ini.

Kode di bawah ini:

HTML:

<div class="container">
    <div class="ng-scope" ng-app="app" ng-controller="Ctrl1">
        <div class="col-xs-12 col-sm-6">
            <h3>Multi Checkbox List Demo</h3>
            <div class="well">  <!-- ngRepeat: role in roles -->
                <label ng-repeat="role in roles">
                    <input type="checkbox" checklist-model="user.roles" checklist-value="role"> {{role}}
                </label>
            </div>

            <br>
            <button ng-click="checkAll()">check all</button>
            <button ng-click="uncheckAll()">uncheck all</button>
            <button ng-click="checkFirst()">check first</button>
            <div>
                <h3>Selected User Roles </h3>
                <pre class="ng-binding">{{user.roles|json}}</pre>
            </div>

            <br>
            <div><b/>Provided by techno2Mahi</b></div>
        </div>

JavaScript

var app = angular.module("app", ["checklist-model"]);
app.controller('Ctrl1', function($scope) {
  $scope.roles = [
    'guest',
    'user',
    'customer',
    'admin'
  ];
  $scope.user = {
    roles: ['user']
  };
  $scope.checkAll = function() {
    $scope.user.roles = angular.copy($scope.roles);
  };
  $scope.uncheckAll = function() {
    $scope.user.roles = [];
  };
  $scope.checkFirst = function() {
    $scope.user.roles.splice(0, $scope.user.roles.length);
    $scope.user.roles.push('guest');
  };
});
Mahendra
sumber
HTML tidak terbentuk dengan baik - ada lebih banyak tag pembuka <div>daripada penutup </div>,. Apakah Anda meninggalkan sesuatu?
Peter Mortensen
0

Coba bayi saya:

**

myApp.filter('inputSelected', function(){
  return function(formData){
    var keyArr = [];
    var word = [];
    Object.keys(formData).forEach(function(key){
    if (formData[key]){
        var keyCap = key.charAt(0).toUpperCase() + key.slice(1);
      for (var char = 0; char<keyCap.length; char++ ) {
        if (keyCap[char] == keyCap[char].toUpperCase()){
          var spacedLetter = ' '+ keyCap[char];
          word.push(spacedLetter);
        }
        else {
          word.push(keyCap[char]);
        }
      }
    }
    keyArr.push(word.join(''))
    word = [];
    })
    return keyArr.toString();
  }
})

**

Kemudian untuk model apa saja dengan kotak centang, itu akan mengembalikan string dari semua input yang Anda pilih:

<label for="Heard about ITN">How did you hear about ITN?: *</label><br>
<label class="checkbox-inline"><input ng-model="formData.heardAboutItn.brotherOrSister" type="checkbox" >Brother or Sister</label>
<label class="checkbox-inline"><input ng-model="formData.heardAboutItn.friendOrAcquaintance" type="checkbox" >Friend or Acquaintance</label>


{{formData.heardAboutItn | inputSelected }}

//returns Brother or Sister, Friend or Acquaintance
Samantha Guergenenov
sumber