Manipulating JQuery .text() output - javascript

I am building a Twitter like site that is fed random tweets that I want to export to the website in a particular manner. I have most of my requirements met up to this point, the only issue I am having is turning the jQuery text of a Twitter user and handle it into a link that can be clicked.
My code snippet below exhibits my work so far:
<script>
$(document).ready(function(){
var $body = $('.middle');
$body.html();
var index = streams.home.length - 1;
var newTweets = function(index){
while(index >= 0){
var tweet = streams.home[index];
var $tweet = $('<div class=tweetBox></div>');
$tweet.text('#' + tweet.user + ': ' + tweet.message + tweet.created_at);
$tweet.appendTo($body);
index -= 1;
}
}
newTweets(index);
$('button').on('click', function(){
index = streams.home.length - 1;
newTweets(index);
});
});
</script>
The line that is giving the issue is $tweet.text('#' + tweet.user + ': ' + tweet.message + tweet.created_at);
I want to take tweet.user and convert it into a click-able link. Any suggestions on ways to attack this would be very much appreciated.

You have to use the HTML function of jQuery. http://api.jquery.com/html/
like this:
var link = $('<a>', {text: tweet.user, href: '#'}).prop('outerHTML');
$tweet.html('#' + link + ': ' + tweet.message + tweet.created_at);
it will do the work.

If I understand correctly, then this is what you want
var link = $('<a>', {text: tweet.user, href: '#'}).prop('outerHTML');
$tweet.html('#' + link + ': ' + tweet.message + tweet.created_at);

Related

Suggestions to make this jQuery function more DRY / more efficient

Following previous post the this code works and does the job but I am conscious this is about as DRY as the Pacific on a wet day.
I's be grateful for any suggestions that will make it more efficient.
$( "#cvl_mb_services .content-switch" ).each(function(index, el) {
var parent = $(el).parent().parent().attr("id");
var inputValue = $('#' + parent + ' input[type=radio]:checked').val();
var targetBox = '#' + parent + ' .cvl-' + inputValue + '-fields';
$(targetBox).removeClass('cvl-hide');
});
$('#cvl_mb_services .content-switch').on('click', 'input[type="radio"]', function(){
var parent = $(this).parent().parent().parent().parent().parent().parent().attr("id");
var inputValue = $(this).closest('input[type="radio"]').attr("value");
var targetBox = '#' + parent + ' .cvl-' + inputValue + '-fields';
if (inputValue == 'content') {
$('#' + parent + ' .cvl-content-fields').removeClass('cvl-hide');
$('#' + parent + ' .cvl-header-fields').addClass('cvl-hide');
$('#' + parent + ' .cvl-footer-fields').addClass('cvl-hide');
} else if (inputValue == 'header') {
$('#' + parent + ' .cvl-content-fields').addClass('cvl-hide');
$('#' + parent + ' .cvl-header-fields').removeClass('cvl-hide');
$('#' + parent + ' .cvl-footer-fields').addClass('cvl-hide');
} else if (inputValue == 'footer') {
$('#' + parent + ' .cvl-content-fields').addClass('cvl-hide');
$('#' + parent + ' .cvl-header-fields').addClass('cvl-hide');
$('#' + parent + ' .cvl-footer-fields').removeClass('cvl-hide');
}
});
Several points to make it more DRY:
Use only one var keyword, and separate the items with commas. Ex. var asdf = 1, sdfg = '', dfgh = true;
Use multiple selectors so you apply the .addClass action only once. See https://api.jquery.com/multiple-selector/
Find a way to get rid of this duplication, such as perhaps adding/using a class to select the right ancestor: .parent().parent().parent().parent().parent().parent()
Don't duplicate strings like 'cvl-hide' Instead make a variable. Many JavaScript minifiers won't touch strings, so you'll end up with this duplication making your overall file larger than it needs to be.
Make variables for duplicate selectors so jQuery doesn't have to do the same lookup twice. For stuff like $('#cvl_mb_services .content-switch') and even for stuff like $(this) which is duplicated.

Creation of buttons and eventlisteners using javascript

I am trying to create a function that will add buttons with their corresponding event listeners
var wordCount = 0;
function createButton(word, alert){
document.querySelector('body').innerHTML += "<button id=\"word-" + wordCount + "\">" + word + "</button>";
document.querySelector('#word-' + wordCount).addEventListener('click', function(){
console.log(alert);
})
wordCount++;
}
createButton('a', 'A');
createButton('b', 'B');
Only the last button(b) responds. Clicking button(a) does not output anything.
How would you fix this? Are there better ways that I could have implemented this?
I am frequently facing this situation and doing it in a simpler way. see this, (the beauty of the method is if you start the variable full with single quotes, you can add any usual double quoted stuff within it, with ease and without any escaping issues). No addEventListener business needed here. :-)
var full = '';
var wordCount = 0;
function createButton(word, alert) {
alert='\'' + alert + '\'';
full = full + '<a href="javascript:void(0)" onclick="alert(' + alert + ');">'
full = full + '<button id="word-' + wordCount + '" >' + word + '</button>';
full = full + '</a>';
document.querySelector('body').innerHTML += full;
wordCount++;
}
function anyFunction(alert) {
console.log(alert);
}
createButton('a', 'A');
createButton('b', 'B');

Fading in appended elements one at a time

