I have a page which has an anchor element:
<a id="courses" href="/courses">Courses</a>
And I want to add or update some params to the href, for example:
Add a country params: <a id="courses" href="/courses?country=US">Courses</a>
Update the country params from US to UK: <a id="courses" href="/courses?country=UK">Courses</a>
What's the best way to do it via JavaScript or jQuery?
You can pass a function as the second parameter to the .attr() to modify the href attribute.
Try the following way:
// set
$("#courses").attr('href','/courses?country=US');
console.log($("#courses").attr('href'));
// update
$('#setParam').click(function(){
$("#courses").attr('href', function(_, el){
return el.replace(/(country=)[a-z]+/ig, '$1UK');
});
console.log($("#courses").attr('href'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a id="courses" href="/courses">Courses</a>
<button id="setParam" type="button">Set Param</button>
Wrrite a custom function to handle adding properties to the href attribute.
// function to change href attribute
function addPropertyToCourses(prop,value) {
var courses = document.getElementById('courses');
if (courses.href.indexOf("?") == -1) {
courses.href += "?";
} else {
courses.href += "&";
}
courses.href += prop + '=' + value;
}
(function() {
// add properties
addPropertyToCourses("country", "UK");
addPropertyToCourses("someProp", "someValue");
})();
<a id="courses" href="/courses">Courses</a>
Use jquery .attr( function ) to add/edit href attribute of element. In function check if attribute hasn't country parameter, add to it and if has edit it.
$("#courses").attr("href", function(i, href){
var index = href.indexOf("?");
return (index == -1 ? href : href.substring(0, index)) + "?country=US";
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a id="courses" href="/courses">Courses</a>
Here's an example in both JavaScript, and jQuery.
Vanilla JavaScript
function updateCountry (element, country) {
var url = element.getAttribute('href');
if (url.includes('country')) {
url = url.replace(/(\?country=)[A-Z]{2}/, `$1${country}`)
} else {
url = url.concat(`?country=${country}`)
};
element.setAttribute('href', url);
console.log(element.getAttribute('href'));
}
var element = document.getElementById('courses');
updateCountry(element, 'US'); // Add
updateCountry(element, 'UK'); // Update
<a id="courses" href="/courses">Courses</a>
jQuery
function updateCountry (element, country) {
var url = element.attr('href');
if (url.includes('country')) {
url = url.replace(/(\?country=)[A-Z]{2}/, `$1${country}`)
} else {
url = url.concat(`?country=${country}`)
};
element.attr('href', url);
console.log(element.attr('href'));
}
var element = $('#courses');
updateCountry(element, 'US'); // Add
updateCountry(element, 'UK'); // Update
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a id="courses" href="/courses">Courses</a>
Related
I'm trying to convert my jquery back to Javascript, but for some reason it states that title is undefined. I'm not sure how to convert it properly or what to do to fix this issue.
Here is the current jquery code
update: function (e) {
var el = e.target;
var $el = $(el);
var val = $el.val().trim();
if (!val) {
this.destroy(e);
return;
}
if ($el.data('abort')) {
$el.data('abort', false);
} else {
this.todos[this.indexFromEl(el)].title = val;
}
this.render();
},
Here is the code from indexFromEl function
indexFromEl: function (el) {
var id = $(el).closest('li').data('id');
var todos = this.todos;
var i = todos.length;
while (i--) {
if (todos[i].id === id) {
return i;
}
}
},
So based off the code above, I tried to convert it myself, but I don't think I did it correctly.
update: function (e) {
var el = e.target;
var val = el.value.trim();
if (!val) {
this.destroy(e);
return;
}
if(val === 'abort') {
return false;
} else {
return this.todos[this.indexFromEl(el)].title = val;
}
this.render();
},
How do I convert the first code block from jquery to javascript? Also, I'm not sure how to edit the first line in the indexFromEl jquery code
Here is the jquery script
<script id="todo-template" type="text/x-handlebars-template">
{{#this}}
<li {{#if completed}}class="completed"{{/if}} data-id="{{id}}">
<div class="view">
<input class="toggle" type="checkbox" {{#if completed}}checked{{/if}}>
<label>{{title}}</label>
<button class="destroy"></button>
</div>
<input class="edit" value="{{title}}">
</li>
{{/this}}
</script>
Since the id for each li is being set in the HTML markup, rather than by jQuery:
<li {{#if completed}}class="completed"{{/if}} data-id="{{id}}">
// ^^^^^^^^^^^^^^^^
Once you have a reference to the element in Javascript, all you need to do is retrieve the id property from the dataset, eg:
li.dataset.id
To do that, in your indexFromEl function, use:
const id = el.closest('li').dataset.id;
Or if you like using destructuring to make things a bit more DRY:
const { id } = el.closest('li').dataset;
Also note that it would be much cleaner to use findIndex if you want to find an index in an array:
indexFromEl: function (el) {
const { id } = el.closest('li').dataset;
return this.todos.findIndex(todo => todo.id === id);
}
(though, the above will return -1 if no index is found, rather than undefined, as your current code does, if that's an issue)
In your query version, you didn't return anything. So why returning JavaScript version?
First try to find what is this.todos[this.indexFromEl(el)] using instanceof
If this.todos[this.indexFromEl(el)] is Element then you can set(as you're assigning val) title attribute by setAttribute()
So,
this.todos[this.indexFromEl(el)].setAttribute('title', val);
I created a function that creates a HTML chunk of code. Its ids are created dynamically with a tag variable collected from a form. Code:
$(function() {
$("#addTag").click(function() {
var tag = $("#tag").val();
$('section').append('<div id="galleryContainer' + tag + '"><div class=".gallery-header"><h1 >Tag:' + tag + '</h1><div class=".gallery-sort"><p>Sort by:</p><button onclick="sortImagesByPublishedDate()" >Data published</button><button onclick="sortImagesByTakenDate()">Data taken</button><div data-tag="' + tag + '" class="gallery component" id="' + tag + '"></div></div></div></div>');
mainFunction(tag);
});
});
Then I want to use sortImagesByPublishedDate() and sortImagesByTakenDate() by clicking a button, but I want them to sort images only in this particular gallery and not in all galleries. If I have one gallery, it works fine. Problems begin when I add more galleries. How should I select the variable $gallery in the following functions?
function sortImagesByPublishedDate() {
var $gallery = $('div.gallery'),
$galleryA = $gallery.children('a');
$galleryA.sort(function(a, b) {
var an = a.getAttribute('data-published'),
bn = b.getAttribute('data-published');
if (an > bn) {
return 1;
}
if (an < bn) {
return -1;
}
return 0;
});
$galleryA.detach().appendTo($gallery);
}
Use the .siblings method to select elements that are siblings of another element. So in your case you can just call
var $gallery = $(buttonElement).siblings(".gallery");
Since you are using inline JS to call the sort functions you need to modify it to pass this to your functions that way you can get a reference to the button that was clicked, ie:
Modified html
<button onclick="sortImagesByPublishedDate(this)">Date published</button>
JS
function sortImagesByPublishedDate(ele){
var $gallery = $(ele).siblings(".gallery"),
Demo
$(function(){
$("#addTag").click(function(){
var tag=$("#tag").val();
$('section').append('<div id="galleryContainer'+tag+'"><div class=".gallery-header"><h1 >Tag:'+tag+'</h1><div class=".gallery-sort"><p>Sort by:</p><button onclick="sortImagesByPublishedDate(this)" >Data published</button><button onclick="sortImagesByTakenDate(this)">Data taken</button><div data-tag="'+tag+'" class="gallery component" id="'+tag+'"></div></div></div></div>');
//mainFunction(tag);
});
});
function sortImagesByPublishedDate(ele){
var $gallery = $(ele).siblings(".gallery"),
$galleryA = $gallery.children('a');
alert($gallery[0].id);
$galleryA.sort(function(a,b){
var an = a.getAttribute('data-published'),
bn = b.getAttribute('data-published');
if(an > bn) {
return 1;
}
if(an < bn) {
return -1;
}
return 0;
});
$galleryA.detach().appendTo($gallery);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="tag">
<button id="addTag">Add</button>
<section>
</section>
Instead of inline js you could use delegated event handling to have listeners setup for your buttons:
Modified html
<button class="sortButton" data-sort="date">Data published</button>
<button class="sortButton" data-sort="taken">Data taken</button>
JS
$("section").on("click",".sortButton",function(){
//'this' will be the button clicked
var $gallery = $(this).siblings(".gallery");
var sortBy = $(this).data("sort");
if(sortBy == "date"){
//do date sort
} else if(sortBy == "taken"){
//do taken sort
}
//... rest of code
});
$(function() {
$("#addTag").click(function() {
var tag = $("#tag").val();
$('section').append('<div id="galleryContainer' + tag + '"><div class=".gallery-header"><h1 >Tag:' + tag + '</h1><div class=".gallery-sort"><p>Sort by:</p><button onclick="sortImagesByPublishedDate()" >Data published</button><button onclick="sortImagesByTakenDate()">Data taken</button><div data-tag="' + tag + '" class="gallery component" id="' + tag + '"></div></div></div></div>');
sortImagesByPublishedDate(tag); **// call the function and pass param tag**
mainFunction(tag);
});
});
function sortImagesByPublishedDate(tag) {
**// instead of class select id**
var $gallery = $('div#galleryContainer'+tag),
$galleryA = $gallery.children('a');
$galleryA.sort(function(a, b) {
var an = a.getAttribute('data-published'),
bn = b.getAttribute('data-published');
if (an > bn) {
return 1;
}
if (an < bn) {
return -1;
}
return 0;
});
$galleryA.detach().appendTo($gallery);
}
// hope this helps
Not tested but I think this will worl:
HTML:
sortImagesByPublishedDate(this)//pass this
JS:
function sortImagesByPublishedDate() {
var $gallery = $(this).siblings('.gallery'),
$galleryA = $gallery.children('a');
.
.
Pass this to sortImagesByPublishedDate(this) in your html of append
so your code is
function sortImagesByPublishedDate(thisObj) {
and then do
var $gallery = $(thisObj).siblings(".gallery");
I've got strings with multiple standard links like
Name of Link
and I'm trying to turn them into
<a onClick="myFunc('http://example.com','Name of Link')">Name of Link</a>
or even just:
<a onClick="myFunc('http://example.com')">Name of Link</a>
would be great if the former was unnecessarily difficult. The links are being dynamically inserted into the DOM so event handlers won't do.
You need event handlers that prevents the default action and get the href
var anchors = document.getElementsByTagName('a');
for (var i=anchors.length; i--;) {
anchors[i].addEventListener('click', func, false);
}
function func(e) {
e.preventDefault();
var href = this.getAttribute('href'),
text = this.innerText;
myFunc(href, text);
}
FIDDLE
If you have to work with strings, you can do something like this
var str = 'Name of Link 1<br />Name of Link 2<br />Name of Link 3<br />Name of Link 4';
var parser = new DOMParser();
var doc = parser.parseFromString(str, "text/html");
var anchors = doc.getElementsByTagName('a');
for (var i=anchors.length; i--;) {
var href = anchors[i].getAttribute('href'),
text = anchors[i].innerText;
anchors[i].setAttribute('onclick', "myFunc('"+href+"', '"+text+"')");
anchors[i].removeAttribute('href');
}
str = doc.body.innerHTML;
document.body.innerHTML = str;
function myFunc(href, text) {
alert(href + ' - ' + text);
}
You can do like this
HTML
<a href="http://example.com" onclick="myFunction(this.href,this.textContent)">
My link
</a>
JS
function myFunction(getAttr,text){
console.log(getAttr,text);
}
EXAMPLE
EDIT
if you are looking to prohibit href action then you have to use
event.preventDefault();
Updated JS
function myFunction(event,getAttr,text){
event.preventDefault();
console.log(getAttr,text);
}
UPDATED JSFIDDLE
Append your string in a temporary element and manipulate it as explained by adeneo
Try this:
var str = 'Name of Link';
var elem = document.createElement('div');
elem.innerHTML = str;
var targetEleme = elem.getElementsByTagName('a')[0];
targetEleme.addEventListener('click', function(e) {
e.preventDefault();
var href = this.getAttribute('href'),
text = this.innerText;
myFunc(href, text);
});
document.body.appendChild(targetEleme);
function myFunc(href, text) {
alert('HREF: ' + href + ' TEXT: ' + text);
}
Fiddle here
I want to create links, based on a specific format.
When I type this:
google->apple
I want get get this link:
https://www.google.hu/search?q=apple
I tried this way, but unfortunately it is not working:
//Intelligent actions start
function replace(){
var str = $('.smile').html();
var re = /google->([^ \n$]+)/g;
var url = "https://www.google.hu/search?q=" + re.exec(str)[1];
}
//Intelligent actions end
Update
Based #vinayakj answer, I start create a solution for this:
//Intelligent actions start
function googleSearch(val){
var url = "https://www.google.hu/search?q=" + val.split('->')[1];
alert(url)
//location.href = url;
}
$( document ).ready(function() {
googleSearch($('.comment-content p').text())
$( ".comment-content p" ).replaceWith( "<a href='url'>url</a>" );
});
//Intelligent actions end
And looks like replacewith function reaplce all content in
.comment-content p
with:
url
And this function it has some problem:
Reaplce all text even if dosen't find this sting in div:
google-->some word
The link is absolute incorrect becouse I get back this value everywhere:
url
What am I doing wrong?
function googleSearch(val){
var url = "https://www.google.hu/search?q=" + val.split('->')[1];
alert(url)
location.href = url;
}
<input onchange="googleSearch(this.value)" type=text>
Here is the final solution after all your comments
var urls = {
"google":"https://google.com/search?q=#",
"bing":"https://....q=#&bla=bla"};
function getUrl(str) {
var parts = str.split("->");
var url = urls[parts[0]].replace("#",encodeURI(parts[1]));
return = $("<a/>",{href: url, class:parts[0]+"-search"}).text("Keresés ..."+parts[1]);
}
$(function() {
$("div.comment-content > p.smile").each(function() {
var $link = getLink($(this).text());
$(this).html($link);
});
});
Old answer
var urls = {
"google":"https://google.com/search?q=#",
"bing":"https://....q=#&bla=bla"};
function getUrl(str) {
var parts = str.split("->");
return urls[parts[0]].replace("#",parts[1]);
}
window.onload=function() {
document.getElementById("myForm").onsubmit=function() {
var str = document.getElementById("q").value;
var url = getUrl(str);
if (url) alert(url); // location.href=url;
return false; // cancel the submit
}
}
<form id="myForm">
<input id="q" type="text">
</form>
I found the solution, but thanks for everybody:
$("div.comment-content > p.smile").each(function(){
var original = $(this).text();
var replaced = original.replace(/google->([^.\n$]+)/gi, '<a class="google-search" href="https://www.google.hu/search?q=$1" target="_blank">Keresés a googleben erre: $1</a>' );
$(this).html(replaced);
console.log("replaced: "+replaced);
});
$("a.google-search").each( function() {
this.href = this.href.replace(/\s/g,"%20");
});
I am trying to pass two variables to a pre-written function that has 2 parameters. The idea is when a users clicks on a filter variable 1 gets set, then when they click on an item variable 2 gets set. Once they click on an item it sets the two variables as the parameters in a pre-written function (I cannot gain access to change this function). Here is what I have.
HTML Filters:
All
filter1
filter2
filter3
HTML Links:
<a data-track="Track Var Link1" href="link1.aspx">Link 1</a>
<a data-track="Track Var Link2" href="link2.aspx">Link 2</a>
<a data-track="Track Var Link3" href="link3.aspx">Link 3</a>
jQ:
var filterText = 'all';
var trackText = '';
$('a.filter').click(function(event) {
filterText = $(this).data('filter');
});
$('.item a').click(function(event) {
trackText = $(this).data('track');
});
$('.item a').click({param1: filterText, param2: trackText}, preWrittenFunction);
Pre-Written-Function:
function preWrittenFunction(type, lname) {
s = s_gi(s_account);
s.linkTrackVars = 'prop5,prop17,prop18,pageName'
s.linkTrackEvents = 'None';
s.prop5 = document.URL.toLowerCase(); // url
s.prop17 = s.pageName; // name and campaign pathing
s.prop18 = type; // widget type
s.tl(this, 'o', type + ": " + lname); // link name includes type
}
Wrap the call to your preWrittenFunction in an anonymous function to be used as click event handler:
$('.item a').click(function() {
preWrittenFunction(filterText, trackText);
});