cannot access property of appended data - javascript

I have a problem. This code worked when the html was static and not appended, but when append data it does not...
I have appended data from a JSON-document like so:
$('#articles').append('<article><time pubdate="pubdate">' + pubDate + '</time><h2>' + headline + '</h2><p>' + bodyText + '</p></article>');
After this I create a variable containing the first article:
var currentElement = $("article:first");
Then I want to access currentElement.position():
console.log(currentElement.position());
But it comes back as undefined... It worked with unappended data? What am I doing wrong?
Thanks for the help!
EDIT: Here is the entire code:
$(document).ready(onDocumentReady);
function onDocumentReady()
{
console.log('Document ready');
$.ajax({
type:'GET',
url:'data.json',
dataType:'json',
success: jsonParser
});
function jsonParser(json)
{
$.getJSON('data.json',runData)
function runData(data)
{
$.each(data.article, writeData)
function writeData(keys,values)
{
var pubDate = values.pubDate;
var headline = values.headline;
var bodyText = values.bodyText;
$('#articles').append('<article><time pubdate="pubdate">' + pubDate + '</time><h2>' + headline + '</h2><p>' + bodyText + '</p></article>');
}
}
}
var currentElement = $("article:first");
console.log(currentElement.position());
EDIT AGAIN:
When I
console.log(currentElement);
I get:
[prevObject: x.fn.x.init[1], context: document, selector: "article:first", jquery: "1.10.2", constructor: function…]
context: document
length: 0
prevObject: x.fn.x.init[1]
selector: "article:first"
proto: Object[0]
Don't really understand that stuff, but thought it might help
UPDATE:
If I do a setTimeOut like this, I am able to access the element:
setTimeout(function()
{
var currentElement = $("article:first");
console.log(currentElement);
console.log(currentElement.position().left);
}, 1000);

It should be $("article:first-child")
Edit
Never mind :first works in jQuery.

Please make your ajax is returning data and article elements are getting created . If no elements are getting created then it will return undefined.

Before the success function, try to add: async: false in your ajax call.
$.ajax({
type:'GET',
url:'data.json',
dataType:'json',
async:false,
success: runData(data)
});
function runData(data){
$.each(data.article, writeData)
function writeData(keys,values){
var pubDate = values.pubDate;
var headline = values.headline;
var bodyText = values.bodyText;
$('#articles').append('<article><time pubdate="pubdate">' + pubDate + '</time><h2>' + headline + '</h2><p>' + bodyText + '</p></article>');
}
}

Related

How to keep JavaScript from adding my text as numbers

I have text like this: 4.72% - 12.04% that I am putting in a JavaScript object property which I am trying to add to the page kind of like this:
$("#container").append("<div>" + rates.fixedrates + "</div>");
And JavaScript keeps trying to calculate the numbers even though that's not what I'm trying to do. It doesn't print the text, just NaN.
How can I tell JS to stop this? I've even tried replacing the "-" with — and it does the same thing. Is there something I don't know about that can stop this?
EDIT:
The data comes in from an ajax call:
$.ajax({
url: "/Search/Rates",
type: "POST",
dataType: "json",
data: { oe: ui.item.oe },
success: function (data) {
data.forEach(function (rates, index, arr) {
$("#container").append("<div>" + currentValue.fixedrates + "</div>");
});
}
});
Controller:
return Json(rates);
"FixedRates" is just a string property off of the c# object "rates". Nothing special.
Works fine in what I can only assume is the most standard way - You're probably doing something wrong with how the value is assigned, or concatenating
const rates = {
fixedRates: ''
};
// Joining ourselves
let a = '4.72%';
let b = '12.04%';
let c = a + ' - ' + b;
// Together already
let d = '4.72% - 12.04%';
rates.fixedRates = c;
$("#container").append("<div>" + rates.fixedRates + "</div>");
rates.fixedRates = d;
$("#container").append("<div>" + rates.fixedRates + "</div>");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container"></div>
Ok, for brevity/clarity I left out a lot of what was in the appended <div>. I found out that I had something like this going on:
"<div>" + <-- extra plus sign
+ rates.FixedRates + "</div>"
So basically it was like this:
"<div>" + + rates.FixedRates + "</div>"
I guess there is something to be said about posting everything.
This solution will take the input and convert it to a text node before inserting it into the div which is then inserted into the container. Let me know how this works out for you..
$.ajax({
url: "/Search/Rates",
type: "POST",
dataType: "json",
data: { oe: ui.item.oe },
success: function (data) {
data.forEach(function (rates, index, arr) {
var div = document.createElement('div');
var textContent = document.createTextNode(currentValue.fixedrates);
var container = document.getElementById('container');
div.appendChild(textContent);
container.appendChild('div');
});
}
});

ajax success event doesn't work after being called

After searching here on SO and google, didn't find an answer to my problem.
The animation doesn't seem to trigger, tried a simple alert, didn't work either.
The function works as it is supposed (almost) as it does what i need to, excluding the success part.
Why isn't the success event being called?
$(function() {
$(".seguinte").click(function() {
var fnome = $('.fnome').val();
var fmorada = $('.fmorada').val();
var flocalidade = $('.flocalidade').val();
var fcodigopostal = $('.fcodigopostal').val();
var ftelemovel = $('.ftelemovel').val();
var femail = $('.femail').val();
var fnif = $('.fnif').val();
var fempresa = $('.fempresa').val();
var dataString = 'fnome='+ fnome + '&fmorada=' + fmorada + '&flocalidade=' + flocalidade + '&fcodigopostal=' + fcodigopostal + '&ftelemovel=' + ftelemovel + '&femail=' + femail + '&fnif=' + fnif + '&fempresa=' + fempresa;
$.ajax({
type: "GET",
url: "/ajaxload/editclient.php",
data: dataString,
success: function() {
$('.primeirosector').animate({ "left": "+=768px" }, "fast" );
}
});
return false;
});
});
you are trying to pass query string in data it should be json data.
Does your method edit client has all the parameters you are passing?
A simple way to test this is doing the following:
change this line to be like this
url: "/ajaxload/editclient.php" + "?" + dataString;
and remove this line
data: dataString
The correct way of doing it should be, create a javascript object and send it in the data like so:
var sendData ={
fnome: $('.fnome').val(),
fmorada: $('.fmorada').val(),
flocalidade: $('.flocalidade').val(),
fcodigopostal: $('.fcodigopostal').val(),
ftelemovel: $('.ftelemovel').val(),
femail: $('.femail').val(),
fnif: $('.fnif').val(),
fempresa: $('.fempresa').val()
}
$.ajax({
url: "/ajaxload/editclient.php",
dataType: 'json',
data: sendData,
success: function() {
$('.primeirosector').animate({ "left": "+=768px" }, "fast" );
}
});
Another thing shouldn't this be a post request?
Hope it helps

javascript passing values dynamically to a method jquery

$(document).bind('pageinit', function () {
var vendor_id = $.urlParam('vendor_id');
$.ajax({
type: "GET",
url: "http://testservice/testmenu",
data: {
vendor_id: vendor_id
},
error: function () {
alert("Could not get the menu : " + url);
},
success: function parseXml(xml) {
var jsonData = $.parseJSON(xml);
$(jsonData).each(function (index, post) {
$(post).each(function (index, row) {
var finalString = [];
for(var index = 0; index < row.menu.length; index++) {
finalString.push('<div id="collapsibleMenu" data-mini="true" data-role="collapsible" data-inset = "true" data-content-theme="g">');
finalString.push('<h3>' + row.menu[index].category_name + '</h3>');
finalString.push('<ul id="menuDetails" data-role="listview">');
for(var j = 0; j < row.menu[index].products.length; j++) {
var output = ['<li data-icon="addToCart" id="addToCart"> <p>' + row.vendor_menu[index].products[j].prod_name + '</p><p> $' + Number(row.vendor_menu[index].products[j].price).toFixed(2) + '</p>' + '</li>'];
finalString.push(output);
}
finalString.push('</ul></div>');
}
$('#output').append(finalString.join(''));
});
});
$('#output').trigger('create');
}
});
});
function test(prod_id) {
alert("entered test " + prod_id);
addToCart(prod_id, 1);
}
In the following code, where I am doing the following:
<a href="javascript:test("+row.menu[index].products[j].prod_id")">
This is obviously giving me an error. The point is, I need to pass the prod_id dynamically into the javascript test method. I am not sure how to do that. If I just call test without passing prod_id, it works great. Please help!
Try removing the quotes in the argument.
I think I might have figured it out.
Try this.
<a href="javascript:test(\''+row.menu[index].products[j].prod_id+'\')">
This looks like the perfect reason to use a template engine. You might use a Jade template like this:
for post in posts
for row in post
for menu in row.menu
#collapsibleMenu(data-mini="true", data-role="collapsible", data-inset="true", data-content-theme="g")
h3= menu.category_name
ul#menuDetails(data-role="listview")
for product in menu.products
li#addToCart(data-icon="addToCart")
a(href="#", data-product-id=product.prod_id)
p= product.prod_name
p= '$' + Number(product.price).toFixed(2)
Then you can simplify your $.ajax call to:
$.ajax({
// ...
dataType: 'json',
success: function(data) {
$('#output').append(templateFunction(data));
}
});
For the click event, use event delegation:
$('#output').on('click', 'a[data-product-id]', function() {
addToCart(Number($(this).data('product-id')), 1);
});
Easy, yeah? Now change all of your ids to classes, because ids must be unique and yours aren't!

Array and while loop: make unique clickable

I have an array (via ajax) that looks like this:
data[i].id: gives the id of user i
data[i].name: gives the name of user i
I want to output the array like this:
X Leonardo Da Vinci
X Albert Einstein
X William Shakespeare
...
The X is an image (x.gif) that must be clickable. On click, it must go to functiontwo(), passing the parameter data[i].id. Functiontwo will open a jquery dialog with the question "Delete id data[i].id"?
I know this can't be too hard to do, but I can't seem to figure it out...
This is what I have so far:
function functionone() {
$.ajax({
type : 'POST',
url : 'post.php',
dataType : 'json',
success : function(data){
var message = "";
var i = 0;
while (i < (data.length - 1))
{
var myvar = data[i].id;
message = message + "<div class=" + data[i].id + "><img src=x.gif></div>" + data[i].name + "<br />";
$('#somediv').html(message).fadeIn('fast');
$("." + data[i].id + "").click(function () {
functiontwo(myvar);
});
i++;
}
}
});
}
function functiontwo(id) {
...}
I know why this isn't working. Var i gets populated again and again in the while loop. When the while loop stops, i is just a number (in this case the array length), and the jquery becomes (for example):
$("." + data[4].id + "").click(function () {
functiontwo(myvar);
});
, making only the last X clickable.
How can I fix this?
Thanks a lot!!!
EDIT:
This is my 2nd function:
function functiontwo(id) {
$("#dialogdelete").dialog("open");
$('#submitbutton').click(function () {
$('#submitbutton').hide();
$('.loading').show();
$.ajax({
type : 'POST',
url : 'delete.php',
dataType : 'json',
data: {
id : id
},
success : function(data){
var mess = data;
$('.loading').hide();
$('#message').html(mess).fadeIn('fast');
}
});
//cancel the submit button default behaviours
return false;
});
}
In delete.php there's nothing special, I used $_POST['id'].
As I pointed out in my comment. The problem is the .click part. Either use bind, or use a class for all the elements, and a click-event like this $('.classnamehere').live('click',function () { // stuff });
function functionone() {
$.ajax({
type : 'POST',
url : 'post.php',
dataType : 'json',
success : function(data){
var message = "";
var i = 0;
while (i < (data.length - 1))
{
var myvar = data[i].id;
message = message + "<div class=\"clickable\" id=" + data[i].id + "><img src=x.gif></div>" + data[i].name + "<br />";
$('#somediv').html(message).fadeIn('fast');
i++;
}
}
});
}
$('.clickable').live('click',function () {
alert($(this).attr('id') + ' this is your ID');
});
The usual trick is create a separate function to create the event handler. The separate function will receive i as a parameter and the generated event will be able to keep this variable for itself
make_event_handler(name){
return function(){
functiontwo(name);
};
}
...
$("." + data[i].id + "").click( make_event_handler(myvar) );

Using Ajax callback variable values in JQuery dynamic click handlers

I'm doing a simple ajax query which retrieves a variable-length list of values as JSON data. I'm trying to make a list based on this data which has click-functions based on the values I got from the JSON query. I can make this work just fine by writing the onClick-methods into the HTML like this:
function loadFooList() {
var list_area = $("#sidebar");
list_area.html("<ul>")
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosesfoo" + item.id;
list_area.html(list_area.html()
+ "<li> <a href='#' onClick='alert(\"" +
link_id + "\");'>" +
item.name + "</a></li>");
});
list_area.html(list_area.html() + "</ul>");
}
});
}
I don't like writing the onClick-function into the HTML and I also want to learn how to create this same functionality via JQuery click-function.
So the problem is obviously variable-scoping. My naive attempt here obviously won't work because the variables are no longer there when the click happens:
function loadFooList2() {
var list_area = $("#sidebar");
var link_ids = Array();
list_area.html("<ul>")
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosefoo" + item.id;
list_area.html(list_area.html()
+ "<li> <a href='#' id='" + link_id + "'>"+item.name+"</a></li>");
link_ids.push(link_id);
});
list_area.html(list_area.html() + "</ul>");
for (link_index=0; link_index<link_ids.length; link_index++) {
$("#" + link_ids[link_index]).click(function() {
alert(link_ids[i]);
});
}
}
});
}
Obviously I'd like to do something else than just alert the value, but the alert-call is there as long as I can get that working and move forward.
I understand that I'll have to make some kind of handler-function to which I pass a state-variable. This works for a single value (I can store the whole link_ids array just fine, but then I don't know which of them is the right value for this link), but how would I do this for arbitrary-length lists?
Here is an example from JQuery docs which I'm trying to copy:
// get some data
var foobar = ...;
// specify handler, it needs data as a paramter
function handler(data) {
//...
}
// add click handler and pass foobar!
$('a').click(function(){
handler(foobar);
});
// if you need the context of the original handler, use apply:
$('a').click(function(){
handler.apply(this, [foobar]);
});
And I quess the last example here, "if you need the context of the original handler..." would probably be what I want but I don't know exactly how to get there. I tried to store the current link_id value into this, use it from this in the applied function (using apply()) but I didn't succeed. The necessary values were still undefined according to FireFox. I'm using JQuery 1.3.2.
So what's the right solution for this relatively basic problem?
Use append instead of html():
function loadFooList() {
var ul = $('<ul>');
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosesfoo" + item.id;
var a = $('<a>').attr('href','#').bind('click', function(e) {
alert(link_id,item_name);
e.preventDefault();
});
$('<li>').append(a).appendTo(ul);
});
ul.appendTo('#sidebar'); // this is where the DOM injection happens
}
});
}
So the problem appears to be getting the link id associated with the link so that your click handler has access to it. Note that if it's alphanumeric it will qualify for the id attribute and you can extract it from there. If it is purely numeric, it will be an illegal id attribute. In that case, you can either use an attribute, like rel, or the jQuery.data() method to store the link id with the link. You can also simplify by using append. I'll show both examples.
var link = $("<li><a href='#' id='" + link_id + "'>" + item.name + "</a></li>";
link.click( function() {
alert( $(this).attr('id') );
});
list_area.append(link);
or (if numeric)
var link = $("<li><a href='#'>" + item.name + "</a></li>";
link.data('identifier', link_id )
.click( function() {
alert( $(this).data('identifier') );
});
list_area.append(link);
Try this:
function loadFooList() {
var list_area = $("#sidebar");
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
var out = '<ul>';
$.each(json, function(i, item) {
var link_id = "choosefoo" + item.id;
out +="<li><a href='#' id='" + link_id + "'>"+item.name+"</a></li>";
});
out +="</ul>"
var $out = $(out);
$out.find('a').click(function(){
var link_id = this.id;
var item_name = $(this).text();
alert(link_id);
alert(link_name);
})
list_area.html($out);
}
});
}
Using multiple appends causing the browser to redraw multiple times in a row. You only want to modify the dom once.

Categories

Resources