Custom Javascript not working in Wordpress - javascript

My intent is to add an excerpt to each portfolio card within a grid (currently, these only show an image, title and category).
I found a way to insert the excerpt into a card and to iterate through all the cards, but excerpt is not inserting into all of the cards even though the loop is working as expected (logging each iteration). The excerpt will only insert into one card if I specific a specific index of the targetsArray. I left this line commented out for reference.
window.onload = function() {
let targets = document.querySelectorAll('.entry-title');
let newElem = document.createElement('p');
let excerpt = 'This will be the excerpt...';
newElem.innerHTML = excerpt;
let targetsArray = [];
for (let i = 0; i < targets.length; i++) {
targetsArray.push(targets[i]);
}
targetsArray.forEach(target => {
console.log(target);
target.parentNode.insertBefore(newElem, target.nextSibling);
});
// targetsArray[1].parentNode.insertBefore(newElem, targetsArray[1].nextSibling);
};
Note: If you're wondering why I didn't use a simplier method for converting the nodes list into an array, it is because they weren't working.
I tried
const targets = [...document.querySelectorAll(".entry-title")];
and...
Array.from(targets)
For reference this is the page I'm trying to make these changes to
equipourkids.org

I don't know if you are trying to do it with pure JS for a specific reason but Wordpress already loads jQuery by default (if you didn't remove it) and doing that with jQuery should be much more simple then that.
let targets = $('.entry-title');
let newElem = $('<p>This will be the excerpt...</p>')
targets.each(function (idx, item){
$(item).parent().insertBefore(newElem);
});
I just don't understand where exactly you want to insert those exceprt based on your HTML structure. Should that be inside entry-info or what?

Related

How to create multiple todolists using a save button?

Below is a snippet of some of my code. Think a todo list on steriods. I am trying to create multiple Div elements that save to a page that contain a different list every time my "Save button is pressed. whats actually happening is that multiple divs are showing but the original div saved is the only one that gets updated with the list information(so like in a todo list when you click submit a new list item appears ive added a save button and an input field that the user can use to name their list and saves that list to a container but only one div gets updated). I know i'm almost there but ive been looking at this for a couple of hours now and cant quite figure it out. https://github.com/W33K5Y/TODO-PIRPLE
const saveButton = document.getElementById("submit-save");
const myLists = document.getElementById("my-lists");
const startNote = document.getElementById("start-note");
const listName = document.getElementById("new-list-name");
const myUl = document.getElementById("my-ul-lists");
// ! savebutton listener
saveButton.addEventListener("click", addNewTodo);
// ! make new html elements
const newTodoOl = document.createElement("ol");
const newTodoLi = document.createElement("li");
const listH1 = document.createElement("h4");
// ! =============== function for creating new todo ================================
function addNewTodo() {
const todoDiv = document.querySelector(".todo-container");
const todos = document.querySelectorAll(".todo-item");
todos.forEach(function(todo) {
createLi(todo);
});
listName.value ? listH1.innerText = listName.value : listH1.innerText = "My List";
newTodoDivWrap.classList.add("new-todo-div");
newTodoDivWrap.appendChild(listH1);
newTodoDivWrap.appendChild(newTodoOl);
myLists.appendChild(newTodoDivWrap);
todoReset(todoDiv, startNote);
startLoginSignUpNoneLobbyFlex();
}
// todo function to go in above that removes all of whats in the tido-container
function todoReset(div, lobbyDiv) {
lobbyDiv.remove();
div.firstElementChild.innerHTML = "";
}
function createLi(todo) {
// ! Create LI
const newTodo = document.createElement('li');
newTodo.innerText = todo.innerText;
newTodo.classList.add("todo-saved-item");
newTodoOl.appendChild(newTodo);
}
I think the following is why it's not working as you intended:
const newTodoOl = document.createElement("ol");
const newTodoLi = document.createElement("li");
const listH1 = document.createElement("h4");
Remember that javascript creates references, so when you do something like this—newTodoDivWrap.appendChild(listH1)—you don't add a new element, you only add a reference to said element.
It's the same as if you had two objects.
var a = {'name': 'Anette'}
var bbbb = a // creates a reference, not a new object.
bbbb.name = 'Bjorn'
console.log(a.name) // Bjorn
So create new elements inside the method, instead of creating and calling public ones.
Also, comments like this are so unnecessary:
function createLi(todo) {
// ! Create LI
You had a method name that perfectly explains what it does. You don't need to comment that. Start making it a habit of naming variables or method to explain what's going on—you're already doing that (ex. startLoginSignUpNoneLobbyFlex)—so you don't have to use comments. Comments are useless, unless it's for documentation.
You have to move
const newTodoOl = document.createElement("ol");
const newTodoLi = document.createElement("li");
const listH1 = document.createElement("h4");
into the addNewTodo function. That way each iteration produces a brand new List
Rickard pointed me in the right direction :)

