I have tried to follow the example in the handlebars documentation on how to create a link, but the instructions are very unclear to me. handlebarsjs.com/expressions.html (see "Helpers")
First of all, without the link helper I can make the link text appear on the screen, but just as text, not a link.
<script id="template" type="text/x-handlebars-template">
<h4>{{{my_link}}}</h4>
</script>
And the text is retrieved from an ajax request.
Then I add the link keyword
<h4>{{{link my_link}}}</h4>
And then nothing is displayed. This is the helper code I have currently, which doesn't work:
$(function(){
Handlebars.registerHelper('link', function(my_link) {
var url = Handlebars.escapeExpression(my_link.url);
var result = "<a href='" + url + "'></a>";
console.log(result);
return new Handlebars.SafeString(result);
});
});
Is it relevant where I put this piece of code in the javascript?
When I click a submit button, the ajax request is made and the link is retrieved. With the link helper, the console.log gives an empty link:
"<a href=''></a>"
Since you registered the name of the helper as link, your template should start with {{{link
So
<h4>{{{my_link}}}</h4>
should be
<h4>{{{link my_link}}}</h4>
And
var url = Handlebars.escapeExpression(my_link.url);
should be changed to
var url = Handlebars.escapeExpression(my_link);
Instead of creating the whole a element I can suggest you to create helper for attribute only. This way you can reuse it to many others elements and also the code will be much simpler and better to read in the templates. For example I have build this attr helper function:
handlebars.registerHelper('attr', function(name, data) {
if(typeof target === 'undefined') target = "";
var result = ' ' + name + '="' + data + '" ';
return new handlebars.SafeString(result);
});
And here is how it looks in the template:
<a target="_blank" {{attr 'href' general.link}}><img src="assets/images/nice_image.png" class="link-icon" /></a>
I think this approach is much more simpler, and even more reusable than having helper to create the whole element. You can name the helper in the way that will match the attribute also, href, src...
Related
I am attempting to use the following bit of JS and jQuery to pass a variable (user's Email address form tfa_27) through an href link on the form.
I can redirect to the page, but the url just reads 'tfa_5?=$VARIABLE' instead populating the Email address into the URL, which ends my login state for the user. I know I am missing something ...
function dynamicLinks(linkClass, fieldId) {
var selection = $("#" + fieldId);
console.log(selection.val()); //Gives 'some.email#domain.ca'
var linkArr = [];
$(selection).each(function() { linkArr.push($(this).val()); });
$(linkClass).attr("href", function(i, origLink) { return origLink.replace(/\$VARIABLE/, linkArr[i]); });
//$(linkClass).attr("href", function(i, origLink) { return "https://tfaforms/XXXXXXX?tfa_5=" + selection.val() }); //Does not update href on form
};
dynamicLinks(".linkClass","tfa_27");
On the page itself, this is what my HTML href looks like this with the form ID hidden from SE for security reasons - the $VARIABLE should be an email address.
Back to Options
Please note this piece of code is partially legacy code, so I may have some extra pieces - if so, please let me know! I am unsure how to move the variable into the href on the form, or how to build that href dynamically - I was told this would work well, but am missing something.
Thanks!
https://example.com/index.php contains the following two anchor tags:
Link 1
Link 2
One or more parameters may be passed in the URL, eg. https://example.com/index.php?a=1&b=2
Using jQuery/Javascript, what is the simplest way to test for the presence of parameter a in the URL and append it to the hrefs in the above links if it exists, so they become:
Link 1
Link 2
You are getting the logic of app design wrong. That is something you should do on the back-end of the web application; you check for the input parameters in the GET request and format the links hyper-reference accordingly.Also if you are going to be passing the value many times it may be easier for you to store it in the user session temporary environment (using cookies).
If you are using PHP (as I may guess by the file's extension) you can do that very easily:
<a href="page1.php<?
if(array_key_exists('your_key', $_GET) {
echo('?your_key=' . $_GET['your_key'])
}
?>" class="hyperlink">Link 1</a>
<a href="page2.php?<?
if(array_key_exists('your_key', $_GET) {
echo('your_key=' . $_GET['your_key'] . '&')
}
?>b=1" class="hyperlink">Link 2</a>
Client side the simplest is use the URL API
var mainUrl = new URL(location.href);
// Won't work in this demo so hard code href
mainUrl = new URL('http://example.com?a=foo&b=2');
var paramA = mainUrl.searchParams.get('a');
$('a.hyperlink').prop('href', function(){
var url = new URL(this.href);
url.searchParams.set('a', paramA);
return url;
})
// set query params as text just for demo
.text(function(){
return 'Query Params: ' + this.search;
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Link 1<br/>
Link 2
You can try using regex, by the way as i can see you are using php so filter them with $_REQUEST
otherwise getting everything after the link in regex
var url = window.location.href
var res = url.match("/\?(.*)/i")
res should contain everything from ?getTO&otherget
I got a javascript onclick event inside a template, and I want to call one of my Django urls with an id parameter from it, like this :
$(document).on('click', '.alink', function () {
var id = $(this).attr('id');
document.location.href ="{% url 'myapp:productdetailorder' id %}"
});
Course this is not working at all. Any idea ?
Thanks in advance !!
I think the best way to do this is to create a html data-* attribute with the URL rendered in a template and then use javascript to retrieve that.
This way you avoid mixing js/django template stuff together. Also, I keep all of my JS in a separate file outside the view (which is a much better practice in general), and therefore trying to mix these two won't work.
For instance, if you have a url you want, just create an html hidden element:
<input type="hidden" id="Url" data-url="{% url 'myapp:productdetail' id %}" />
Then, in your JS:
$(document).on('click', '.alink', function () {
var url = $("#Url").attr("data-url");
});
I frequently use this pattern for dropdown lists so that I don't have to serve all of the options when I first render the page (and this usually speeds it up).
You are trying to access javascript variable that is created at user click on frontend within your Django template at the backend. But, you already know that it would not work.
A better option would be to reconstruct the url in javascript:
$(document).on('click', '.alink', function () {
// Generate URL without "id" bit
var url = "{% url 'myapp:productdetail' %}";
var id = $(this).attr('id');
// Construct the full URL with "id"
document.location.href = url + "/" + id;
});
If you don't have a django url helper that would return a URL that you need, you can print out just any and simply replace it in javascript like so:
$(document).on('click', '.alink', function () {
var url = "{% url 'myapp:productdetail' 123 %}";
var id = $(this).attr('id');
// Construct the full URL with "id"
document.location.href = url.replace('123', id);
});
The problem seems to be in that you using django template language in js static file(am i right?)
Try to move that variable to html template file, ex:
<script type=text/javascript>
var a = "{% url'myapp:productdetail' id %}" </script>
And in static js file:
document.location.href = a;
You can use javascript code " window.location.origin " , this will give base url and after that you can add "/pathname"
You don't need to pass any of that...
Write.
location.href = "/" + id
That's all.
I have a dynamic variable that gets updated by users of a webpage in a script and when the user clicks on a hyperlink I need to be able to send that variable to another webpage. So I need something like
Link
to work but I am not sure the exact syntax on how to do this. I already have a getter in my JavaScript I just need to be able to access it when the user clicks on a link.
You could either use an onclick action to send you to a function that navigates the page for you.
Or
You could update the href attribute anytime that value of variable needs to be changed.
The second option is probably preferable, but it largely depends on what else is going on in the page and how variable is set
it looks very familiar with this:
How to redirect on another page and pass parameter in url from table?
link
Native JS:
document.getElementById('redirectwithid').setAttribute('href','yoururl?variable=' + variableGetter());
jQuery:
$("#redirectwithid").click(function() {
var yourVariable = variableGetter();
if (yourVariable != null) {
window.location = 'yoururl?variable=' + yourVariable;
}
});
Add for Native JS:
I don't know your code so just insert the code where you want to update your variable - at the same time the href will change.
Edit:
If you want to add multiple variable like ?variable=1 and a second variable2=2 you can achieve this by adding a & between the variables, like this:
NativeJS:
document.getElementById('redirectwithid').setAttribute('href','yoururl?variable=' + variableGetter() + '&variable2=' + variable2Getter());
JQuery:
$("#redirectwithid").click(function() {
var yourVariable = variableGetter();
var yourVariableTwo = variableTwoGetter();
if (yourVariable != null) {
window.location = 'yoururl?variable=' + yourVariable + '&' + yourVariableTwo;
}
});
I have a jQuery ajax call that looks like this:
$.ajax({
type : 'GET',
dataType : 'json',
url : '/Zoo/animals',
success : function(data){
var count = data.length;
for(var i = 0; i < count; i++) {
${'#tableBody').append('<tr><td>');
${'#tableBody').append('' + data[i].name + '');
${'#tableBody').append('</td></tr>');
}
}
})
Now all of this works fine except for the href attribute. Play! gives me the following error:
Exception raised was NullPointerException : Cannot get property 'name' on null object.
The json string that gets returned from the ajax call is fine as the text of the link shows up as the name of the animal as expected. I would like to pass the name of the animal to the Animal.index action however have been unable to do so.
Update:
As others have mentioned, I have also tried this:
${'#tableBody').append('' + data[i].name + '');
which just results in the link of:
localhost:9000/animal/index?name=+%2B+data[i].name+%2B+
The problem is that Play! generates the url when the file is served, well before any javascript is executed. No change to the string or quotes here or there is going to help you.
A workaround:
var url = "#{Animal.index(XXX)}".replace('XXX', data[i].name);
${'#tableBody').append('' + data[i].name + '');
This allows Play! to generate its url at "compile" time, and then javascript simply executes a replace at "run" time. Not sure if Play! will look for a variable named XXX, if so, add a dumby variable named XXX with value "XXX" on the server side.
UPDATE
I don't have a Play! instance in front of me to fiddle with, but instead of a variable, you could probably also insert the string directly as a value by quoting the XXX:
var url = '#{Animal.index("XXX")}'.replace('XXX', data[i].name);
And then you wouldn't need a variable named XXX. The details require a bit of playing around, although the idea is the same.
This sounds like a job for the jsAction tag. It generates a javascript function which works along the same lines as davin's answer.
You would put var animalAction = #{jsAction #Animals.index(':name') /}; somewhere before your ajax call, then change your link generation code to:
${'#tableBody').append('<tr><td>');
${'#tableBody').append('' + data[i].name + '');
${'#tableBody').append('</td></tr>');
You'll notice the generated function takes an object as it's argument, so it can support as many parameters as you want.
What isn't explicitly clear in the docs is that the label (:name) must be the same as the name of the parameter in the corresponding controller action (public static void index(String name)), which of course must be the same as how it's specified in the routes file (GET /animals/{name} Animals.index).
data is a javascript object, you need to specify that similar to how you are printing the text of the link. Can you try this?
${'#tableBody').append('' + data.name + '');
You are looping over data array but you need to reference each data object by the index i so like data[i]. I would try this:
$.each(data, function(k, item) {
$('#tableBody').append('<tr><td>' + item.name + '</td></tr>');
});
This will replace everything inside your success callback
you should change this line-
${'#tableBody').append('' + data[i].name + '');
to this-
${'#tableBody').append('' + data[i].name + '');