jQuery append string to url after ajax load - javascript

I am adding query string to urls using this jQuery
$( 'a' ).attr( 'href', function(index, value) {
return value + '?appp=3';
});
This works fine, but after the ajax load, the new href's created are not recognized by the above jQuery. Is there a way to reload the code so to affect the new posts URL's which are loaded via ajax. Super thanks.

Perfect, thanks #developer, that worked nicely. Here how I did it as you mentioned:
function apendquery(){
$( 'a' ).attr( 'href', function(index, value) {
return value + '?appp=3';
});
};
$(document).ready(function(){
apendquery();
});
$(document).ajaxComplete(function () {
apendquery();
});

Of course it wont work on new elements. You can create function which you shuold call each time when new 'a' elements appears in DOM. Also you will need to create some kind of flag which helps you identify and update the href only for the new elements.
var updateHref = function(){
$( 'a[data-updated!=1]' ).attr( 'data-updated',1).attr( 'href',
function(index, value) {
return value + '?appp=3';
});
};
...
$.ajax(...)
.done(function() {
...
// add new 'a' tags
....
// then call our function to update href
updateHref();
});

Actually here is my final code which is better version in case the URL already appended a query should anyone might find useful:
function apendquery() {
$('a').attr('href', function(index, value) {
return value + (value.indexOf('?') !== -1 ? "&" : "?") + 'appp=3';
});
};
$(document).ajaxComplete(function() {
apendquery();
});

Related

JavaScript reading multiple images and displaying them in different div

My script:
$(document).ready(function(){
var folder = "/img/gallery/";
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
$("#galleryColumnOne").append( "<img src='"+ folder + val +"'>" );
$("#galleryColumnTwo").append( "<img src='"+ folder + val +"'>" );
}
});
}
});
});
html:
<body>
<div class="wrapGalleryList" id="galleryColumnOne"></div>
<div class="wrapGalleryList" id="galleryColumnTwo"></div>
</body>
Target: to load full set of images from the folder and display them in div like: pic1 in galleryColumnOne, pic2 in galleryColumnTwo, etc..
Current state: each div display complete full set of images.
Edit: current state of the script generate:
<div1> pic1, pic2, pic3, etc. ; <div2> pic1, pic2, pic3, etc.
should be:
<div1>pic1, pic3, pic5, etc. ; <div2> pic2, pic4, pic6, etc.
So, final working script for my problem (thanks to #cars10m)is:
<script>
$(document).ready(function(){
var folder = "/img/gallery/";
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
$("#galleryColumn"+(i%2?'One':'Two')).append( "<img src='"+ folder + val +"'>" );
}
});
}
});
});
</script>
As a simple fix you could change your success function to something like this:
function (data) {
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
$("#galleryColumn"+(i%2?'One':'Two')).append( "<img src='"+ folder + val +"'>" );
}
});
Although this will not be the quickest way of doing it and it would get "out of sync", when there are <a> links in data that do not point to images.
A better solution would be
function (data) {
var imgs=[];
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
imgs.push(folder+val);
}
});
$("#galleryColumnOne").append( "<img src='"+imgs.filter((v,i)=>i%2).join("'><img src='")+"'>" );
$("#galleryColumnTwo").append( "<img src='"+imgs.filter((v,i)=>(i+1)%2).join("'><img src='")+"'>" );
}
My answer is not tested, therefore no guarantees. But the main idea is to get the .append() part out of the loop over the individual links. This way the (slow).append() function will only be called once for each div. The contents (an HTML string) is prepared by using a fast Array.filter() and .join() operation.
There is one further point I would like to remark upon: You are using the expression
$(data).find("a").attr("href", function (i, val) {...});
to loop over <a> elements in your data HTML string. It works, as you have confirmed. I was puzzled, why you used this function, as its primary purpose is to set the href attribute of each matched element. After having had a closer look at the jQuery .attr documentation it became clear to me that this is a valid way to directly access the chosen attribute value for all matched elements and do something with it. As long as the function does not return anything, the attribute will remain unchanged. However, the more conventional way of looping over DOM elements with jQuery would be:
$(data).find("a").each(function (i, elm) {...});
elm is the DOM element and you would get its href attribute with elm.href.

Issue with .on() method