How to use a same image multiple times by loading it only once when I need different id for every element

I am a newbie to programming and web developing. The project I am doing is only for practice, if my approach seems ameteur to you, please suggest any better options.
I am trying to develop a parking lot booking system. And in the UI, I want to show all the empty/filled slots (like it is while booking movies or bus tickets).
I couldn't find a top view icon of a car, so I thought of using an image instead of icon.
But as of the image, if I use say 50 images on a single page, the page will get very heavy.
But one important thing is that I need all the elements as seperate entities, only then I will be able to book them with their id(unique address). So I want 50 different divs with seperate distinct ids but want to use only one image for all the slots, or a maximum of 2 different images(keeping the directions in mind).
how to display same image multiple times using same image in javascript
I went through this answer, and found a piece of code that might be useful:
var imgSrc = 'http://lorempixel.com/100/100';
function generateImage() {
var img = document.createElement('img')
img.src = imgSrc;
return img;
}
for (var i = 0; i < 20; i++ ) {
document.body.appendChild(generateImage());
}
While I can make use of a function and a loop in javascript to create as many copies of one image, I don't know how to alot them to the different div tags with distinct ids.
use a function :)
const addMessage = (element, msg, cls) => {
const patt = new RegExp("<");
const messageElement = document.createElement("div");
if (patt.test(msg)) {
messageElement.innerHTML = msg
} else messageElement.textContent = msg;
if (cls) messageElement.classList.add(cls);
element.appendChild(messageElement);
}
const imgPath = "/somepath";
const body = document.querySelector("body");
addMessage(body, `<img src=${imgPath} class="whatever">`, "img1"); //creates new divs with classes. the 3rd arg is optional
the best approach for this is the client side already receiving all this content as a string but as it made clear that it is for study I deduce that it is not the intention to use back end to solve this problem
let allContent = '';
for (var i = 0; i < 20; i++ ) {
allContent += `<div class="wrapper-image"><img src="/path"></div>`
}
document.getElementById('idWrapper').innerHTML = allContent;
speaking in performace the browser will only download the image once, so you can use it as many times as you like, which is disruptive to the changes you make in the DOM (remove, add or edit a content)
In my example you create all the content to be displayed on the page and then add it in a single time, it is not too bad if it is performace but the ideal is to do it on the back side
in the DIV you can put an image address of a variable to do some logical type this:
let allContent = '';
let imgOne = '/oneimg';
let imgOne = '/twoImg';
for (var i = 0; i < 20; i++ ) {
if(i>10){
allContent += `<div class="wrapper-image"><img src="${imgOne}"></div>`
}else {
allContent += `<div class="wrapper-image"><img src="${twoImg}"></div>`
}
}
document.getElementById('idWrapper').innerHTML = allContent;

JavaScript and HTML element manipulation

