Jquery Json not working properly - javascript

I have the following which works fine:
$('<li><a id=' + loc.locId + ' href="/DataEntry" rel="external">' + loc.locName + '</a></li>').appendTo("#btnList");
$("#btnList a").click(function () {
alert(siteName);
localStorage["dataEId"] = $(this).attr("id");
localStorage["dataESiteName"] = siteName;
localStorage["dataESysName"] = sysName;
localStorage["dataELocName"] = $(this).text();
}
When I have the following, I can't even get to the click to display an alert message:
$.getJSON('/Home/GetLocType', { "locId": loc.locId }, function (result) {
var str = JSON.stringify(result);
if (str == '1') {
$('<li><a id=' + loc.locId + ' href="/DataEntry" rel="external">' + loc.locName + '</a></li>').appendTo("#btnList");
} else {
$('<li><a id=' + loc.locId + ' href="/DataEntry/PotableForm" rel="external">' + loc.locName + '</a></li>').appendTo("#btnList");
}
$("#btnList").listview('refresh');
});
$("#btnList a").click(function () {
alert(siteName);
localStorage["dataEId"] = $(this).attr("id");
localStorage["dataESiteName"] = siteName;
localStorage["dataESysName"] = sysName;
localStorage["dataELocName"] = $(this).text();
}
Note sure what the difference is. I need to use Json as based on value, I need to go to a either of the 2 hyperlinks.

Use event delegation since anchor is created dynamically in your ajax call or bind the event (only for the added element) inside the ajax success callback. on syntax will work if your jquery version >= 1.7 for earlier versions take a look at live
$("#btnList").on('click', 'a', function () {
alert(siteName);
localStorage["dataEId"] = $(this).attr("id");
localStorage["dataESiteName"] = siteName;
localStorage["dataESysName"] = sysName;
localStorage["dataELocName"] = $(this).text();
}
Your first syntax works because it binds the click event to the anchor that exists underneath btnList, but it doesn't bind event to the ones added during the ajax calls in a later point in time.

Related

How to clear table inside a dialog when dialog is closed

When the button is clicked, 2 sets data is added. I use material design.
Button needs 2 clicks to run function for first time. Due to this, the data is added to table 2 times.
Code
HTML
<button onclick="purchaseList(orderid)" id="dialog">Button</button>
JS
function popup(listid) {
var starCountRef = firebase.database().ref('Orders/' +
listid).child('foodItems');
starCountRef.on('child_added', snapshot => {
var snaps = snapshot.val();
var itemPrice = snaps.price;
var itemName = snaps.productName;
var itemQuantity = snaps.quantity;
console.log(itemName);
$("#producttable").append(
'<tr><td class="mdl-data-table__cell--non-numeric">' + itemName +
'</td><td>' + itemQuantity + '</td><td>' + itemPrice + '</td></tr>'
);
});
var dialog = document.querySelector('dialog');
var showDialogButton = document.querySelector('#dialog');
if (!dialog.showModal) {
dialogPolyfill.registerDialog(dialog);
}
showDialogButton.addEventListener('click', function() {
dialog.showModal();
});
dialog.querySelector('.close').addEventListener('click', function() {
var element = document.getElementById("producttable")
while (element.lastChild) {
element.removeChild(element.lastChild);
}
dialog.close();
});
}
This should work:
var element = document.getElementById("producttable")
while (element.lastChild) {
element.removeChild(element.lastChild);
}
Add this as necessary.
I suggest you change your firebase function from using .on to .once to avoid multiple additions of data to your table and as your data isn't expected to change frequently or require active listening you better use .once for performance benefits.
firebase.database().ref('Orders/' +
listid + '/foodItems').once('value').then(function(snapshot) {
// the rest of your code goes here
});
this remocve element with class name ".mdl-data-table__cell--non-numeric"
when user click .close
dialog.querySelector('.close').addEventListener('click', function () {
dialog.close();
$(".mdl-data-table__cell--non-numeric").remove();
});
UPDATE:
to open dialog on 2nd click use pseudo element to activate like this
<div class=pseudo><button onclick="purchaseList(orderid)"id="dialog" disabled>Button</button></div>
var i=0;
$('.pseudo').click(function(){
i++;
if(i==2){
$("#dialog").prop('disabled',false);
}
});

deleting elements created by jquery in a sequence

I'm trying to build my first plugin using jquery.
So far successful, but I'm stuck in deleting the notifications.
I was able to delete the notification on a click event.
Notification.prototype.destroy = function(element) {
var self = this;
element.closest('.notification-container').remove();
};
And I call that function inside init method.
Notification.prototype.init = function() {
var self = this;
self.$el.on('click', function() {
self.build();
});
self.$body.on('click', '.close', function() {
self.destroy(this);
})
};
Now I wanted to give a auto close option to the user, and I thought of using the setTimeout function, but as I've created the function passing the parameter as current element, I'm unable to get it.
Here's the pen.
Any help will be much appreciated.
Thanks!
You had several problems there:
The setTimeout function must be called upon display (and not upon build), otherwise it can be called even before you display the notification (hence your notification will not be automatically removed).
When you call the setTimeout in order to destroy the notification - you need to pass the container of the notification you just created, so the destroy function will be able to find the relevant element to remove (when you use the click option - you pass the X element, so it's easy to find the closest container, but when you use the setTimeout you must pass the container element himself).
I think all of the changes I made are in the build function, here it is:
Notification.prototype.build = function() {
var self = this;
var closeHTML = self.options.autoClose ? '' : '';
if (self.options.type == 'thumb') {
var $notificationHTML = $('<div class="notification-container">' +
'<i class="close">x</i>' +
'<div class="notification">' +
'<div class="thumb-container">' +
'<img src="' + self.options.src + '">' +
'</div>' +
'<p>' + self.options.text + '</p>' +
'</div>' +
'</div>');
} else {
var $notificationHTML = $('<div class="notification-container">' +
'<i class="close">x</i>' +
'<div class="notification ' + self.options.style + '">' +
'<p>' + self.options.text + '</p>' +
'</div>' +
'</div>');
}
self.$body.prepend($notificationHTML);
if(self.options.autoClose) {
setTimeout(function() {
self.destroy($notificationHTML);
}, 5000)
} else {
self.$body.on('click', '.close', function() {
self.destroy(this);
})
}
};
And a working codepen:
http://codepen.io/anon/pen/JKgPgB?editors=0010

Using OR condition in combined attribute selector

I asked this question earlier and got it solved:
AND selector jQuery
But now I would like to know how I could add an OR condition to it.
I have this statement:
$('div.job:not([data-province="'+province+'"][data-employment="'+employment+'"][data-education="'+education+'"][data-branch="'+branch+'"])').fadeOut('slow');
And now I would like to fade them out if for example data-province="'+province+'" OR data-province="" (so empty).
Jsbin:
http://jsbin.com/qomub/14/edit
Try filter() with multiple selector
$('div.job').filter('[data-province="' + province + '"], [data-province=""]').fadeOut('slow');
Based on the update
$(document).ready(function () {
var $jobs = $('.job');
var $selects = $("#province, #employment, #education, #branch").on("change", function () {
var $filtered = $jobs;
$selects.each(function () {
if (this.value) {
$filtered = $filtered.filter('[data-' + this.id + '="' + this.value + '"], [data-' + this.id + '=""]');
}
});
$filtered.show();
$jobs.not($filtered).hide();
});
});
Demo: Fiddle

jQuery getting .preventDefault() to work on generated elements

I'm having a bit of a problem with getting the .preventDefault to work on some elements I am generating via JQuery.
I am getting a JSON file using the following code and putting the data into individual p elements:
$.getJSON(searchURL, function(data) {
$.each(data, function(key, value) {
if (typeof value === 'object') {
for (var i = 0; i < data.count; i++) {
var fullPlayerURL = "<p class='entry'>" + "<a href=" + playerURL + data.data[i].id + ">"
+ "Nickname - " + data.data[i].nickname + "</a>" + "</p>"
$('#results').append(fullPlayerURL);
}
}
});
}); //end getJSON
Then I'm using the following code to stop the link from redirecting when clicked (links to another JSON file):
$('.entry').click(function(event) {
event.preventDefault();
var linkClicked = $(this).attr("href");
console.log(linkClicked);
});
I don't know if it matters but #results is just an empty div.
Here's all the code if this isn't enough info (sorry it's such a mess).
You'll need delegated event handlers for dynamic elements
$('#results').on('click', '.entry', function(event){
event.preventDefault();
var linkClicked = $('a', this).attr("href");
console.log(linkClicked);
});
Sorry, I'm not allowed to comment on adeneo's answer.
For me var linkClicked = $('a', this).attr("href"); gives undefined.
I had to make var linkClicked = $(this).attr("href"); out of it.
Edit: Know it, I wanted to address the anchor.
$('#results').on('click', 'a', function(event) {
event.preventDefault();
var linkClicked = $(this).attr("href");
console.log(linkClicked);
});

empty() then run the rest of the function

I have some json that's loaded into li.ui-state-default pending user entry.
The user can then enter a new entry. I want it to empty li.ui-state-default every time a new entry is loaded but it seems to just stay empty.
//data for DOM
var timeout = '';
$('.call-json').keyup(function () {
clearTimeout(timeout);
var val = this.value;
timeout = setTimeout(function () {
$('.ui-state-default').empty();
$.getJSON('json/' + val + '.json', function (data) {
// load data
var items = [];
for (key in data[0].attributes) {
if (key.match('.stat.prop.type')) {
items.push(data[0].attributes[key])
}
};
displaySortLabel(items, "type-details");
function displaySortLabel(items, parentClass) {
$('<span/>', {
'class': 'el-data',
html: items.join('')
}).hide().fadeIn().appendTo('.' + parentClass + ' .sort-label');
}
Appending to li.ui-state-default by using .appendTo('.' + parentClass + ' .sort-label') will not work as it searches for a .sort-label to be present inside that parentClass variable.
Make sure you have the correct selector while trying to append.
Furthermore, you don't need to hide() and fadeIn():
$('<span/>', {
'class': 'el-data',
html: items.join(''),
'css': {
'display': none
}
}).fadeIn().appendTo('.' + parentClass + ' .sort-label');

Categories

Resources