Does ng-app on HTML element act like an on/off switch? - javascript

I'm using Angular 1.6.1. The goal is to click on a list item, and it shows the tab number. This bit of code doesn't work on its own:
<ul>
<li ng-click="tab = 1" >
Thing 1
</li>
<li ng-click="tab = 2" >
Thing 2
</li>
</ul>
<p>{{tab}}</p>
However, once we add this, it works:
<html ng-app="">
</html>
And it even works when the ul is outside the ng-app scope. So:
<ul>
<li ng-click="tab = 1" >
Thing 1
</li>
<li ng-click="tab = 2" >
Thing 2
</li>
</ul>
<p>{{tab}}</p>
<html ng-app="">
</html>
Does not work when element is a div:
<div ng-app="">
</div>
Am I just mixing up an understanding of some low-level HTML functionality, or how is this working?

ng-app bootstraps Angular on your code. You can put it on the body tag if you prefer, but your Angular code must be in that block.
I would not say that "ng-app acts like an on/off switch", and I do not recommend using it like this.
If you want to "activate/desactivate" some parts of your code, you should use ng-if (or other, it depends of your needs).
From the examples you provided:
Example 1
It does not as Angular is not bootstraped in your application (as explained before)
Example 2
It works, as it is the good way to write your code
Example 3
It is probably the most strange:
As your document is not well-written and not HTML valid, your code is rewritted by your browser. So:
<ul>
...
</ul>
<p>{{tab}}</p>
<html ng-app="">
</html>
Becomes
<html ng-app="">
<ul>
...
</ul>
<p>{{tab}}</p>
</html>
Example #4
It does not work, as your Angular code is not inside this div (and it is not rewritted by your browser like Example #3).

Related

Unexpected strings in tags after v-for

I'm now writing a web page with Vue on Nuxt to replace the old one.(VScode)
And I faced the problem that when I used v-for to create lists,
inside the tag there's a unknown string(attribute).
And this unknown string seemed to effect my CSS, so it really bothers me.
p.s.
I'm rookie on web design.
I guess is the v-bind key, which I haven't fully understood effects the result
Thanks for your answering!
The unknown string(attribute): data-v-768556b7=""
<a data-v-768556b7="" href="#">Notebook</a>
And here's part of my code:
<div class="prod-sub-menu products-menu sub-menu">
<ul class="sub-nav">
<li
v-for="(pName, index) in productMenuList"
:id="pName.idName"
:key="index"
class="prod-sub-item sub-item current"
>
<a :href="pName.url">{{pName.menuName}}</a>
<ul v-for="(subName,index2) in pName['subMenu']" :key="index2">
<li>
<a :href="subName.url">{{subName.subMenuName}}</a>
</li>
</ul>
</li>
...
...
As much as I know the data-v string appears when you're using scoped css.
Here is the documentation for it: https://vue-loader.vuejs.org/guide/scoped-css.html
Are you by any chance using
<style scoped>
/* Your css here */
</style>
If you are, that might be the problem. Try just removing the scoped word.

How to add an image to a locked html code

I'm having a big problem here. I want to add an image to html code. No big deal if only I had access to the html code. Unfortunately it's locked and it looks like that:
<ul class="cc-nav-level-0 j-nav-level-0">
<li id="cc-nav-view-1691317785" class="jmd-nav__list-item-0 j-nav-has-children cc-nav-parent j-nav-parent jmd-nav__item--parent">
Sound Packs
<span data-navi-toggle="cc-nav-view-1691317785" class="jmd-nav__toggle-button"></span>
</li>
<li id="cc-nav-view-1691317885" class="jmd-nav__list-item-0">
Apps
</li>
<li id="cc-nav-view-1691318285" class="jmd-nav__list-item-0">
Comments
</li>
<li id="cc-nav-view-1701055985" class="jmd-nav__list-item-0">
News
</li>
</ul>
The image I would like to add should be to the right of the font. Is there a way to insert the code somehow?
Sure, you should be able to do what you want. Look at the jQuery commands: .append(), .html(), etc. For example:
Note that you can also inject new CSS the same way...
$(function(){
var newstuff = '\
<style>\
#new{color:red;}\
</style>\
<div id="new">Here is a newly-injected DIV</div>\
';
$('#mt').html(newstuff);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="mt">You can replace what is there with modified/enhanced code.</div>
You could try to link a script that inserts an element after the DOM loads. Something like this:
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('ul').insertAdjacentHTML('afterend', '<div></div>')
})
Then you could use inline styling to make it whatever height, width and background you'd like:
<div style="height:300px;width:300px;background:url(yourImg.jpg);></div>
I made a quick pen to show you what it looks like.

Targeting a html element but only on specified page

I'm using a shop CMS that allows me to apply a side menu for all product categories, let's call them Necklaces and Rings, that CMS also has an option to add "New" and "Promotions" to that side menu globally, however what I cannot do is specify where I want these "New" and "promotions" to be. For example I want them to be displayed in Rings category but not in Necklaces.
This is a rough sketch how the website is made:
<div class="menu" id="side_menu">
<ul class="standard">
<li id="category_newstuff">New</li>
<li id="category_14">Collection1
<li id="category_14">Collection2
<li id="category_14">Collection3
<li id="category_14">Collection4
<li id="category_promotions">Promotions</li>
</div>
What I want to achieve:
If the page is: rings.html then find "li id="category_newstuff" and apply "style="display"none">
I'm sorry if this is all gibberish lol.
Just add a class on your body tag. For example, the page you want to apply the style to, will have <body class="with-style"> and in the css file, you can simply write .with-style .category_newstuff { display: none; }, or just find .with-style .category_newstuff via JS and hide it.

Extract data from existing HTML with Angular.js

angular.js is great for complex client side JavaScript based web applications, but I also thinking about to use it for smaller simple JavaScript tasks.
For example I have a list with some items:
<ul>
<li data-id="1">Foo</li>
<li data-id="2">Bar</li>
</ul>
Now I want to add some buttons to the HTML which should filter and/or sort the list after some user input, which should be an easy task.
Is there any way to extract the data from existing HTML elements to use them with angular.js? The data need to be in the HTML, so search engine could also get a hold of whats
Edit for clarity:
The end result would be that the data from the ul list will be pushed into a model of the controller that handling the list. ([{id:1, text:"Foo"}, {id:2, text:"Bar"}])
If I push more objects into the model, the list should display them.
If I apply a filter to the model it should filter the li elements.
Best case scenario would be something similar to this:
<div ng-model="data">
<ul ng-repeat="object in data | filter:filterCriteria">
<li data-id="1">Foo</li>
<li data-id="2">Bar</li>
<li data-id="{{object.id}}">{{object.text}}</li>
</ul>
</div>
Okay. Apparently there is no way to this in a default Angular.js application.
I ran into the same problem in a project I'm working on. My solution was to add the data from the html to a variable in my angular controller and then hide the initial html. This method keeps the original list in the html for SEO, old browsers and users without javascript. It replaces this list with an angular generated one for other users.
A working example using your code is pasted below or you can see it at this link.
I'm aware this is an old question so my answer might not be of help to the initial poster. My solution is aimed at anyone else who runs into the same problem we did.
<!doctype html>
<html xmlns:ng="http://angularjs.org" id="ng-app">
<head>
<script src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script>
function Ctrl($scope) {
$scope.objects = [];
$scope.init = function(){
$("ul.data").hide();
$("ul.data li").each(function(){
var $this = $(this);
var newObject = {
name: $this.html(),
id: $this.attr("data-id")
};
$scope.objects.push(newObject);
});
};
}
</script>
</head>
<body>
<div ng-app>
<div ng-controller="Ctrl" ng-init="init()">
<ul>
<li ng-repeat="object in objects" data-id="{{object.id}}">{{object.name}}</li>
</ul>
<ul class="data">
<li data-id="1">Foo</li>
<li data-id="2">Bar</li>
</ul>
</div>
</div>
</body>
</html>
If I am understanding the question correctly, you could just use the angular.element().scope for the html element in question.
I use this method for certain interaction that can't be handled directly out of the box with angular.

javascript document.anchors.length returning 1 in firefox

I am trying to run through a list of 6 anchors in a page using javascript to do some operations on them. However, the loop is not getting executed because anchors.length is return 1. The following is my code snippet:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
function load()
{
alert(document.anchors.length);
for (i = 0; i <= document.anchors.length; i++)
{
alert(document.anchors[i].innerHTML);
}
}
</script>
</head>
<body onload="load()">
<div>
<ul>
<a id="sectionlinks" href="page1.html">link 1</a></li>
<a id="sectionlinks" href="page2.html">link 2</a></li>
<a id="sectionlinks" href="page3.html">link 3</a></li>
<a id="sectionlinks" href="page4.html">link 4</a></li>
<a id="sectionlinks" href="page5.html">link 5</a></li>
<a id="sectionlinks" href="page6.html">link 6</a></li>
<ul>
</div>
</body>
</html>
This is working fine in IE9. But in Firefox and Chrome, it is saying that the count is equal to 1. Would be great if someone can point me to what I have missed here.
As you might have guessed, I am a newbie to JS and am just learning it.
At least, you're learning the correct way, keep going!
What you've done wrong is that document.anchors refers to anchor links (old anchor links using the name attribute), not normal links. For example, the following is an anchor:
<a name="tab"></a>
And the following is a link:
The links are in the document.links HTMLCollection, so you can use document.links.length.
If you want to get all the <a> elements, no matter what's in their attribute, you can use document.getElementsByTagName( 'a' ).length.
See the note in the MDN documentation:
For reasons of backwards compatibility, the returned set of anchors only contains those anchors created with the name attribute, not those created with the id attribute.
The property is designed to find anchors to link to, not from.
Use document.getElementsByTagName('a') to get a collection of <a> elements or document.links to get those and <area>s

Categories

Resources