AngularJS - Expand Elements - javascript

I'm making FAQ page with AngularJS and I want expand/collapse elements.
This is my HTML:
<div id="faq" class="">
<div class="faq-item" collapse>
<div class="expend-element">
<div class="question">
<div class="text">Question 1</div>
</div>
</div>
<div class="answer">ANSWER 1</div>
</div>
<div class="faq-item" collapse>
<div class="expend-element">
<div class="question">
<div class="text">Question 2</div>
</div>
</div>
<div class="answer">ANSWER 2</div>
</div>
<div class="faq-item" collapse>
<div class="expend-element">
<div class="question">
<div class="text">Question 3</div>
</div>
</div>
<div class="answer">ANSWER 3</div>
</div>
</div>
My Directive:
return {
scope: {},
template: "<div class='faq-item' ng-click='expend()' ng-class='{ expended: active }'><div ng-transclude></div></div>",
replace: true,
transclude: true,
link: function(scope) {
scope.active = false;
scope.expend = function() {
scope.active = !scope.active;
};
}
};
This works fine, but it has one problem.
My main aim was to expand was only one element, but this expands all the elements.
How can I make this?

Related

How to implement a component to show a number of div elements initially, and then show a number of more elements?

I have build a review-system in HTML, PHP and AJAX so users can post their opinion on a website. This review-system consists of two scripts:
PHP-script:
<?php
... code
?>
<div class="overall_rating">
<span class="num"><?=number_format($reviews_info['overall_rating'], 1)?></span>
<span class="stars"><?=str_repeat('★', round($reviews_info['overall_rating']))?></span>
<span class="total"><?=$reviews_info['total_reviews']?> reviews</span>
</div>
Schrijf review
<div class="write_review">
<form>
<input name="name" type="text" placeholder="Uw voornaam" required>
<input name="rating" type="number" min="1" max="5" placeholder="Uw beoordeling (1-5)" required>
<textarea name="content" placeholder="Schrijf hier uw review" required></textarea>
<button type="submit">Plaats review</button>
</form>
</div>
<?php foreach ($reviews as $review): ?>
<div class="review">
<h3 class="name"><?=htmlspecialchars($review['name'], ENT_QUOTES)?></h3>
<div>
<span class="rating"><?=str_repeat('★', $review['rating'])?></span>
<span class="date"><?=time_elapsed_string($review['submit_date'])?></span>
</div>
<p class="content"><?=htmlspecialchars($review['content'], ENT_QUOTES)?></p>
</div>
<?php endforeach ?>
HTML-/AJAX-script:
<div class="container wow fadeInDown content home" data-wow-duration="500ms">
<div class="reviews"></div>
<script>
const reviews_page_id = 1;
fetch("reviews.php?page_id=" + reviews_page_id).then(response => response.text()).then(data => {
document.querySelector(".reviews").innerHTML = data;
document.querySelector(".reviews .write_review_btn").onclick = event => {
event.preventDefault();
document.querySelector(".reviews .write_review").style.display = 'block';
document.querySelector(".reviews .write_review input[name='name']").focus();
};
document.querySelector(".reviews .write_review form").onsubmit = event => {
event.preventDefault();
fetch("reviews.php?page_id=" + reviews_page_id, {
method: 'POST',
body: new FormData(document.querySelector(".reviews .write_review form"))
}).then(response => response.text()).then(data => {
document.querySelector(".reviews .write_review").innerHTML = data;
});
};
});
</script>
</div>
I don't know how to implement a component to show a number of div elements initially, and then show a number of more elements. For example: when opening the website only show 10 reviews initially (but keep the overall rating), and after clicking on a component show 10 more.
So it's not about filtering data, but about showing or not showing div elements. I tried to reproduce this with a simple example from Stackoverflow (see snippet below), but I still can't figure out how to implement this into my own code. Do you have any idea how to achieve this?
Example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="reviews">
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 1</div>
<div class="review">data 2</div>
<div class="review">data 20</div>
</div>
show more
<script>
var limit = 5;
var per_page = 5;
jQuery('#reviews > div.review:gt('+(limit-1)+')').hide();
if (jQuery('#reviews > div.review').length <= limit) {
jQuery('#results-show-more').hide();
}
jQuery('#results-show-more').bind('click', function(event){
event.preventDefault();
limit += per_page;
jQuery('#reviews > div.review:lt('+(limit)+')').show();
if (jQuery('#reviews > div.review').length <= limit) {
jQuery(this).hide();
}
});
</script>
</body>
</html>
The typical way of preforming a "Load More" type functionality is to display the 10 items immediately on load.
Then when the user asks for additional items, you would make an AJAX call to get the additional items, and then use Javascript to append them to the list.
In order to take your snippet and apply it to your code, it should be fairly straightforward. You can continue to print out all the reviews and hide the ones .review:gt(x) the limit. This won't follow the above pattern, but should continue to give you the results you're looking for.

