I have a list of elements, each one targeting a file like this:
<ul>
<li id="G367" class="list-group-item">
<button class="btn dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">2015-10-21-1445461638-8821023-ag_0666.jpeg</button>
(...)
<li id="G366" class="list-group-item btn btn-secondary">
(...)
</li>
</ul>
In dropdown actions I got for each a replace function which delete the file and replace it with a new one.
I thought of updating the row by replacing the contentText and also the id attribute of the row. Apparently it works but the DOM is not updated and keep tracking the old id.
Reading further, I've seen it's not recommended to change IDs. I don't understand why. How would one replace lines in this case?
Here is the js I use:
// Replace file
$(document).on('submit', '#replace-file', function (e) {
e.preventDefault();
let formData = new FormData(this);
$.ajax(
{
url: this.action,
type: 'post',
data: formData,
processData: false,
contentType: false,
}).done(function (resp) {
$('#' + resp.old_ref)[0].firstElementChild.textContent = resp.data;
$('#' + resp.old_ref).attr('id', resp.new_ref);
$('#form-modal').modal('toggle');
});
});
destroy the entire element and replace with a new one with correct id:
var li = $('#' + resp.old_ref);
li.closest("ul").append("<li id='" + resp.new_ref + "'>" + resp.data + "</li>");
li.remove();
You have to use innerHTML instead of textContent
Try this
$('#' + resp.old_ref)[0].firstElementChild.innerHTML= resp.data;
Related
I have this unslider which display tweets polled from some sources via Ajax which refreshes every 8 sec. The Unslider works fine for the first time but subsequently when new ajax queries are fired, it is supposed to clear the first tags and repopulate with new one. For some reason, it doesn't clear out the old tags and instead appends the new tags to the old.
Here are the screenshots:
var flag = false;
(function setTweets() {
$.ajax({
type: "GET",
url: "../tweets/get_latest_tweets",
success: function(data) {
//clear all children first
$('#tweets-list').children().remove();
for (var i = 0; i < data.length; i++) {
$('<li>' + data[i].text + '<div class="card-footer bg-twitter"><div class="card-profile-image"><img src="' + data[i].pic + '" class="rounded-circle img-border box-shadow-1" alt="Card Image"></div>' +
'<footer class="blockquote-footer bg-twitter white"><strong>#' + data[i].screen_name + '</strong></footer></div></li>').appendTo($('#tweets-list'))
}
if (!flag) {
$('#tweet-slider').unslider({ //initialize unslider only once
autoplay: true,
arrows: true,
speed: 1000,
delay: 7000,
});
flag = true;
}
},
error: function(err) {
console.log(err);
}
}).then(function() {
setTimeout(setTweets, 8000); //Todo: Check how to do this async (dynamic adding of points)
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card bg-twitter white">
<div class="card-content p-2">
<div class="card-body">
<div class="text-center mb-1">
<i class="ft-twitter font-large-3"></i>
</div>
<div class="tweet-slider" id="tweet-slider">
<ul id='tweets-list' class="text-center">
</ul>
</div>
</div>
</div>
Similar to .empty(), the .remove() method takes elements out of the DOM. Use .remove() when you want to remove the element itself, as well as everything inside it. In addition to the elements themselves, all bound events and jQuery data associated with the elements are removed. To remove the elements without removing data and events, use .detach() instead.
According to this, you are removing # tweets-list as an element, I think if you use .empty () you will clean it
uses $('#tweets-list').empty();
I was reading the unslider website and it says that if you delete or add slides you should use the method slider.unslider('calculateSlides');
var flag = false;
(function setTweets() {
$.ajax({
type: "GET",
url: "../tweets/get_latest_tweets",
success: function(data) {
//clear all children first
$('#tweets-list').children().remove();
for (var i = 0; i < data.length; i++) {
$('<li>' + data[i].text + '<div class="card-footer bg-twitter"><div class="card-profile-image"><img src="' + data[i].pic + '" class="rounded-circle img-border box-shadow-1" alt="Card Image"></div>' +
'<footer class="blockquote-footer bg-twitter white"><strong>#' + data[i].screen_name + '</strong></footer></div></li>').appendTo($('#tweets-list'))
}
if (!flag) {
$('#tweet-slider').unslider('calculateSlides');
flag = true;
}
},
error: function(err) {
console.log(err);
}
}).then(function() {
setTimeout(setTweets, 8000); //Todo: Check how to do this async (dynamic adding of points)
});
})();
apparently there is no need to reinitialize the unslider, try it but, you restart it
So here's whats going on, I have a couple scenarios where I can't seem to apply any styles to content coming from a get request, and on one of them I managed to be able to but it wouldn't be considered best practice.
Premise:
I have an empty Ul to which Li's will be attached from a GET request to an API.
Scenarios
1) I create DOM objects using JQuery and append LI <-- SPAN <-- string to the empty UL and then state that all the children of the UL will be colored green.
(this does not work & yes I could target the UL and have everything inherit the styles but that wont work for what I have in mind)
2) I append a string which contains HTML markup within it to then add styles and concat them with what the GET request spits out. ( for some reason it seems to work this way but I really don't want to be creating LI's and SPANS + classes all in one string)
//scenario 1
var $orders = $("#orders");
$.ajax({
type: 'GET',
url: 'http://rest.learncode.academy/api/johnbob/friends',
success: function (data) {
$.each(data, function (i, item) {
if (item.name && item.drink) {
var $spn = $("<span></span>");
var $lli = $("<li></li>");
// $spn.append(String(item.name));
$spn.css({width: "20px"});
$orders.append($lli).append($spn).append("name: "+item.name+", Order: " + item.drink);
$orders.children().css({ color: "green" });
console.log($spn);
}
})
}
});
/* scenario 2
var $orders = $("#orders");
$.ajax({
type: 'GET',
url: 'http://rest.learncode.academy/api/johnbob/friends',
success: function (data) {
$.each(data, function (i, item) {
if (item.name && item.drink) {
var $spn = $("<span>hell</span>");
var $lli = $("<li></li>")
// $spn.append(String(item.name));
$spn.css({width: "20px"});
$orders.append("<li>Name: <span class='tato'>" + item.name + ",</span> Order: " + item.drink + "</li>");
$orders.children().css({ color: "green" });
console.log($spn);
}
})
}
});
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Coffee Orders</h2>
<br />
<ul id="orders">
<li>control group</li>
</ul>
<br />
<h4>Add a coffee order</h4>
<p>name: <input type="text" id="name"></p>
<p>drink: <input type="text" id="drink"></p>
<button id="add_order">Add!</button>
I haven't been able to find a reliable answer as to why this is happening, eventually I'll want to line up the orders regardless of the name length using a span.
edit:
What was happening (as stated in the answer) was I was appending empty LI's SPANs and Strings to the original UL. When using append() keep in mind anything you add (in a chain form) will be appended to the original stated element and not the previous one.
Side note:
For more information on better practice of templating incoming GET stuff check out this vid I found.
https://www.youtube.com/watch?v=GbNWPn8vodo&index=9&list=PLoYCgNOIyGABdI2V8I_SWo22tFpgh2s6_
As noted by #Taplar the issue is use of .append(). You are appending <span> elements and #text nodes to <ul> at
$orders.append($lli).append($spn).append("name: "+item.name+", Order: " + item.drink);
which are not valid child elements of <ul>
Permitted content zero or more <li> elements, which in turn often
contain nested <ol> or <ul> elements.
To correct issue, set #text node as .innerHTML of <span> element, and span element as .innerHTML of <li> element using html of jQuery(html, attributes) function attributes property.
Also set span css display property to block for width property to be applied to the element.
//scenario 1
var $orders = $("#orders");
$.ajax({
type: 'GET',
url: 'http://rest.learncode.academy/api/johnbob/friends',
success: function(data) {
$.each(data, function(i, item) {
if (item.name && item.drink) {
var $spn = $("<span></span>", {
html: "name: "
+ item.name
+ ", Order: "
+ item.drink,
css: {
width: "20px",
display: "block",
position: "relative"
}
});
var $lli = $("<li></li>", {
html: $spn
});
$orders.append($lli)
.children().css("color", "green");
}
})
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Coffee Orders</h2>
<br />
<ul id="orders">
<li>control group</li>
</ul>
<br />
<h4>Add a coffee order</h4>
<p>name:
<input type="text" id="name">
</p>
<p>drink:
<input type="text" id="drink">
</p>
<button id="add_order">Add!</button>
i have one question about jquery on click.
This is DEMO from jsfiddle.net
When you click the demo you can see there is a green and yellwo div.
The question is when you click the data-id="1" and change this div class:
<div class="icon-kr icon-globe"></div>
change icon-globe to icon-contacs
and when you click data-id="2" then change:
change icon-globe to icon-lock-1
also same think is for data-id="0"
How can i do that anyone can help me in this regard ?
HTML
<div class="container" id="1">
<div class="icon_ar"><div class="icon-kr icon-globe"></div>1</div>
<div class="pr_type">
<div class="type_s change_pri" data-id="0"><div class="icon-pr icon-globe"></div>1</div>
<div class="type_s change_pri" data-id="1"><div class="icon-pr icon-contacs"></div>2</div>
<div class="type_s change_pri" data-id="2"><div class="icon-pr icon-lock-1"></div>3</div>
</div>
</div>
JS
$('.change_pri').click(function(){
var dataid = $(this).attr('data-id');
var id = $(this).closest('.container').attr('id');
$.ajax({
type: "POST",
url: "chage_number.php",
data: { dataid : dataid, id: id }
}).success(function(result){
alert(result);
});
});
One way to do this is below. I have only done the class changing bit based on click. I am not sure about your ajax code. Let me know if you need further help.
$('.change_pri').click(function(){
var class_name = $(this).find(".icon-pr").attr("class");
class_name = class_name.replace(/icon\-pr\s+/gi, "");
$(this).closest(".container").find(".icon-kr")
.removeClass().addClass("icon-kr " + class_name);
});
Updated fiddle
You need to use .data(), you are not accessing the data correctly.
https://api.jquery.com/jquery.data/
var dataid = $(this).data('id');
You are accessing this data-* attribute incorrectly,
Use this,
$('.change_pri').click(function(){
var dataid = $(this).data('id');
$(this).parent().siblings('.icon_ar').find('div').removeClass("icon-globe icon-contacs icon-lock-1");
if(dataid=="0")
{
$(this).parent().siblings('.icon_ar').find('div').addClass("icon-globe");
}
else if(dataid==1)
{
$(this).parent().siblings('.icon_ar').find('div').addClass("icon-contacs");
}
else
{
$(this).parent().siblings('.icon_ar').find('div').addClass("icon-lock-1");
}
//AJAX CODE.
});
I`m kind of novice in jquery and want to make a sliding table.
The orinal table has 3 levels:
<ul class="categories">
<li id="category1">1 element</li> //parentid=0
<li id="category2">2 element</li> //parentid=0
<ul>
<li id="category3">1 element of element id2</li> //parentid=2
<ul>
<li id="category4">1 element id3</li> //parentid=3
</ul>
</li>
</ul>
</li>
</ul>
The first level elements have parentid = 0, id=1++, the next level have nested parentid and there own id and so on.
Page loads with only 1 level with parentid = 0.
<ul class="categories">
<li id="category1">1 element</li> //parentid=0
<li id="category2">2 element</li> //parentid=0
</ul>
Then I want to click the li, take id ID - go to file, execute mysql, get the new table in variable, bring it back and slideToggle it under LI.
php side
if(isset($_POST['subcategory'])){
$subcategory = str_replace('category', '', $_POST['subcategory']);
echo build_category_tree($subcategory); // builds the UL tree
}
this returns me id, i need to return the list and toggle it.
NOW the new UL is connected BUT i jquery cant work with it, updated the script with the one below but still cant.
UPDATED JQuery
$(".tablecategoryname").on('click', function(){
var $a = $(this).closest('li').attr('id');
var $c = $(this).closest('li');
$.ajax({
type: "POST",
url: "functions.php",
data: {subcategory:$a},
cache: false,
success: function(data)
{
$(data).hide().insertAfter($c).slideDown(400);
}
});
});
ID's should not contain just a number (or start with a number), you should probably use #a1 or something similar. In the data parameter you're sending an object, and equalsigns does'nt really work.
$(".table li").on('click', function(){
var self = this;
$.ajax({
type: "POST",
url: "functions.php",
data: {id : self.id},
cache: false
}).done(function(data) {
//guessing you're returning valid HTML
$(data).hide().insertAfter(self).slideDown(400);
});
});
EDIT:
Your build_category_tree() function needs to return the HTML so you can echo it back to the ajax request:
if(isset($_POST['subcategory'])){
echo $subcategory = str_replace('category', '', $_POST['subcategory']);
$ULtree = build_category_tree($subcategory); // builds the UL tree
echo $ULtree; //echo back to Ajax
}
You should put an id in your main ul to catch his parent and them toggle the list inside the main ul.
$("ul.umenu > li).click(function (e) {
e.preventDefault();
var element = $(this);
if (element.parent().find("ul").is(":visible")) {
} else {
$("ul.umain> li > ul").slideUp();
element.parent().find("ul").slideToggle("fast");
}
});
I am working on a project, i have two anchors in my View(for voting functionality),
I have a div inside which i am having a <ul> and in 3 <li> i am having anchor for upvote,vote count (in <h2>) and anchor downvote respectively
I want functionality that when i click on any anchor, the h2 html show the vote count, i've implemented the functionality but because of i am unable to do this,
this is my View
<div class="voting" style="margin-left:20px;">
<ul>
<li class="addvote"><a href="#" class="voteAnswer" answerid="#answer.AnswerID" name="Voted">
Up</a></li>
<li class="votecounter">
<h2>
#answer.AnswerLikes.Where(a => a.IsActive == true).Count()</h2>
</li>
<li class="subvote"><a href="#" class="voteAnswer" answerid="#answer.AnswerID" name="Voted">
Down</a></li>
</ul>
</div>
and this is my JS
$(".voteAnswer").click(function (event) {
var answerid = $(this).attr('answerid');
var name = $(this).attr('name');
var id = $(this).attr('id');
var output = $(this);
$.ajax({
url: ResourceAjaxUrl.VoteUnvoteTheAnswer,
type: "POST",
data: JSON.stringify({ answerID: answerid }),
dataType: "html",
contentType: "application/json; charset-utf-8",
success: function (Result) {
alert("Voted");
// $(output).html("Voted (" + Result + ")");
$(output).closest("li").find("h2").html(Result);
$(output).attr("name", "Voted");
},
error: function (msg) {
alert("Unable to Vote answer: " + msg);
}
});
event.preventDefault();
});
i have tried using $(output).closest("li").find(".votecounter") but its still not working
The UL is the closest common ancestor.
Try:
$(output).closest("UL").find(".votecounter")
there are some problems in your code .
here
$(".voteAnswer").click(function (event) {
var id = $(this).attr('id');
there is no attribute id in .voteAnswer
and also how do you differentiate upvote and downvote .
you have to check the anchor's parent li tag's class and check it is upvote or down vote .
also you can select the .votecounter
simply by
$(".votecounter").find("h2").html(Result);
or
$(output).closest("ul").find(".votecounter");