I have an array with IDs and I am loading elements with these IDs from another page.
$.each(idArr, function() {
var divline = '<div class="line" id="' + this + '">';
var url = 'allitems.php #' + this + ' div';
$('#the-list').append($(divline).load(url).hide().fadeIn());
});
It works fine but I would like the loaded elements to fade in one at a time, or at least not all att once. I cannot figure out how to use .delay with my code. Or is there maybe another way?
Thank you :)
$.each(idArr, function(i,el) {
var divline = $('<div />', {'class':'line', id: el}),
url = 'allitems.php #' + el + ' div';
$('#the-list').append(divline.load(url).hide().delay(i*1000).fadeIn());
});
A simple solution is to use setTimeout :
$.each(idArr, function(i) {
var divline = '<div class="line" id="' + this + '">';
var url = 'allitems.php #' + this + ' div';
setTimeout(function(){
$('#the-list').append($(divline).load(url).hide().fadeIn());
}, i*1000);
});
Try this way:
$(".elements").each(function(i, e) { $(e).delay(i * 400).fadeIn(400); });

Increase Google Map Info Window Size

I have a google map.
And there's an information window.
Now the size is standard and there r loads of texts inside.
So, my boss asked me to increase it.
We are useing ektron CMS and thus I need to go into ektron workarea and edit map.js
Even if it is ektron, it is still using google map.
I managed to find out which part is displaying as info window.
This is the part of code where info window pops up and display information inside.
marker = new GMarker(point, icon);
var infoWindow = map.getInfoWindow();
GEvent.addListener(marker, "mouseover", function () {
if (EMap.SearchData != 'content') {
if (qlink && qlink.length > 0) {
_userTB = '<span>' + title + '</span>';
}
else {
_userTB = title;
}
var theHtml1 = '<div id="IW_' + markerid + '" style="overflow:auto;width:240px;height:100px;">' + markerid + '. ' + _userTB + _summarytxt + '<br/>' + EGlobal.Format(EMap.Geolocation, new Array('javascript:EMap.SetAddress(\'' + EGlobal.Replace(address, '#', ' ') + '\',\'to\');', 'javascript:EMap.SetAddress(\'' + EGlobal.Replace(address, '#', ' ') + '\',\'from\');')) + '</div>';
map.openInfoWindowHtml(theHtml1);
}
else {
var theHtml2 = '<div id="IW_' + markerid + '" style="overflow:auto;width:240px;height:100px;">' + markerid + '. <span><b>' + title + '</b></span><br/>' + _summarytxt + '<br/>' + EGlobal.Format(EMap.Geolocation, new Array('javascript:EMap.SetAddress(\'' + EGlobal.Replace(address, '#', ' ') + '\',\'to\');', 'javascript:EMap.SetAddress(\'' + EGlobal.Replace(address, '#', ' ') + '\',\'from\');')) + '</div>';
marker.openInfoWindowHtml(theHtml2);
}
});
I try to search on google and found out that this is how a guy tried to change the info window size.
var infoWindow = map.getInfoWindow();
var point = new GLatLng(0,0);
var marker = new GMarker(point);
GEvent.bind(marker,”click”,marker,function() {
map.openInfoWindowHtml(this.getPoint(),this.address,{onOpenFn:function(){
infoWindow.reset(this.getPoint(),infoWindow.getTabs(),new GSize(200,200),null,null);
}});
});
The full article is on this site.
But I cannot merge them into 1.
especially that guy is using map.openInfoWindowHtml() with 3 parameters and ektron is using marker.openInfoWindowHtml() with only one parameter.
Any idea how to get this done? Tkz a lot.
And.. I am very new to google map. So, forgive me if my question is wasting your time.
Maybe this answer is too simple but did you allready tried to edit this line in the openInfoWindowHTML() call?
style="overflow:auto;width:240px;height:100px;">

JQuery: get a child as you append it

I am appending p tags to a div as I process a json request and would liek to style it according to what is in the request.
$(document).ready(function() {
function populatePage() {
var numberOfEntries = 0;
var total = 0;
var retrieveVal = "http://www.reddit.com/" + $("#addressBox").val() + ".json";
$("#redditbox").children().remove();
$.getJSON(retrieveVal, function (json) {
$.each(json.data.children, function () {
title = this.data.title;
url = this.data.url;
ups = this.data.ups;
downs = this.data.downs;
total += (ups - downs);
numberOfEntries += 1;
$("#redditbox").append("<p>" + ups + ":" + downs + " " + title + "<p>");
$("#redditbox :last-child").css('font-size', ups%20); //This is the line in question
});
$("#titlebox h1").append(total/numberOfEntries);
});
}
populatePage()
$(".button").click(function() {
populatePage();
});
});
Unfortunately things are not quite working out as planned. The styling at the line in question is applying to every child of the div, not just the one that happens to be appended at the time, so they all end up the same size, not sized dependent on their numbers.
how can I apply a style to the p tags as they are appended ot the div?
Edit: Thanks Fortes and Veggerby both worked, but i went with Fortes in the end because I did.
You can use JQuery's appendTo instead of append. For your example:
$("<p>" + ups + ":" + downs + " " + title + "<p>")
.css('font-size', ups%20)
.appendTo('#redditbox');
Here are the docs for appendTo: http://docs.jquery.com/Manipulation/appendTo
Replace:
$("#redditbox").append("<p>" + ups + ":" + downs + " " + title + "<p>");
with
var p = $("<p>" + ups + ":" + downs + " " + title + "<p>");
$("p", p).css('font-size', ups%20)
$("#redditbox").append(p);
Can probably be condensed even further.
Edit:
Condensed like:
$("#redditbox").append(
$("<p></p>").css('font-size', ups%20).append(ups + ":" + downs + " " + title + "")
);
Certain browsers/versions do not support the :last-child CSS selector. In that case they often ignore it and return all elements matching the remainder of the selector. This is possibly what you are seeing.
As usual IE is one such browser.
veggerby's approach should help you get around the need to use :last-child.

Categories

Resources