I am trying to make an MVC for training purposes and I am following a tutorial for that which is rather old. The implementation in the tutorial was made using live() but I decided to use jQuery 2.1.1 and have to implement on() method. I made a small use case for clarification.
I can insert new elements on the page while adding them in the DB
I can delete preloaded elements which existed in the DB at page load both from the DB and DOM
I can not remove elements which are added live neither from the db nor the DOM.
this is my entire code regarding that.
$(function(){
$.get('dashboard/xhrGetListings', function(o){
for (var i = 0; i < o.length; i++ )
{
$('#listInserts').append('<div>' + o[i].text + '<a class="del" rel="' + o[i].id + '" href="#">x</a></div>');
}
$('.del').on("click", function() {
delItem = $(this);
var id = $(this).attr('rel');
$.post('dashboard/xhrDeleteListing', {'id': id}, function(o) {
delItem.parent().remove(); // THIS IS NOT EXECUTED AT ALL
}, 'json');
return false;
});
}, 'json');
//Not necesarly relevant, it just helps for code clarity
$('#randomInsert').on("submit", function() {
var url = $(this).attr('action');
var data = $(this).serialize();
console.log(data);
$.post(url, data, function(o) {
$('#listInserts').append('<div>' + o.text + ' <a class="del" rel="' + o.id + '" href="#">X</a></div>');
}, 'json');
return false;
});
});
Another issue that I'm not focussing on at this point is that if I delete the parent inside the $.post method (as shown in the code above) it's not deleted, only if I move that line outside of the post method. Any clarification on that would be also very appreciated.
Use event delegation and event.preventDefault() it stops the default action
$('#listInserts').on("click", '.del' , function(event) {
event.preventDefault();
// your code come here
});

Simplifying a jQuery functions

