Jquery .replaceWith not working proper - javascript

i have a jquery code that is preventing a link to go to that link but executing it. The problem i have is that after it executs the script and script is returning data i want to replace it with a new one but with the same class. The replace is doing inside the dom but next time i press that link is not prevening going to that link but the class is the same, here is my code:
<script>
$(".recomanda").click(function(e){
e.preventDefault();
var test=$(this);
var href = $(this).attr('href');
$.getJSON(href, function(data) {
if(data.recom==1)
{
$(test).replaceWith('<a class="recomanda" href="app/recomanda_produs.php?id=' + data.id + '&recom=' + data.recom + '">Recomandat</a> ');
}
if(data.recom==0)
{
$(test).replaceWith('<a class="recomanda" href="app/recomanda_produs.php?id=' + data.id + '&recom=' + data.recom + '">Recomanda</a> ');
}
});
});
</script>
html
<a class="recomanda" href="app/recomanda_produs.php?id='.$row['ID_Produs'].'&recom=0">Recomanda</a>

yeah, I ran into that problem too before, it's because when you attach click to recomanda on ready(), but when ajax load, everything in ready() won't fire again, that why you need to attach the event to non-dynamic elements, and let it find it's child selector.
$('body').on('click', '.recomanda', function() {});

When you call a replaceWith actually you are removing elements that are bound to onclick handler:
.replaceWith()
Description: Replace each element in the set of matched elements with
the provided new content and return the set of elements that was
removed.
The main idea is that you handler must be bound to the same element (that is not removed when clicking).
So instead of using replaceWith method use method that modify existing element like this:
test.attr('href', blablabla);
And this is not a problem, but second time you don't need to use $ with test variable.

You need to delegate the event to a parent so that it can be applied to specific children wether they exist now or in the future.
See: http://learn.jquery.com/events/event-delegation/
$("body").on("click", ".recomanda", function(e){
e.preventDefault();
var test=$(this);
var href = $(this).attr('href');
$.getJSON(href, function(data) {
if(data.recom==1){
$(test).replaceWith('<a class="recomanda" href="app/recomanda_produs.php?id=' + data.id + '&recom=' + data.recom + '">Recomanda"+((data.recom==1)?"t":"")+"</a> ');
}
if(data.recom==0){
$(test).replaceWith('<a class="recomanda" href="app/recomanda_produs.php?id=' + data.id + '&recom=' + data.recom + '">Recomanda</a> ');
}
});
});

Related

jQuery bind click not adding elements

I have a button that when I click it more than once it is adding elements from the previous click. It works fine the first time through. We are using jQuery 1.11.1.
$(function() {
$('a[name="generateReport"]').bind('click', function() {
$(this).attr('href', $(this).attr('href') + '?est=' + est.value + '&prodcd=' + prodcd.value + '&startDate=' + startDate.value + '&endDate=' + endDate.value + '&tracking=' + tracking.value);
})
})
What I am seeing is that the URL past to the server is adding the fields from the prior click. This of course causes issues when it gets to the server. Does this need to be cleared out after each click?
This is the code that calls it from our Grails app(2.4.3)
<g:link class="btn btn-primary" name="generateReport" controller="generateTTLReport" action="renderOutput">
<i class="icon-print icon-white"></i>
Generate Report
</g:link>
Thanks,
Tom
Split the current href at the "?" to remove the query string parameters. Also, let jQuery build your new query string parameter string.
$(function() {
$('a[name="generateReport"]').on('click', function() {
var $this = $(this),
path = $this.attr('href').split('?')[0],
params = {
est: est.value,
prodcd: prodcd.value,
startDate: startDate.value,
endDate: endDate.value,
tracking: tracking.value
},
href = [path, $.param(params)].join('?');
$this.attr('href', href);
});
});
The problem with your code is, every time you click on that button, bind callback is invoked. So the first time you clicked, it got the href attribute added some parameters and replaced it. Again when you clicked on that for the second time, it does the same thing. It gets the href attribute which now contains parameters from previous update and then replace the existing. If you keep the href as it is, and only update the query parameters, you can define that as a global variable and use that in your event handler
You can hard code that link as a variable within in your script like this
$(function() {
// define your variable within document.ready but outside your event handler
var reportURL = '/LSRTIS/generateTTLReport/renderOutput';
$('a[name="generateReport"]').bind('click', function() {
var urlWithParams = reportURL + '?est=' + est.value + '&prodcd=' + prodcd.value + '&startDate=' + startDate.value + '&endDate=' + endDate.value + '&tracking=' + tracking.value;
$(this).attr('href', urlWithParams );
});
});
Hope this helps :)

