jQuery - Loaded HTML Doesn't Respond to Clicks - javascript

Here is my original code:
<tr class="song" id="'.$this->i.'">
<td class="clickable" id="td1_'.$this->i.'">
...
</td>
</tr>
And the jQuery for that:
$(".clickable").click(function()
{
//
//Make only certain parts of songs clickable
//Hacky Way to Get Index
var temp = $(this).attr("id");
temp = temp.split('_');
var i = temp[1];
var status = $('#status_'+i).val();
alert('Clicked ' + i);
var maxid = $('#maxid').val();
if(status == "max") //if maximized
{
alert("max");
}
else
{
var user = $("#user_min"+i).val();
var ytcode = $("#ytcode_min"+i).val();
var title = $("#title_min"+i).val();
var artist = $("#artist_min"+i).val();
var genre = $("#genre_min"+i).val();
var score = $("#score_min"+i).val();
var ups = $("#ups_min"+i).val();
var downs = $("#downs_min"+i).val();
var id = $("#id_min"+i).val();
var upload_date = $("#upload_date_min+i").val();
//Maximizing New Song
dataString = 'user='+ user + '&ytcode=' + ytcode +
'&title=' + title + '&artist=' + artist +
'&genre=' + genre + '&score=' + score +
'&ups=' + ups + '&downs=' + downs +
'&id=' + id + '&upload_date=' + upload_date +
'&i=' + i;
$.ajax({
type: "POST",
url: "maxSongAjax.php",
data: dataString,
cache: false,
success: function(html){
$('#'+i).fadeIn(1000).html(html);
}
});
//Setting Max ID to New Song
$('#maxid').val(i);
}
return false;
});
I have the ajax returning identical html to what was replaced for testing purposes. However, after I click the loaded html, it does not respond to clicks. No pop-ups are shown from the alerts.
Why is this? How come the loaded html isn't responding like the first?

This is a very common issue for people new to jQuery; you have to use .live()
.click() only binds to existing elements.
An alternative to .live() is .delegate()

Related

I want to clear my table data before adding new data from the api request? i have tried to use multiple methods [duplicate]

This question already has an answer here:
JQuery clear HTML table and insert new rows
(1 answer)
Closed 3 years ago.
$("#artistButton").on('click', function () {
var artist = $("#artistSearch").val().trim()
var queryURL = "https://rest.bandsintown.com/artists/" + artist + "/events?app_id=test&date=upcoming" + artist + "?app_id=test";
console.log(artist)
$.ajax({
url: queryURL,
method: "GET"
}).then(function (response) {
var imageURL = response[0].artist.image_url;
var image = $("<img id='pictureSize'>")
var artistName = response[0].artist.name
console.log(response)
$("#artistName").html(artistName)
image.attr('src', imageURL)
$("#artistImage").html(image)
$("#venue").html(response[125].venue.name)
for (var i = 0; i < response.length || 5; i++) {
var time = moment(response[i].datetime).format("MMM Do, hh:mm");
var venueName = response[i].venue.name
var city = response[i].venue.city;
var region = response[i].venue.region
if (i == 5) {
break;
}
$(".tableData").before($("<tr><td>" + venueName + "</td>" + "<td>" + city + ', ' + region + "</td>" + "<td>" + time + "</td></tr>"))
}
});
$(".tableData").val("");
})
Wanted to answer my own question in case someone had the same issue but i simply added $("#concertInfo").find("td").remove(); after my ajax call and it will remove all table data!
You can use empty or remove function to set the table content before adding new ones.
Empty: "Remove all child nodes of the set of matched elements from the DOM."
Remove: "Remove the set of matched elements from the DOM."

Iterate over all fields in custom app / transform code from single field

