Can't find Element Inside Template with querySelectorAll - polymer-1.0

Im done with visual things of my proj. Now, trying to put template tags. But my 'click toggle' event isnt working now. Tried lots of solutions. At the same time you may give hints about polymer.
Putted template tags like this:
<template is="dom-if" if="{{isUnis(tabSelected)}}">
<template is="dom-repeat" items="{{unis}}">
<paper-icon-item u="{{item.name}}">
<iron-image src="{{unImg(item.name)}}" sizing="contain" style="width:32px;height:32px" item-icon fade preload></iron-image>
<div class="flex">{{item.name}}</div>
<span>1</span>
</paper-icon-item>
</template>
</template>
<template is="dom-if" if="{{isDers(tabSelected)}}">
<paper-icon-item u="İstanbul">
<iron-image src="/unis/uni/istanbul.png" sizing="contain" style="width:32px;height:32px" item-icon fade preload></iron-image>
<div class="flex">İstanbul</div>
<span>1</span>
</paper-icon-item>
</template>
And my script inside template:
var notarApp = Polymer.dom(document).querySelector('notar-app');
document.addEventListener('polymer-ready', function() {
var p = Polymer.dom(notarApp.root).querySelectorAll('paper-icon-item'),
sifir = 0,
buyuttu = document.getElementById('#buyuttu'),
selected = document.getElementById('#selected');
for (var i = 0; i < p.length; i++) {
p[i].addEventListener('click', function() {
this.classList.toggle('shadow-2');
var listme = [];
for (var j = 0; j < p.length; j++) {
if (!(hasClass(p[j], 'shadow-2'))) {
continue;
}
listme.push(" " + p[j].attributes[0].nodeValue);
selected.innerHTML = listme;
}
if (listme.length == 0) {
selected.innerHTML = 'Listelemek için üniversite ve/ya ders seçin';
}
if (sifir == 0 && listme.length > 4) {
buyuttu.show();
sifir++;
}
});
}
});
Last i tried this inside polymer-ready and nothing happened:
if(p.length) {
console.log(p);
}
My guess is dom-if doesnt load content when if state is false.

Related

How to dynamically use object property as width in AngularJS (in ng-repeat)?

I cannot get the object's property to be read in ng-style(shape.radius || shape.length). I can't even get 1 to work at the moment, but would like to have an or statement included. Similar to my ng-class.
There is a button to generate shapes, and the shapes were created with a random size. Here is my code:
html:
<div ng-controller='ShapeController as sc'>
<div>
<p><input type="submit" value="Generate Random Shapes" ng-click="sc.generateShapes()"/></p>
<div ng-repeat="shape in sc.shapes">
<div class="shape" ng-class="{circle: shape.radius, square: shape.length}" ng-style="{'width': shape.length}"></div>
</div>
</div>
</div>
script:
var app = angular.module('app', []);
app.controller('ShapeController', function(){
var vm = this;
vm.shapes = [];
vm.randomShapes = [];
vm.width = 30;
function createCircle(radius) {
let circle = new Circle(radius);
vm.shapes.push(circle);
} // end createCircle
function createSquare(length) {
let square = new Square(length);
vm.shapes.push(square);
} // end createSquare
vm.generateShapes = function() {
let times = 50
for (let i = 0; i < times; i++) {
createCircle(getRandomNumber());
}
for (let i = 0; i < times; i++) {
createSquare(getRandomNumber());
}
sort(vm.shapes);
console.log(vm.shapes);
}; // end generateShapes
}); // end controller
function sort(arr) {
arr.sort(function(a,b){
return b.getArea() - a.getArea();
});
} // end sort function
function getRandomNumber() {
return Math.random() * (100-1) + 1;
}
width should be either in px(some unit like em, pt, etc) or %
ng-style="{'width': shape.length + 'px'}"

Why my splice or push its not working with AngularJS

