Separate scope variablesin angular - javascript

I have one scope variables for four elements in div. When I change the variable it affects all the four elements within which it is included. I am beginner in angular js and can't handle it alone.
Here is an example to explain better:
JS:
/* controller-home.js ********************************************************/
app.controller("homeController", function($scope, $http, $state) {
$scope.heading = "SWITCHES";
$scope.button1 = "Хол"
$scope.button2 = "Кухня"
$scope.button3 = "Баня"
$scope.button4 = "Балкон"
$scope.imageSrc = "LitLamp.png";
$scope.onOf = function() {
console.log("Switched");
if ($scope.imageSrc === "LitLamp.png") {
$scope.imageSrc = "NotLit.png";
}
}
})
The HTML:
<div style="text-align: center;">
<h1 >SWITCHES</h1>
<div ng-controller="homeController">
<div style="display:inline-block;">
<button ng-click="onOf()" class="homeSwitchButton">{{button1}}</button>
<img class="homeButtonImage" src="{{imageSrc}}" alt="Lamp" >
</div>
<div style="display:inline-block;">
<button ng-click="onOf()" class="homeSwitchButton">{{button2}}</button>
<img class="homeButtonImage" src="{{imageSrc}}" alt="Lamp" >
</div>
<div style="display:inline-block;">
<button ng-click="onOf()" class="homeSwitchButton">{{button3}}</button>
<img class="homeButtonImage" src="{{imageSrc}}" alt="Lamp" >
</div>
<div style="display:inline-block;">
<button ng-click="onOf()" class="homeSwitchButton">{{button4}}</button>
<img class="homeButtonImage" src="{{imageSrc}}" alt="Lamp" >
</div>
</div>
</div>
The problem is that when I hit one of the four buttons, all the images change. How to group image with button, or when I hit the first button only the image below it to change and the rest three to remain unchanged?

The problem here is because you are using the same variable imageSrc for all image. What you can do here is create an object for each image.
$scope.images = {
button1: 'source.png',
button2: 'source.png',
button3: 'source.png',
button4: 'source.png'
}
In the onOf method you can pass the name of the button you are changing
$scope.onOf = function(buttonName) {
if ($scope.images[buttonName] === 'bla.png') {
$scope.images[buttonName] = 'yay.png';
}
}
And in the html you set the images calling each property and passing the name of the button as argument on onOf
<div style="display:inline-block;">
<button ng-click="onOf('button1')" class="homeSwitchButton">{{button1}}</button>
<img class="homeButtonImage" src="{{images.button1}}" alt="Lamp" >
</div>
Better approach: You can put the buttons as an array and use ng-repeat
$scope.buttons = [{ name: 'bla', image: 'yay.png'}]
$scope.onOf = function(button) {
if (button.image === 'yay') {
...
}
}
And in the html
<div ng-repeat="button in buttons" style="display:inline-block;">
<button ng-click="onOf(button)" class="homeSwitchButton">{{button.name}}</button>
<img class="homeButtonImage" src="{{button.image}}" alt="Lamp" >
</div>

Related

Problems with toggling more than one Image when clicking

