jQuery get href initial value once before it changes - javascript

In my application I have an ajax call, and on success it appends some data to an existing links href.
This works great. The issue is, If I want to run the ajax call again and on success, append some different data, it is taking the href value + the new value from the previous ajax call, and than adding the new data after that.
I want it to add the data to the inital href value, before it was appended.
Below is my code:
(I have the sample sample value being appended each time for testing purposes)
//get next page link value, so we can add filter to url
var next_link = $("a.next").attr("href");
$.ajax({
type: "POST",
url: "ajax_calls.php",
data: "instrument="+selected.val()+"&filter=true",
success: function(listing){$("#listings").html(listing);
$("a.next").attr("href", next_link + '&field=x');
},
error: function(){alert(3);$("#error").text("Could not retrieve posts").fadeIn(300).delay(900).fadeOut(300)}
});
Any help on this would be appreciated.
Thank you

How about using jQuery's .data method?
$('#change').click(function(){
var newData = Math.random() * 1000; // fake new data
$('a').each(function(i,e){
var oldHref = $(this).data('oldHref');
if (!oldHref){
var oldHref = $(this).attr('href');
$(this).data('oldHref',oldHref);
}
$(this).attr('href',oldHref + '#' + newData);
});
});
Hello, world!<br />
<input type="button" id="change" value="Change HREF" />
example
Store the old value in a data element, then reference before each new change.

Related

AJAX success not render properly since second request