I am trying to do an update for an array and i have to splice first that element and then make a push. That list I am using it in a HTML file, where i am using an ng-repeat.
vm.editTemplate=function() {
var selectedTemplate = localStorage.getItem("selectedTemplate");
localStorage.removeItem("selectedTemplate");
$mdDialog.show({
controller: 'EditTemplateCtrl',
controllerAs: 'template',
templateUrl: 'views/templatess/addTemplate.html',
locals: {
template:selectedTemplate
}
})
.then(function() { },
function(item) {
console.log(item);
console.log($scope.templatesArray);
for (var i = 0; i < $scope.templatesArray.length; i++) {
if (item.id == $scope.templatesArray[i].id) {
$scope.templatesArray.splice(i,1);
}
}
});
}
in my HTML file i have this
<div class="hover"
ng-repeat="list in templatesArray"
ng-click="temp.selectUser(list)"
ng-class="{'active': temp.selectedRow.id == list.id}"
style=" cursor:pointer;border-bottom:1px solid #fff; margin-bottom:0;"
layout-align="space-around center"
layout="row">
<span flex="5"></span>
<span id="{{list.id}}" flex="90" ng-click="temp.selectTemplate(list)">
{{list.description}}
</span>
<span flex="5"></span>
</div>
Don't think it's good to do a splice inside a loop on the same array.
Furthermore, as already mentioned here, you should assign the results of splice.
So I would rather do:
1. Find the index, something like following (or with the help of a
library like underscore.js to avoir to write your own loop)
var index = -1;
for (var i = 0; i < $scope.templatesArray.length; i++) {
if (item.id==$scope.templatesArray[i].id) {
index = i;
}
}
2. Then splice
if (index > -1) {
$scope.templatesArray = $scope.templatesArray.splice(index,1);
}

Controller function not applying to ng-include file

I am trying to use the "minisCtrlOverall" controller in my ng-include file, but none of the functionality in my controller works for the included file unless I put ng-controller in the actual overall.html file. What I am trying to do is access the "ring-fill" class that is in my overall.html file from my controller. I want to add the class "active" too all "ring-fills" but its not working. I'm guessing this isn't working because the included files comes after the controller runs? Anyone know how I can fix this?
Controller:
angular.module('ciscoImaDashboardAdmin',[])
.controller('minisCtrlOverall', function ($scope, $rootScope, dummyData) {
$scope.overallOn = true;
$scope.switchView = function(element) {
var value = element.target.attributes['value'].value;
if(value == "overall") {
$scope.overallOn = true;
$scope.swimlaneOn = false;
}
else if(value == "swimlane") {
$scope.swimlaneOn = true;
$scope.overallOn = false;
}
};
var totalRings = 9;
var maxScore = 10;
var data_overall = {
average_score: 6
}
var ringToHighlight = Math.floor((data_overall.average_score/maxScore)*totalRings); //round down
var i = 0;
var rings = [];
var ringClass = 'path.ring-fill:not(.ring-border)';
$(ringClass).each(function(){
rings.push($(this)[0]);
});
while( i < ringToHighlight) {
fillPath(i);
i = i + 1;
}
function fillPath(i) {
if(i < ringToHighlight) {
var selectedRing = $(rings[i]);
selectedRing.attr("class", "ring-fill active");
}
}
});
HTML:
<div class="row mini" ng-show="overallOn" ng-controller="minisCtrlOverall">
<div class="col-sm-3">
<div ng-include="'svgs/overall.html'"></div>
</div>
</div>

My ng-repeat uses bad links