I have my code set so that an image can change after clicking the image. I understand getElementById is meant to get results from one class name, but I don't know how to expand on that, and have the same result without changing the class name. I tried querySelector, but I think I am missing something. Any help would be appreciated. Here is my code:
<!--how do I make this apply to all images?-->
function changeImage() {
let displayImage = document.querySelector('#img-area, #star-picture, #colorful')
if (displayImage.src.match('Kabuto.jpg')) {
displayImage.src = 'PersonalCreations/LylatForce.jpg'
} else {
displayImage.src = 'Kabuto.jpg'
}
}
<!--image area or main img-->
<div class="row">
<div class="column">
<img id="img-area" src='Kabuto.jpg' class="responsive" alt="" onclick="changeImage()" height="200" with="200">
<button class="first" onclick="document.getElementById('img-area').src='PersonalCreations/LylatForce.jpg'">Change Image</button>
</div>
<div class="column">
<img id="star-picture" src="Kabuto.jpg" height="200" with="200" />
<button onclick="document.getElementById('star-
picture').src='PersonalCreations/Year6969.jpg'">Change Image</button>
</div>
<div class="column">
<img id="colorful" src="Kabuto.jpg" height="200" with="500" />
<button onclick="document.getElementById('colorful').src='PersonalCreations/BallInTheShoeProductions.jpg'">Change Image</button>
</div>
<div class="column">
<img id="holiday" src='Kabuto.jpg' alt="" onclick="changeImage()" height="200" with="200">
<button onclick="document.getElementById('holiday').src='PersonalCreations/ChristmasFestivalProject.jpg'">Change Image</button>
</div>
</div>
<p>Hello World</p>
<script src="imgchanger.js"></script>
First, CSS styling and JavaScript should not be used inline with HTML. You should separate out those things.
Your issue is that you have:
let displayImage = document.querySelector ('#img-area, #star-picture, #colorful')
But, .querySelector() will only return the first matching element. You need .querySelectorAll(), which will return a collection of all matching elements.
Or, you can avoid all of that and do this:
// Set up a single event handler for all clicks in the document
document.addEventListener("click", function(evt){
// But test to see if the click originated at a button
if(evt.target.nodeName === "BUTTON"){
// Get the button's parent div and then the source of the first img within that
let img = evt.target.closest("div").querySelector("img").src;
// Find out which button was clicked by looking at its class
switch (evt.target.className){
case "first":
// Change the source
img = "PersonalCreations/LylatForce.jpg";
break;
case "second":
img = "PersonalCreations/Year6969.jpg";
break;
case "third":
img = "PersonalCreations/BallInTheShoeProductions.jpg";
break;
case "fourth":
img = "PersonalCreations/ChristmasFestivalProject.jpg";
break;
}
console.clear();
console.log("Image source is now: " + img);
}
});;
.img200x200 { height:200px; width:200px; }
.img200x500 { height:200px; width:500px; }
<!-- See how much cleaner the HTML is now that the CSS and
JavaScript have been separated out? -->
<div class="row">
<div class="column">
<img src="Kabuto.jpg" class="responsive img200x200" alt="">
<button class="first">Change Image</button>
</div>
<div class="column">
<img src="Kabuto.jpg" class="responsive img200x200" alt="">
<button class="second">Change Image</button>
</div>
<div class="column">
<img src="Kabuto.jpg" class="responsive img200x500" alt="">
<button class="third">Change Image</button>
</div>
<div class="column">
<img src="Kabuto.jpg" class="responsive img200x200" alt="">
<button class="fourth">Change Image</button>
</div>
</div>
<p>Hello World</p>

Changing innerHTML