I use ajax to render output to below HTML element.
<p class="result-box" id="result-box">The result is : <br><strong id="result"></strong></p>
Everything works fine when rendering result for the 1st input request.
When I update my input, the console changes and prints desired data but the webpage including the text does not change.
I get Cannot read property 'setAttribute' of null at canvas_and_ploton the 2nd+ time refresh below, If I remove setAttribute, I get Cannot read property 'getAttribute' of null at canvas_and_plot.
$(document).on('submit','#cat_select',function(e){
e.preventDefault();
$.ajax({
type:'POST',
url:'/cat_select',
data:{
l2:$('#l2').val(),
l3:$('#l3').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val()
},
success: function server_response(response) {
const r = JSON.parse(response);
console.log(r); //updated
var cat_result = r.cat_result;
console.log(cat_result[0]) //updated
var text=$('<i></i>');
$.each(cat_result, function(idx, value) {
text.append('<id="result'+idx+'">' + cat_result[idx][0]+ '<br>'); //even the text output are not updated
text.append('<canvas id="canv_'+idx+'" width="200" height="200"></canvas><br>');
});
$('#result').replaceWith(text);
$.each(cat_result, function(idx, value) {
canvas_and_plot(idx,cat_result[idx][9],cat_result[idx][10],cat_result[idx][11])});
}
function canvas_and_plot(idx,a,b,c) {
var canv = document.getElementById('canv_'+idx);
canv.setAttribute('id', 'canv_'+idx);
var C = document.getElementById(canv.getAttribute('id'));
//plot...
}
I tried adding cache: false and adding random number to the url but neither of them works.
Why only error after the first request? How can I fix this? Thanks
The reason for it not changing is that you are replacing your block #result with received data.
$('#result').replaceWith(text);
After which you'll a dom tree that looks something like this:
<p class="result-box" id="result-box">
The result is : <br>
<i>
<id="result123">...<br>
<canvas id="canv123" width="200" height="200"></canvas><br>
<id="result321">...<br>
<canvas id="canv321" width="200" height="200"></canvas><br>
</i>
</p>
So the second time you click there is no element with #result id.
I suggest (as a rough and quick solution):
On every request remove all children of your #result element and fill it again with new data. So add this line before making the request - $('#result').empty(); and replace $('#result').replaceWith(text); with $('#result').append(text);
The main idea is to keep the place you put and add your server data. Hope this helps!

How to avoid appending duplicates on ajax after second call?

I have a button called File which is a dropdown that has another button called open. Once the user clicks open I have an ajax GET request that appends a button after each call.
When the user clicks open once, the button is appended. However, when the user clicks open again, the same button is appended again with the same attributes and if the user clicks the open button the third time the button is appended once more, so a total of three times.
How do I ensure the button is only appended once?
The {{}} is from the django web framework and is not a concern
<input type = "button" class = "openGraph" value = "{{titles}}" id="{% url 'openGraph' title=titles.id %}">
This is the occurence when the user presses the open button.
$(document).ready(function(){
$('#openXML').on('click',function(event){
var csrftoken = getCookie('csrftoken');
$.ajax({
type: "GET",
url: "/loadTitles/",
dataType: 'text',
headers:{
"X-CSRFToken": csrftoken
},
success: function(data){
var json = JSON.parse(data)
var length = Object.keys(json).length
var pk = "/openGraph/" + json[length-1]['pk']
var title = json[length-1]['fields']['title']
myButton="<input type=\"button\" class = \"openGraph\" value=\""+title+"\" id="+pk+"/\>";
$("#loadAllTitles").append(myButton)
}
});
})
});
Because the IDs must be unique I'd suggest to test if the button already exist before adding. Hence, you need to change this line:
$("#loadAllTitles").append(myButton)
with:
if ($("#loadAllTitles").find('#' + $.escapeSelector(pk + '/')).length == 0)
$("#loadAllTitles").append(myButton)
I get the following console error: Uncaught Error: Syntax error, unrecognized expression: #/openGraph/104 –
If you are using jQuery 3.x you need to use:
jQuery.escapeSelector(): Escapes any character that has a special meaning in a CSS selector.
UPDATE
While pk is the ID when you create a new element you add to this ID a final /. This is your issue.
$('button').on('click', function(e) {
var pk = '#/openGraph/104';
var title='title';
myButton="<input type=\"button\" class = \"openGraph\" value=\""+title+"\" id="+pk+"/\>";
if ($("#loadAllTitles").find('#' + $.escapeSelector(pk + '/')).length == 0)
$("#loadAllTitles").append(myButton)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="loadAllTitles">
</form>
<button type="button">Click to add the same input field</button>
Check for the presence of a button on line 3
$(document).ready(function(){
$('#openXML').on('click',function(event){
if (!$('#+pk+').length) {
// Your code
}
}
}

Callback function on a url?

In my web app, I want to be able to click on a href link within a datatable that loads a second table on a new page, which in turn filters out rows so that the table only displays rows with the same id as the id of the row I clicked on in the previous table/page.
The code below does not work. I believe this is because before it has had time to save the row data from the first table, a new web page is already being opened and it is too late to save the data as it is no longer there. Is there a way to create a callback so that my javascript function is executed before the href link is opened?
Or maybe I am doing this completely wrong?
Any help would be appreciated.
Datatable.Column() code: (the user clicks on an image/url link within the table):
"data": "ErrorCount",
"render": function (data, type, row) {
if (type === 'display') {
return (data === 0)
? data = '<span data-search="0"></span>'
: data = '<a id="errors" href="http://localhost/WTM/LogError/Index" type="hidden" class="fas fa-exclamation-triangle" style="color:red"></a>';
}
return data;
},
Javascript filter function:
var clickError = document.getElementById("errors")
var xTable = $('#TABLE_ONE').DataTable();
var yTable = $('#TABLE_TWO').DataTable();
$('clickError').click(function () {
var rowData = xTable.row(this).data();
yTable.columns(0).search(rowData.TaskSchedulerLogUid).draw();
});
Multiple issues here:
ID's can't be repeated in a page, use class instead
$('clickError') is invalid selector
The elements in question are dynamically rendered and thus won't all exist when the code is run. Use event delegation
The row is not the <a>
Fixes:
HTML
'<a ̶i̶d̶=̶"̶e̶r̶r̶o̶r̶s̶"̶ class="errors"...
JS
$('#tableID').on('click', 'a.errors', function(e){
e.preventDefault();
var row = $(this).closest('tr')[0];
var rowData = xTable.row(row).data();
yTable.columns(0).search(rowData.TaskSchedulerLogUid).draw();
})
For anyone interested. I found a different way of doing this.
First I added the search query/row ID to the url of the new page I wanted to open like this:
'
then I extracted the search query/ID from the url, and searched the table on the new page using the newly extracted search query/ID, like this:
var queryString = window.location.search;
queryString = queryString.substring(4);
if (queryString == null) {
throw "Error: id is null"
} else {
WtmDetails.vars.secondaryTable.columns(0).search(queryString).draw();
}

How do I Call a URL Action from Javascript?

I am doing:
var url = '#Url.Action("Attachments", "Transactions")';
url += '/?id=' + 3201;
$("#attachments").load(url);
However, on load it doesn't do anything. Am i missing something?
I essentially want to call something similar to:
#{Html.RenderAction("Attachments", "Transactions", new { id = 3301 });}
I get the following error on console:
http://server:54137/Transactions/#Url.Action(%22Attachments%22,
You must be using an external JavaScript file which will not parse your razor syntax hence the error in your console of #Url.Action(%22Attachments%22..
You have a couple of options:
Create a JavaScript function and pass in the url:
function loadUrl(url) {
$("#attachments").load(url);
}
Then in your razor call it within a script tag:
loadUrl(#Url.Action("Attachments", "Transactions", new { id = #Model.Id })
Add the url to the html element as data and read it from your JavaScript with the data method.
In your razor markup add this:
<button data-url="#Url.Action("Attachments", "Transactions", new { id = #Model.Id })" />
From your JavaScript event handler read it with:
var url = $(this).data('url');
$("#attachments").load(url);
I prefer the second option.
You Need to use Html.Raw check below
var url = "#Html.Raw(Url.Action("Attachments", "Transactions"))";
url += '/?id=' + 3201;
$("#attachments").load(url);

How to get text field value from another page javascript

Here My script code
page 1 / index.php
$(document).ready(function(){
$("#list").load("load_list.php");
function reloadlist(){
var total_list = $("#total").val();
$.get('load_list.php', function(data){
var values = $("input[name='total']", data).val();
alert(values);
});
} setInterval(reloadlist, 3000);
})
<body>
<div id="list"></div>
</body>
page 2 / load_list.php
[My query for get the total data]
<input type="hidden" name="total" id="total" value="<?=$total?>">
When i load that index page, and alert value will be undefined. how to get text field value from load_list.php
save the value in a cookie and retrive it in next page
The element is at root level, and the contex selector uses find() internally, and that only works on descendants.
You can avoid any and all issues with elements being descendants or at root level by appending the content to another element, and then using find(), or you could use filter() directly
$.get('load_list.php', function(data){
var values = $('<div />', {html: data}).find("input[name='total']").val();
alert(values);
});
Also, the element has an ID, and it would be more efficient to use that in the selector.
You're in kind of a bad situation since you're just reloading the list after 3 seconds even if the call failed. You should try to clean up the whole idea a bit.
function reloadList = setTimeout(function(){
$.get('load_list.php', function(result){
var value = $(data).filter('#total').val();
alert(value);
reloadList();
});
}, 3000);
reloadList();

Categories