I'm working on a web app using the MEAN stack which is 99% complete except for this persistent error that's been annoying me. I've deployed it to https://find-nightlife.herokuapp.com/#/
My issue is that when you do a search for a location, the web console will always throw these errors:
GET https://find-nightlife.herokuapp.com/%7B%7Bplace.rating_img_url%7D%7D 404 (Not Found)
%7B%7Bplace.image_url%7D%7D:1 GET https://find-nightlife.herokuapp.com/%7B%7Bplace.image_url%7D%7D 404 (Not Found)
Link to the full code on github is here https://github.com/JordanBourne/NightLife
The relevant code:
<section class = "results">
<div ng-repeat = "place in results track by $index | limitTo: 10" class = "resultContainer">
<div class = "resultsList">
<div class = "placeImg"><img src = "{{place.image_url}}" alt = "{{place.name}}"/></div>
<div class = "placeAbout">
<div class = "placeName">
{{place.name}} <img src = "{{place.rating_img_url}}" /></div>
<div class = "placeSnippet">{{place.snippet_text}}</div>
</div>
<div class = "areyouGoing"><span style = "color: red">{{error}}</span> {{place.going}} Going
<button class = "placeGo notGo" ng-click = "plusOne(place, $index)" ng-show = "attend($index)">Not Going</button>
<button class = "placeGo letsGo" ng-click = "plusOne(place, $index)" ng-hide = "attend($index)">Let's Go!</button>
</div>
</div>
<div class = "divider" ng-hide="$last"></div>
</div>
app.controller('NightLifeCtrl', [
'$scope',
'yelp',
'auth',
function ($scope, yelp, auth) {
if(yelp.places.data) {
var attendanceIndex = [];
yelp.bars.forEach(function(bar) {
if (bar.people.indexOf(auth.currentUser()) < 0) {
attendanceIndex.push(0);
} else {
attendanceIndex.push(1);
}
})
$scope.attend = function (num) {
if (attendanceIndex[num] == 1) {
return true;
} else {
return false;
}
}
$scope.results = yelp.bars;
$scope.plusOne = function(place, num) {
if (!auth.isLoggedIn()) {
$scope.error = 'You must be logged in!';
return;
}
yelp.addOne(place);
if (attendanceIndex[num] == 1) {
return attendanceIndex[num] -= 1;
} else {
return attendanceIndex[num] += 1;
}
}
}
}
]);
All the angular.js is in public/js/scripts.js, the guilty ng-repeat is in public/nightlife.html, homepage in views/index.ejs
I appreciate any help!
Replace <img src = "{{ ..}}"> with <img ng-src = "{{ ..}}">. ng-src attribute supports dynamic content.
Always use the ng-href="" attribute when having {{<expressions>}} within your href attributes.
This will stop most of the unwanted behaviour.
Here's the documentation for ng-href.
Quote from the documentation:
The wrong way to write it:
link1
The correct way to write it:
<a ng-href="http://www.gravatar.com/avatar/{{hash}}">link1</a>

how to wrap text in angularjs and save the position

I would like to wrap text with span tag and save the position.
I know how to do it with JS but i dont know how to do it with angularjs
Here is what i have done:
http://jsfiddle.net/ymeaL06j/1/
This function gives me the position of the text in the DIV
function getSelectionPosition() {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(document.getElementById("code"));
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
}
};
I take the start and end positions and insert them as an attribute in the span tag
After this i would like to save all the marked positions and load it later, i have a function that select text and then i can wrap it (i hope that there is a better solution)
function setSelection(savedSel) {
var charIndex = 0, range = document.createRange();
range.setStart(document.getElementById("code"), 0);
range.collapse(true);
var nodeStack = [containerEl], node, foundStart = false, stop = false;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
You can use the same code that you illustrated above and put it inside of your angularjs controller.
Refer to my plunker code; it is a simple angularjs version of your jsfiddle code.
For example, suppose that a snippet of the index.html looks like this:
<body ng-controller="MainCtrl">
<div id="code">This is <b>some text</b> bla bla bla</div>
<br />
<input type="button" value="Mark!" ng-click="markText()" />
<input type="button" value="Remove marks!" ng-click="removeMarks()" />
</body>
Then the example angularjs controller, MainCtrl, could look like this:
app.controller('MainCtrl', function($scope) {
var getSelectionPosition = function () {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(document.getElementById("code"));
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
}
}
$scope.markText = function() {
var currPosition = getSelectionPosition();
var selection = window.getSelection().getRangeAt(0);
var selectedText = selection.extractContents();
var span = document.createElement("span");
span.className = "Mark";
span.setAttribute("PosStart", currPosition.start);
span.setAttribute("PosEnd", currPosition.end);
span.appendChild(selectedText);
selection.insertNode(span);
};
$scope.removeMarks = function() {
$(".Mark").each(function () {
$(this).contents().unwrap();
});
};
});
Notice that the MainCtrl is the angularjs controller for the body. The ng-click on the buttons reference the markText and removeMarks functions in the controller's scope. The logic in the functions are exactly the same as you referenced in your question (and jsfiddle).
None of your JS code changed other than moving the functions inside of the controller. Again, check out the plunker above to see the actual code working.

Resources