I am trying to change the innerHTML of a page twice, more explanation, I am trying to make a single page like app. I'm a newbie. I want to change the inner HTML content of the section after one click then get the classList of the changed inner HTML then change it again, but it does not seem to work, I don't know what I am doing wrong.
my thought process for the code is below
select the whole container which is the features container
on click, change the container innerHTML
on click of the changed container innerHTML, change the inner HTML again but It doesn't work, it keeps giving me the first innerHTML but when i do not display the main container that works, how can i solve this?
const hold = document.querySelector('#features');
const holds = document.querySelector('.features');
let hel;
hold.addEventListener('click', function() {
holds.innerHTML = `<div class="ddd">h is here </div>`;
// const self = this;
hel = document.querySelector('.ddd');
// console.log(hel.innerText);
hel.addEventListener('click', function() {
// holds.style.display = 'none';
// this.style.display = 'none';
holds.innerHTML = '<div class="q">mess</div>';
console.log(this);
});
});
<section id="features" class="features section-hidden">
<div class="container container-pal1">
<h2 class="features-description highlight">Features</h2>
<div class="features-contain">
<div class="features-text">
<h3 class="features-header">
We are here to provide you with the
<span class="features-highlight">Best</span> services
</h3>
<p class="features-title">
Everything you need in a modern bank and more, get on our waiting list today by clicking the button below
</p>
<a href="" class="hero-cta-1 features-button">View our services <img src="./assets/arrow-right.svg" alt="" />
</a>
</div>
<div class="features-props">
<div class="features-list">
<div class="features-item">
<img src="./assets/fast-delivery.svg" alt="" />
<h5>Swift Delivery 🚀</h5>
<p>No late transfer, get it instantly</p>
</div>
<div class="features-item">
<img src="./assets/0-fees.svg" alt="" />
<h5>$0 Fee's</h5>
<p>No fees on your account like the other banks</p>
</div>
<div class="features-item">
<img src="./assets//0-interest.svg" alt="" />
<h5>Interest &percnt;</h5>
<p>
Interest when applying for loans depends on your agreement from the bank
</p>
</div>
<div class="features-item">
<img src="./assets/no-credit-check.svg" alt="" />
<h5>Credit Card</h5>
<p>Credit cards available at your demand</p>
</div>
<div class="features-item">
<img src="./assets/chat-support.svg" alt="" />
<h5>Chat Support</h5>
<p>Chat with a company representative anytime</p>
</div>
<div class="features-item">
<img src="./assets/fixed-payment-option.svg" alt="" />
<h5>Fixed Payment Option</h5>
<p>Payment Options will be provided</p>
</div>
</div>
</div>
</div>
</div>
</section>
Here's a simple example how to switch elements that already exist in the DOM.
Use a data-* attribute to reference the desired ID element to show.
Use classList.toggle to switch the Elements.
const ELS_pages = document.querySelectorAll(".page");
const ELS_buttons = document.querySelectorAll("[data-page]");
const goToPage = (id) => {
ELS_pages.forEach(EL => EL.classList.toggle("u-none", EL.id !== id));
};
ELS_buttons.forEach(EL => EL.addEventListener("click", () => {
goToPage(EL.dataset.page);
}));
nav {display: flex;} nav a {color: #00f; padding: 5px 10px; cursor: pointer; }
/* Utility classes */
.u-none {display: none;}
<div class="page" id="page-login">
<h1>Welcome</h1>
<button type="button" data-page="page-main">ENTER</button>
</div>
<div class="page u-none" id="page-main">
<nav>
<a data-page="page-settings">User Settings</a>
<a data-page="page-login">Logout</a>
</nav>
<h1>MAIN PAGE</h1>
</div>
<div class="page u-none" id="page-settings">
<nav>
<a data-page="page-main">Back to Main</a>
<a data-page="page-login">Logout</a>
</nav>
<h1>SETTINGS PAGE</h1>
</div>
This is basic, and does not change the URI address in the browser. To achieve that some more code should be added to handle such case.
Try keeping a flag(if there are only two different data you want to show) and based on the flag show data or a counter
const hold = document.querySelector('#features');
let count = 0;
hold.addEventListener('click', function() {
switch (count){
case 0:
holds.innerHTML = `<div class="ddd">h is here </div>`;
case 1:
holds.innerHTML = `<div class="ddd">now some other is here </div>`
};
});
and please provide more info for the remaining answer
Simply run your second innerHTML code after the next repaint using requestAnimationFrame and it will work.
const hold = document.querySelector("#features");
const holds = document.querySelector(".features");
let hel;
hold.addEventListener("click", function (e) {
e.preventDefault();
holds.innerHTML = `<div class="ddd">h is here </div>`;
// const self = this;
hel = document.querySelector(".ddd");
// console.log(hel.innerText);
hel.addEventListener("click", function () {
// holds.style.display = 'none';
// this.style.display = 'none';
requestAnimationFrame(() => {
holds.innerHTML = '<div class="q">mess</div>';
});
console.log(this);
});
});
if you need further information about why it's happening read this article.

How to bind this within js nested object iteration within a function. Jquery

again, probably a terrible title - but what I'm trying to do is to make a simple search feature on my website. You click a nav button, which updates the search bar, whi in turn triggers an onchange event to update the current appended list.
function update() {
var list = $("#comic__modern-list");
list.empty();
$.each(Object.keys(comics), function() {
var currentObject = comics[this];
var filter = comics[this].type;
var publisher = comics[this].publisher;
if (search == "") {
if(filter == "modern") {
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
} else if (search == publisher) {
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
});
}
The current list is generated by this, which works fine:
$.each(Object.keys(comics), function() {
var currentObject = comics[this];
var currentObject2 = comics[this].type;
console.log(currentObject2);
if (search == "") {
if(currentObject2 == "modern") {
var list = $("#comic__modern-list");
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
}
});
From what I can gather, this has to do with the keyword "this" no longer meaning what it did when it was outside of the function, so I'm assuming the fix will be to do with bind(), but I can't make heads nor tails of it.
p.s, if there's an easier/simpler way to set up a search system, please enlighten me!

How to change a dynamic button text

Created 3 dynamic divs(sea_p,sea_p_div,div_btns), inside the third(div_btns) created 2 buttons
how can i change the text inside these dynamic buttons before adding to body?
let div = $(`<div class="Search_div"></div>`)
let p = $(`
<div class="sea_p">
<div class="sea_p_div">
<div class="p_img">
<img src="" alt="" width="80" />
<div class="div_span">
<span class="p_name"></span>
<span class="p_surname"></span>
</div>
</div>
<div class="div_btns">
<button class="req_btn req_check1" data-id="">Text1</button>
<button class="req_btn req_check2" data-id="">Text2</button>
</div>
</div>
</div>`)
div.append(p)
//change text here
$('body').append(div)
let div = $(`<div class="Search_div"></div>`)
let p = $(`
<div class="sea_p">
<div class="sea_p_div">
<div class="p_img">
<img src="" alt="" width="80" />
<div class="div_span">
<span class="p_name"></span>
<span class="p_surname"></span>
</div>
</div>
<div class="div_btns">
<button class="req_btn req_check1" data-id="">Text1</button>
<button class="req_btn req_check2" data-id="">Text2</button>
</div>
</div>
</div>`)
div.append(p)
//change text here
p.find(".req_check1").html('New Text');
p.find(".req_check2").html('New Text 2');
$('body').append(div)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Please try this.
window.onload = function() {
$(".req_check1").html('New Text');
$(".req_check2").html('New Text 2');
}
Thank you.
You can use text() method of jQuery, on the jQuery object of button whose text you want to change.
NOTE : Use it just after appending the p tag to the body.
var buttonWrap = $('.sea_p .div_btns button');
buttonWrap.eq(0).text("Text for button 1");
buttonWrap.eq(1).text("Text for button 2");

How to pass different id's while using ng-repeat to an ng-click function

This is my HTML code.In this i am taking multiple values from ng-repeat and for each value i want the respective button to show and hide two div elements.In my web page , the buttons from different member blocks are working to show/hide only the first member block... The button with id=round should toggle btw div elements with id= first and id= second for all members that i get through ng-repeat.
<section id="team">
<div ng-controller="teamController as tctrl">
<div class="container">
<div class="row">
<div class="col-md-3 bord" ng-repeat="member in tctrl.members">
<button id="round" ng-click="showHide($index)">
<img id="direction" src="img/icon/uparrow.png">
</button>
<img ng-src="{{member.image}}">
<div id="first" class="memberabout" >
<h3 ng-bind="member.title"></h3>
<h2 ng-bind="member.name"></h2>
</div>
<div id="second" class="hid" >
<p ng-bind="member.about"></p>
</div>
</div>
</div>
</div>
</div>
</section>
and this is the js function i am trying to use:
$scope.showHide = function(index) {
if (document.getElementById('first') !== undefined) {
if (document.getElementById('first').style.display == 'none') {
document.getElementById('first').style.display = 'block';
document.getElementById('second').style.display = 'none';
var down = document.getElementById('round');
down.style.top = "201px";
var direction = document.getElementById('direction');
direction.src = 'img/icon/uparrow.png';
} else {
document.getElementById('first').style.display = 'none';
document.getElementById('second').style.display = 'block';
var down = document.getElementById('round');
down.style.top = "71px";
var direction = document.getElementById('direction');
direction.src = 'img/icon/arrowdown.png';
}
}
};
How should I pass the id's so that each button works to show/hide the div elements in their block?
Angularjs has many options to cancle using jQuery in your applications; options like modeling, directive and etc...
In your case you didn't need to use id because when we use ng-repeat in fact all of items are unique, so we just use them to show/hide or many other option you can do with object in the ng-repeat.
I hope this sample helps you to figure out how to use it:
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
var main = this;
main.members = [{
image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR4f5PCRqcMgg_KHymC29ABsy-PDFI08mb6qHqMviqbDDHjjuYM9g",
title: "A",
name: "jack",
about: "Hello World"
},
{
image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAxySZHmSrUU1_iIFJHGdDTdmTCAE610QnPwptWGWbMRAbSUzgNA",
title: "B",
name: "philip",
about: "Hello World 2"
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div ng-app="app" ng-controller="ctrl as tctrl">
<section id="team">
<div class="container">
<div class="row">
<div class="col" ng-repeat="member in tctrl.members">
<small>this is unique id if you want to use it: <b>id_{{$index}}</b> </small>
<div class="card">
<button ng-click="member.show = !member.show">
show/hide
</button>
<img ng-src="{{member.image}}">
<div ng-hide="member.show">
<h3 ng-bind="member.title"></h3>
<h2 ng-bind="member.name"></h2>
</div>
<div ng-show="member.show">
<p ng-bind="member.about"></p>
</div>
</div>
</div>
</div>
</div>
</section>
</div>

Categories

Resources