I have the below code which works well inside a custom application I'm building in the app 'Knack'.
However, rather than just save a single field, I'd like to be able to autosave ALL fields in the application.
Is it possible to loop over all 'views' and 'fields' to make this jQuery work on all 'views' and 'fields' in the application?
var viewId = "view_19";
var fieldId = "field_31";
var autoSaveDelay = 2000; // Value in milliseconds, 800 = .8 seconds
// Listen to our Article Edit view, when rendered register our actions
$(document).on('knack-view-render.' + viewId, function(event, view, records) {
console.log(" >>> Rendered view");
// Temporarily store data for comparison later
var initialData = $("#" + viewId).find("#" + fieldId).val();
var timer = {};
var autoSaveLabel = document.createElement('span');
autoSaveLabel.id = "autosave_label_" + viewId + "_" + fieldId;
autoSaveLabel.style = "font-style: italic;";
// Add autosave checkbox flag to field
$("#kn-input-" + fieldId).append(autoSaveLabel);
// Add listener for keyup
$("#" + viewId).find("#" + fieldId).on('keyup', function() {
// If the data is the same... don't save it!
if (initialData !== $("#" + viewId).find("#" + fieldId).val()) {
// Show edited label
var autoSaveLabelElement = $("#autosave_label_" + viewId + "_" + fieldId);
autoSaveLabelElement.html("This field was edited...");
autoSaveLabelElement.show();
// Cancel timer if it was already running
clearTimeout(timer);
// Start timer
timer = setTimeout(function() {
// Call Knack API to update field
var data = {};
data[fieldId] = $("#" + viewId).find("#" + fieldId).val();
$.ajax({
url: 'https://api.knack.com/v1/pages/scene_12/views/' + viewId + '/records/' + records.id,
type: 'PUT',
headers: {
'Authorization': Knack.getUserToken(),
'X-Knack-Application-Id': Knack.application_id,
'X-Knack-REST-API-Key': '6bf3a9a0-caf1-11e8-bbe4-556d6e072f02',
'Content-Type': 'application/json'
},
data: JSON.stringify(data),
success: function(records) {
console.log(" >>> Auto Saved...");
autoSaveLabelElement.html("Automatically saved...");
autoSaveLabelElement.fadeOut(autoSaveDelay);
// Re-save data in var for future comparisons
initialData = $("#" + viewId).find("#" + fieldId).val();
}
});
}, autoSaveDelay);
}
})
});
You can assign event handler to multiple elements at once.
You can try something like below -
var viewId = "view_";
var fieldId = "field_";
var viewIdSelector = $('id^="'+ viewId + '"');
var fieldIdSelector = $('id^="'+fieldId + '"');
$(viewIdSelector).find(fieldIdSelector).on('keyup', function() {
..your logic
}
This would work for all views and all fields in the application.
For more information,
http://api.jquery.com/on/#on-events-selector-data

How can I make sure each dynamically created image is taking on its own information/data pulled from the API?

Is there a way for me to make sure each img tag created also contains or can be linked with its individual data from the api? If only one image is returned in the search, it will give me the data for that image. However, if multiple images are returned, once clicked, it will return a only one possible image and data. I am new to coding and javascript in general, so please forgive any rookie mistakes. Thanks!
var scryfallURL = "https://api.scryfall.com/cards/search?q=";
var cardName = "";
var container = $("#list");
$("#searchBtn").on("click", function(event) {
event.preventDefault();
container.empty();
cardName = $("#search").val().trim();
queryURL = scryfallURL + cardName;
$.ajax({
url: queryURL,
method: "GET"
}).then(function(response) {
debugger;
var result = response.data;
console.log(result);
$('#search').val('');
//loops through creating an image tag for each search result
for (let index = 0; index < result.length; index++) {
var showCard = $("#list").append("<image src=' " + result[index].image_uris["normal"] + "' ></image>", "</br>");
var name = result[index].name + "<br>";
var creature = result[index].type_line + "<br>";
var flavorText = result[index].flavor_text + "<br>";
var legality = result[index].legalities + "<br>";
var cardFront = "<image src=' " + result[index].image_uris["large"] + "' ></image>" + "<br>";
};
// click function to clear the div and replace with only one card image and info
showCard.click(function() {
$("#searchForm").empty();
container.empty();
$("#info").append(name, creature, flavorText, legality);
$("#oneCard").append(cardFront);
})
});
});

Categorising SharePoint list items on a HTML using Javascript and JSON

I have a JavaScript page which is querying a SharePoint list. The information on the list regards IT hardware, Lap Tops, Tablets etc. The user inputs the specific type, and I have a drop down of more general hardware types.
This is what I've got:
and this is what I need:
So under the hardware headings the specifics get categorised. What's the best way to do this? JavaScript below:
function getDeviceDetails() {
var txtTitle = "";
var txtOverview = "";
var txtAccessories = "";
var txtDevicetype = "";
var txtTypicalDeviceUsage ="";
var txtKnownSystemIssues ="";
var txtLifeCycles = "";
var txtTrafficlight = "";
var imgDevicePicture = "";
var tempLCS2 = "";
var query = "http://collaboration-dev.norgine.com/sites/it/SystemInventory/_vti_bin/listdata.svc/Devices?$expand=Priority&$filter=Id eq " + window.DeviceId + "";
var call = $.ajax({
url: query,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
});
call.done(function (data,textStatus, jqXHR){
$.each(data.d.results, function(index, item) {
var tempID = item.Id;
var tempTitle = item.Title;
var DeviceOverView = item.Description;
var AccessDetails = item.Accessories;
var DeviceKind = item.DevicetypeValue;
var Usage = item.TypicalUsage;
var DevicePriority = item.PriorityValue;
var DeviceImage = item.DeviceImage;
txtTitle = "<p>"; //+ LifeCycleStart + "</p><p>" + LifeCycleStatus + "</p>";
txtOverview = "<p>" + DeviceOverView + "</p>";
txtAccessories = "<p>" + AccessDetails + "</p>";
txtDevicetype = "<p>" + DeviceKind + "</p>";
txtTypicalDeviceUsage = "<p>" + Usage + "</p>";
txtTrafficlight = "<p>" + DevicePriority + "</p>";
imgDevicePicture = "<img src='" + DeviceImage + "'>";
});
$('#devicedetails').append($(txtTitle));
$('#deviceoverview').append($(txtOverview));
$('#devicekind').append(txtDevicetype);
$('#deviceacc').append(txtAccessories);
$('#deviceuse').append(txtTypicalDeviceUsage);
$('#devicestatus').append(txtTrafficlight);
$('#imageContainer').append("<img src='/sites/IT/SiteAssets/"+txtTrafficlight.replace(/<[^>]*>/g, '')+".png' />");
$('.deviceimage').append(imgDevicePicture);
});
call.fail(function (jqXHR,textStatus,errorThrown){
alert("Error retrieving data: " + jqXHR.responseText);
});
}
You're taking records from a SharePoint list and displaying them grouped by a common column value. There are two ways to accomplish this.
Option 1: Perform Separate Queries
If you have three categories of devices (e.g. Laptop, Desktop, and Tablet) you can query the SharePoint list once for each category of items you wish to retrieve.
var urlEndpoint = "http://collaboration-dev.norgine.com/sites/it/SystemInventory/_vti_bin/listdata.svc/Devices$expand=Priority,Devicetype&$filter=Id eq " + window.DeviceId + " and ";
var laptopFilter = "DevicetypeValue eq 'Laptop'",
desktopFilter = "DevicetypeValue eq 'Desktop'",
tabletFilter = "DevicetypeValue eq 'Tablet'";
$.ajax({
url: urlEndpoint + laptopFilter,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
}).done(displayLaptopResults);
$.ajax({
url: urlEndpoint + desktopFilter,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
}).done(displayDesktopResults);
$.ajax({
url: urlEndpoint + tabletFilter,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
}).done(displayTabletResults);
function displayLaptopResults(data){ /* your code here */ }
function displayDesktopResults(data){ /* your code here */ }
function displayTabletResults(data){ /* your code here */ }
This is only possible if you know the different categories beforehand and can compose your queries to filter against those categories. It has the advantage of working with smaller chunks of data at a time, and might be necessary when dealing with large lists.
If you don't know all the possible categories then consider the next option.
Option 2: Perform One Query and Post-process The Results
Alternatively, you can get all the results and place them into an in-memory data structure according to their category before displaying the records on the page.
Instead of having an array of items...
var results = [item1, item2, item3, item4, item5]
You'll have a hashmap with an array property for each category.
var results = {
category1: [item1, item4],
category2: [item2, item3],
category3: [item5]
}
The following code example demonstrates how you can process an array of items to categorize them, then render the results afterwards.
var data = {d:{results:[
{title:"X1 Carbon",DevicetypeValue:"laptop"},
{title:"T470",DevicetypeValue:"laptop"},
{title:"MS Surface Pro3",DevicetypeValue:"tablet"},
{title:"X270",DevicetypeValue:"laptop"},
{title:"M910",DevicetypeValue:"desktop"},
{title:"MS Surface Pro4",DevicetypeValue:"tablet"}]}};
var i = 0, len = data.d.results.length, item, category, devicesByCategory = {};
// loop through the results and add them to the devicesByCategory object
while(i < len){
item = data.d.results[i];
category = item.DevicetypeValue;
if(devicesByCategory[category]){
// if devicesByCategory already has an array for this item's category, add the item to it
devicesByCategory[category].push(item);
}else{
// otherwise, create a new array for the category
devicesByCategory[category] = [item];
}
i++;
}
// loop through all the categories and render them
for(var category in devicesByCategory){
var div = createCategorySection(category);
addResultsToSection(div,devicesByCategory[category]);
}
function createCategorySection(value){
var div = document.getElementById("output").appendChild(document.createElement("div"));
div.appendChild(document.createElement("h1")).appendChild(document.createTextNode(value));
return div;
}
function addResultsToSection(section,results){
var ul = section.appendChild(document.createElement("ul"));
i = 0; len = results.length;
while(i < len){
item = results[i];
ul.appendChild(document.createElement("li")).appendChild(document.createTextNode(item.title));
i++;
}
}
<div id="output"></div>

How to populate new html pages with xml data in jQuery

I have an RSS reader that fetches events with ajax. I want the user to be able to click the link of the event and have it transition to a new page with the details. Here is an example I found: http://jsfiddle.net/hellosze/t22QP/ I am have trouble understanding what is happening since I am rather new to jQuery so I was hoping someone code direct me as to what is happening. Thanks!
Here is how I extract the xml data and display it to a main page:
$.ajax({
type: 'GET',
url: 'categoryURL',
dataType: 'xml',
success: function (xml) {
var data = [];
$(xml).find("item:lt(40)").each(function () {
var dateText = $(this).find("Date").text().toString();
var eventDate = moment(dateText,"YYYY-MM-DD");
var title = $(this).find("title").text();
var region = dateText.substr(8).toUpperCase();
if (region.length < 3) { region = "ALL"; }
var description = $(this).find("description").text();
var dateDisplay = description.substr(0, description.indexOf(",")+6); //Parsed DATE from description
if (dateDisplay.length > 35) { dateDisplay = "See event for details"; }
//var locationdisplay = description.substr(description.indexOf(",")+6,4); //Parsed the location from description
var category = $(this).find("category").text();
var linkUrl = $(this).find("link").text();
var displayTitle = "<a href='" + linkUrl + "' target='_blank'>" + title + "</a>"
var item = {title: displayTitle, DateDecription: dateDisplay, Date: new Date(eventDate), Region: region,}
data.push(item);
// $('#feedContainer').append('<h3>'+displaytitle+'</h3><p>'+"Event Date: "+descriptdisplay+'</p><p>'+"Location: "+region+'</p');
}); //END .each()
data.sort(function (a, b) {
a = new Date(a.Date);
b = new Date(b.Date);
return a>b ? -1 : a<b ? 1 : 0;
});
$.each(data, function (index, item) {
$('#feedContainer').append('<h3>' + item.title + '</h3><p>' + "Event Date: " + item.DateDecription + '</p><p>' + "Location: " + item.Region + '</p');
});
} //END success fn
});
});

Categories