Updating an Array with .innerHTML, issue when removing/adding - javascript

Trying to get my array to update onto the front end dynamically, when a user either adds/removes an item.
HTML/PHP for frontend below:
<div class="row">
<div class="col-12">
<div class="custom--css_pills">
<span class="tag filtering">Edit Products</span>
<span id="pills--container"></span>
</div>
<?php
$items = get_posts( array (
'post_type' => array('products'),
'posts_per_page' => -1
));
echo '<div class="enquire--surround_div">';
foreach($items as $item) {
echo '<input class="enquiry--add_chk" type="checkbox" value="'.$item->post_title.'" id="'.$item->post_title.'" />
<label for="'.$item->post_title.'">'.$item->post_title.'</label>';
}
echo '</div>';
?>
</div>
</div>
So far, I set my array
var pills = ["test","test2"];
Then setup a function which loops through this array and echos out a div, with the array item and a close icon
function looparray(){
var str = '';
pills.forEach(function(pill) {
str += '<div class="tag">'
str += '<span>' + pill + '</span>';
str += '<span class="tag-exit"></span>';
str += '</div>';
});
// Echo
document.getElementById("pills--container").innerHTML = str;
}
then call this function on load
looparray();
Then I have an onclick, for the radio buttons (Front end). Which will add to the array or remove depending if the checkbox is checked
$('.enquiry--add_chk').click(function(){
$valuetoaddcolour = $(this).next();
$valuetoaddcolour.toggleClass('enquiry--tabs_colour')
$valuetoadd = $(this).next().text();
if ( $(this).is(':checked')) {
console.log('notfilled');
pills.push($valuetoadd);
console.log(pills);
}
else{
pills.splice( $.inArray($valuetoadd, pills), 1 );
console.log(pills);
}
looparray();
});
And then an on close, to remove the selected from the array.
//On close..
$('.tag-exit').click(function() {
$valuetoremove = $(this).parent(); // Get parent to hide (surround div)
$valuetoremovetext = $(this).parent().text(); // Get text to remove from array
// remove from array
pills.splice( $.inArray($valuetoremovetext, pills), 1 );
$valuetoremove.hide(); // Hide the pill
looparray();
});
now the issue is, when I first select a remove, it will run fine. If i then add an item, then try to remove via the .tag exit, it doesn't run the function. I've narrowed it down to the looparray(); causing the issue, but can't see what the issue is. All i can think is it's wiping the data and re-adding, which may cause an issue with pre-defined functions?
I've put a little codepen together to give a better understanding.
https://codepen.io/anon/pen/QoQrZw

As #avraham said, this was due to the element not in the DOM.
Fixed by adding:
//On close..
$('body').on('click', '.tag-exit', function () {
// $('.tag-exit').click(function() {
$valuetoremove = $(this).parent(); // Get parent to hide (surround div)
$valuetoremovetext = $(this).parent().text(); // Get text to remove from array
// remove from array
pills.splice( $.inArray($valuetoremovetext, pills), 1 );
$valuetoremove.hide(); // Hide the pill
looparray();
});

Related

Have a list overflow into another column only when there's no room left

