Wordpress remove and replace posts with AJAX - javascript

I'm trying to delete and replace "article" tags by new one using as source a json array, but i'm always getting only the last element of the JSON array…
Here how look my html structure:
<main id="main" class="site-main" role="main">
<article >
<header class="entry-header">
TEST 1
test
<div>TAGS:dog</div>
</header>
</article>
<article >
<header class="entry-header">
TEST 2
test
<div>TAGS:cat</div>
</header>
</article>
</main>
and here is my javascript function, using jquery to remove and replace the previous posts with the new ones.
function get_posts($params){
var $container = $('#main');
var $content = $container.find('article');
var $status = $('.ajax_tag');
var counter = 0;
…
Jquery.ajax statement here
…
$.each(data,function(index, post){
//$content.children().remove();
$content.empty();
console.log(index);
//$content.replaceWith('<article>' + post.title + '</article>');
//console.log(data.length);
if ( counter != data.length ) {
console.log('before : ' + counter);
$content.append('<article>' + post.title + '</br>' + '</article>');
counter += 1;
console.log('after : ' + counter);
} else {
return false;
}
});
So from here it's not clear to me how I can perform that operation.
The only way i manage to have the full list of my array was using «.append()» but without «.empty()» which then append the array content to each «article» tags.
PS: i have look at the .each(), $.each(), .map(), $.map(), for and for…in all the example and explanation i found are using the CSS "li" tag which seems to have implicite iteration where the tags «article», «div», «span» doesn't.
Hope i'm clear enough, any input would be much appreciated.
Thanks!

I finally fixed my issue with this solution, basically i'm using the jQuery .remove() method instead of the .empty() one, and the it works perfectly.
$.each(data,function(index, post){
$content.remove();
$content.append('<article>' + post.title + '</br>' + '</article>');
});

Related

how to generate different html if the given object has no results

I am talking to WP REST API and if I do have results in data object I generate HTML code to frontend, and that is working fine, but what to do, and how to generate different HTML output (for example "There is no search result") if there is not data in data object.
I try with if statement but no luck with that. I am new to coding so forgive me if this is trivial problem...
var searchVal = this.inputField.val();
$.getJSON('http://localhost:8888/wptest/wp-json/wp/v2/posts?search=' + searchVal,
data => {
this.createHtml.html(`
<h2 class="search-overlay__section-title">Posts Info</h2>
<ul class="link-list min-list">
<li>${data[0].title.rendered}</li>
</ul>
`);
});
Your code should work if its as below:
var searchVal = this.inputField.val();
$.getJSON('http://localhost:8888/wptest/wp-json/wp/v2/posts?search=' + searchVal,
data => {
if (data.length == 0) {
// no results html
} else {
this.createHtml.html(`
<h2 class="search-overlay__section-title">Posts Info</h2>
<ul class="link-list min-list">
<li>${data[0].title.rendered}</li>
</ul>
`);
}
});
Hope this helps !!
Hello guys I did a little research and found a more concise solution, Ternary Operator... sorry if I didn't say it was ES6 syntax and I used a compiler to run regular javascript in the browser
var searchVal = this.inputField.val();
$.getJSON('http://localhost:8888/wptest/wp-json/wp/v2/posts?search=' + searchVal,
data => {
this.createHtml.html(`
<h2 class="search-overlay__section-title">Posts Info</h2>
${data.length == 0 ? '<p>No Results</p>' : '<ul class="link-list min-list">'}
${data.map(item => `<li>${item.title.rendered}</li>`).join('')}
${data.length == 0 ? '</ul>' : ''}
`);
});

Opening a div in a {{/if}} and closing it later with meteor/blaze

I'm trying to make something that is not possible in HTML/Blaze only.
By that I mean that I'm trying to open a div in a {{#if}} without closing it in this specific if. Impossible to do it the following way :
{{#each getData}}
{{#if equals this.level first}}
<div><p>content</p>
{{/if}}
{{#if equals this.level last}}
</div>
{{/if}}}
{{/each}}
So I found something that could solve this problem. Using triple curly braces and generate the HTML part in JS.
{{#each getData}}
{{{getContent this}}}
{{/each}}
getContent() return my HTML. It looks like this :
getContent(obj) {
if (obj.level == first)
return "<div><p>content</p>";
if (obj.level == last)
return "<p>content></div>";
else
return "<p>content</p>";
}
It works, it render the HTML, but there is one problem. The div I'm opening seems to close itself.
This is what's rendered :
<div><p>Content</p></div>
<p>content</p>
<p>content</p>
instead of :
<div><p>content</p>
<p>content</p>
<p>content</p>
</div
I'm really tired, I apologize if I'm not clear enough or if the solution is obvious.
EDIT: What I have now, and it's working fine, is the following :
HTML
{{#with getDataFromButton}}
{{formatData this}}
{{/with}}
JS
formatData(data) {
var res = "";
for (var i = 0; i < data.length; i++) {
if (data[i]["level"] == 0) {
if (res.length > 0)
res += "</div>";
res += "<div class=\"whiteBox\"><p>" + data[i]["value"] + "</p>";
}
else if ('last' in data[i]) {
res += "<p>" + data[i]["value"] + "</p></div>";
}
else {
res += "<p>" + data[i]["value"] + "</p>";
}
}
return res;
},
Thanks to all of you for the explanations ! And happy new year (it's not too late).
This is done because of browser try to fix HTML structure on any change. If you using Blaze, then HTML is rendered on the client side and in any evaluation of your helper code is injected to DOM. Then browser gets this HTML and tries to fix it.
Best solution is use simple pattern
<div>
{{#each getData}}
<p>content</p>
{{/each}}
</div>
If you want to apply the logic that you presented you have to prepare full correct HTML element in JS. You can to it as follow.
In template type: {{ myFullCorrectNodeElement }}
In JS type:
helpers: {
myFullCorrectNodeElement() {
let html = "";
const data = Template.instance().getData;
for(let i=0; i<data.length; i++) {
// your logic
if(i===0) {
html += `<div><p>content</p>`
// there you can access to variables by syntax ${}
// insde of ``, you can read about template strings from ES6
}
// ... and rest of your logic
}
return html;
}
}

Getting and setting attributes with Kendo sortable on change event

Would just like to get and set different attributes when a list item is moved to the other list on my mvc page... I can't access anything so far. The problem is in the javascript, it hits the onchange event fine. I didnt post the "available list" in the cshtml for brevity. this is what the console.log as the bottom reads:
SpecialNeedInActiveList change: Meds per tube newIndex: -1 oldIndex: 5 action: remove
SpecialNeedActiveList change: Meds per tube newIndex: 3 oldIndex: -1 action: receive
Any help would be appreciated, this has taken way too long for me.
HTML:
<div class="col-md-6" id="SpecialNeedContainerLL">
<ul id="SpecialNeedActiveList" class="col-md-6">
#if (Model.SelectedSpecialNeeds.Any())
{
foreach (var y in Model.SelectedSpecialNeeds)
{
<li class="list-item" selected-personspecialneed="#y.PersonSpecialNeedId" selected-need-type="#y.SpecialNeedTypeId"> #y.SpecialNeedDescription </li>
}
}
</ul>
</div>
#(Html.Kendo().Sortable()
.For("#SpecialNeedActiveList")
.ConnectWith("#SpecialNeedInActiveList")
.PlaceholderHandler("placeholder")
.Events(events => events.Change("onChange"))
)
Javascript:
function onChange(e) {
var id = e.sender.element.attr("id"),
text = e.item.text(),
newIndex = e.newIndex,
oldIndex = e.oldIndex;
if (id == 'SpecialNeedActiveList' && newIndex > -1) {
//add item to selected list
//remove item from availables list
/*NONE of the following works...*/
//var oldPersonSpecialNeedId = e.sender.element.getAttribute('available-personspecialneed');
//var oldSpecialNeedTypeId = e.sender.element.getAttribute('available-need-type');
//e.sender.element.removeAttribute('available-personspecialneed');
//e.sender.element.removeAttribute('available-need-type');
//e.sender.element.setAttribute('selected-personspecialneed', oldPersonSpecialNeedId);
//e.sender.element.setAttribute('selected-need-type', oldSpecialNeedTypeId);
}
console.log(id + " change: " + text + " newIndex: " + newIndex + " oldIndex: " + oldIndex + " action: " + e.action);
}
When you are in the change event handler(onChange()), e.sender.element is NOT the item that was dragged, it is the list that sent the change event, the <ul> element.
The item being drag/dropped is contained in the e.item field, which you should be able to manipulate as normal, for example using jQuery(but you may use whatever DOM manipulation technique you like):
var $item = $(e.item);
var oldPersonSpecialNeedId = $item.attr('selected-personspecialneed');
var oldSpecialNeedTypeId = $item.attr('selected-need-type');
$item.attr("selected-personspecialneed", "new" + oldPersonSpecialNeedId);
$item.attr("selected-need-type", "new" + oldSpecialNeedTypeId);
Here's a working example showing the attributes being changed:http://dojo.telerik.com/#Stephen/arUpO
It is based on single list from the code in your question rather than 2 lists but it simply demonstrates how to access the dragged element from the sortable change event, which is the core of your problem.
Having said that, I would probably investigate using a DataSource-bound list so that you can manipulate fields of a model instead of attributes of a DOM element. http://demos.telerik.com/aspnet-mvc/sortable/integration-listview is a good place to start.

How do you apply an item, from a list of results, to the parent Div tag for the current object?

I am trying to build a function for inserting the number of Facebook Likes into a Div tag. So far, I have a script that can get the URL from a Div tag which is inside of another Div tag called 'entry' and then have the .getJSON() method retrieve the number of Facebook likes for each entry.However, I can't get each retrieved value of Facebook Likes to insert into a Div tag for each entry. Please note, I simplified my code to where it alerts each Facebook Like value. This is what I have so far:
<div class="entry">
<div class="fburl">https://graph.facebook.com/zombies</div>
<div class="facebook-likes"></div>
</div>
<div class="entry">
<div class="fburl">https://graph.facebook.com/starwars</div>
<div class="facebook-likes"></div>
</div>
And here's my jQuery:
$(document).ready(function(){
$(".entry").each(function() {
var fbURL = $(this).find(".fburl").html();
$.getJSON(fbURL, function(fbData) {
var fbArr = fbData['likes'];
alert(fbArr);
});
});
});
​So what I am trying to do is iterate through each entry, get the Open Graph URL for it, retrieve the Likes value, and then insert it into the appropriate Div tag, so the code should render as:
<div class="entry">
<div class="fburl">https://graph.facebook.com/zombies</div>
<div class="facebook-likes">2,586 Likes</div>
</div>
<div class="entry">
<div class="fburl">https://graph.facebook.com/starwars</div>
<div class="facebook-likes">8,905,721 Likes</div>
</div>
​
​
$(document).ready(function() {
$('.entry').each(function() {
var $this = $(this),
fbURL = $this.children('.fburl').html();
$.getJSON(fbURL, function(fbData) {
$this.children('.facebook-likes').html(fbData['likes'] + ' Likes')
});
});
});
See: http://api.jquery.com/children
Demo: http://jsfiddle.net/9EALz/2/
Note: Using children() is going to be marginally more efficient than using find() as it limits the DOM traversal to a single level ( http://jsperf.com/find-vs-children/13 ). Cashing the jQuery object $(this) via var $this = $(this) is also slightly more efficient as it prevents unnecessary selector interpretation ( http://jsperf.com/jquery-cache-vs-no-chace ).
You may want this
$(document).ready(function(){
$(".entry").each(function() {
var entry=$(this), fbURL=$(".fburl", entry).html(),
el=$('.facebook-likes', entry);
$.getJSON(fbURL, function(fbData) {
el.html(numberWithCommas(fbData['likes'])+" Likes");
});
});
});​
A thousand separator function from here
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
DEMO.
Update:
Alternatively you can use this too (using data-attribute) without an extra div for fburl, i.e.
<div class="entry">
<div data-fburl="https://graph.facebook.com/zombies" class="facebook-likes"></div>
</div>
JS
$(".entry").each(function() {
var entry=$(this), fbURL = $(".facebook-likes", entry).attr('data-fburl'),
el=$('.facebook-likes', entry);
$.getJSON(fbURL, function(fbData) {
el.html(numberWithCommas(fbData['likes'])+" Likes");
});
});

HTML Node Map Generator?

Alright, what I'm looking for is something that could generate a graphical tree-style map of a web pages nodes.
So essentially it could theoretically transform something like this:
<aside id="leftCol">
<section class="container">
<header class="child1">
<hgroup>
<h1 class="title">Demo Project</h1>
<h3 class="subTitle">WEBSITE 2011</h3>
</hgroup>
</header>
<div class="child2" id="thisDiv">
<div class="subChild1">
<div class="anotherChild1"></div>
<div class="anotherChild2"></div>
<div class="anotherChild3"></div>
</div>
<div class="subChild2">
<p>Some Text</p>
</div>
</div>
<footer class="child3">
Link to project here
</footer>
</section>
</aside>
(This would of course be inside the HTML and BODY tags but for the sake of an example I'm going to use a snippet from my portfolio page with some generated text)
Into something like this:
Example http://www.deviantart.com/download/287437946/node_map_by_wild_fire126-d4r4sje.png
There's absolutely no design thought put into this so don't criticize it, purely for the example purpose. I made this image in photoshop quickly just to illustrate exactly what I'm talking about. All of this could be easily generated with CSS for the most part. It does not by any means have to be this graphical but for the sake of me being bored, it is.
I'm looking for a plugin or a piece of software that can do this for me. I would prefer that it would generate this map in HTML or as an image. I guess any map type would be okay as long as it would be easy to follow.
As a last resort if I can't find quite what I'm looking for I might end up just writing it myself, if that happens, I would be happy to be looking for some people to help with the coding of the plugin.
You could retrieve all children of a certain element and return their tag, class, id and depth. Then you can get creative with css to create a visual tree. Something like this should work. Example at http://jsfiddle.net/elclanrs/UHbMa/.
jQuery plugin:
$.fn.buildTree = function() {
var tree = {};
this.find('*').andSelf().each(function(i, v) {
var parents = $(this).parents().length - 1;
for (var i = 0; i < parents; i++) {
tree[v.tagName.toLowerCase()] = {
id: v.id,
className: v.className,
depth: i
}
}
});
return tree;
};
And then you call it like:
var tree= $('aside').buildTree(),
html = '';
for (tag in tree) {
html += '<p><strong>Tag:</strong> ' + tag +
' | <strong>Class:</strong> ' + tree[tag].className +
' | <strong>Depth:</strong> ' + tree[tag].depth;
}
$('#tree').append(html);
Graphviz is a nice tool for doing such a thing.
You could use a piece of Javascript to generate a Graphviz file and generate a png with the tool.
The javascript should recursively visit all Elements and Generate unique IDs for every Element and write them out in the fairly easy to understand Graphviz format.
Here's a Bookmarklet to convert a page to the Graphviz format.
javascript:void((function() {var f = function(pid, e) { var id = "id" + Math.round(Math.random()*1000000), c = e.childNodes, r = id+'[label="'+(e.tagName ? e.tagName : e.nodeValue.replace(/[\n\r]+/g," "))+'"];\n'; for(var i = 0; i < c.length; i++) { r+=f(id, c[i]); }; if(pid) {r += pid + "->" + id + ";\n";}; return r;}; document.body.innerText = "digraph {\n" + f(false, document.getElementsByTagName("html")[0]) + "}"})())
Here's a quick workthrough to the format: http://www.orient-lodge.com/node/3408
Then generate a png file: (example works under Unix)
dot -Tpng < graph.dot > g.png
There's a Javascript Renderer for Graphviz, too. Canviz I haven't tried it yet, but looks promising.

Categories

Resources