Vijju Sena
Vijju Sena

Reputation: 183

How to change selected element class names

i want to change selected buttons name and their classes, names are changing perfectly,, but i am little bit confusing to change button classes, in the below code if i change class name all buttons classes are changing ,, how can i change only selected button class? please edit my below code and suggest me how to solve this.. DEMO

// Code goes here

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

app.controller('MainCtrl', function($scope) {
  $scope.class = 'col-sm-12';
  $scope.textVal = 'click a button';
  $scope.selectedEvent = {};
  $scope.setText = function(element) {
    $scope.selectedEvent = element;
     $scope.textVal = element.currentTarget.innerHTML;
  };
  $scope.changeButtonText = function(){
    $scope.selectedEvent.currentTarget.innerHTML = $scope.textVal;
  };
    $scope.changetoLarge = function(){
    $scope.class = 'col-sm-12'
  }
  $scope.changetoMedium = function(){
    $scope.class = 'col-sm-6'
  }
  $scope.changetoSmall = function(){
    $scope.class = 'col-sm-4'
  }
});
   
<!DOCTYPE html>
<html ng-app='myapp'>

  <head>
    <script data-require="jquery@*" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
    <script data-require="[email protected]" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <h1>Hello Plunker!</h1>
<div>
  <button type="button" ng-class="class" class="btn btn-primary" ng-click="setText($event)">one</button>
  <button type="button" ng-class="class" class="btn btn-primary" ng-click="setText($event)">two</button>
  <button type="button" ng-class="class" class="btn btn-primary" ng-click="setText($event)">three</button>
</div><br>
<div>
<input type="text" ng-model="textVal" ng-change="changeButtonText()">//change button name here//<br>

<input ng-click="changetoLarge()" type="radio" name="button">Large
<input ng-click="changetoMedium()" type="radio" name="button">medium
<input ng-click="changetoSmall()" type="radio" name="button">Small 
</div>//change button class here//
</body>

</html>

Upvotes: 1

Views: 1292

Answers (7)

Nimesh.Nim
Nimesh.Nim

Reputation: 388

Below is the script code... update this from previous answer.

app.controller('MainCtrl', function($scope) {
$scope.class = '';
 $scope.textVal = 'click a button';

  $scope.selectedEvent = {};

  $scope.setText = function(element) {
    $scope.selectedEvent = element;
    $scope.textVal = element.currentTarget.innerHTML;
    var currentbtnClass = element.currentTarget.classList;
    alert(currentbtnClass[2])

    $scope.CSSClass = currentbtnClass[2]
    alert($scope.CSSClass)
  };
  $scope.changeButtonText = function(){
    $scope.selectedEvent.currentTarget.innerHTML = $scope.textVal;
  };

  $scope.setCSSClass=function(value){   
    angular.element($scope.selectedEvent.currentTarget).removeClass($scope.selectedEvent.currentTarget.className)

    angular.element($scope.selectedEvent.currentTarget).addClass('btn btn-primary '+value)
  }
});



 Below is the HTML which you need to update..

  <button type="button" id="btn1" ng-model="btn1"  class="btn btn-primary" ng-click="setText($event)">one</button>
  <button type="button" id="btn2" ng-model="btn2"  class="btn btn-primary" ng-click="setText($event)">two</button>
  <button type="button" id="btn3" ng-model="btn3" class="btn btn-primary" ng-click="setText($event)">three</button>
</div><br>
<div>

<input type="text" ng-model="textVal" ng-change="changeButtonText()">//change button name here//<br><br><br>

<input type="radio" ng-model="value1" name="rdbtn[]" value="col-sm-12" ng-click='setCSSClass(value1)' ng-checked="CSSClass==value1" >
<input type="radio" ng-model="value2" name="rdbtn[]" value="col-sm-6" ng-click='setCSSClass(value2)' ng-checked="CSSClass==value2">
<input type="radio" ng-model="value3" name="rdbtn[]" value="col-sm-3" ng-click='setCSSClass(value3)' ng-checked="CSSClass==value3"> 

