Find element and change its content in AngularJs - javascript

I Want to change default content of my header div:
<div>
<div>
<div class="page-header">
<h1><span>{{messages['default_title']}}</span></h1>
</div>
<div>
<!-- other elements-->
<div>
In my controller, i wrote this:
var titleElement = angular.element('div.page-header');
titleElement.html('<h1><span>Hello</span></h1>');
The content of div changes successfully:
<div class="page-header"><h1><span>Hello</span></h1></div>
But i get this error, and page can't be loaded successfully:
TypeError: Cannot read property 'childNodes' of undefined
at g (https://localhost/test/js/angular/angular.min.js:47:278)
at g (https://localhost/test/js/angular/angular.min.js:47:273)
at g (https://localhost/test/js/angular/angular.min.js:47:273)
at g (https://localhost/test/js/angular/angular.min.js:47:273)
at g (https://localhost/test/js/angular/angular.min.js:47:273)
at https://localhost/test/js/angular/angular.min.js:46:377
at link (https://localhost/test/js/angular/angular-route.js:915:7)
at J (https://localhost/test/js/angular/angular.min.js:54:373)
at g (https://localhost/test/js/angular/angular.min.js:47:256)
at https://localhost/test/js/angular/angular.min.js:46:377 <div ng-view="" class="ng-scope">

Instead of manipulating the page-header.
Try to update the variable in your controller
$scope.messages['default_title'] = "Hello";

angular.element accepts a string of HTML or a JS element, not a selector
var titleElement = angular.element(document.querySelector('.page-header'));
titleElement.html('<h1><span>Hello</span></h1>');

Related

How can I target an element, held within a template, using JavaScript?

<script type="text/html" id="tmpl-wp-travel-itinerary-items">
<div class="panel-wrap panel-wrap-itinerary">
<label><?php esc_html_e( 'Etape', 'wp-travel' ); ?></label>
<select id="selectjs"></select>
</div>
</script>
getElementById() on selectjs is null; ow can I target this element, via its id, within a script tag?
There is a way to — ultimately — retrieve the element via its id property using the <script> template approach; however it is convoluted, and requires - so far as I can tell - the creation of a temporary element to hold the template content and then querying that element:
// retrieve the innerHTML of the template, using the id of the template itself:
let templateSource = document.getElementById('tmpl-wp-travel-itinerary-items').innerHTML,
// creating an element to hold, and from which to retrieve, that content:
template = document.createElement('div');
// assigning the content of the template as the innerHTML of the created-element:
template.innerHTML = templateSource;
// finally, retrieving the <select> element via its id, from the
// created-element and Element.querySelector():
let selectElement = template.querySelector('#selectjs');
// logging the selectElement to the console:
console.log(selectElement);
<script type="text/template" id="tmpl-wp-travel-itinerary-items">
<div class="panel-wrap panel-wrap-itinerary">
<label><?php esc_html_e( 'Etape', 'wp-travel' ); ?></label>
<select id="selectjs"></select>
</div>
</script>
JS Fiddle demo.
There is, however, a slightly easier approach, using the HTML <template> element:
// retrieving the <template> via its id:
let template = document.querySelector('#templateContent'),
// accessing the <select> from the content property
// of the <template>:
select = template.content.querySelector('select');
// logging the <select> element to the console:
console.log(select);
<template id="templateContent">
<div class="panel-wrap panel-wrap-itinerary">
<label></label>
<select id="selectjs"></select>
</div>
</template>
JS Fiddle demo
References:
document.createElement().
document.querySelector().
Element.innerHTML.
HTMLTemplateElement.
<template> element.

Uncaught object that's exist - jquery

I'm facing a comportment on jquery witch i'm not understanding, neither fixing.
I got this structure in a php
<div class="tutProgress">
<div class="progressStep ball"></div>
<div class="progressStep ball"></div>
<div class="progressStep ball"></div>
<div class="progressStep ball"></div>
<div class="progressStep ball"></div>
</div>
and i'm trying to access using jquery.
var $text = [..., ".tutProgress," ...]
let $filled = $text.find(".progressStep");
for(var i = 0; i < progress; i++){
$filled[i].css("background-color", "#3498DB");
}
I keep getting uncaught object $filled[i].css is not a function. Why this happening and how to fix?
Thanks forwards!
EDIT NOTE: the $text array content is not important. It's filled with a bunch of classes names
The problem here is that when you access $filled[i], this is an array of html elements, and no jquery elements. The .css function is defined in jquery elements, so you must access it like this:
$($filled[i]).css(..........)

HTML Button Appears as Text after $compile [duplicate]

This question already has answers here:
how can we use $compile outside a directive in Angularjs
(5 answers)
"Thinking in AngularJS" if I have a jQuery background? [closed]
(15 answers)
Closed 4 years ago.
I am trying to create a pop up dialog with two buttons created in JS code with angular. The following code that produces the buttons...
var html = $('<button ng-click = "cancelAlert()" > Cancel</button > <button ng-click="continueAlert()">Continue</button>');
var div = $compile(html);
var content = div($scope);
document.getElementById('dialogboxhead').innerHTML = "header";
document.getElementById('dialogboxbody').innerHTML = "body";
document.getElementById('dialogboxfoot').innerHTML = content;
Gives me the following html text instead of the actual buttons themselves...
[[object HTMLButtonElement], [object Text], [object HTMLButtonElement]]
Am I missing something here that I have forgotten to add in?
The HTML looks like the following...
<div id="dialogoverlay"></div>
<div id="dialogbox">
<div>
<div id="dialogboxhead"></div>
<div id="dialogboxbody"></div>
<div id="dialogboxfoot"></div>
</div>
</div>
The $compile method accepts a string argument if you want to provide markup in this way.
Avoid wrapping the input for $compile with anything (ie $(..)). Instead, just pass the html string directly to the $compile() method, and also attach the div via the DOM append() method, and you should find this will work as expected:
var html = '<button ng-click="cancelAlert()">Cancel</button><button ng-click="continueAlert()">Continue</button>';
var div = $compile(html);
...
document.getElementById('dialogboxfoot').append( div[0] );
For more infromation see the usage on the official docs.
Here's a link to a working jsFiddle
It is not wise to mix AngularJS and jQuery this way.
The major problem with this approach is that $compile adds watchers to the specified scope. Those watchers will remain after added elements are removed from the DOM. This will result in memory leaks. If this is a dialog box that is constantly being added and removed -- beware.
But if you must, don't use innerHTML to append compiled content:
̶d̶o̶c̶u̶m̶e̶n̶t̶.̶g̶e̶t̶E̶l̶e̶m̶e̶n̶t̶B̶y̶I̶d̶(̶'̶d̶i̶a̶l̶o̶g̶b̶o̶x̶f̶o̶o̶t̶'̶)̶.̶i̶n̶n̶e̶r̶H̶T̶M̶L̶ ̶=̶ ̶c̶o̶n̶t̶e̶n̶t̶;̶
var foot = document.getElementById('dialogboxfoot');
$(foot).append(content);
The DEMO
angular.module("app",[])
.controller("ctrl",function($scope, $compile) {
var html = $('<button ng-click = "cancelAlert()" > Cancel</button > <button ng-click="continueAlert()">Continue</button>');
var div = $compile(html);
var content = div($scope);
document.getElementById('dialogboxhead').innerHTML = "header";
document.getElementById('dialogboxbody').innerHTML = "body";
var foot = document.getElementById('dialogboxfoot');
$(foot).append(content);
})
<script src="//unpkg.com/jquery"></script>
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
<div id="dialogoverlay"></div>
<div id="dialogbox">
<div id="dialogboxhead"></div>
<div id="dialogboxbody"></div>
<div id="dialogboxfoot"></div>
</div>
</body>

How to add Bootstrap class to element?

I'm getting this error from the console:
Uncaught DOMException: Failed to execute 'add' on 'DOMTokenList': The
token provided ('si col-md-4') contains HTML space characters, which
are not valid in tokens.
This is my HTML snippet, I want to append the div to the row:
<div id = 'data' class="container">
<div id = 'row1' class = 'row'>
</div>
</div>
This is my javascript code:
var row = document.getElementById('row1');
var div = document.createElement('div');
div.classList.add('si col-md-4');
row.append(div);
I should also note that I'm using a firebase database to get the information I want to append.
To add multiple class, separate class with ,(comma)
var row = document.getElementById('row1');
var div = document.createElement('div');
div.classList.add('si', 'col-md-4');
row.append(div);
<div id = 'data' class="container">
<div id = 'row1' class = 'row'>
test
</div>
</div>
Use , separator if you want to add/remove several classes.
div.classList.add('si','col-md-4');
If you only need to add the class col-md-4,
div.classList.add('col-md-4');
just add multiple classes with space seperated as shown below
div.className='si col-md-4';
Here you go with a solution
$("#row1").append("<div class='si col-md-4'>Test</div>");
.si {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = 'data' class="container">
<div id = 'row1' class = 'row'>
</div>
</div>
Used jQuery append method.
Well you can use .setAttribute("class","si col-md-4").It will add the whole new class to it.
As you're adding a class so you should also .setAttribute("class","previos-class si col-md-4") do this trick.

How to select elements from a handelbars template?

We have a div within our webpage:
<div id="person-details">
<div></div>
...
</div>
We select the relevant elements from this div using the following jQuery code:
var person = $("#person-details");
var children = release.find("div");
var fullname = children.first();
We use a render function to perform an ajax request to get a handlebars template that we're storing in an external file:
function _render() {
var templateScript;
template.getTemplate(filename).done(function(template) {
templateScript = Handlebars.compile(template);
fullname.html(templateScript(context));
});
}
The template looks like the following:
<div>
<div>
<p>{{name}}</p>
</div>
<div>
<p>{{value}}</p>
</div>
</div>
After the render function has been called, we want to select any of the elements from within the template. For example we have tried using:
fullname.children('div');
but as the content has been dynamically generated we aren't able to get the nodes from within the DOM.
Is it even possible to select elements from within a generated handlebars template like this?
Thanks to #DanielShillcock for highlighting render() being asynchronous. Here is a solution:
function _render() {
var templateScript;
template.getTemplate(filename).done(function(template) {
templateScript = Handlebars.compile(template);
selector.html(templateScript(attribute));
value = selector.find("div");
});
}

Categories