AngularJS ng-switch-trigger within its own ng-switch-wrapper - javascript

I am trying to switch 2 buttons which are their own switch-triggers. For better understanding:
<span ng-switch on="patientSwitch">
<span ng-switch-when="edit">
<button ng-click="patientSwitch='save'">save</button>
</span>
<span ng-switch-when="save">
<button ng-click="patientSwitch"='edit'">edit</button>
</span>
</span>
Here is some jsFiddle: http://jsfiddle.net/g7vKz/

Use an object instead:
myApp.controller("PatientCtrl", function($scope) {
$scope.viewModel = { patientSwitch: "edit" };
});
And:
<span ng-switch on="viewModel.patientSwitch">
<span ng-switch-when="edit">
<button ng-click="viewModel.patientSwitch='save'">save</button>
</span>
<span ng-switch-when="save">
<button ng-click="viewModel.patientSwitch='edit'">edit</button>
</span>
</span>
Demo: http://jsfiddle.net/M7EX2/
ngSwitch creates a new scope, which means unless you use an object you will get this problem due to how prototypal inheritance works in JavaScript.
Very good post on the subject can be found here.

Related

Change style of an element in a forEach loop

Goal: Change style of an element in a forEach loop
Issue: Style not being applied
In my loop, if I console.log(element), I do get the right list of filtered elements.
Running this works, but I want my function to modify every element that match my filter:
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview[0].style.color = 'yellow'
All elements are correctly assigned.
function changeNotificationColor() {
// Notification button that opens list of notifications
let notifyButton = document.querySelector('.dropdown-toggle.o-no-caret[title="Conversations"]');
notifyButton.addEventListener('click', function () {
// List of notifications - each notification is contained in a .o_last_message_preview class
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview.forEach(function (element) { if (element.innerText.includes('Marine')) {element.style.color = 'yellow'}})
})
}
changeNotificationColor();
HTML Notifications Dropdown button:
<a class="dropdown-toggle o-no-caret" data-toggle="dropdown" data-display="static" aria-expanded="true" title="Conversations" href="#" role="button">
<i class="o_mail_messaging_menu_icon fa fa-comments" role="img" aria-label="Messages"></i> <span class="o_notification_counter badge badge-pill">366</span>
</a>
HTML template of a notification node (each notification creates one of these nodes):
<div class="o_preview_info">
<div class="o_preview_title">
<span class="o_preview_name">
You have been assigned to Backorder xx
</span>
<span class="o_preview_counter">
(1)
</span>
<span class="o_last_message_date ml-auto mr-2"> 3 minutes ago </span>
</div>
<div class="o_last_message_preview">
Marine
</div>
<span title="Mark as Read" class="o_discuss_icon o_mail_preview_mark_as_read fa fa-check"></span>
</div>
I don't know what your issue is, but it's not in the code that you showed; this works fine:
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview.forEach(function (element) { if (element.innerText.includes('Marine')) {element.style.color = 'yellow'}})
<div class="o_last_message_preview">This contains Marine</div>
<div class="o_last_message_preview">This does not</div>
<div class="o_other_message_preview">This has a different class</div>

AngularJS ng-click multiple calls

I wrote the next code, but when I click on the trash icon, the ng-click of this element is thrown, but the ng-click of the div container is thrown too, I don't need the second one, just the first call, could some body help me.
<div ng-if="order.selectedProducts === null || order.selectedProducts.length > 0"
class="cartCol hoverable" ng-repeat="product in order.selectedProducts track by $index"
ng-click="showProductDetailed(product)">
<div class="cartHeading" ng-bind="product.name"></div>
<a href="" class="trashIcon" ng-click="removeSelectedProduct(product);">
<i class="fa fa-trash"></i>
</a>
<div class="cartSizeInfo">
<span class="fltLft">{{product.productTypeName}}</span>
<span class="fltRht">Bs. {{product.price}}</span>
</div>
</div>
I had to put $event.stopPropagation(); after the first call.

How can I conditionally display HTML in a button using AngularJS?

