How to avoid appending duplicates on ajax after second call? - javascript

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
}
}
}

Related

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();
}

Generating a List and Subsequent Pages from JSON

In my project, I have a JSON file. I display the data that is parsed inside a list (ul) under a div with the class, "inner", and show only the name and cost of each product that you can see in my JSON.
{
"product": [
{
"name": "samsung galaxy",
"image": "https://rukminim1.flixcart.com/image/832/832/mobile/v/z/x/samsung-galaxy-on-nxt-sm-g610fzdgins-original-imaenkzvmnyf7sby.jpeg?q=70",
"cost": "RS.10,000",
"detail": "Flaunt your style with the Samsung Galaxy On Nxt. Featuring a drool-worthy body and impressive features, this smartphone is built to perform. Talk to your mom, chat with your friends, browse the Internet - stay connected the way that suits you best - this smartphone is powerful enough to keep up with your busy lifestyle."
}
]
}
When I click on the first product (first list item), I want to show the detail (value detail) of this product in another page from that same JSON object; when I click on the second product, I want that to show in a different page too, but also from that same object.
Here's my HTML:
<html>
<head>
<title>jquery</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
$.ajax({
url: 'http://sonsofthunderstudio.in/jj/product.json',
dataType: 'jsonp',
jsonpCallback: 'jsonCallback',
type: 'get',
crossDomain : true,
cache: false,
success: function(data) {
$(data.product).each(function(index, value) {
console.log(value);
$( ".inner" ).append("<li>"+value.name+"<img src='" + value.image + "' width='50px' height='50px' / >"+value.cost+"</li>");
});
}
});
</script>
<div class="inner">
</div>
</body>
</html>
Where can I go from here?
When you want to show details of your product, You have to create a "ProductList.html" to show your product list, and create a "ProductDetail.html" to show product detail based on selected product.
when user click on a product, You have to pass the selected product to "ProductDetail.html" via url and get it in that page.
the 2 "encodeURIComponenet()" and "decodeURIComponent()" are javascript defined functions to make this action encoded and safe.
To achieve this, You have to append a "Link"(A Tag) to $(".inner"):
$(".inner").append("<a href='#'>"+value.name+"</a>");
in code above, you create a link, you pass the Product ID to destination page and In codes below, You set the "href" attribute for the link:
var _SelectedProduct = "ID=" + ProductID;
var _EncodeID = encodeURIComponenet(_SelectedProduct);
document.getElementById("YourLink").href = "ProductDetail.html?" + _EncodeID;
with these codes, when user click on a product, he will be redirected to "ProductDetail.html" with the selected product ID. You can get this ID in Your ProductDetail.js:
var _DecodeURL = decodeURIComponent(window.location);
var ID = _DecodeURL.split("=");
var _ProductID = ID[1];
with these codes, you split the passed url base on ("="), which means you will get the passed Product ID.(_ProductID).
and :
for(i=0;i<=product.lenght; i++){
if(product[i].ID == _ProductID){ ... }
}
You can add onclick event on li and call a function which will store the particular detail in localStorage.
On the next page you can access detail from localStorage and display it.
//--[Appending in your code]--
.
.
.
$(data.product).each(function(index, value) {
console.log(value);
$( ".inner" ).append("<li onclick='foo('"+value.detail+"')'>"+value.name+"<img src='" + value.image + "' width='50px' height='50px' / >"+value.cost+"</li>");
});
<script type="text/javascript">
function foo(detail)
{
localStorage.setItem("DETAIL",detail);
}
</script>
//--[On second page]--
<head>
<script type="text/javascript">
var detail = localStorage.getItem("DETAIL");
$("#details").html(detail);
</script>
</head>
<body>
<div id="details"></div>
</body>
When you append data first you need to do is to add an Identifier because you need to differentiate the elements and you need to put onClick to each element that you will append you can put it like this: '<li id="'+ index +'" onClick="clicklist(this)">'+ value.name (...) +'</li>'
The second thing you need to declare is a function called clicklist or something with the param element.
function clicklist(element) { }
Fill it with the code I will explain now:
You can access to your list data through the element with your jQuery functions. So first you can get id with var id = $(element).attr('id'); then you can find your list elements and get it value with var itemname = $(element).find("typeofelement.class").attr('value'); etc...
When you get all data in your list you need to open a new window with the params you get in the function. Then use this code:
//Add all the values you need in the other html (id and values) So repeat this line:
sessionStorage.setItem("ID", id);
//Open the window
window.open("yourother.html","_blank");
This is the simple way.