I was wondering the method of simplifying this script, because somehow I am repeating myself all over again...
$('.userprofile').click(function(){
card_profile.load(url_settings).dialog('open');
});
$('.cust-profile').click(function(){
card_profile.load(url_customer).dialog('open');
});
$('.my-profile').click(function(){
card_profile.load(url_my).dialog('open');
});
var obj = {
'.userprofile' : url_settings,
'.cust-profile': url_customer,
'.my-profile' : url_my
};
$.each(obj, function(sel, url) {
$(sel).click(function(){
card_profile.load(url).dialog('open');
});
});
or
$(".userprofile,.cust-profile,.my-profile").click(function() {
var url = $(this).hasClass("userprofile") ? url_settings :
$(this).hasClass("cust-profile") ? url_customer :
url_my;
card_profile.load(url).dialog("open");
});
This is somewhat better, but you can't get significant gain I guess:
$('.userprofile').data('url',url_settings);
$('.cust-profile').data('url',url_customer);
$('.my-profile').data('url',url_my);
$('.userprofile, .cust-profile, .my-profile').click(function(){
card_profile.load($(this).data('url')).dialog('open');
});
If you assign URL to every button, then you don't have to repeat the classes:
$('button').click(function(){
card_profile.load($(this).data('url')).dialog('open');
});
One way to do this would be to iterate over an array (or two) of strings.
Edit: declared i outside of for loop to address comment from #crazytrain
arr = ['user', 'cust', 'my'];
url_arr = [urlA, urlB, urlC];
var i;
for (i in arr){
$('.' + arr[i] + '-profile').click(function(){
card_profile.load(url_arr[i]).dialog('open');
});
}
$(document).on('click', function(e){
if($(e.target).hasClass('userprofile')){
card_profile.load(url_settings).dialog('open');
}
if($(e.target).hasClass('cust-profile')){
card_profile.load(url_costumer).dialog('open');
}
if($(e.target).hasClass('myprofile')){
card_profile.load(url_my).dialog('open');
}
It's a little better with a function:
$('.userprofile').click(function(){
loadDiag(url_settings);
});
$('.cust-profile').click(function(){
loadDiag(url_customer);
});
$('.my-profile').click(function(){
loadDiag(url_my);
});
function loadDiag(url){
card_profile.load(url).dialog('open');
}
You could also switch through the parameter and do multiple things per click
$('.my-profile, .userprofile, .cust-profile').click(function(){
card_profile.load(url).dialog('open');
});
Edit: on second thoughts - do what Eltier says.
Assign a url attribute to each element. Then you can retrieve that value and use in your code in this way.
$('.userprofile').attr('url',url_settings);
$('.cust-profile').attr('url',url_customer);
$('.my-profile').attr('url',url_my);
$('.my-profile, .userprofile, .cust-profile').click(function(){
var url = $(this).attr('url');
card_profile.load(url).dialog('open');
});
You could use the html data attribute and have it simple like this
$('.userprofile, .cust-profile, .my-profile').click(function(){
var url = $(this).attr('data-url');
card_profile.load( url ).dialog('open');
});
<div class="userprofile" data-url="settings.php">Settings</div>
And to make it even better you could add a class to all load items like this
$('.load-box').click(function(){
var url = $(this).attr('data-url');
card_profile.load( url ).dialog('open');
});
<div class="userprofile load-box" data-url="settings.php">Settings</div>
Throwing another hat in the ring here...
var links = [{profile: '.userprofile', url: url_settings, clickDialog: 'open'},
{profile: '.cust-profile', url: url_customer, clickDialog: 'open'},
{profile: '.my-profile', url: url_my, clickDialog: 'open'}];
function clickOpen(url,value) {
card_profile.load(url).dialog(value);
}
links.forEach(function(element) { $(element.profile).click(
clickOpen(element.url,element.clickDialog) });
You can save a parameter in de caller object and then do something like this:
$('.userprofile, .cust-profile, .my-profile').on('click',function(){
var parameter = $(this).data( 'parameter' );
card_profile.load( parameter ).dialog( 'open' );
});
You can find more information about storing data here, is very easy.

Need function like jquery empty() that removes elements added by jquery

I have a blank div called "content". Links are later added to "content" using jquery append. Using empty() does not work; I am guessing empty() wont clear the links added by jquery because the links are not added to the DOM?
function should clear, then display new links, but its not clearing the links, just appending to whatever was present.
function getSubRedditLinks(url)
{
$("#content").empty(); //doesnt work
$.getJSON(
url + suffix,
function foo(data)
{
$("#content").empty(); //doesnt work
$.each(
data.data.children,
function (i, post)
{
$("#content").append( '<section>' +
'' + post.data.title + '' +
'</section>' );
}
);
}
);
$("#content").empty(); //doesnt work
}
Function is called like this:
<li><a class="link" href="#" onclick=getLinks("localhost")>Blogroll</a></li>
Apparently, empty() should work. I simplified my code above, put its not working in the 3 places I put them. It just keeps adding links to the #content
Try this out:
function getLinks(url)
{
$.getJSON(
url + suffix,
function(data)
{
var items = [];
$.each(
data.data.children,
function (i, post)
{
var section = $('<section></section>').append('<a></a>');
section.find('a').attr('href', '#post=post-' + i).text(post.data.title);
items.push(section[0].outerHTML);
}
);
$('#content').empty().append(items.join(''));
});
}
Use $(...).remove() instead... Or $("#content").html("")
Works for me, check this out
http://jsfiddle.net/gzNFK/2/
note: remove the comment to use it

Link detect and replace the other,in js

Hello
I wonder how Replace automatically links on my site
that start with:
http://site.com/00000/
to:
http://site.com/11111/
detects> replaces
CSS3 attribute "starts with" selectors help you there (and jQuery supports them on all of the browsers it supports — with native features if possible, for speed). Then just use an each loop and update the href property of the raw a element:
$("a[href^='http://site.com/00000/']").each(function() {
this.href = "http://site.com/11111/" + this.href.substring(21);
});
You can use jQuerys .attr() method. You don't need to explicitly invoke .each(), jQuery will take care of you if your selector hits multiple nodes. Since version 1.4.1, .attr() like many other setters, takes a function as argument. This function gets the index and the actual value passed in. Whatever you return from this callback is going to be the new value.
$(document).ready(function () {
$('a').attr('href', function(_, href) {
return href.replace('246619', '262257');
});
});
Demo: http://www.jsfiddle.net/qR2NU/
Reference: .attr()
<script type="text/javascript">
$(document).ready(function () {
var urlContain = new RegExp('Detect Value Here');
$('a').each(function () {
var href = this.getAttribute('href').replace(urlContain, 'Replacement here');
$(this).attr('href', href);
});
});
</script>
This code loops through every link on the page that has a href attribute once the DOM has loaded and performs the required replace:
$(function() {
$('a').each(function() {
var href = $(this).attr('href');
if (href !== undefined) {
href = href.replace(/246619/g, '262257');
}
$(this).attr('href', href);
});
});
The above relies on jQuery but judging by the tags you used for your question, you are already using it.
Untested:
$("a[href^=http://site.com/00000/]").each(function() {
this.href = "http://site.com/11111/" + this.href.substr("http://site.com/00000/".length");
});

Categories

Resources