</div>//change button class here//

Let me know if this helps you ?

Upvotes: 1

Klante
Klante

Reputation: 141

ngClass needs an expression or {'className': expression } object.

EDIT

Since you want to update them seperatly i made a new DEMO

old code

You could do something like this

JS:

$scope.getClass = function(){
  return $scope.class;
}

HTML:

<button type="button" ng-class="getClass()" class="btn btn-primary" ng-click="setText($event)">two</button>

Upvotes: 1

Anand G
Anand G

Reputation: 3200

Making DOM related operations on Controller is not good practice. Create a directive and then do the operations. Edit: Try below code

// Code goes here

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

app.controller('MainCtrl', function($scope) {
  $scope.class = 'col-sm-12';
  $scope.textVal = 'click a button';
  $scope.selectedEvent = {};
  $scope.selectedButton = '';
  $scope.setText = function(element) {
    $scope.selectedEvent = element;
     $scope.textVal = element.currentTarget.innerHTML;
     $scope.selectedButton = element.toElement.id;
  };
  $scope.changeButtonText = function(){
    $scope.selectedEvent.currentTarget.innerHTML = $scope.textVal;
    
  }; 
});

app.directive('addClassName', function() {
  return {
        restrict: 'A',
        replace: false,
        link: function (scope,elm, attr) {
          elm.click(function( e, rowid ) {
             var btn = angular.element('#'+attr.btnselected);
             var inpt = angular.element('textVal');
             console.log(btn);
             //if (inpt.val() != '') {
                if (attr.txt == 'Large') {
                  btn.attr('class','');
                  btn.addClass('btn btn-primary col-sm-12');
                } else if (attr.txt == 'Medium') {
                  btn.attr('class','');
                  btn.addClass('btn btn-primary col-sm-6');
                } else {
                  btn.attr('class','');
                  btn.addClass('btn btn-primary col-sm-4');
                } 
             //}
             
          });
        }
     } 
});
/* Styles go here */

.col-sm-12 {
    color: #fff;
    background-color: #337ab7 !important;
    border-color: #2e6da4 !important;
}

