Need Advice in Javascript - New font family for every div - javascript

I'm making a post site, but I'm trying to make each post have it's own individual font family.
You can see here with the cursive font, it is assigning it properly, but to all of a class. I need to break each post into it's own individual iteration.
Since I am doing it on load, i can't seem to grab their Id's or Attributes easily and put them into an array.
my current solution is something like this, full code below
The randfontlist doesn't return a normal object, it returns something I've never seen before, like the entire post or something.
Does anyone have a smart solution to iterate through the items with .randfont tag?
Thank you
randfontlist = $('.randfont').toArray()
randfont_idlist = $('.randfont').attr("id").toArray()
$(`.randfont`)[i].addClass(random)
.html
{% for poopfact in poopfacts %}
<div class="col">
<div class="row">
<p>{{ poopfact.date }} </p>
<p class="randfont randfont{{poopfact.id}}" id="{{poopfact.id}}">{{ poopfact.fact }}</p>
<p> {{ poopfact.author }}</p>
</div>
.script
$( document ).ready( function() {
$('.randfont').load(randomizeFonts())
function randomizeFonts() {
let fonts = ['caveat', 'indieflower', 'nanum', 'pacifico', 'pmarker', 'tangerine'];
const randfonts = $('.randfont')
for (let i = 0; i < randfonts.length; i++) {
var random = fonts[Math.floor(Math.random() * fonts.length)];
//get the ids of those items and put it into another array
$(`.randfont`).addClass(random)
}
}

Assuming every font name in the fonts array has its equivalent CSS class to set the font-family...
$( document ).ready( function() {
const fonts = ['caveat', 'indieflower', 'nanum', 'pacifico', 'pmarker', 'tangerine'];
$('.randfont').each(function(index, element){
$(element).addClass(fonts[Math.floor(Math.random() * fonts.length)])
})
}

Related

How to set the values from the json response to the <p> fields in php and javascript?

I am developing one web application where, there is one page, with the search bar, where one can search the projects by name. we'll get the list of projects or the desired project just below that search bar. Now when I click on the project name, I want to get the list of team members for that project to be visible just below that project details. I have the following code, I used 'post' call to call the backend and get the list of members for that project and get the result into JSON. Now I want to put these values to the <p> tags for that team member information. Following is the code:
In Index.php
<div id="members" class="list" style="display: none;">
<div class="result">
<div class="photo">
<img>
</div>
<div class="team_info">
<div class="tm">
<div class="member_name">
<h5>Member Name</h5>
<p id="member_name"></p>
</div>
<div class="prof">
<h5>profession</h5>
<p id="mem_profession"></p>
</div>
</div>
</div>
<div class="contact_button">
<h4 id="contact">See Contact</h4>
</div>
</div>
</div>
<script type="text/javascript">
$('#project_name').on("click",function(){
$.post('/teamMembers.php', {}, function(res){
for(var i=0; i < res.length; i++ ){
$('#member_name').val(res[i]['name']);
$('#mem_profession').val(res[i]['profession']);
}
$('#members').show();
});
});
</script>
In teamMembers.php Controller file
<?php
if(isset($_SESSION['project_name'])){
$project_name = $_SESSION['project_name'];
$members = \Model\Team_Member::getList(['where'=>"project_name = '$project_name'"]);
$this->toJson($members);
}
?>
I have stored the project name in $_SESSION and I get the response of these json request in the following manner:
[{
"name":"ABC",
"email":"test#test.com",
"phone":"9874563210",
"project_name":"Test Project",
"profession":"student",
"id":1312
}]
After all this code, I am still facing some issues like: I am not able to see the any of the team members details, not even the label, even though I use .show() function. Another I am not sure if that was the correct way to set the values to the <p> element from the json response. Help is appreciated
Paragraphs cannot have values, you need to set the text within them:
for(var i=0; i < res.length; i++ ){
$('#member_name').html(res[i]['name']);
$('#mem_profession').html(res[i]['profession']);
}
OR
for(var i=0; i < res.length; i++ ){
$('#member_name').text(res[i]['name']);
$('#mem_profession').text(res[i]['profession']);
}
If your markup repeats, you need to make sure each element has unique ID's. ID's Must Be Unique, specifically because it will cause problems in JavaScript and CSS when you try to interact with those elements.
EDIT: I tested with the following code. You do not need the for() loop (unless you're planning to expand this, at which point the unique ID's come into play):
// you do not need the first couple of lines of code, was just used for testing
var json = '[{"name":"ABC","email":"test#test.com","phone":"9874563210","project_name":"Test Project","profession":"student","id":1312}]';
var res = JSON.parse(json);
$('#member_name').html(res[0]['name']);
$('#mem_profession').html(res[0]['profession']);
$('#members').show();
EDIT 2: If you have more than one member of a project you can append their data to each paragraph like this:
var json = '[{"name":"ABC","email":"test#test.com","phone":"9874563210","project_name":"Test Project","profession":"student","id":1312},{"name":"XYZ","email":"test#test.com","phone":"9874563210","project_name":"Test Project","profession":"teacher","id":1312}]';
var res = JSON.parse(json);
for(var i = 0; i < res.length; i++) {
$('#member_name').append(res[i]['name'] + ', ');
$('#mem_profession').append(res[i]['profession'] + ', ');
}
This results in output like this:
Member Name
ABC, XYZ,
profession
student, teacher,

How should i display number in HTML for later calculation in javascript

I am trying to figure out how to display number a right and efficient way for later calculation in HTML. This is what i can think of right now but doesn't seems right.
<p class = "price"> <span class ="sign">$</span> 10 </p>
Later implementation includes
$("p.price") * (the desire currency rate being called)
It then updates the whole page with the p.price
Consider using data attributes:
<p class="price" data-usd-price="10"> any markup you want </p>
You can then format it however you like and access the raw value later with:
$("p.price").data("usd-price")
Here a bit more complicated example:
<p class="price" data-usd-price="10">foo<span class="converted"></span></p>
<p class="price" data-usd-price="30">bar<span class="converted"></span></p>
<p class="price" data-usd-price="49.99">buzz<span class="converted"></span></p>
<p class="price" data-usd-price="99.99"><span class="converted"></span></p>
$('p.price').each(function () {
$(this)
.children('span.converted')
.html(
$(this).data('usd-price') * 22
)
})
The selector $("p.price") will give you an array of all paragraph elements with the class price. So your first issue is that you need to be aware of that, and your current multiplication code is not.
Second, you're trying to multiply the elements rather than the value of the one element.
Third, the value will be a string and you need a number.
I'd try something like:
<p class="price"><span>$</span><span class="amount">10</span>
Then your JS could look like this (minus smart error checking and optimization and such)
var amount = parseFloat($("span.amount:first").text(), 10);
$("span.amount:first").text(amount * exchangeRate);
Try to loop through paragraph children and check, if nodeName of the children is text then parse it's wholeText
var pContent = $('.price')[0].childNodes,
elem, num;
$.each(pContent, function (i, e) {
elem = $(e)[0];
if (elem && elem.nodeName == "#text") {
num = parseInt(elem.wholeText);
}
})
console.log(num)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<p class = "price"> <span class ="sign">$</span> 10</p>
when the page load the span is left empty but i want it to be shown (GBP as the base)
Simply change the spans text on window load instead of onchange event
var selectedIndex = select.selectedIndex;
$('.sign').text(prefix[selectedIndex ]);
$('.converted').text(currency[selectedIndex ] * $(price).data('price'));
Also i have some notes, if you have just one element you don't need to implement each function , and you don't need to make loop on each change as selectedIndex will filter the option which has selected attribute. http://jsfiddle.net/whoq9zd0/2/

Trouble setting the HTML of a variable in JQuery

What I've done is loaded some HTML from a file and I am attempting to modify some elements within that HTML.
The initialization looks like this:
var id = player_info["ID"];
$("#main_container").append(
$("<div />").attr({class: "player_container", id: "player_" + id}).css("display", "none")
);
// Add all information to the player container
var player_container = $("#player_" + id);
player_container.load("player_layout.html");
With player_layout.html looking like this:
<div class="player_name">
</div>
<div class="player_chips">
Chips:
<br/>
<span class='bidding'></span>/<span class='chips'></span>
</div>
<div class="player_stats">
Wins / Losses
<br/>
<span class="wins"></span>/<span class="losses"></span>(<span class="total_games"></span>)
<br/><br/>
Chips Won / Chips Lost
<br/>
<span class="chips_won"></span>/<span class="chips_lost"></span>
</div>
<button class="player_won">Player Has Won</button>
I then want to modify some of the elements, specifically classes. An example of the way I was initially doing this is:
player_container.find(".player_name").text(player_info['username']);
This wasn't working so I then tried to switch find with children and text with html but that didn't seem to work. I then tried this:
$('> .player_name', player_container).html(player_info['username']);
but that also didn't work. I understand that I can use DOM to grab the childNodes and compare the class names but there are a lot of classes that need modifying and I'd also like to know if this is possible in JQuery. Thanks in advance for any help.
You need to use complete callback method of .load()
var player_container = $("#player_" + id);
player_container.load("player_layout.html", function(){
player_container.find(".player_name").text(player_info['username']);
});

Octobercms Component Twig

Can someone show me how to set unique Id for components?
I only know I have to put this code in my default.htm
{% set uid = '{{__SELF__.id}}' %}
how to use it in javascript?
and what is this for?
var avatar_{{uid}} = {{ avatar }};
for example this is my js
$(function(){
$("#tab-close").click(function() {
$("#tab").addClass("hidden");
});
});
How do I set a unique Id for it so that when I duplicate the component both can still work normally without errors?
It might be better to encapsulate your control with a single identifier, like this
<div id="mycontrol{{ __SELF__.id }}">
...
</div>
Then in JavaScript, you can target elements inside:
function initTabs(controlEl) {
var $control = $(controlEl)
$(".tab-close", $control).click(function() {
$(".tab", $control).addClass("hidden");
});
}
The code above targets the class names found only inside the $control container. You would call this function from the markup like so
<script>
$(function(){
initTabs('#mycontrol{{ __SELF__.id }}');
});
</script>

What's the best way to append an element using angular?

My objective is to show a grid of products and ads between them.
warehouse.query({limit: limit, skip: skip}).$promise
.then(function(data) {
for (var i = 0; i < data.length; i++) {
var auxDate = new Date(data[i].date);
data[i].date = auxDate.toISOString();
}
Array.prototype.push.apply($scope.products, data);
//add an img ad
var warehouseElem = angular.element(document.getElementsByClassName('warehouse')[0]);
var newAd = $sce.trustAsHtml('<img src="/ad/?r=' + Math.floor(Math.random()*1000) + '"/>');
warehouseElem.append(newAd);
skip += 9
});
Doesn't work.
I already tried simply using pure javascript like,
var warehouseElem = document.getElementsByClassName('warehouse')[0];
var newAd = document.createElement('img');
warehouseElem.appendChild(newAd);
Also doesn't work.
I suppose I need to do something with angular, can't find out what. I think it's sanitize but maybe I just don't know how to use it.
Remember I need to inject an img every once in a while between products.
This is a job for ng-repeat!
<div ng-repeat="data in datas">
<div>[show data here]</div>
<img src="/ad/?r=' + Math.floor(Math.random()*1000) + '"/>
</div>
If you have bind your "datas" in scope and Math too like this in your controller like this it should works
$scope.datas // this is your list of products
$scope.Math = Math;
If you don't want to spam add for each line you can use ng-if with $index like this :
<div ng-if="$index%2==0">
<img src="/ad/?r=' + Math.floor(Math.random()*1000) + '"/>
</div>
This will make it display add every 2 lines.
Since you seemed to come from a jQuery-like (or native DOM manipulation) background, I suggest you to read that post : "Thinking in AngularJS" if I have a jQuery background?.
This will explain you why in angular you almost don't manipulate DOM and quite some other things (only in directives).
EDIT : to fix the grid problem, just merging my two html block build your array of datas like this :
$scope.myArray = [product[0], ad[0] or just an empty string it will work still, product[1], ad[1]]
And the html
<div ng-repeat="data in datas">
<div ng-if="$index%2==0">[show data here]</div>
<img ng-if="$index%2==1 src="/ad/?r=' + Math.floor(Math.random()*1000) + '"/>
</div>
In AngularJS you should generally avoid doing DOM manipulation directly and rather rely on angular directives like ng-show/ng-hide and ng-if to dynamically hide sections of a template according to the specific case.
Now back to the problem at hand.
Assuming that you are trying to render a list of products loaded with the code displayed above and display an ad for some of them, you can try the following.
<!-- place the img element in your template instead of appending -->
<div ng-repeat="product in products">
<!-- complex product template-->
<!-- use ng-if to control which products should have an ad -->
<img ng-src="product.adUrl" ng-if="product.adUrl" />
</div>
Then in your controller set adUrl for products that should have an ad displayed.
warehouse.query({limit: limit, skip: skip}).$promise
.then(function(data) {
for (var i = 0; i < data.length; i++) {
var hasAd = // set to true if this product should have an add or not
var auxDate = new Date(data[i].date);
data[i].date = auxDate.toISOString();
if(hasAd){
data.adUrl = "/ad/?r=" + Math.floor(Math.random()*1000);
}
}
Array.prototype.push.apply($scope.products, data);
skip += 9
});
I am most probably assuming too much. If that is the case please provide more details for your specific case.
If you declare a scope variable,
$scope.newAd = $sce.trustAsHtml('<img src="/ad/?r=' + Math.floor(Math.random()*1000) + '"/>');
and in your HTML template, have a binding like
<div ng-bind-html="newAd"></div>,
it should work.

Categories