I have a dynamically created list that's added to a webpage whenever the user clicks a button. Sometimes the list is short, which is fine, but sometimes it's long and it flows off the bottom of the page. How do I make it so that any overflow will instead create a new column? (I don't want the columns to be even in length- I want the first column to be used for as much of the text as possible, and the next column only used when the first one runs out of room.)
You could reduce a list of items to a list of columns of items (array of arrays). Then use this to render the html:
var longList = [1,2,3,4,5,6,7,8,9,10,11];
var htmlList = function(list){
return "<ul>" +
list.map(
function(listItem){
return "<li>"+listItem+"</li>";
}
).join("")
+"</ul>"
}
var htmlColums = function(listOfList){
return listOfList.map(
function(list){
return "<div style='float:left'>" +
htmlList(list) +
"</div>";
}
).join("");
}
//takes a list of items and returns a list of list items
// list of columns
var toColumns = function(list,itemsInColumn){
return list.reduce(
function(acc,item){
if(acc.slice(-1)[0].length===itemsInColumn){
acc.push([])
}
acc.slice(-1)[0].push(item);
return acc;
}
,[[]]
)
};
document.getElementById("createContent").addEventListener(
"click",
function(e){
var itemsInColumn = parseInt(
document.getElementById("itemsInColumn").value
,10
);
if(isNaN(itemsInColumn)){
itemsInColumn=3;
}
document.getElementById("content").innerHTML = htmlColums(
toColumns(longList,itemsInColumn)
);
}
)
<input type="number" placeholder="Items in column" id="itemsInColumn">
<input type="button" value="render items" id="createContent">
<div id="content">

how do i capture which number <div> got clicked on inside my container <div> and store it in a variable

edit: my code is all held inside a $(document).ready(function() {} because of this, and because my html code is generated inside my javascript file on the fly, i am experiencing issues using .click() when applying the answer that was given to use
$('.movies_cell').click(function(){
var tmp = $(this).index();
});
original:
i have 20 div elements on a page with a class of .movies_cell that are all generated from an ajax file. All of the div's are created within container div called #movies.
any of the .movies_cell div's can be clicked to bring up a modal box, because i am going to place information from my json file in that modal depending on what gets clicked i need to know which div got clicked, for instance, if it was the 5th div i want to know that the 5th div was clicked and then store that number in a variable, if it was the 2nd, or 3rd i want that number to be stored in a variable and then clear when another .movies_cell div gets clicked.
how would i write a javascript or jquery script to accomplish this? :(
thanks!
$('#myMovies').click(function () {
$.getJSON('data/movies.json', function (allData) {
$.each(allData, function (i, field) {
$('#movies').append(function () {
var movies = '<div class="movies_cell">';
movies += '<div class="movies_image">';
movies += '<img src="img/movies/' + (field.image) + '" alt="' + (field.name) + ' Poster" style="width: 100%; height: 100%">';
movies += '</div>';
movies += '<div class="movies_detail">';
movies += '<h1>' + (field.name) + '</h1>';
movies += '<img src="img/rating/' + (field.myRating) + '.png" alt="movie rating" style="margin: auto;">';
movies += '</div>';
movies += '</div>';
counter++;
console.log(counter);
return movies;
});
});
});
});
Use event delegation.(https://api.jquery.com/on#direct-and-delegated-events) At the top
$('#movies').on( "click", ".movies_cell > div", function() {
var tmp = $(".movies_cell > div").index(this);
console.log(tmp);
});
then
$('#myMovies').click(function () {
//rest of code
Can you use .index() ? It is a zero-based index of the collection of items with, for example, class="movies_cell"
$('.movies_cell').click(function(){
var tmp = $(this).index();
});
jsFiddle Demo

javascript get all inputs inside div including select and textarea

I have been trying to figure out how to get all the input elements inside a div including select and textarea and pass them to editor, so far i figured out with input but i am just stuck with the rest.
Here is the code so far
function InsertShortcode(elem) {
var shortcodeName = elem.parentElement.id;
var inputs = document.getElementById(shortcodeName).getElementsByTagName('input'), i=0, e;
var inputs_val = '[' + shortcodeName;
while(e=inputs[i++]){
if(e.id){
inputs_val += ' ' + e.id + '="' + e.value + '"';
}
}
inputs_val += ']';
window.send_to_editor(inputs_val);
}
By this i am able to grab all the inputs inside a div where submit button is but still i am not sure how to grab textarea or select inputs.
The problem is that i have to make it dynamic. I will have many "shortcodes" and each will be in it's own div where the button is. But each will have it's own inputs which i can't control so i need to grab them all and send values to editor. Here's example of the code.
<div class="output-shortcodes">
<?php foreach( $theme_shortcodes as $key => $name ) { ?>
<div id="<?php echo $key ?>">
<p>
<h2><?php echo $name ?></h2>
</p>
<?php $form = $key . '_form';
if(function_exists($form)) {
$form(); // this is where the input fields are dynamically created on each shortcode.
}
?>
<button class="button-primary" onclick="InsertShortcode(this)">Insert shortcode</button>
</div>
<?php } ?>
</div>
Use jQuery and the :input pseudo selector:
$('.output-shortcodes').find(':input');
That simple.
https://api.jquery.com/input-selector/
Or wrap it in a <form>, then you can use:
document.getElementById("outputForm").elements...
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements
You can target your wrapper element and locate thru .find() all inputs within:
var inputs = $("#" + shortcodeName).find("select, textarea, input");
If you can use jQuery here is a fiddle: https://jsfiddle.net/q33hg0ar/
<div id="form">
<input type="text" name="input1" />
<select name="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<textarea name="notes"></textarea>
<button class="button-primary" onclick="InsertShortcode(this)">Insert shortcode</button>
</div>
<script>
$(document).ready(function() {
$('#form').find('input, select, textarea').each(function() {
console.log($(this).attr('name'));
});
});
</script>
And here it is w/o jQuery: https://jsfiddle.net/67pp3ggu/
window.onload = runIt();
function runIt() {
var elements = document.getElementById('form').childNodes;
var inputTypes = ['text', 'select-one', 'textarea'];
for (var i = 0; i < elements.length; i++) {
var elm = elements[i];
if (typeof elm.type !== 'undefined' && inputTypes.indexOf(elm.type)) {
console.log(elm);
console.log(elm.type);
}
}
}
At the end i switched to jQuery code completely and using :input helped me to resolve the problem.
Here is the complete code that i use now.
$('.vivid-framework-submit-shortcode').click(function(event) {
event.preventDefault();
var shortcodeName = $(this).closest('div').attr('id');
var inputs = $('#' + shortcodeName).find(':input');
var inputsVal = '[' + shortcodeName;
inputs.each(function() {
if($(this).attr('id') != 'content') {
inputsVal += ' ' + $(this).attr('id') + '="' + $(this).val() + '"';
console.log(inputsVal);
}
});
inputs.each(function() {
if($(this).attr('id') == 'content' ) {
inputsVal += ']' + $(this).val() + '[/' + shortcodeName;
}
});
inputsVal += ']';
window.send_to_editor(inputsVal);
});
What does it do? So now when i click on a button within shortcode div first using preventDefault to prevent page to scroll to top, next i grab the id of that div using it as shortcode name, and lastly i grab all the inputs and check if one of the inputs have id content because that will decide if shortcode is enclosed or selfclosed and loop through all inputs outputting their id's and values. and at the end return that to the editor.
Some of the terms may be unfamiliar but those who are familiar to WordPress will recognize terms like shortcode...
At the end final output is:
[bartag foo="value" bar="value"]content from textarea[/bartag]
If you downvote my questions or answers please explain why because i always tend to explain or ask as detailed as i can.

Add div selections if visible to get total at the end

I have a list of divs that pull integer values from a SQL table. All of those divs are not visible unless a certain selection is made in the form. I want to create another div that sum's all visible divs at the end for the user to see their ending total.
Edit: The below code is now what I have but it totals all divs not ones that are only visible.
$("#clicky").click(function () {
var total = 0;
$('.equipmentmprice').each(function() {
total += parseFloat($(this).find('span.price').eq(0).text());
});
$('#totalamount').text('Total is: $' + total);
});
I know I can use javascript or jquery but I'm not sure really where to start.
Here is an example of one of my divs:
<div class="largeplantablefive equipmentmprice" style="display:none">
<?php
$connection = mysql_connect('localhost', 'test', 'testone');
mysql_connect('localhost', 'test', 'testone');
mysql_select_db('test');
$queryone = mysql_query("SELECT price FROM pricing WHERE value = 'plantablefive'");
$query_row = mysql_fetch_array($queryone);
echo "Plan Tables: $" . ($query_row[price]) . "<span style='color:red'><i> Price does not include cost of the physical table.</i></span>";
?>
</div>
Right now I'm thinking I will have to create another div or other tag inside the echo statement where the value equals $query_row.
You can do this with jQuery...
var divCount = $("div :visible").length;
If you need to loop through them...
$("div :visible").each(function(index) {
console.log( index + ": " + $( this ).text() );
//etc.. etc..
});
Found the answer with some searching and using multiple suggestions combining it into my own. Below is what I did and the answer. Just added the :visible into the class select.
$("#clicky").click(function () {
var total = 0;
$('.equipmentmprice:visible').each(function() {
total += parseFloat($(this).find('span.price').eq(0).text());
});
$('#totalamount').text('Total is: $' + total);
});

How to add elements in span using javascript

I am having the drop down list by selecting the country sode the state drop down list populated dynamically using javascript
<div id="ddlState" class='selectBox'>
<span class='selected' id="StatesID">Select a State</span>
<span class='selectArrow'>&#9660</span>
<div class="selectOptions" id="stateSelectOption">
<span class="selectOption" id="ddlStateText" >Select a State</span>
</div>
</div>
on clicking country the state is populated for tht the code is below
$('#CountriesID').click(function () {
var items;
$('#CountriesID').removeClass("input-validation-error");
if (!$("select#CountriesID").val() == "Select a Country") {
document.getElementById("disableasterisk9").style.display = "";
}
else {
document.getElementById("disableasterisk9").style.display = "none";
}
var countryid = $('#CountriesID').text();
$.getJSON(
"#Url.Action("StateList1", "UserRegistration")" + '/' + countryid,
function (data) {
var items = "<span id='ddlStateText' class='selectOption'>Select a State </span>";
$.each(data, function (i, state) {
items += "<span id='ddlStateText' value='" + state.Value + "' class='selectOption'>" + state.Text + "</span>";
});
$('#stateSelectOption span').html(items);
}
);
});
the list is populated but the selection is not working properly it rendering all the state items in one span tag so for selecting any element all list get selected
I need that the individual element should get selected
What see in the code on this line is that you are adding your html inside the span, so just take away that:
$('#stateSelectOption span').html(items)
The line must look like this (it will insert the code inside the div and not the span):
$('#stateSelectOption').html(items)
I tested it on jsfiddle:
http://jsfiddle.net/uz2vf/

Categories

Resources