.col-sm-6 {
   color: #fff;
   background-color: #f89406 !important;
   border-color: #f89406 !important;

}
.col-sm-4 {
   color: #fff;
   background-color: #000 !important;
   border-color: #000 !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app='myapp'>

  <head>
    <script data-require="jquery@*" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
    <script data-require="[email protected]" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <h1>Hello Plunker!</h1>
<div>
  <button type="button" id= 'one' class="btn btn-primary {{class}}" ng-click="setText($event)">one</button>
  <button type="button" id= 'two' class="btn btn-primary {{class}}" ng-click="setText($event)">two</button>
  <button type="button" id= 'three' class="btn btn-primary {{class}}" ng-click="setText($event)">three</button>
</div><br>
<div>
<input type="text" id = 'textVal' ng-model="textVal" ng-change="changeButtonText()">//change button name here//<br>

<input type="radio" name="button" txt="Large" btnSelected= '{{selectedButton}}' add-class-name>Large
<input  type="radio" name="button" txt="Medium" add-class-name btnSelected= '{{selectedButton}}'>medium
<input  type="radio" name="button" txt="Small" add-class-name btnSelected= '{{selectedButton}}'>Small 
</div>//change button class here//
</body>

</html>

Check this plnkr https://plnkr.co/edit/spYR8kcndwZ2yfqXQ9iW?p=preview

Upvotes: 1

Nimesh.Nim
Nimesh.Nim

Reputation: 388

Change your function to below..

$scope.changetoLarge = function(){
       angular.element($scope.selectedEvent.currentTarget).removeClass($scope.selectedE vent.currentTarget.className)

      angular.element($scope.selectedEvent.currentTarget).addClass('btn btn-primary col-sm-12')
 }
  $scope.changetoMedium = function(){
       angular.element($scope.selectedEvent.currentTarget).removeClass($scope.selectedEvent.currentTarget.className)
       angular.element($scope.selectedEvent.currentTarget).addClass('btn btn-primary col-sm-6')
   }
   $scope.changetoSmall = function(){
     angular.element($scope.selectedEvent.currentTarget).removeClass($scope.selectedEvent.currentTarget.className)
     angular.element($scope.selectedEvent.currentTarget).addClass('btn btn-primary col-sm-3')
 }

Upvotes: 1

Neil Atkinson
Neil Atkinson

Reputation: 774

First point: remember that class is a reserved word in javascript (i.e. don't use it for variables). People often use klass as a variable name instead.

Regarding your problem, there are lot's of ways to do this. My favourite would be a button directive with an isolate scope, but I'll try to keep this answer simple.

I think the following code does what you want.

<body ng-controller="MainCtrl">
  <h1>Hello Plunker!</h1>
  <div>
    <button type="button" class="btn btn-primary" ng-click="setText($event)">one</button>
    <button type="button" class="btn btn-primary" ng-click="setText($event)">two</button>
    <button type="button" class="btn btn-primary" ng-click="setText($event)">three</button>
  </div>
  <br>
  <div>
    <input type="text" ng-model="textVal" ng-change="changeButtonText()">//change button name here//
    <br>

    <input ng-click="changetoLarge()" type="radio" name="button">Large
    <input ng-click="changetoMedium()" type="radio" name="button">medium
    <input ng-click="changetoSmall()" type="radio" name="button">Small
  </div>//change button class here//
</body>

...

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

app.controller('MainCtrl', function($scope) {
  $scope.textVal = 'click a button';
  $scope.selectedButton = null;

  $scope.setText = function(event) {
    $scope.selectedButton = event.target;
    $scope.textVal = $scope.selectedButton.innerHTML;
  };
  $scope.changeButtonText = function(){
    $scope.selectedButton.innerHTML = $scope.textVal;
  };
  $scope.changetoLarge = function(){
    $scope.selectedButton.className = 'btn btn-primary col-sm-12'
  }
  $scope.changetoMedium = function(){
    $scope.selectedButton.className = 'btn btn-primary col-sm-6'
  }
  $scope.changetoSmall = function(){
    $scope.selectedButton.className = 'btn btn-primary col-sm-4'
  }
});

I didn't like the way you were referecing your dom elements, so I changed that. Other than that the main change is to set the class on the selectedButton directly, without using Angular interpolation in your html. Simple and gives you the result you want.

Upvotes: 1

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

I did change a lot of refactoring in code, as I don't like the way you are playing with DOM element.currentTarget.innerHTML. Refactoring will make less repeatative code by converting it to array and rendering the same using ng-repeat.

Also by having buttons array, that will contains each button information. Each element of array will represent a button & you can have any special information to button element.

Markup

<div>
  <button ng-class="button.class" class="btn btn-primary" ng-click="$parent.selected = $index" 
      ng-repeat="button in buttons">
        {{button.text}}
  </button>

  </div>
  <br>
  <div>
    <input type="text" ng-model="buttons[selected || 0].text" value="click a button">
    <br>

    <input ng-click="changetoLarge()" type="radio" name="button">Large
    <input ng-click="changetoMedium()" type="radio" name="button">medium
    <input ng-click="changetoSmall()" type="radio" name="button">Small
</div>

Code

$scope.changetoLarge = function() {
    $scope.buttons[$scope.selected].class = 'col-sm-12'
}
$scope.changetoMedium = function() {
    $scope.buttons[$scope.selected].class = 'col-sm-6'
}
$scope.changetoSmall = function() {
    $scope.buttons[$scope.selected].class = 'col-sm-4'
}
$scope.buttons = [{
    text: 'Feed',
    id: '1',
    class: "col-sm-12"
  }, {
    text: 'the',
    id: '2',
    class: "col-sm-12"
  }, {
    text: 'Input',
    id: '3',
    class: "col-sm-12"
}];

Demo Plunkr

Upvotes: 0

rory
rory

Reputation: 1438

You need to use ID's to uniquely identify the buttons

Upvotes: 0

Related Questions