AngularJS icon changes with a list? - javascript

I'm working in AngularJS / Jade, and I need to change an icon when you click on something. Currently I have the following code:
a(onclick='return false', href='#general', data-toggle='tab') General
span.glyphicon(ng-class='isGeneralChanged(selected) ? "glyphicon-ok-circle" : "glyphicon-adjust"')
Then below that:
.form-group
label Has the design entered?
toggle-switch(model='selected.general_engineer_made_inspection', on-label='Yes', off-label='No')
So basically the problem I have is that here it's easy, it's either "yes" or "no" and that changes the icon, but the next tab is just a list of names that once you just click on one the icon in the tab should change. I'm not sure how I could solve this. ng-click event?

Use a boolean to hide,show,toggle elements. Angular makes this easy. (look up ng-show, ng-hide, ng-switch)
Also, I prefer to use ng-class this way:
i.fa.fw(ng-class="{true:'fa-lock', false:'fa-unlock'}[locked]")
The initial value is set in the controller:
$scope.locked = true;
Then, a button that toggles the boolean (and thus, the class) is added to the view. Note the ng-click="locked=!locked"
button(ng-click="locked=!locked" ng-switch="locked")
span(ng-switch-when="true") Lock
span(ng-switch-when="false") Unlock
We can also employ the boolean to hide or show whatever we'd like:
pre(ng-show="locked") Locked!
pre(ng-show="!locked) Unlocked!
Here's a Plunk http://plnkr.co/edit/0PDT2cpQGwFKsu8h1hdg?p=preview that covers all of the above (albeit, in HTML, not Jade). The demo uses FontAwesome.

Related

Identifying Which Toggle Was Toggled - Office UI Fabric - React

I am trying to use multiple toggles in my add-in but having trouble identifying which one was toggled.
I am able to get the id of the toggle in most cases, but if a user clicks on the smaller knob within the toggle, I am unable to get the toggle's id.
From the example above, if I click on the toggle thumb, where the red arrow points, I get the following output as the target.id
I have no way to identify which toggle this came from and do not believe I can set the id of the toggle thumb.
When the user clicks anywhere in the green sections, I get the following log where I can grab the ID and do conditional logic.
Before reporting this as a bug on github, I wanted to make sure I wasn't doing something wrong. I came across this which was similar but not what I am looking for: https://github.com/OfficeDev/office-ui-fabric-react/issues/6753
This code pen will show the issue:
https://codepen.io/rocketlobster5/pen/eYOvGjz
I don't think it should considered as a bug, to get the element that the event listener is attached to currentTarget property should be used instead of target.
The following example demonstrates how to retrieve id of toggle element:
private handleChange(ev: React.MouseEvent<HTMLElement>, checked: boolean) {
console.log(ev.currentTarget["id"]);
}
Modified codepen

Two way binding for checkbox inside an accordion not workiing

In my angular 1.5 html5 application, I have an accordion group and inside it's body I have Couple of check-boxes. Since direct scope binding will not work inside accordion, I'm using ng-click event as attached.
This works as expected, I'm getting click events with correct value.
I have another reset button on screen, when user clicks this button I have to reset all filters including the checkbox inside the accordion. Even after I reset the model value to false, checkbox still shows as checked. I know this is because the binding is not there.
How can I update the checkbox value from javascript. Is there any angular way. I'm not a big fan of JQuery.
Regards,
Nixon
We faced a similar issue with the data bindings while using accordian.
Instead of using directly model variable, we created an object of it.
For eg, instead of using $scope.includeLocalParties, try using $scope.checkbox.includeLocalParties.
Also initialize it in your controller. Something like this:
$scope.checkbox = { includeLocalParties : false};
Hope it helps!

Bootstrap collapse section and expand another with one button

I have a bunch of HTML fields logically separated as such: half the fields reside in: div id="general" and the other half reside in: div id="advanced"
What I'm trying to implement (and failing) is the following:
The fields in the general div to be shown (by default). A button with the caption "Advanced" shown. And the fields in the advanced div to be hidden.
When this button is clicked, the following should occur:
General section collapses hiding all it's fields
Advanced section expands showing all it's fields
Button caption is changed to "General".
Subsequent clicks toggles the above.
E.g. upon the next click, the advanced section now is hidden, general section now is shown, and button caption changes to "Advanced"
Notes: This seems trivial but being new to web front-end, I can't get this easily. If my div section is incorrect, then scrap it. I suspect I'm on the right track, and just need some jQuery code to collapse and expand divs.
Below are my attempts:
I used the Bootstrap collapse plugin with accordian markup, but this isn't what I want. It comes close though, but each section has a heading/button. I'd like one heading/button to toggle each section in an opposite manner.
I used the Bootstrap collapse plugin without the accordian markup, but same result as attempt 1 - two button again.
I tried using jQuery to do this dynamically, but can't get the logic (or syntax) correct.
I'm using Bootstrap, but happy to go with jQuery (or JavaScript) solution if it can't be done solely in Bootstrap with the collapse plugin.
You can do it using jquery by toggling a class on element which decides which fields to be shown.
for e.g. Take an outer div, and put general and advanced div inside outer div and show only the fields based on outer div class like advanced using css. And bind a button to toggle the class on the outer div.
Checkout JSFiddle here : http://jsfiddle.net/eqhw2mxx/2/
Check the JSFiddle :- JSFiddle
$("#advanced").addClass('hide');
$(".button").click(function(){
$("#advanced").toggleClass('hide');
$("#general").toggleClass('hide');
if($(this).attr("value") == "Advanced"){
$(this).attr("value","General");
}
else if($(this).attr("value") == "General"){
$(this).attr("value","Advanced");
}
});

How do I destroy all instances of Bootstrap Popover?

I have a single page app using Backbone, and whenever I over over something and then click the "back" button, the popover forever stays.
I want to destroy all instances of popover when a new instance is loaded.
Finding the popovers that are created through the data API is not difficult and has been covered in other answers like those of David Mulder and Amir Popovich. You just do:
$("[data-toggle='popover']").popover('hide');
Or you can use destroy if you need to or prefer to.
The challenge is to handle those popovers that are created dynamically.
Marking the Elements with Popovers
I would implement something like this. I'd override the default popover method and I'd try to perform this override as early as possible so that everything that needs a popover uses my override. What it does is just mark elements that use a popover with a class. Bootstrap does not mark them itself:
// Override popover so as to mark everything that uses a popover.
var old_popover = $.fn.popover;
function my_popover() {
this.addClass('marked-as-having-a-popover');
return old_popover.apply(this, arguments);
}
$.fn.popover = my_popover;
Then to clear everything before the unloading, I'd put in the code that detects the unloading the following:
$(".marked-as-having-a-popover").popover('hide');
Or it could use destroy rather than hide if testing shows that it works better for your use-case.
Now, the method above will work if the override happens early enough and you do not have a page where multiple jQueries are loaded. (Yep, this is possible.) I use something similar to deal with tooltips in one of my applications so I know the principle is sound. It so happens that in my app, all tooltips are created by my code so there is no risk of missing something.
Finding All Elements with Popovers, Even Unmarked
If you are in a situation where a popover can be created without being marked (I call this an "escapee"), then you need to query the whole DOM and find which elements have popovers. There is no shortcut here. You cannot rely on attributes like data-content because popovers can be created wholly dynamically (i.e. without any of the data- attributes). Also, all kinds of elements can get popovers, so you cannot reliably assume that only button elements will have a popover. The only surefire way to find everything that needs handling is to look at each element in the DOM and check whether it has a popover:
// Obviously this is quite expensive but in a situation where there *can* be escapees
// then you have to check all elements to see if they have a popover.
$("*").each(function () {
// Bootstrap sets a data field with key `bs.popover` on elements that have a popover.
// Note that there is no corresponding **HTML attribute** on the elements so we cannot
// perform a search by attribute.
var popover = $.data(this, "bs.popover");
if (popover)
$(this).popover('hide');
});
Again, destroy could be used rather than hide.
Proof of Concept
Here is a fiddle that illustrates the entire thing:
"Add a Dynamic Popover" simulates code that would add a popover when the override is in effect.
"Add an Escapee" simulates code that would add a popover and somehow manage to use the original Bootstrap code.
"Clear Marked" clears only the marked popovers.
"Clear All" clears every single popover marked or not.
try with this:
$('YOUR_ELEMENT_SELECTOR').popover('dispose');
reference url: https://getbootstrap.com/docs/4.1/components/popovers/
Its very simple, just you have to call one function popover() with argument "destroy" to destroy the popover. It will destroy all popovers which is created by $("[data-toggle=popover]").popover();
you can check documentation for more options and arguments of popover().
I suggest you to destroy popovers with having specific class name instead of using following code.
$("[data-toggle='popover']").popover('destroy');
The above code will destroy all popovers in the page. So instead of this, use class selector.
$(".YourClassName").popover('destroy');
If you have problems and need to remove all for sure:
$('.popover').remove();
will help (Popover automatic add this class, even for dynamicly created objects). It destroys all the popover DOM-Object incl. callbacks, etc.
But thats the rough way. Typically I displose all by popover class (clean way) and to be sure I do a hard clean up after. Works for me fine!
$('.popover').popover('dispose');
$('.popover').remove();
If you like to remove all execpt one, use a filter() with :not-Selector
$('.popover').filter(':not(#yourID)').popover('dispose');
$('.popover').filter(':not(#yourID)').remove();
popover adds also a id with a random number
#popoverxxxxx where xxxxx is a five digit number.
this helps sometimes to compare popovers. Of cause this could also be used to identify the popovers.
Something generic like this (assuming you're using data-bindings) should do the trick:
$('[data-toggle="popover"]').popover('hide')
or the more extreme call
$('[data-toggle="popover"]').popover('destroy')
though I doubt that would make sense often. Still to address the specific bug you're encountering you should create a minimal test case so that that bug itself can be addressed.
Oh and if you specifically want to check for open popovers you can use .data("bs.popover").$tip.parent().length (which is a bit of an hack), for example:
$('[data-toggle="popover"]:eq(0)').data("bs.popover").$tip.parent().length == 1
You can hide all popovers by using this:
$("[data-toggle='popover']").popover('hide');
You can destroy all popovers by using this:
$("[data-toggle='popover']").popover('destroy');
The difference between hide and destory is that when you hide a popover you do not need to reactive it, but when you destroy it you do.
Check out my JSFIDDLE and then:
Click on all popovers and then click hide. After clicking hide you can click on the popovers again.
Click on all popovers and then click destroy. After clicking destroy try clicking on the popovers again and see that nothing will happen since they are destroyed. In order to make them functional again, you will need to click on reactive and then try.
Popovers must be initialized manually, so you know exactly what you have to destroy because you did initialize it.
You should just call the destroy function with the same selector.
Or maybe I am missing something ?

Create button in rendered template

Let me get straight to the point :). In my project I'm rendering an template, with jquery-tmpl, like this:
box = $.tmpl('<div> [....] <button></button> [....] </div>')
If I insert box in the DOM, nice JQuery buttons show up. According to the DOM (inspected with Chrome) the buttons have already been converted to jquery-ui buttons.
The question: I want to modify these buttons, but - after trying for two hours - I can't figure out how to. I figured
$('button', box).button({'icons' : {'primary' : 'icon name'}})
for example, would do the trick, but it doesn't. How do I modify my buttons?
jQueryUI generally follows a pattern of updating widgets after they've been initialized on DOM elements:
$("#foo").button("option", "optionname", value);
So to update the button's icon after init, you'd do this:
$("button", box).button("option", "icons", {primary:'icon-name'});

Categories

Resources