I have a small angular app going and I'm stuck on something that seems so simple! (New to angular here).
Scenario:
I have two buttons on the page that should toggle the display of their associated content.
Few things need to happen:
Buttons:
1. Should be an active button on page load (also displaying its appropriate content)
2. When other button is clicked, this should change the active state (for button and associated content)
3. If active button is clicked, nothing should happen. It should stay active.
Can't figure out how to do this. All help is appreciated.
Code
<div class="toggle-btns">
<button class="toggle-btns__btn toggle-btns__btn--active">Button 1</button>
<button class="toggle-btns__btn" >Button 2</button>
</div>
<div class="content-one">
<!-- content here -->
</div>
<div class="content-two">
<!-- content here -->
</div>
If you can't figure this out, you clearly haven't tried very hard ;)
I'd do something like this:
<div class="toggle-btns">
<button class="toggle-btns__btn" ng-click="content = 1" ng-class="{ toggle-btns__btn--active: content == 1}">Button 1</button>
<button class="toggle-btns__btn" ng-click="content = 2" ng-class="{ toggle-btns__btn--active: content == 2}">Button 2</button>
</div>
<div class="content-one" ng-show="content == 1">
<!-- content here -->
</div>
<div class="content-two" ng-show="content == 2">
<!-- content here -->
</div>
In your controller:
angular.module('Blah')
.controller('MainCtrl', ['$scope', function($scope) {
$scope.content = 1;
});
There are literally 1 000 000 ways of doing that.
One way of using data binding in view:
<div class="toggle-btns" ng-init="active = true">
<button ng-click="active = true" class="toggle-btns__btn toggle-btns__btn--active">Button 1</button>
<button ng-click="active = false" class="toggle-btns__btn" >Button 2</button>
</div>
<div ng-if="active" class="content-one">
<!-- content here -->
<p>content1</p>
</div>
<div ng-if="!active" class="content-two">
<!-- content here -->
<p>content2</p>
</div>
Plnkr here: http://plnkr.co/edit/bVK9VUum7KRLNccgPc5D?p=preview
Related
I have a few buttons in the HTML file code with Bulma similar like this:
<a class="button" data-target="A">Section A</a>
<a class="button" data-target="B">Section B</a>
<a class="button" data-target="C">Section C</a>
And there are a few section like this which can interact with the buttons:
<div id="A" class="contentswitch">
<article class="message">
<div class="message-header" id="h1">
<p>Section A-1</p>
</div>
<div class="message-body">
Message 1 of section A
</div>
<div class="message-header">
<p>Section A-2</p>
</div>
<div class="message-body">
Message 2 of section A
</div>
</article>
</div>
As I add code like this in the JS, it can add a class called "is-hidden" to all the div ejectment which contains "contentswitch" class.
$("a.button").on("click", function(){
$("div.contentswitch").addClass("is-hidden");
});
What can I do if I want to remove the class ("is-hidden") from specific div element, like if I click the button of Section A, then it add "is-hidden" class to all the div element contain content switch then remove it from the div element with the id "A"?
Thank you so much
You can use data-target to connect the clicked button to the div you want to show. And hide the rest of them.
Also, use button iso a tag. a tag has a specific purpose in HTML and should be used only in combination with href attribute.
const buttons = $('.button');
const contentSwitchDivs = $('.contentswitch');
buttons.on("click", function(){
const btnTarget = $(this).data('target')
const contentToShow = $(`#${btnTarget}`)
contentSwitchDivs.not(btnTarget).hide();
contentToShow.show();
});
.contentswitch {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button" data-target="A">Section A</button>
<button class="button" data-target="B">Section B</button>
<button class="button" data-target="C">Section C</button>
<div id="A" class="contentswitch">
A contentswitch
</div>
<div id="B" class="contentswitch">
B contentswitch
</div>
<div id="C" class="contentswitch">
C contentswitch
</div>
I have a block of HTML:
<form>
<section>
<div class="row normalTopPadding personalInfomation">
<!--Loads of HTML and Stuff-->
<a id="myButton" class="reg-next-button btn btn-default">Next</a>
</div>
</section>
<section>
<div class="row normalTopPadding employerInfomation">
<!--Loads of HTML and Stuff-->
<a id="myButton" class="reg-next-button btn btn-default">Next</a>
</div>
</section>
<section>
<div class="row normalTopPadding accountInfomation">
<!--Loads of HTML and Stuff-->
<a id="myButton" class="reg-next-button btn btn-default">Next</a>
</div>
</section>
</form>
What I'm trying to achieve is for every time a button is clicked to hide the panel that the button has been clicked from and display the next panel down, so..
<script>
$('.personalInfomation .reg-next-button, .employerInformation .reg-next-button', .accountInformation .reg-next-button').click(function (e) {
// Get the section that this button lives in
var form = $(this).closest("section");
//validation and other functions commented out for ease of reading
// Hide this section...
section.toggle();
// And show the next section
section.next().toggle();
});
</script>
Although this hides the section that the button has been clicked from it doesn't display the next one down.
Could someone point out my mistake?
Thanks,
C
you can check if next section is available or not and then hide current section.
NOTE: there is extra single quote in your jquery selector, which i have removed. Also, you have declared variable form but used section, so rename form to section
$('.personalInfomation .reg-next-button, .employerInformation .reg-next-button, .accountInformation .reg-next-button').click(function (e) {
// Get the section that this button lives in
var section = $(this).closest("section");
//validation and other functions commented out for ease of reading
// Hide this section...
var $next = section.next();
if($next.length>0) { // check condition first and then hide current section and show next
section.toggle();
// And show the next section
$next.toggle();
}
});
Instead of putting each section in button click handler you can generalise it and improve your code so that when you add new section you don't need to change your script.
NOTE - do not use same id for multiple html elements as you have used it for button
$(function(){
$('section .row.normalTopPadding .reg-next-button').on('click', function (e) {
var section = $(this).closest("section");
var $next = section.next();
if($next.length>0) { // check condition first and then hide current section and show next
section.addClass('hide');
$next.removeClass('hide');
}
});
});
.hide {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<section>
<div class="row normalTopPadding personalInfomation">
<!--Loads of HTML and Stuff-->
This is SECTION 1
<a id="myButton" class="reg-next-button btn btn-default">Next</a>
</div>
</section>
<section class="hide">
<div class="row normalTopPadding employerInfomation">
<!--Loads of HTML and Stuff-->
This is SECTION 2
<a id="myButton" class="reg-next-button btn btn-default">Next</a>
</div>
</section>
<section class="hide">
<div class="row normalTopPadding accountInfomation">
<!--Loads of HTML and Stuff-->
This is SECTION 3
<a id="myButton" class="reg-next-button btn btn-default">Next</a>
</div>
</section>
</form>
You may try to hide all the sections first, and then on click of a, find the next .row to be shown.
See the demo below:
$('.row').not(':first').css('display', 'none');
$('.row > a').click(function() {
$(this).parents('.row').toggle();
$(this).parents('section').next('section').find('.row').toggle();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<section>
<div class="row normalTopPadding personalInfomation">
<!--Loads of HTML and Stuff-->
<a id="myButton" class="reg-next-button btn btn-default">Next 1</a>
</div>
</section>
<section>
<div class="row normalTopPadding employerInfomation">
<!--Loads of HTML and Stuff-->
<a id="myButton" class="reg-next-button btn btn-default">Next 2</a>
</div>
</section>
<section>
<div class="row normalTopPadding accountInfomation">
<!--Loads of HTML and Stuff-->
<a id="myButton" class="reg-next-button btn btn-default">Next 3</a>
</div>
</section>
</form>
I have hide and show functionality on dynamically generated cards after form submission.
{{#each newaction}}
<div class="workflowcard">
<div class="module-card-small">
<div class="res-border"></div>
<div class="card-img">{{team}}</div>
<div class="res-content">
<div class=" newaction-name">{{action_title}}</div><hr>
<div class="newaction-des">{{description}}</div>
<!-- <div class=" due-on">Due on:{{d_date}}</div><hr>-->
</div>
<div class="due">
Due on:
<div>
<div class="day-stamp">{{weekday d_date}}</div>
<div class="date-stamp">{{date d_date}}</div>
<div class="month-stamp">{{month d_date}}</div>
</div>
</div>
{{> actioncardsubcontent}}
</div>
<div class="btn-box">
<button type="button" class="cancelsub">Hide Option</button>
<button type="submit" class="createbtnsub">Show Options</button>
</div>
</div>
</div>
{{/each}}
</div>
</div>
<template name="actioncardsubcontent">
<div class="subcontent" >
<div class="modulepath"><div>{{module_list}}</div></div>
<div class="linkto"><div>Linked To: <div class="linkto-color">{{link}}</div></div></div>
<div class="description"><div>Notes:<br>{{description}}</div></div>
</div>
</template>
When I click on show options button the action card subcontent is displaying and when I click on hide option it is hiding.
The problem is, the hide and show functionality is applying for all the cards which are creating dynamically at a time when I click on single card. I understand the reason is I have given the class name for the buttons. So how to stop that and make it work to current target.
Here is my JS:
Template.actioncardsubcontent.rendered = function(){
this.$(".subcontent").hide();
};
Template.workflow.events({
"click .createbtnsub":function(){
$('.subcontent').show();
},
"click .cancelsub":function(){
$('.subcontent').hide();
}
What you need to do is give a unique ID for each iteration to your cards div class attribute.
in JSTL usually has indexId attribute. You can use that and set your class.
Sample:
{{#each newaction indexId="i"}}
{{/each}}
<div class="btn-box">
<button type="button" class="cancelsub<%=i%>">Hide Option</button>
<button type="submit" class="createbtnsub<%=i%>">Show Options</button>
</div>
In your javascript:
use i to hide.
You have a couple of options here. The one I prefer is to put everything in the {{#each}} into its own template. If you do that, you can put the button click events inside of the child template's event which makes it much simpler to manipulate your data. An example:
Templates:
<template name='workflow'>
{{#each newaction}}
{{> card}}
{{/each}}
</template>
<template name='card'>
<div class="workflowcard">
<div class="module-card-small">
<div class="res-border"></div>
<div class="card-img">{{team}}</div>
<div class="res-content">
<div class=" newaction-name">{{action_title}}</div><hr>
<div class="newaction-des">{{description}}</div>
</div>
<div class="due">
Due on:
<div>
<div class="day-stamp">{{weekday d_date}}</div>
<div class="date-stamp">{{date d_date}}</div>
<div class="month-stamp">{{month d_date}}</div>
</div>
</div>
{{> actioncardsubcontent}}
</div>
<div class="btn-box">
<button type="button" class="cancelsub">Hide Option</button>
<button type="submit" class="createbtnsub">Show Options</button>
</div>
</div>
</div>
</template>
Javascript (template.$ docs):
Template.cards.events({
"click .createbtnsub":function(event, template){
template.$('.subcontent').show();
},
"click .cancelsub":function(event, template){
template.$('.subcontent').hide();
}
});
-- OR --
You can do a better DOM query.
Without more info on what is actually in the actioncardsubcontent template or proper testing, this is a best guess on what you're trying to find. You should be able to tweak this query to meet your specific needs easily enough through trial and error. Please read the jQuery Traversing docs as it should clear this up a bit for you.
Template. workflow.events({
"click .createbtnsub":function(event, template){
$(event.target).siblings('.due').find('.subcontent').show();
},
"click .cancelsub":function(event, template){
$(event.target).siblings('.due').find('.subcontent').hide();
}
});
So, I was working through a bug concerning the ngOptions directive within an ngInclude. I came across sample code showing the directive working, copy-pasted it in, and saw that both my (non-functioning) old ngOptions was now functioning. I'm curious as to how that worked.
I no longer have access to the old code, but it looked something like this:
HTML:
<div ng-controller="Widget" ng-class="{{widget.properties.styleClass}}" ng-init="optionsShow = false" class="irrelevant" "style = "height:100%;" >
<div>
<!-- ... -->
<!-- my options button-->
<span class="icon" ng-click="showOptions(); adjustHeight()">
options
</span>
</div>
<!-- Options div shows only when button is clicked -->
<!-- Canvas Options -->
<div class="options command-options" ng-show="optionsShow" style="height:50%;">
<!-- ... -->
<span ng-click="addCommand()">Add New Command +</span>
<div class="row">
<div class="col-xs-3">
<label>Command to edit:<br/>
<select ng-model="selected" ng-change="verifySelected()" ng-options="object as object.index for object in widget.objects"></select>
<!-- The select here wouldn't show any options no matter what I did -->
</label>
</div>
</div>
</div>
<!-- ... -->
JS, within the controller:
//...
$scope.widget.objects = [];
//...
$scope.addObject = function(){
$scope.widget.objects.push({index:$scope.widget.objects.length + 1, type:$scope.objectTypes[0]});
}
$scope.addObject();
$scope.verifySelected = function(){
console.log("irrelevant")
}
The working HTML now looks like this:
<div ng-controller="Widget" ng-class="{{widget.properties.styleClass}}" ng-init="optionsShow = false" class="irrelevant" "style = "height:100%;" >
<div>
<!-- ... -->
<!-- The following comments help make thing work in the options div. Don't ask why, I don't know. Just don't remove them
<b>Total Things:</b> {{totalThings}}
<p ng-repeat="oneThing in things">
<input value="{{oneThing.text}}" type="checkbox" ng-model="oneThing.checked" />
{{oneThing.text}}
</p>
<ul class="unstyled">
<li ng-repeat="oneThing in things">
<span>{{oneThing.text}}</span>
</li></ul>-->
<!-- my options button, everything below this point unchanged-->
<span class="icon" ng-click="showOptions(); adjustHeight()">
options
</span>
</div>
<!-- Options div shows only when button is clicked -->
<!-- Canvas Options -->
<div class="options command-options" ng-show="optionsShow" style="height:50%;">
<!-- ... -->
<span ng-click="addCommand()">Add New Command +</span>
<div class="row">
<div class="col-xs-3">
<label>Command to edit:<br/>
<select ng-model="selected" ng-change="verifySelected()" ng-options="object as object.index for object in widget.objects"></select>
<!-- The select here wouldn't show any options no matter what I did -->
</label>
</div>
</div>
</div>
<!-- ... -->
The working JS controller now also has these lines:
$scope.totalThings = 5;
//...
$scope.things = [{text: 'This is needed in order to make things work... for some reason.'}];
What happened to make it work?
ngOptions works as expected with your old code, I have made a plunker with your old code widget plunker$scope.widget = {}; and $scope.objectTypes = ["something"]; are added to make your code working.
I have a ng-repeat loop, which displays individual panels (one for each loop iteration). In each panel I have a 'mark as read' button that has a ng-click event. I want to be able to hide the panel that the mark as read button is clicked on, but so far I can only get all the panels to show and hide, not the individual selected panel.
How can I get the ng-click to hide the selected panel?
Thanks
Sorry here is some code of what I am doing now:
The panel section:
<section class="card" ng-repeat="item in notifications" ng-hide="msgRead">
<div class="item item-header notification wrap">
<h2>{{item.title}}</h2>
<div class="notification-content">
{{item.text}}
</div>
<button class="button button-block button-stable" ng-click="markAsRead(item.id)">
Mark As Read
</button>
</div>
</section>
And this is my controller function:
$scope.msgRead = true;
$scope.markAsRead = function (id) {
$scope.msgRead = $scope.msgRead === false ? true : false;
};
Stephen
You can write like:
<section class="card" ng-repeat="item in notifications" ng-hide="item.readonly">
<div class="item item-header notification wrap">
<h2>{{item.title}}</h2>
<div class="notification-content">
{{item.text}}
</div>
<button class="button button-block button-stable" ng-click="item.readonly = true">
Mark As Read
</button>
</div>
</section>
You don't need to write a scope method for this.