I would like for a certain button element to contain plain text by default, but then contain HTML based on some variable in my Angular scope. My goal is to have the button say "Save", but then become disabled and display a loading wheel when clicked (while awaiting a response from a long AJAX request). The problem is, Angular is displaying the literal text of my ternary operator in the button rather than the result of the expression.
Here's what my button looks like:
<button type="submit" ng-disabled="IsLoading" ng-click="OnClick()">
{{ IsLoading === false ? "Save" : "<i class='fa fa-spinner fa-pulse'></i>" }}
</button>
When I change the HTML to just some plain text (for instance, "Loading..."), then it works fine.
How can I get it to display the result of the expression rather than the text of the expression itself? Thanks.
Side note: I tried to get a demo up and running, but it seems that I can't figure out how to wire up the Angular properly using JSFiddle. This is not the purpose of my question, but I'd really like to know where I'm going wrong so I can successfully make simple Angular demos in the future. Any advice is appreciated.
Check out this fiddle
<div ng-app="myApp" ng-controller="LoadingController">
<div style="float: left;">
<button type="submit" ng-disabled="IsLoading" ng-click="OnClick()">
<span ng-if="!IsLoading">
Save
</span>
<span ng-if="IsLoading">
<i class="fa fa-spinner fa-pulse"></i>
</span>
</button>
</div>
<div style="float: left;">
<button type="submit" ng-disabled="IsLoading" ng-click="OnClick()">
<span ng-if="!IsLoading">
Save
</span>
<span ng-if="IsLoading">
Loading...
</span>
</button>
</div>
</div>
js
angular.module("myApp",[]).controller('LoadingController', function LoadingController ($scope) {
$scope.IsLoading = false;
$scope.OnClick = function() {
$scope.IsLoading = true;
window.setTimeout(function() {
$scope.IsLoading = false;
}, 1000);
};
});
note:Angular 1.1.5 added a ternary operator support, and your fiddle pointing to older version, that's why its not working
I will suggest to google about the following 3 things which will serve your needs in any way. You will easily find it
ng-if
ng-show
ng-hide
ng-hide & ng-show will just play around by switching the css display property while ng-if will only add the html in case required condition equals to true.
<input type="checkbox" ng-model="flag" ng-init="flag= true">
<div ng-if="flag">
<h1>Welcome</h1>
<p>Hello mate.</p>
</div>
I think you are trying to achieve this
All codes are in that link. Posted important part code
<button type="submit" ng-disabled="IsLoading" ng-click="OnClick()">
<span ng-hide="IsLoading">Save</span>
<span ng-show="IsLoading"><i class='fa fa-spinner fa-pulse'></i </span>
</button>
WORKING DEMO
Try this:
https://plnkr.co/edit/rguvZ2Xs4lwl4QhA9Cv0
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $timeout) {
$scope.isLoading = false;
$scope.click = function() {
$scope.isLoading = true;
$timeout(function() {
$scope.isLoading = false;
}, 2000);
}
});
</script>
<style>
.loadingButton.loading span {
display: none;
}
.loadingButton.loading i {
display: block;
}
.loadingButton i {
display: none;
}
</style>
<button type="submit" ng-disabled="isLoading" ng-click="click()" class="loadingButton" ng-class="{'loading': isLoading}">
<span>Save</span>
<i class='fa fa-spinner fa-pulse'>icon</i>
</button>
The "Angular way" would by this
<button type="submit" ng-disabled="IsLoading" ng-click="OnClick()">
<span ng-hide="IsLoading">Save</span>
<i ng-show="IsLoading" class='fa fa-spinner fa-pulse'></i>
</button>
But you need to actually load Angular.js in your jsfiddle, i.e. <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script>
Working Plunker: http://plnkr.co/edit/ELYDsfIsbeo7sSvub6Nx?p=preview
Wrap your i element in an div with the ng-show or ng-hide element and then apply your expression to the value of either of those two directives.
Check this jsfiddle , Its a working example of what you are asking for
Updating a little code :
<div ng-app ng-controller="Controller">
<div style="float: left;">
<button type="submit" ng-disabled="IsLoading" ng-click="OnClick()">
{{ IsLoading === false ? "Save" : "<i class='fa fa-spinner fa-pulse'></i>" }}
</button>
</div>
<div style="float: left;">
<button type="submit" ng-disabled="IsLoading" ng-click="OnClick()">
{{ IsLoading === false ? "Save" : "Loading..." }}
</button>
</div>
</div>

Show/Hide(toggle) several blocks via Angular template engine