jQuery .on() event ignores selector

I have a function to create a div, ID it and add content before binding it to a click event using the .on() method using a selector as the second parameter. Here is the code I am using.
$('#overlayLeft').append(createOption('Item ID'));
function createOption(name){
var element = document.createElement('div');
var noSpaceName = name.replace(" ", "_");
element.id = 'toolOverlay' + noSpaceName;
element.innerHTML = '<input type="checkbox"><label>' + name + '</label>';
$('body').on('click', $('#' + element.id),function(){
alert("Test");
});
return element;
}
However instead of binding the click event to the body using the id of the generated element as the selector, the event acts whenever a click occurs on the body of the page.
How do I get the event to occur only on clicking the element without first creating the element and then binding the event separately?
You do not need jquery object, you need selector.use:
$('body').on('click', '#' + element.id,function(){
alert("Test");
});
also you can bind the click event without delegation using:
$('#' + element.id).click(function(){
alert("Test");
});
You have a strange mix of JQuery and native JS code. Maybe this works for your.
function createOption(){
return $('<div></div>')
.attr('id', 'toolOverlay' + name.replace(" ", "_"))
.append(
$('<input></input>')
.attr('type', 'checkbox'))
.append(
$('<label></label>')
.text(name))
.click(function(){
alert('test');
});
}
Try to put just selector string:
$('body').on('click', '#' + element.id,function()
That's not a selector that you are using, it's a jQuery object.
You can solve it by using just the selector, but instead of binding a lot of delegates to the body element, you can just bind the event on the element. That means that you don't need an id on the element to target it.
$('#overlayLeft').append(createOption('Item ID'));
function createOption(name){
var element = $('<div>');
element.html('<input type="checkbox"><label>' + name + '</label>');
element.click(function(){
alert("Test");
});
return element;
}
Binding global delegates is what the live method did, and it was deprecated because that is not a good way to use delegates.
If you're going to use jQuery, may as well use it everywhere. Note that the .click event is attached to the jQuery object/element as soon as it's created:
$('#overlayLeft').append(createOption('Item ID'));
function createOption(name) {
var noSpaceName = name.replace(" ", "_");
var div = $('<div>', {'id': 'toolOverlay' + noSpaceName})
.append('<label><input type="checkbox">' + name + '</label>')
.click(function () {
alert('test');
});
return div; // returns a jQuery object now, not a DOM element,
// which is fine when using .append() as you do here
}
http://jsfiddle.net/mblase75/bdvk9ssa/

How to get ID of listview item Clicked. [javascript / jquery / jquery mobile]

I need advice on how to detect which <li> is tap/click by the user, then write the 'ID' of the tap/clicked <li> into Localstorage, then use the saved Localstorage to retrieve data for Detail Page.
I'm new to javascript/jquery, if you can provide some simple example code will be very much appreciated.
I know how to write Localstorage, read Localstorage, get JSON data from server API, generate Loop for Listview with unique ID for each <li>.
What I need is, how to use JS to make <li> clickable (link to Detail Page) and write to Localstorage at the same time.
I have tried:
$('.liClass').click(function() { //block of code to write Localstorage };
But the <li> is not clickable and no key/value written to Localstorage. Not to mention to detect which <li> is clicked (this I have no idea).
Please advice, thank you.
Code update:
//Show restaurant listing - NOTE: This is not first page. Link from other Page.
$('#restaurantList').on("pagebeforecreate", function() {
$.getJSON("http://mydomain.com/api/restaurant", function( data ) {
function rstListing(data) {
if ($.isEmptyObject(data) === true) {
alert ('JSON return empty');
} else {
for (i=0; i<data.length; i++){
$('#restaurantListing').append('<li id="' + data[i].restaurant_id + '" class="rstList"><img src="http://mydomain.com/file/img/' + data[i].restaurant_logo + '"><h2>' + data[i].name + '</h2><p>' + data[i].city + '</p></li>');
$('#restaurantListing').listview('refresh');
}
}
}
rstListing(data);
}
);
});
//Listview link to Detail Page
$(document).ready(function(){
$('.rstList').click(function() {
var id = $(this).attr("id"); // Get the ID
alert(id);
console.log(id);
});
});
Also tried:
//Listview link to Detail Page
$('#restaurantList').on("pageload", function() {
$('.rstList').click(function() {
var id = $(this).attr("id"); // Get the ID
alert(id);
console.log(id);
});
});
You don't need to make any <li> element to be clickable by your self, when you add the click event to any element, that will be triggered when the item is clicked.
Your problem will basically be that the element is not loaded when the event is bind to it. So you have to add your code inside document ready event like this.
$(document).ready(function(){
$('.liClass').click(function() {
var id= $(this).attr("id"); // Get the ID
};
});
$('.liclick').click(function() {
alert($(this).attr("id"));//Get id of clicked li
localStorage.setItem($(this).attr("id"),$(this).attr("id")); //stored into localStorage
alert("Data from localStorage "+localStorage.getItem($(this).attr("id"))); // get stored id
});
Working Fiddle
You will need to use the event delegation to assign the click event since you are building the HTML DOM dynamically via JSON request, thus not being able to locate the 'li' elements at the time of the page load. So, it would look like:
$(document).on("click", ".rstList", function (event) {
// click event
}
See this link for more details:
jQuery event delegation
I have solved my problem with the example code provided by stackoverflow member here. My previous problem is because I separate the creation of the listview and bind the click listener in two different page event.
After testing the page event sequence, I'm now putting the click listener into the same page event instead of separate to two. Now my code look like this, hope this will help someone bump into the same problem as me:
//Show restaurant listing
$('#restaurantList').on("pagebeforecreate", function() {
alert('pagebeforecreate event triggered');
$.getJSON("http://mydomain.com/api/restaurant", function( data ) {
function rstListing(data) {
if ($.isEmptyObject(data) === true) {
alert ('JSON return empty');
} else {
for (i=0; i<data.length; i++){
$('#restaurantListing').append('<li id="' + data[i].restaurant_id + '" class="rstList"><img src="http://mydomain.com/file/img/' + data[i].restaurant_logo + '"><h2>' + data[i].name + '</h2><p>' + data[i].city + '</p></li>');
$('#restaurantListing').listview('refresh');
}
}
}
rstListing(data);
alert('rstListing() executed');
$('.rstList').click(function() {
alert($(this).attr("id"));//Get id of clicked li
localStorage.setItem($(this).attr("id"),$(this).attr("id")); //stored into localStorage
alert("Data from localStorage "+localStorage.getItem($(this).attr("id"))); // get stored id
});
}
);
});

jQuery: Moving element to another element and back again renders the element unclickable

In my script, I'm attempting to move an element (list) from one parent (just the text) to another and then back again (to the list). The problem is that when I have moved the element back to the original parent (ul), it has become un-clickable. I thought using the detach() over the remove() might do the trick but it doesn't make a difference.
$(document).ready(function() {
$("#inventoryWeapon li").click(function(event) {
var clickedId = event.target.id;
if ($("td#weapon").is(":empty")) {
$("td#weapon").text(clickedId);
$(this).detach();
}
});
$("td#weapon").click(function(event) {
var unequipping = $(this).text();
$("#inventoryWeapon").append("<li id='" + unequipping + "'>" + unequipping + "</li>");
$(this).detach();
});
});
As suggested in the popular comment above, you are not moving the element. To move it, do this.
$("td#weapon").click(function(event) {
$(this).appendTo($("#inventoryWeapon"));
});
You're not moving the element, you're removing the element in one function, and creating a new element with the same ID and content in the other. But the original event handler was only bound to the original element.
If you want your event handler to work with dynamically created elements, use event delegation:
$("#inventoryWeapon").on("click", "li", function(event) {
...
});
Alternatively, you could save the element when you detach it, instead of recreating it:
var savedLI;
$("#inventoryWeapon li").click(function() {
if ($("td#weapon").is(":empty")) {
savedLI = $(this).detach();
$("td#weapon").text(this.id);
}
});
$("td#weapon").click(function() {
if (savedLI) {
$("#inventoryWeapon").append(savedLI);
$(this).detach();
}
});

preventDefault not working on anchor

I'm trying to log the click on an anchor that's being generated asynchronously.
The asynchronous call - which works perfectly fine - looks like this:
$("#txt_search").keyup(function() {
var search = $("#txt_search").val();
if (search.length > 0)
{
$.ajax({
type: "post",
url: "<?php echo site_url ('members/searchmember') ;?>",
data:'search=' + search,
success: function(msg){
$('#search_results').html("");
var obj = JSON.parse(msg);
if (obj.length > 0)
{
try
{
var items=[];
$.each(obj, function(i,val){
items.push($('<li class="search_result" />').html(
'<img src="<?php echo base_url(); ?>' + val.userImage + ' " /><a class="user_name" href="" rel="' + val.userId + '">'
+ val.userFirstName + ' ' + val.userLastName
+ ' (' + val.userEmail + ')</a>'
)
);
});
$('#search_results').append.apply($('#search_results'), items);
}
catch(e)
{
alert(e);
}
}
else
{
$('#search_results').html($('<li/>').text('This user does not have an account yet'));
}
},
error: function(){
alert('The connection is lost');
}
});
}
});
The anchor I want to get to is <a class="user_name" href="" rel="' + val.userId + '">' + val.userFirstName + ' ' + val.userLastName + ' (' + val.userEmail + ')</a>'
I detect the click on these anchors with this function:
// click op search results
$("a.user_name").on('click', function(e) {
e.preventDefault();
});
The problem seems to be that the preventDefault is not doing anything... I've looked at most of the questions involving this problem on Stackoverflow and checked jQuery's own documentation on the topic, but I can't seem to find what's wrong. I've tried adding a async: false statement to the AJAX-call, because perhaps the asynchronous call might be the problem, but that didn't fix it.
Event does not bind with dynamically added element unless you delegate it to parent element or document using on(). You have to use different form of on for event delegation.
$(document).on('click', 'a.user_name', function(e) {
e.preventDefault();
});
delegated events
Event handlers are bound only to the currently selected elements; they
must exist on the page at the time your code makes the call to .on().
To ensure the elements are present and can be selected, perform event
binding inside a document ready handler for elements that are in the
HTML markup on the page. If new HTML is being injected into the page,
select the elements and attach event handlers after the new HTML is
placed into the page. Or, use delegated events to attach an event
handler, as described next.
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to avoid the need to
frequently attach and remove event handlers, Reference
The .on() syntax you showed will only bind handlers to elements that match the selector at that moment - not to elements added in the future. Try this instead:
$("#search_results").on("click", "a.user_name", function(e) {
e.preventDefault();
});
This binds a handler to the parent element, and then when a click occurs jQuery only calls your callback function if the actual target element matches the selector in .on()'s second parameter at the time of the click. So it works for dynamically added elements (as long as the parent exists at the time the above runs).
This should work for you -
$('.search_result').on('click', 'a.user_name', function(){
// your code here
// code
return false;
});
try this
$("a.user_name").on('click', function(e) {
return false;
});
or
$(document).on('click', 'a.user_name', function(e) {
e.preventDefault();
});
Difference between .on() functions calls
May be your a href linked with other listeners too. Check with event.preventDefault
event.stopImmediatePropagation();
together.
You can check this site for more info
https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/
I had this problem too, and it turned out my selector was wrong.

Categories

Resources