Changing multiple elements with on mouse hover and Angular

How can I get all the elements within a wrap to change color when mouse hovers on the cube in http://codepen.io/Feners4/pen/KggAwg? Currently, I can only get it to change on a single side the mouse hover on. I want to do this strictly with Angular for learning purposes.
This is my HTML:
<html>
<header>
Angularity
</header>
<h1>hjskl</hi>
<body ng-app="App">
<div class="wrap">
<div class="cube"change-background colorcode=¨#f45642¨>
<div class="front" change-background>AAA</div>
<div class="back" change-background></div>
<div class="top" change-background></div>
<div class="bottom" change-background></div>
<div class="left" change-background></div>
<div class="right" change-background></div>
</div>
</div>
<div class="wrap2">
<div class="cube2">
<div class="front2" change-background colorcode=¨#f45642¨>AAA</div>
<div class="back2" change-background ></div>
<div class="top2" change-background></div>
<div class="bottom2" change-background></div>
<div class="left2" change-background></div>
<div class="right2" change-background></div>
</div>
</div>
</body>
</html>
This is my JS:
angular.module('App', [])
.directive('changeBackground', ['$animate', function($animate) {
return {
restrict: 'EA',
scope: {
colorcode: '#?'
},
link: function($scope, element, attr) {
element.on('mouseenter', function() {
element.addClass('change-color');
element.css('background-color', $scope.colorcode);
});
element.on('mouseleave', function() {
element.removeClass('change-color');
element.css('background-color', '#red');
});
}
};
}])
One way to do this is add your directive to the parent of the cube sides, then inside use .children() to apply your function to each child item. Also you will want to have your class change-color to be general as in have not :foo, otherwise the CSS will still only apply to the hovered element even if they all have the class.
HTML
<div class="wrap">
<div class="cube" change-background colorcode=¨#f45642¨>
<div class="front" >AAA</div>
<div class="back" ></div>
<div class="top" ></div>
<div class="bottom" ></div>
<div class="left" ></div>
<div class="right" ></div>
</div>
</div>
<div class="wrap2">
<div class="cube2" change-background>
<div class="front2" colorcode=¨#f45642¨>AAA</div>
<div class="back2"></div>
<div class="top2"></div>
<div class="bottom2"></div>
<div class="left2"></div>
<div class="right2"></div>
</div>
</div>
JS
link: function($scope, element, attr) {
element.on('mouseenter', function() {
element.children().addClass('change-color');
element.children().css('background-color', $scope.colorcode);
});
element.on('mouseleave', function() {
element.children().removeClass('change-color');
element.children().css('background-color', '#red');
});
}
CSS
.change-color {
color: #fff;
background-color: #f45642;
cursor: pointer;
}
Pen Example

SlideUp() running twice [duplicate]

This question already has answers here:
Callback of .animate() gets called twice jquery
(2 answers)
Closed 8 years ago.
I'm creating a multi-tabbed accordion using jQuery. The "Headline 1" panel works fine but on "Headline 2" the panel runs the SlideDown() method twice. Another small problem I noticed is there being some delay in between when I click on a button/link and when the panel slides down.
You can take a look at the jsfiddle here to test and see the problem:
http://jsfiddle.net/3VzTj/1/
jQuery:
$(document).ready(function() {
var class_link, class_div, content_div;
var all_panels = $('article > div.row').not(':first-child');
$(all_panels).hide();
$('div.buttons a').click(function() {
class_link = $(this).attr('class');
class_div = class_link.match(/[^-]+$/);
content_div = $(this).closest('article').find('div.' + class_div).parent();
if ($(content_div).is(':visible')) {
$(all_panels).slideUp();
} else {
$(all_panels).slideUp(function() {
$(content_div).hide().slideDown();
});
}
return false;
});
});
HTML:
<section class="grid-container">
<article>
<div class="row clearfix">
<div class="column half">
<h2>Headline 1</h2>
</div>
<div class="column opposite half buttons">
<a class="button-content1" href="#">Content 1</a>
<a class="button-content2" href="#">Content 2</a>
</div>
</div>
<div class="row clearfix">
<div class="column full content1">
<h1>Content 1</h1>
</div>
</div>
<div class="row clearfix">
<div class="column full content2">
<h1>Content 2</h1>
</div>
</div>
</article>
<article>
<div class="row clearfix">
<div class="column half">
<h2>Headline 2</h2>
</div>
<div class="column opposite half buttons">
<a class="button-content1" href="#">Content 1</a>
<a class="button-content2" href="#">Content 2</a>
</div>
</div>
<div class="row clearfix">
<div class="column full content1">
<h1>Content 1</h1>
</div>
</div>
<div class="row clearfix">
<div class="column full content2">
<h1>Content 2</h1>
</div>
</div>
</article>
</section>
// replace
$(all_panels).slideUp(function() {
$(content_div).hide().slideDown();
});
//with
$(all_panels).slideUp().promise().done(function() {
$(content_div).hide().slideDown();
});

