Passing string from onclick to a Javascript function - javascript

I have this line:
$twizz.html(
'<a class="username" href="#">' + twizz.user + '</a>' + ': ' + twizz.message
)
and a JQuery line that executes a function when clicked:
$('.username').click(function() {displayUserTwizz(); return false; });
For example. JohnDoe (twizz.user) - Hello everyone (twizz.message) (with John Doe calling the displayUserTwizz function when clicked)
How do I dynamic pass the twizz.user string into my displayUserTwizz function. For example if I click JohnDoe, the function will run as
displayUserTwizz = function () {
var index = message.JohnDoe.length;
}

You need to get the content of the <a> element (event.target.innerText), then pass it to the displayUserTwizz() function:
$('.username').click(function() {displayUserTwizz(event.target.innerText); return false; });
Then, you can handle the user in the displayUserTwizz() function:
displayUserTwizz = function (user) {
var index = message[user].length;
}

Related

jQuery, Passing object on click from array to another function

I have a list of objects coming into my web page. One property of the object is firstName. I display some of the properties and have a clickable one that calls another fuction. I want to pass the object from the array to the second function
jQuery.each(x, function () {
$('#results').append("<a href='javascript:void(0)' onClick='workSup(" + '"' + $(this) + '"' + ")' >" + decodeURI(this.firstName) + ' ' + decodeURI(this.lastName) + " - " + decodeURI(this.preApprovalSupervisorName) + " <a/><br/> ");
});
function workSup(x) {
alert(x.firstName);
}
I've tried passing this as well as $(this). The alert reads "undefined"
What am I doing wrong? Thanks!
jQuery has a great function, .data(), I'd recommend you look into:
$('#selector').data("key", "value (string, number, object, etc.)")
$('#selector').data("key"); //Returns the data, or null if not yet set
Also, I highly recommend moving away from onclick to
$('.myClassName').on("eventName (such as click, change or keyup)", "jqSelector", handlerFunction);
var x = [{firstName:"John", lastName:"Lennon"}, {firstName:"Phil", lastName:"Ochs"}]
$(document).ready(function() {
jQuery.each(x, function () {
var linkEl = $('<a class="myLink" href="javascript:void(0)">' + this.firstName + " " + this.lastName + '</a>');
linkEl.data("myObjData", this);
$('#results').append(linkEl);
});
$(document).on("click", ".myLink", function() {
var myObjData = $(this).data("myObjData");
//myObjData.firstName can be accessed here
alert(JSON.stringify(myObjData));
});
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div id="results"></div>
</body>
</html>
$('.myClass').on() is even better than $('.myClass').click() because it will even listen to elements that are dynamically added later
jQuery.each(x, function() {
//create the a element
var $a = $("<a href='javascript:void(0)'>"+
decodeURI(this.firstName) +' '+ decodeURI(this.lastName) +
" - "+ decodeURI(this.preApprovalSupervisorName) +
"</a><br/>");
//bind the event handler to it
$a.on('click', function(){
workSup(x);
});
});
As mentioned by #taplar you're creating inline binding. Basically what happens is that your $(this) gets resolved as string and later inside your workSup() method you're trying to access firstName property of the string which is obviously undefined.
What you have to do instead is to dynamically create your link and attach event listener to it (in which you call the workSup() method) like so:
// Your data
const x = [
{ firstName: 'First', lastName: 'Last', preApprovalSupervisorName: 'Super' },
{ firstName: 'Another', lastName: 'One', preApprovalSupervisorName: 'His super' },
];
// Your workSup method
const workSup = x => alert(x.firstName);
// Loop though each item
$.each(x, function() {
// Create new <a> element
const $element = $('<a></a>')
// Add href attribute
.attr('href', 'javascript:void(0)')
// Set its text
.text(`${decodeURI(this.firstName)} ${decodeURI(this.lastName)} ${decodeURI(this.preApprovalSupervisorName)}`)
// Attach onClick listener
.on('click', () => workSup(this));
// Append the element to the results and add line break
$('#results')
.append($element)
.append('<br />');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="results"></div>
var x =[{firstName: "John", lastName:"DG", preApprovalSupervisorName: "sup"}];
jQuery.each(x, function (index, value) {
$('#results').append(
$("<a>")
.attr("href","#")
.html( decodeURI(value.firstName) + ' ' + decodeURI(value.lastName) + " - " + decodeURI(value.preApprovalSupervisorName))
.click(function(){
workSup(value);
})
);
});
function workSup(x) {
alert(x.firstName);
}

Find all Divs after being created with JQuery on click event

I'm trying to find all divs that have been created from my click event and split them into another div (.wrapAll) on a count of 3. I can't seem to get anything back when i console.log the vars length. I know this works when I do that same process on the html thats been statically typed. Below is my code and thank you fo the thoughts!
jQuery(document).ready(function($) {
// load default twitch channels
$.getJSON('https://api.twitch.tv/kraken/streams/freecodecamp?callback=?', function(data) {
//console.log(data);
});
// Bind 'Enter' to click event
$(document).bind('keypress', function(e) {
if (e.keyCode == 13) {
$('#search').trigger('click');
}
});
// manually search for games
$('#search').on("click", function() {
// clear previous results and get search term
$('#results').html('');
search = $('#searchTerm').val();
// begin API call
$.getJSON( "https://api.twitch.tv/kraken/search/streams?q=" + search + "", function(data2) {
// console.log(data2.streams.length);
data2.streams.forEach(function(entry) {
//console.log(entry._links);
var streamURL = entry.channel.url;
url = entry.preview.medium;
$('#results').append('<div class="searchResults"><img class="games" src=' + url + '/><p id="title"> Game: ' + entry.channel.game + '<br> Viewers: ' + entry.viewers +'<br> Is Mature: ' + entry.channel.mature + '<br> Status: ' + entry.channel.status + ' </p></div><hr>');
});
});
// Get 3 divs and slice into one div to style ** problem child **
var a = $('div[id^=searchResu]').find('div');
console.log(a.length);
for( var i = 0; i < a.length; i+=3 ) {
a.slice(i, i+3).wrapAll('<div class="slide"></div>');
}
});
});
Check out this plunker here. I believe this does what your looking for.
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#2.1.4" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
<script>
jQuery(document).ready(function($) {
function appendHtmlContent(resultHtmlContent) {
resultHtmlContent = '<div class="slide">' + resultHtmlContent + '</div>';
$('#results').append(resultHtmlContent);
}
function processSvcResponse(data2) {
var count = 0,
searchResultContents = '',
$div = $("<div>", { class: "searchResults"});
data2.streams.forEach(function(entry) {
var streamURL = entry.channel.url;
url = entry.preview.medium;
searchResultContents += '<div class="searchResults"><a href="' + streamURL
+ '" target="_blank"><img class="games" src=' + url + '/><p id="title"> Game: ' + entry.channel.game
+ '<br> Viewers: ' + entry.viewers + '<br> Is Mature: ' + entry.channel.mature
+ '<br> Status: ' + entry.channel.status + ' </p></a></div><hr>';
count++;
if(count === 3) {
appendHtmlContent(searchResultContents);
searchResultContents = '';
count = 0;
}
});
// more results that have not been appended?
if(searchResultContents) {
appendHtmlContent(searchResultContents);
}
}
// load default twitch channels
$.getJSON('https://api.twitch.tv/kraken/streams/freecodecamp?callback=?', function(data) {});
// Bind 'Enter' to click event
$(document).bind('keypress', function(e) {
if (e.keyCode == 13) {
$('#search').trigger('click');
}
});
// manually search for games
$('#search').on("click", function() {
// clear previous results and get search term
$('#results').html('');
search = $('#searchTerm').val();
// begin API call
$.getJSON("https://api.twitch.tv/kraken/search/streams?q=" + search, processSvcResponse);
});
});
</script>
</head>
<body>
<input id="searchTerm" type="text" />
<button id="search" type="button">Search</button>
<div id="results"></div>
</body>
</html>
If I understand correctly you are wanting to iterate over the results and for every third one wrap it inside a div with class "slider". As mentioned in the comments by #charlietfl in order to query newly created DOM elements using jQuery you have to query them after they are created. In the call to jQuery.getJSON the second argument accepts a callback function. The signature is jQuery.getJSON(url, someCallbackFunction). In order to make your code a bit more readable I moved "function(data2)" up and named it processSvcResponse. Inside processSvcResponse I build up an HTML string from the results and track how many results are processed by using a counter variable. Once the counter reaches 3 I append the contents to the results div and reset the counter. This solution does not "find" the divs and slice/wrapAll as you were intending to do originally, however, I believe this still accomplishes your goal.
As #charlietfl said, you'll need to place the code that wraps your divs in the callback for getJSON. Your click event listener would look something like this then:
$('#search').on("click", function() {
// clear previous results and get search term
$('#results').html('');
search = $('#searchTerm').val();
// begin API call
$.getJSON( "https://api.twitch.tv/kraken/search/streams?q=" + search + "", function(data2) {
// console.log(data2.streams.length);
data2.streams.forEach(function(entry) {
//console.log(entry._links);
var streamURL = entry.channel.url;
url = entry.preview.medium;
$('#results').append('<div class="searchResults"><img class="games" src=' + url + '/><p id="title"> Game: ' + entry.channel.game + '<br> Viewers: ' + entry.viewers +'<br> Is Mature: ' + entry.channel.mature + '<br> Status: ' + entry.channel.status + ' </p></div><hr>');
});
// Get 3 divs and slice into one div to style ** problem child **
var a = $('div[id^=searchResu]').find('div');
console.log(a.length);
for( var i = 0; i < a.length; i+=3 ) {
a.slice(i, i+3).wrapAll('<div class="slide"></div>');
}
});
});

__doPostBack trigger on html render from javascript(before real click)

I'm trying to create some new buttons from js like:
var nextYearList ="";
...
nextYearList += "<button type='button' customparam='" + newCatalogList[l].code + "|" + newBaseName + "' ><span class='catName'>" + newCatalogList[l].name + "</span><span class='catYears'>" + newCatalogList[l].startDate + " - " + newCatalogList[l].endDate + "</span></button>";
...
ok('#YearNavigation .panelNextYear')[0].innerHTML = nextYearList;
var xListYears = ok('.panelNextYear button[customparam]');
for (var f = 0; f < xListYears.length; f++)
{
xListYears[f].addEventListener('click', changeCatalogPostback(xListYears[f].getAttribute('customparam'),true));
}
Where ok is my document.querySelectorAll wrapper;
ok = function (model)
{
return document.querySelectorAll(model);
};
changeCatalogPostback= function (parameter,checker)
{
if(checker)
__doPostBack('changeCatalog',parameter);
};
The main problem is that my __doPostBack is triggered on html rendering... so bye bye current page...
So how can I avoid a __doPostBack trigger on html render from javascript? I really need it to be there but working on click and not on render...
When you are adding an event listener you are actually calling the function which returns undefined and makes a postback. So if you will remove a __doPostBack call from changeCatalogPostback function the line with addEventListener call would evaluate to the end and will be equal to:
xListYears[f].addEventListener('click', undefined);
Instead addEventListener should accept a function as a second parameter. Use a bind call:
xListYears[f].addEventListener(
'click',
changeCatalogPostback.bind(this, xListYears[f].getAttribute('customparam'), true));

How to access a parameter from second page?

I have a page that lists courses. When a student clicks on one of the course titles, it will use AJAX to pass the parameter (courseId) to a second page which will return the course details. How can the parameter (courseId) be accessed in the second page? If I put a value directly in the source instead of accessing the parameter, it shows the details:
var idInput = 12345;
var regNoInput = 098766;
When I tried getElementById to access the parameter, it didn't show any details:
var idInput = document.getElementById("courseId").value;
var regNoInput = document.getElementById("regNo").value;
I also tried accessing the parameter as a PHP variable, but still no details:
var idInput = "${courseId}";
var regNoInput = "${regNo}";
this is my first page script, the parameter is pass using url:
success: function(json_results){
$('#list').append('<ul data-role="listview" data-inset="true"</ul>');
listItems = $('#list').find('ul');
$.each(json_results.rows, function(key) {
html = "<li data-mini='true' id='icon'><a href='MRegisteredClassesDetail.html?
courseId=" + [json_results.rows[key].courseId] + "&regNo=" +
[json_results.rows[key].regNo] +"' rel='external'>" +
json_results.rows[key].courseName+ "</a>" + "<a
href='http://137.57.102.146:8080/Training/MRateCourse.phone?courseId="+
[json_results.rows[key].courseId] + "&regNo=" +
[json_results.rows[key].regNo] + "' rel='external'>RATE THIS COURSE</a>
</li>" ;
listItems.append(html);
});
and this is my second page, it should read the parameter value:
var idInput = "${courseId}";
var regNoInput = "${regNo}";
success: function(json_results){
$('#list').append('<ul data-role="listview" data-inset="true"</ul>');
listItems = $('#list').find('ul');
$.each(json_results.rows, function(courseId) {
html ='<h1 align=center>'+json_results.rows[courseId].courseName+'</h1>';
html +='<li>Registration Number:'+json_results.rows[courseId].regNo+'</li>';
html +='<li>Registration Date:'+json_results.rows[courseId].regDate+'</li>';
listItems.append(html);
});
if the parameter in the url,try this:
var params=window.location.search.substr(1).split("&"),
idInput=params[0].split("=")[1],
regNoInput=params[1].split("=")[1];
i declare a variable
var idInput = getParameterByName('courseId');
and define the function
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
it works well.

How can I display multiple (but seperate) JSON requests on the same page

I have a web page where I want to display hotel reviews from the yelp.com API for a number of hotels.
I have managed to do this for one hotel, and it works perfectly displaying the data under that specific hotel's details on the page. However, how can I now multiply this process so that I have separate reviews for each hotel?
My web page can be seen at http://dev.bhx-birmingham-airport.co.uk/pages/hotels.php to get an idea of what I'm trying to do.
The source code I am using so far looks like:
<script>
function showData(data) {
$.each(data.businesses, function(i,business){
// extra loop
$.each(business.reviews, function(i,review){
var content = '<p>Review - ' + review.text_excerpt + ' Read more...</p>';
content += 'Rating - <img src="' + business.rating_img_url + '" />';
content += '<p>Date Added - ' + review.date + '</p>';
$(content).appendTo('#hilton');
});
});
}
$(document).ready(function(){
// note the use of the "callback" parameter
writeScriptTag( "http://api.yelp.com/business_review_search?"+
"term=hilton%20metropole"+
"&location=B26%203QJ"+
"&ywsid=[...]"+
"&callback=showData"); // <- callback
});
function writeScriptTag(path) {
var fileref = document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", path);
document.body.appendChild(fileref);
}
</script>
Your question is somewhat unclear.
I assume that you want to send multiple requests to Yelp and have them processed by different callback functions.
You can do that by making a buildCallback method that takes information about the request to generate a callback for and returns a function.
You can then use an invocation of that function as the callback parameter, like this: callback=buildCallback('something') It will return a script that looks like this:
buildCallback('something')({"message: ... })
This code calls the buildCallback method, then calls the function that the buildCallback method returns.
For example:
(Assuming that each hotel has a <div class="HotelReviews" id="giveThisToYelp">)
function buildCallback(hotelName) {
return function(data) {
$.each(data.businesses, function(i,business){
// extra loop
$.each(business.reviews, function(i,review){
var content = '<p>Review - ' + review.text_excerpt + ' Read more...</p>';
content += 'Rating - <img src="' + business.rating_img_url + '" />';
content += '<p>Date Added - ' + review.date + '</p>';
$(content).appendTo('#' + hotelName);
});
});
};
}
$(function() {
$('.HotelReviews').each(function() {
$.getScript("http://api.yelp.com/business_review_search?"+
"term=" + this.id +
"&location=B26%203QJ"+
"&ywsid=[...]"+
"&callback=buildCallback(" + this.id + ")"
);
});
});
Instead of inserting a script tag on the page with the request url and a callback function name, You should make multiple requests to Yelp services manually.
A simple example in JQuery:
function LoadReviews() {
for (var i = 0; i < myhotels.length; i++) {
$.getJSON("http://api.yelp.com/business_review_search?" + myhotels[i], null, showData);
}
}
Where the myhotels array contains the search parameters for each of your hotels.

Categories