i need to show one and hide others.
in jquery i used 'this':
$('div').click(functiuon(){ this.show() });
maybe in Angular we can you use something like that?
<div class="toggle">
<span ng-click="this=!this ? true : false"></span><br/>
<span ng-if="this" >
111111111
</span>
</div>
<div class="toggle">
<span ng-click="this=!this ? true : false"></span><br/>
<span ng-if="this" >
2222222222222
</span>
</div>
etc this, this , this
I need to use only one varible for all blocks.
Any dom element interaction like clicking an element should be done within the directive and you can follow this to achieve what you want:
var app = angular.module('demoapp', []);
app.directive('toggleIt', function() {
return {
restrict: 'A',
link: function(scope, el, attrs) {
console.log(el.find('span'));
el.find('span').eq(0).on('click', function() {
el.find('span').eq(1).toggleClass('hide show');
});
}
};
});
.show{display:block;}
.hide{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='demoapp'>
<div data-toggle-it class="toggle">
<span>toggle1</span>
<br/>
<span class='spn show'>
111111111
</span>
</div>
<div data-toggle-it class="toggle">
<span>toggle2</span>
<br/>
<span class='spn hide'>
2222222222222
</span>
</div>
<div data-toggle-it class="toggle">
<span>toggle3</span>
<br/>
<span class='spn hide'>
3333333333333
</span>
</div>
</div>
You can use ng-hide for hiding an element on true or ng-show for showing an element on true:
<div class="toggle">
<span ng-click="pop1=!pop1 ? true : false"></span><br/>
<span ng-show="pop1" >
111111111
</span>
</div>
<div class="toggle">
<span ng-click="pop2=!pop2 ? true : false"></span><br/>
<span ng-show="pop2" >
2222222222222
</span>
</div>
You can use ng-if, ng-show, ng-hide, ng-class (in conjunction with css), and ng-switch.
ng-show, ng-hide and ng-if have kind of the same logic behind them (if the given variable is true/false, show/hide the following content). There are some performance differences between them, but this subject is out of scope.
Showing/hiding elements with ng-class is just a particular use case of it, but its achievable nonetheless.
To sum it up, ng-hide, ng-show, ng-if hide/show elements based on the truth evaluation of a given variable, while ng-class toggles a class, like
$('#someElement').toggleClass('randomClassName');
Example:
HTML
<div ng-app="exampleApp" ng-init="switchr1 = true; switchr2 = true; switchr3 = true; switchr4 = show; ">
<h2>ng-if</h2>
<div class="toggle">
<span ng-click="switchr1 = switchr1 ? false : true">click me</span><br/>
<span ng-if="switchr1" >
shown by ng-if
</span>
</div>
<h2>ng-show</h2>
<div class="toggle">
<span ng-click="switchr2 = switchr2 ? false : true">click me</span><br/>
<span ng-show="switchr2" >
shown by ng-show
</span>
</div>
<h2>ng-hide</h2>
which is the same thing as ng-show, but with reversed logic<br>
<div class="toggle">
<span ng-click="switchr3 = switchr3 ? false : true">click me</span><br/>
<span ng-hide="!switchr3" >
shown by ng-hide
</span>
</div>
<h2>ng-class</h2>
<div class="toggle">
<span ng-click="switchr4 = (switchr4=='show') ? 'hide' : 'show'">click me</span><br/>
<span ng-class="switchr4" >
hidden by ng-class
</span>
</div>
</div>
Notice, that you initiate switchr1, switchr2 and so on in the ng-init directive. You could have also done that in the js code, using $scope, but I did it this way for the sake of simplicity.
JS
var app = angular.module('exampleApp', []);
CSS
.hide {
display: none;
}
.show {
display: initial;
}
I also wrote some working code/full example for you:
http://codepen.io/VanTudor/pen/EKYZwM

How to change html inside a span

I want to change the content of a span in my form
HTML:
<form action="javascript:submit()" id="form" class="panel_frame">
<label>Origin:</label>
<div class="input-group" id="input-group">
<input type="text" id="origin" name="origin" class="form-control">
<span class="input-group-btn">
<button id="btn-default" class="btn btn-default" type="button">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>
</span>
</div>
What I want change is che content of <span class="input-group-btn"> with
<button id="btn-default" class="btn btn-default" type="button">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
So what change is: the icon pushpin to remove and the action useCurrentPosition to clearPosition.
I' using jquery and despite I've read other answer about similar question on Stack like: How can I change the text inside my <span> with jQuery? and how to set a value for a span using JQuery I haven't solved the issue.
I tried:
$("#input-group span").html('
<button id="btn-default" class="btn btn-default" type="button" onclick="br_bus.useCurrentPosition()">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>
');
,giving an id to the span and also modify the full div, but none solved my problem.
What am I missing?
Here's a way to overcome the problem of changing the onclick attribute, which is bad practice, without storing a Global var, and using jQuery delegation (learn to use it, it's really good):
$(document).on('click','.btn', positionChange); // Give that button an id on his own and replace '.btn' with '#newId'
// Not using an anonymous function makes it easire to Debug
function positionChange(){
var $btn = $(this), // Caching jQuery elements is good practice
$span = $btn.find('span'), // Just caching
pushpinApplied = $span.hasClass('glyphicon-pushpin'); // Check which icon is applied
( pushpinApplied ) ? useCurrentPosition() : clearPosition();
$span.toggleClass( 'glyphicon-pushpin glyphicon-remove' );
}
Rather than changing the function called in the onclick attribute I suggest having a flag in one function to define the logic it should follow.
For example:
function positionChange(this){
var $this = $(this);
if(!$this.data("currentpositionused")){
//useCurrentPosition() code here
$this.data("currentpositionused", true);
}
else {
//clearPosition() code here
$this.data("currentpositionused", false);
}
Then change your HTML to:
<button class="btn btn-default" type="button" onclick="positionChange(this)">
If you want to change only the onclick attribute of the button inside the particular span you can use the following in your script.,
$(document).ready(function(){
$("span.input-group-btn button").attr("onclick","clearPosition()");
});
EDIT
$(document).ready(function(){
$("span.input-group-btn button").attr("onclick","clearPosition()");
$("span.input-group-btn button span").attr("class","Your_class");
});
And also learn about how to change/add/remove attribute values....
Try this:
$("span.input-group-btn").html('<button class="btn btn-default" type="button" onclick="clearPosition()">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>');
Is it like This ?
how to change onclick event with jquery?
$("#id").attr("onclick","new_function_name()");
jquery change class name
$("#td_id").attr('class', 'newClass');
If you want to add a class, use .addclass() instead, like this:
$("#td_id").addClass('newClass');

Categories

Resources