David Washburn David Washburn - 4 months ago 20
Javascript Question

Onclick Change Function Inside Script Tag

The below pulls Reddit content via JSON and places it in corresponding 's. My own mini-reddit. Right now you can see the URL is pulling from /r/images. I want to be able to type "buildapcsales" in an input box and have that part of the page reload with a script that pulls from the /r/buildapcsales reddit.

I cannot seem to find a way to change the contents of the script, or any other workaround for this. I have attempted to create multiple files and have them load on.click, however it would be impossible to have a script already built to match every possible outcome someone would type in the input box.

Is there a way to edit the contents of an HTML on-page on.click? Or through an input box? I found no evidence that this is possible through my research online.

<script>
$.getJSON(
"https://www.reddit.com/r/images.json?jsonp=?",
function foo(data) {
$.each(
// iterate over 10 children, starting at the 0th index
data.data.children.slice(0,12),
function (i, post) {
// put data into the corresponding DIV
$('#news' + i + ' .redditTitle').append('<a href="https://www.reddit.com/' + post.data.permalink + '">' + post.data.title + '</a>');
$('#news' + i + ' .redditPermalink').append('<div class="info">expand_more</div>');
$('#news' + i + ' .redditUps').append(post.data.ups);
$('#news' + i + ' .redditDowns').append(post.data.downs);
$('#news' + i + ' .redditPost').append('<p>' + post.data.selftext_html + '</p>');
$('#news' + i + ' #subredditName').append('<p class="subredditName smalltext alignleft floatleft s-l-padding">r/' + post.data.subreddit + '</p>' );
$('#news' + i + ' .redditThumbnail').append('<a href="' + post.data.url + '"><img src="' + post.data.thumbnail + '" class="floatleft image news hide">' + '</a>');
$('#news' + i + ' #redditUsername').append('<p class="smalltext p-color alignleft floatleft s-l-padding redditUsername">'
+ '<a href="https://www.reddit.com/user/' + post.data.author + '">' + post.data.author + '</a>' + '</p>');
//Decodes HTML into correct format
//Also replaces "null" post text with blank value
$('.redditPost').each(function(){
var $this = $(this);
var t = $this.text();
$this.html(t.replace('&lt','<').replace('&gt', '>'));
$this.html(t.replace('null','').replace('null', ''));
});
//Checks for "self" tagged images and replaces them with a default placeholder image
function changeSourceAll() {
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
if (images[i].src.indexOf('self') !== -1) {
images[i].src = images[i].src.replace("self", "/images/default.png");
}
}
for (var i = 0; i < images.length; i++) {
if (images[i].src.indexOf('default') !== -1) {
images[i].src = images[i].src.replace("self", "/images/default.png");
}
}
}
changeSourceAll();

}
)
}
).error(function() { alert("error"); })




Thanks for any suggestions in advance!

Answer

I want to be able to type "buildapcsales" in an input box and have that part of the page reload with a script that pulls from the /r/buildapcsales reddit.

For that you need an input box.

<input type="text" name="subreddit" />

Then, you need a way to get that input box's value.

$('input[name="subreddit"]').val();

It might also be useful to get that value when the field changes.

$('input[name="subreddit"]').on('change', function () ...

Then, you need to build a dynamic URL. You should encode anything with encodeURIComponent to ensure any special characters are escaped properly.

'https://www.reddit.com/r/' + encodeURIComponent(subreddit) + '.json'

Also, I see you were using JSON-P. No need... Reddit has Access-Control-Allow-Origin: * in their headers, allowing this data to be loaded cross-domain without issue. Loading the data directly is far more reliable, and allows you to properly catch errors.

I cannot seem to find a way to change the contents of the script, or any other workaround for this.

You don't need to change the script. What you need is a function that you can call with a parameter that then gets concatenated into the rest of the URL. That way, you can load any subreddit you want.

function loadRedditData(subreddit) {
    $.getJSON('https://www.reddit.com/r/' + encodeURIComponent(subreddit) + '.json').then(function (data) {
        console.log(data);
    });
}

$(function () {
  $('input[name="subreddit"]').on('change', function () {
      loadRedditData($(this).val()); // Pass the value of the input to the loadRedditData function
  });
});

Is there a way to edit the contents of an HTML on-page on.click? Or through an input box? I found no evidence that this is possible through my research online.

Of course it's possible. Otherwise, sites like Stack Overflow, Gmail, Google Maps, Facebook, pretty much all of them, wouldn't be possible. Not sure what you were looking for, but the key words here are, "DOM manipulation". The DOM is the document object model... it's a tree structure that represents the page. By modifying elements, you control them on page.

You need to shift your thinking from, "writing HTML elements as formatting instructions", to "writing HTML that is interpreted and loaded as elements of a tree". Once you see it this way, you won't worry about concatenating data into tags. You'll just be editing properties of these tags. This should get you started:

$('.content').append(
  $('<a>')
    .attr('href', 'https://www.reddit.com/' + post.data.permalink)
    .text(post.data.title)
);

If you concatenate text into the context of HTML, it will be interpreted as HTML which is not what you want at all. Imagine someone creating a post with a title of <script src="somethingEvil.js"></script>. That's one of the reasons it's critical you set element attributes and text.