JQuery how to click html element to copy into text area?

Is it possible to click text in a list to add into a text box. I have made a JSON api that gets a list of people in the database. I then have a form that has a text field and displays the list of people. I would like to click a particular person and add it to the text box.
main.js
var ajax_call = function() {
var $people = $('#people');
$.ajax({
type: 'GET',
url: '/all/api',
success: function(people) {
$.each(people, function(i, person) {
$people.empty()
});
$.each(people, function(i, person) {
$people.append('<li>name: ' + person.first_name+', last: '+ person.last_name + '</li>');
});
}
});
$("#people").on("click", "li", function() {
var content = $(this).html();
//$("#testbox").val(content); //replace existing name in textbox
$("#testbox").val($("#testbox").val() + content + "\n"); //add new name to textbox
});
};
var interval = 800;
setInterval(ajax_call, interval);
form.html
<form id="textbox" action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="create" />
</form>
<ul id="people"></ul>
Try this "click" function attached to the ul but filtered by the li's (this allows the list to remain dynamic), it allows you to add the individual names (two versions one that overwrites the existing textfield info and the second that appends to it): DEMO
$("#people").on("click", "li", function() {
var content = $(this).html();
//$("#testbox").val(content); //replace existing name in textbox
$("#testbox").val($("#testbox").val() + content + "\n"); //add new name to textbox
});
I think the answer to your question is pretty easy.
In your code you have the line
$("#people").keyup(function() {
Which is probably not what you wanted to do, cause now you are waiting for a keyup (release of a key) event on a list. First of all your question stated that you want the user to click and not to press a button and second you want the list items not the list itself.
So IMO you have to change that part to something like:
$("li","#people").click(function(){
var content = this.html();
$("#testbox").val(content);
});
Try this :
replace this
$("#people").keyup(function() {
var content = $('#people').html();
$("#testbox").val(content);
});
with this
$("#people").click(function() {
var content = $('#people').html();
$("#testbox").val(content);
});
If I have understood your question right away then
$("#people").click(function(){
var content = $('#people').html();
$("#testbox").val(content);
});
should do the work. But I think you should use something like custom attribute instead of id as there can be only one id for a specific tag.

using the method onclick () to trigger a function that opens a window it grabs from the clicked button

<script language="JavaScript">
function goThere()
{
var the_url = window.document.form.button.value;
var good_url = fixURL(the_url);
var new_window = window.open(good_url,"new_window","menubar,resizeable");
}
function fixURL(the_url)
{
var the_first_seven = the_url.substring(0,7);
the_first_seven = the_first_seven.toLowerCase();
if (the_first_seven != 'http://')
{
the_url = "http://" + the_url;
}
return the_url;
}
</script>
</head>
<body>
<form name="the_form" onclick="goThere()"; return false;">
<input type="button" name="the_url" class="broadGroups" onClick="goThere()" value="http://en.wikipedia.org/wiki/Category:Sports"></input>
<input type="button" name="the_url" class="broadGroups" onclick="goThere()" value="http://en.wikipedia.org/wiki/Category:Film"></input>
</form>
</body>
</html>
So this code may be totally messed up, but here is what I am trying to do.
There are two buttons inside the tag. I want each to use the method onsubmit to trigger the function goThere(). How do I set it up so that the_url is set to a value that I pull from the button tag. I also want to be able to put non-url text on the button itself while allowing it to call goThere () through the method call onsubmit.
In the end it should just take the url, make sure it starts with http:// (in this case it doesnt matter because the user isn't inputting the url, but I'd like to keep it in for other purposes later on) and open it in a new window with a menubar and the resizable property.
Sorry for the long post. Any help would be greatly appreciated.
Pass in this in your goThere call. This will bring in the clicked element to your goThere function. Then you access the attributes for the clicked button.
http://jsfiddle.net/wJMgb/
onClick="goThere(this)"
function goThere(elem) {
var the_url = elem.value;
var good_url = fixURL(the_url);
var new_window = window.open(good_url, "new_window", "menubar,resizeable");
}
function fixURL(the_url) {
var the_first_seven = the_url.substring(0, 7);
the_first_seven = the_first_seven.toLowerCase();
if (the_first_seven != 'http://') {
the_url = "http://" + the_url;
}
return the_url;
}

jQuery get href initial value once before it changes

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.

Categories