Remove elements in DOM

can some one show how to work with few elements in DOM and move them from one block to another, I need use jQuery, for example I have this structure
<div class="block">
<div class="block_left">
<div class="title">title 1</div>
<div class="image">image 1 for title 1</div>
</div>
<div class="block_right">
</div>
</div>
<div class="block">
<div class="block_left">
<div class="title">title 2</div>
<div class="image">image 2 for title 2</div>
</div>
<div class="block_right">
</div>
</div>
<div class="block">
<div class="block_left">
<div class="title">title 3</div>
<div class="image">image 3 for title 3</div>
</div>
<div class="block_right">
</div>
</div>
<div class="block">
<div class="block_left">
<div class="title">title 4</div>
<div class="image">image 4 for title 4</div>
</div>
<div class="block_right">
</div>
</div>
I was trying to use jQuery .each() but not that I need. In result I need this:
<div class="block">
<div class="block_left">
<div class="title">title 1</div>
</div>
<div class="block_right">
<div class="image">image 1 for title 1</div>
</div>
</div>
<div class="block">
<div class="block_left">
<div class="title">title 2</div>
</div>
<div class="block_right">
<div class="image">image 2 for title 2</div>
</div>
</div>
<div class="block">
<div class="block_left">
<div class="title">title 3</div>
</div>
<div class="block_right">
<div class="image">image 3 for title 3</div>
</div>
</div>
<div class="block">
<div class="block_left">
<div class="title">title 4</div>
</div>
<div class="block_right">
<div class="image">image 4 for title 4</div>
</div>
</div>
How do I remove elements? Thanks
To append the .image elements to the next .block_right elements you can do
$('.block_right').append(function() {
return $(this).prev().find('.image');
});
FIDDLE
$(".image").each(function() {
$(this).parent().parent().find(".block_right").append($(this));
});
Try that code, should work!
Goodluck.
One possible solution with .each():
$('.block .image').each(function() {
$(this).closest('.block').find('.block_right').append(this);
});
DEMO: http://jsfiddle.net/6afBy/
Try to use appendTo() here:
$('.block_left .image').each(function() {
$(this).appendTo($(this).parent().next());
});
Fiddle Demo

Sorting nested elements based on various columns

I'm not sure if this is possible. I can't seem to even get started but I have the following HTML. Is it possible to click on a title (Column 1, Column 2 or Column 3) and have everything in the bodyModule get sorted?
<div class="moduleRowTitle">
<div class="column1">Column 1</div>
<div class="column2">Column 2</div>
<div class="column3">Column 3</div>
</div>
<div class="bodyModule">
<div class="row">
<div class="column1">AAAAA</div>
<div class="column2">BBBBB</div>
<div class="column3">CCCCC</div>
</div>
<div class="row">
<div class="column1">BBBBB</div>
<div class="column2">AAAAA</div>
<div class="column3">CCCCC</div>
</div>
<div class="row">
<div class="column1">BBBBB</div>
<div class="column2">CCCCC</div>
<div class="column3">AAAAA</div>
</div>
</div>
Clicking on column2 should sort as the following:
<div class="row">
<div class="column1">BBBBB</div>
<div class="column2">AAAAA</div>
<div class="column3">CCCCC</div>
</div>
<div class="row">
<div class="column1">AAAAA</div>
<div class="column2">BBBBB</div>
<div class="column3">CCCCC</div>
</div>
<div class="row">
<div class="column1">BBBBB</div>
<div class="column2">CCCCC</div>
<div class="column3">AAAAA</div>
</div>
Demo FIDDLE
Jquery
$(document).ready(function(){
$('.moduleRowTitle div').click(function(){
var vals = [];
var className=$(this).attr('class');
$( ".bodyModule ."+className).each(function(){
vals.push($(this).html());
});
vals.sort();
var i=0;
$( ".bodyModule ."+className).each(function(){
$(this).html(vals[i]);
i=i+1;
});
});
});
I hope this is what you expect

Categories

Resources