Project Concept: Creating an "exam maker", which can be accessed by a teacher to create and let a student be able to access it to take. Many features would be included but to keep it simple on the question at hand i wont be including all info.
Front End: List all questions in the database, using a php file, to a select field in HTML. When the item is selected add it to the test. Display the test, and assign scoring to each question.
My Actual Question/Help: My addq() function is supposed to, get the value of selected item, append it on the global testArray=[]; while the for loop iterates through each one to display them individually after each one is added.
The Problem: What mine is displaying in HTML... it keeps adding the arrays so the output is repeated over and over after each addq(). Please help fix it! -- the array needs to be outside the function so I can access it later and send it off to a php file.
<h4><center>Test</center></h4>
<ol id="test">
</ol>
<script>
var testArray= [];
function addq(){
var addingquestion = document.getElementById('questionSelect').value;
var myArray = testArray.push(addingquestion);
var node = document.createElement("LI");
for(i=0;i<20;i++){
var textnode = document.createTextNode(testArray[i].toString());
node.appendChild(textnode);
document.getElementById("test").appendChild(node);
}
}
</script>
Example Output Issue Picture:
enter image description here
the problem is that you're appending the array every time to the node element. So, every time it will output the old values with the new ones
You don't have to make it as an array because it stacks without an array,
you just need to replace this :
var textnode = document.createTextNode(testArray[i].toString());
with this :
var textnode = document.createTextNode(addingquestion);
Here, you need to be creating you LI each time, it is an object.
var testArray = [1,2,3,4,5,6,7,8,9,10];
function addq() {
// REMOVED because not provided.
//let addingquestion = document.getElementById('questionSelect').value;
//let myArray = testArray.push(addingquestion);
let test = document.querySelector('#test');
testArray.forEach(t => {
// create new li for each item.
let li = document.createElement('li');
let textnode = document.createTextNode(t);
li.appendChild(textnode);
test.appendChild(li);
});
}
addq();
<h4>
<center>Test</center>
</h4>
<ol id="test">
</ol>

Checking if any class in an array is present on the current page and saving the matched class as a variable using jQuery

I am building a plugin for a CMS that has lots of different templates. As part of the plugin I am pulling text from a specific description box on the page. The problem is that every template has a different class name for the description box. I have gotten the plugin to work on a specific template that uses ".class1" but I would like to make it work no matter what template its installed on.
I basically want to put the class names from each template in an array and then check and see which one is on the page. I then want to store the matched class name in a variable that I can use.
This will loop through an array of classes and check to see if there are any elements matching each class on the page. The matched class names get pushed into a new array.
var classes = [".abc", ".def", ".ghi"];
var found = [];
for(var i = 0; i < classes.length; i++) {
if($(classes[i]).length > 0) {
found.push(classes[i]);
}
}
If you're certain that only one class in the initial list will be found, you can stop after your first hit:
var classes = [".abc", ".def", ".ghi"];
var found;
for(var i = 0; i < classes.length; i++) {
if($(classes[i]).length > 0) {
found = classes[i];
break;
}
}
You can use document.querySelector() to find the element with one of the classes.
Note that if you want to find more than one instance - document.querySelectorAll() will create a node list.As #Hydrothermal says - if there are multiple elements with that class - you will need to push them into an array and using an index [0] to identify them.
var templates = ["first-template", "second-template", "third-template"];
var currentTemplate;
templates.forEach(function(template){
let test = document.querySelector("." + template);
if(test !== null) {currentTemplate = template};
})
console.log(currentTemplate); // gives secondTemplate
<div class="second-template">I am a template</div>

How to get the next element of an array with Jquery onclick

Hi all i am trying to change the html of an object from an array of htmls. But i am having problem iterating properly. I managed to make it work once
EDIT
After a few complains about the clarity of my question I will rephrase it. I have a div panel called .trpanel and a button called #trigger2 (it is a next button). Then I have a series of divs with texts that contain translations. I want when I press the button (called next) to cycle through the translations one by one on the trpanel.
var ltranslation = [];
ltranslation[0] = $("#translation-en-1").html();
ltranslation[1] = $("#translation-ur-en").html();
ltranslation[2] = $("#translation-fr-en").html();
ltranslation[3] = $("#translation-it-en").html();
ltranslation[4] = $("#translation-sp-en").html();
ltranslation[5] = $("#translation-po-en").html();
ltranslation[6] = $("#translation-fr-en").html();
ltranslation[7] = $("#translation-de-en").html();
var l= ltranslation;
$("#trigger2").off('click').on('click',function(){
for (var i = 0; i <= ltranslation.length; i++){
if (i==7){i=0;}
$(".trpanel").html.ltranslation[i]; or ???//replace().ltranslation[]+i??? the code throws errors
}
});
I am quite new to Javascript and i am getting a bit confused with the types of objects and arrays and loops. I managed once to add the htmls but without replacing them ... so they all came one after the other. The i tried to change the code and it hasn't worked since. Any help will be greatly appreciated.
A lot of guessing, but seems like you are trying to do this :
var trans = $('[id^="translation-"]'),
idx = 0;
$("#trigger2").on('click',function(){
$(".trpanel").html( trans.eq(idx).html() );
idx = idx > 6 ? 0 : idx+1;
});
FIDDLE
I think you are trying to do this:
if (i == 7) {
i = 0; // I don't really know why you are doing this, but it will reset the loop
}
$(".trpanel").html(ltranslation[i]); //I'm passing ltranslation[i] to the html method. Instead of .html.ltranslation[i].
}
Also, without seeing any html, I'm not sure but I think you may want to iterate over .trpanel ?
Something like:
$(".trpanel").eq(i).html(ltranslation[i]);
Another thing (so you can make your code clearer I think). You can abstract the array population in a function, like this:
var ltranslation = [];
var languages = ["en-1", "ur-en", "fr-en", "it-en", "sp-en", "po-en", "fr-en", "de-en"];
$.each(languages, function(index) {
ltranslation[index] = $("#translation-" + this).html();
});
// Then you can use ltranslation
If you want to flip through several translations I would implement it that way:
var translations=["hej","hello", "hallo","hoy"];
var showTranslation=function(){
var current=0;
var len=translations.length;
return function(){
var direction=1;
if (current>=len) current=0;
$("#text").text(translations[current]);
current+=direction;
}
}();
$("#butt").on("click", showTranslation);
Fiddle: http://jsfiddle.net/Xr9fz/
Further: You should give your translations a class, so you could easily grab all of them with a single line:
$(".translation).each(function(index,value){ ltranslation.push(value); })
From the question : I managed once to add the htmls but without replacing them -
I think you want to add all of these items into $(".trpanel"). First, dont take the HTML of each element, clone the element itself :
//method ripped from Nico's answer.
var ltranslation = [];
var languages = ["en-1", "ur-en", "fr-en", "it-en", "sp-en", "po-en", "fr-en", "de-en"];
$.each(languages, function(index) {
ltranslation[index] = $("#translation-" + this).clone();
});
Then you could append everything into the container, so add the htmls but without replacing them. append takes in an array without replacing the previous html.
$("#trigger2").off('click').on('click',function() {
$(".trpanel").append(ltranslation);
});
I don't know what exactly you're tring to do, but I've put comments in your code to help you better understand what your code is doing. The net effect of your code is this (which I doubt you want) :
$("#trigger2").off('click').on('click',function(){
$(".trpanel").html(ltranslation[7]);
});
This is your code with some comments and minor changes
var ltranslation = [];
ltranslation[0] = $("#translation-en-1").html();
ltranslation[1] = $("#translation-ur-en").html();
ltranslation[2] = $("#translation-fr-en").html();
ltranslation[3] = $("#translation-it-en").html();
ltranslation[4] = $("#translation-sp-en").html();
ltranslation[5] = $("#translation-po-en").html();
ltranslation[6] = $("#translation-fr-en").html();
ltranslation[7] = $("#translation-de-en").html();
var l= ltranslation;
$("#trigger2").off('click').on('click',function(){
for (var i = 0; i < ltranslation.length; i++){
//if (i==7){i=0;} <-- This will cause an infinite loop won't it? are you trying to reset i? i will reset next time loop is called,
$(".trpanel").html(ltranslation[i]); //<-- this will overwrite elements with class .trpanel ltranslation.length times...
///you'll see only the value of translation[7] in the end
}
});
EDIT
To do what you want to do based on your comments, try this:
var ltranslation = [];
ltranslation[0] = $("#translation-en-1").html();
ltranslation[1] = $("#translation-ur-en").html();
ltranslation[2] = $("#translation-fr-en").html();
ltranslation[3] = $("#translation-it-en").html();
ltranslation[4] = $("#translation-sp-en").html();
ltranslation[5] = $("#translation-po-en").html();
ltranslation[6] = $("#translation-fr-en").html();
ltranslation[7] = $("#translation-de-en").html();
var counter = 0;//a global counter variable
$("#trigger2").click(function(){ //eeverytime button is clicked do this
$(".trpanel").html(ltranslation[counter]); //set the html to an element of array
counter++; //increment counter
if(counter==ltranslation.length) //reset the counter if its bigger than array len
counter=0;
});

Categories