How to remove attribute found within a variable? - javascript

I have
var $imageSelected = '<div style="position: absolute"><span>hello</span></div>';
I need to remove the style attribute form the created variable
I tried:
$imageSelected + "*").removeAttr("style");
and
$imageSelected).find("*").removeAttr("style");
Full code with added replace functionality as per first answer:
$(".grid-item").on("click", function() {
var $imageSelected = $(this).prop('outerHTML');
var $paste = $imageSelected.replace(/style.+"/, '');
$('#usp-custom-4').val(function(_, currentValue) {
return currentValue + $paste
});
});
Using $imageSelected).removeAttr("style"); doesn't work and by using the code above it does remove style yet it is pasting many times the code into the text area, not this clicked only
$('#usp-custom-4') is the textarea id

Clone, remove attr, select the html
$(".grid-item").on("click", function() {
var $imageSelected = $(this).clone().removeAttr("style"),
code = $("<div></div>").append($imageSelected).html();
//code = $imageSelected.prop('outerHTML');
$('#usp-custom-4').val(function(_, currentValue) {
return currentValue + code
});
});
div {
padding: 1em; border: 1px solid black; margin: .5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid-item" style="display:block;">1</div>
<div class="grid-item" style="display:block;">2</div>
<div class="grid-item" style="display:block;">3</div>
<div class="grid-item" style="display:block;">4</div>
<textarea id="usp-custom-4"></textarea>

You can use e.g. replace function.
var $myValue = '<div style="position: absolute"><span>hello</span></div>';
$myValue = $myValue.replace(/ style.+"/, '');
console.log($myValue);

Related

How can i simplify this? (noob here)

i got this very long block and i think that it can be simplify but i dont know how to do it
const one = document.getElementById("one");
const two = document.getElementById("two");
const three = document.getElementById("three");
const four = document.getElementById("four");
one.onclick = () => {
one.innerHTML = "";
};
two.onclick = () => {
two.innerHTML = "";
};
three.onclick = () => {
three.innerHTML = "";
};
four.onclick = () => {
four.innerHTML = "";
};
I agree with Alex, using a class on the elements you wish to run the logic on makes more sense. For example:
const elements = document.querySelectorAll('.js-clear-on-click');
elements.forEach(el => el.addEventListener('click', event => {
el.textContent = '';
}));
Now you can reuse this functionality by just adding the class 'js-clear-on-click' on the DOM-element, so there will be no need to go back to your js-code and update it with 'five' for example.
Edit: If you wish to clear the element of all inner HTML, replace .textContent = ''; with .innerHTML = '';
You can create an array of id and use forEach on that and add event listeners dynamically
['one', 'two', 'three', 'four'].forEach(x => {
const element = document.getElementById(x);
element.onclick = function(){
element.innerHTML = '';
}
})
Or you can put 1 class for all elements, and use document.getElementsByClassName().
let eles = document.getElementsByClassName('yourClass');
for (let i = 0; i < eles.length; i++) {
eles[i].onclick = function () {
eles[i].innerHTML = '';
}
}
May be this way ?
['one','two','three','four']
.forEach(el=>document.getElementById(el)
.onclick=e=>e.target.textContent='');
proof:
['one','two','three','four']
.forEach(el=>document.getElementById(el)
.onclick=e=>e.target.textContent='');
div {
display: block;
width: 3em;
height:1.3em;
border: 1px solid grey;
margin: .7em 1em;
padding: .3em;
}
<div id="one" contenteditable >div 1</div>
<div id="two" contenteditable >div 2</div>
<div id="three" contenteditable >div 3</div>
<div id="four" contenteditable >div 4</div>
or if All elements have the same class (named "clearOnClick" here on snippet)
document.querySelectorAll('.clearOnClick')
.forEach(el=>el.onclick=e=>e.target.textContent='');
proof:
document.querySelectorAll('.clearOnClick')
.forEach(el=>el.onclick=e=>e.target.textContent='');
.clearOnClick {
display: block;
width: 3em;
height:1.3em;
border: 1px solid grey;
margin: .7em 1em;
padding: .3em;
}
<div id="one" contenteditable class="clearOnClick">div 1</div>
<div id="two" contenteditable class="clearOnClick">div 2</div>
<div id="three" contenteditable class="clearOnClick">div 3</div>
<div id="four" contenteditable class="clearOnClick">div 4</div>

jQuery Select Visible Elements After Append

I'm trying to select visible children after appending them into a temp div.
But I got undefined. I've prepared a pen here: codepen
function createTemp() {
var innerObj = $('.main');
var el = $('<div class="doc-temp" style="display: none;"><div class="temp2">' + innerObj.html() + '</div></div>');
$('body').append(el);
var visible = el.children(':visible');
return visible;
}
console.log(createTemp().html());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<span>Well</span> Hello
<span>Three</span> Hi Hello
<span style="display: none;">Four</span>
<span>Five</span> See you
</div>
If your element is hidden it will NOT have ANY :visible descendants!
Also you need the HTML of main
If you want the children that WOULD be visible if the PARENT was, you can do this:
function createTemp() {
var innerObj = $('.main').html();
var el = $('<div class="doc-temp"><div class="temp2"></div></div>');
$("body").append(el);
$(".temp2").append(innerObj);
var children = $(".temp2")[0].childNodes;
return [...children].map(el => {
if (el.getAttribute) {
return el.getAttribute("style") === "display: none;" ? null : el.outerHTML
}
return el === null ? null : el.textContent;
})
}
$("#ta").val(createTemp().join(""));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<span>Well</span> Hello
<span>Three</span> Hi Hello
<span style="display: none;">Four</span>
<span>Five</span> See you
</div>
<textarea rows="100" cols="100" id="ta"></textarea>
Modify your function to below:
function createTemp(){
var innerObj = $('.main');
var el = '<div class="doc-temp" style="display: none;"><div class="temp2">' + innerObj.html() + '</div></div>';
$('body').append(el);
var visible = $('.main').find(':visible');
return visible;
}
After this change, you can iterate through the visible array. Use $.each for this iteration process.

JS add +10 then sort DIV

GOAL script returns 20,13,12,11
Hi I am trying to make these two operations into a single operation on Load.
when loaded the page returns 3,2,10,1
so I have added a button to trigger a +10 function.
which returns 13,12,20,11
Both these functions work independently, however i need the the entire thing to work together so that it returns 20,13,12,11 on load
I don't want any buttons>>>>
<script src="js/jquery-1.4.1.min.js"></script>
<!--CSS-->
<style type="text/css">
.box {
border: 1px solid #000;
padding: 2px;
margin: 2px;
}
</style>
<!--JAVASCRIPT-->
<!-- (A) ADDS +10 to div No-->
<script type='text/javascript'>
$(document).ready(function(){
$("#increase").click(function(event){
$("div.box").each(function(idx,elem){
$(this).text( parseInt($(this).text(),10) +10 );
});
return false;
});
});
</script>
<div id="containerSort">
<!-- (B) SORTS div -->
<script type='text/javascript'>
$(function(){
var $divs = $("div.box");
$( "#numBnt" ).one("load", function() {
console.log('loaded')
var numericallyOrderedDivs = $divs.sort(function (a, b) {
return $(a).find("h7").text() < $(b).find("h7").text();
});
$("#containerSort").html(numericallyOrderedDivs);
});
});
</script>
<!--HTML-->
<div class="box"><h7>1</h7></div>
<div class="box"><h7>2</h7></div>
<div class="box"><h7>3</h7></div>
<div class="box"><h7>10</h7></div>
<img src="http://myscot.com/ImagesMain/myscotLogoResp120.jpg" id="numBnt"/>
</div>
<button id="increase">+10</button>
window.addEventListener("load", function(){...}) how would I combine the 2 functions to the event listener?
There are 2 ways to solve your problem
Call button's click event on page load.
Create a function which will wrap everything and assign it as eventListener.
Note:
$(function(){}) is a short hand for $(document).ready() and its a bad practice to have multiple document.ready functions.
H7 is not a valid header tag as mentioned by #Niet the Dark Absol. Browser might consider it as a custom element and process similar to span tag. (This is just a guess).
Below code:
$("div.box").each(function(idx, elem) {
$(this).text(parseInt($(this).text(), 10) + 10);
});
this will make multiple DOM operation. Its bad practice to manipulate DOM in a loop.
Following is a sample code. Also I have updated your code a bit.
JSFiddle.
$(document).ready(function() {
$("#increase").trigger("click");
});
$("#increase").click(function() {
var valArr = getValues();
valArr = addNumber(valArr);
valArr = sortValues(valArr);
createAndRenderHTML(valArr, "#containerSort");
});
function getValues() {
var returnArray = [];
$("div.box").each(function(id, el) {
returnArray.push(parseInt($(el).text(), 10));
});
return returnArray;
}
function addNumber(arr) {
return arr.map(function(item) {
return parseInt(item, 10) + 10;
});
}
function sortValues(arr) {
return arr.sort(function(a, b) {
return a > b ? -1 : a < b ? 1 : 0
});
}
function createAndRenderHTML(arr, el) {
var _html = arr.map(function(item) {
return "<div class='box'> <h7>" + item + "</h7></div>"
}).join("");
$(el).html(_html);
}
.box {
border: 1px solid #000;
padding: 2px;
margin: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
<div id="containerSort">
<!--HTML-->
<div class="box">
<h7>1</h7>
</div>
<div class="box">
<h7>2</h7>
</div>
<div class="box">
<h7>3</h7>
</div>
<div class="box">
<h7>10</h7>
</div>
<img src="http://myscot.com/ImagesMain/myscotLogoResp120.jpg" id="numBnt" />
</div>
<button id="increase">+10</button>

Custom html tab implementation problems

my use case : create tab like experience. clicking on add button creates a (horz tab button) and a corresponding div, which is linked via onclick listener, dynamically.
problems :
on clicking add button, values from previous tabs are reset (which is obvious wrt to the way $tabs_prev & $menu_prev is populated) and
their respective js goes away (which I can't understand, why?)
a remove tab implementation (because the way I've coded these tabs, removing a tab and corresponding div isn't really simple, so, any clues in this direction, maybe?)
code : fiddle : http://jsfiddle.net/g58fzs75/1/
HTML:
<body>
<input id="hidden" type="hidden" value="1"></input>
<div id="template_tabBtn" style="display:none">
<input type="button" value="add" onclick="addTab()"></input>
</div>
<ul id="menu">
</ul>
<div id="tabs">
</div>
<div id="template_tabBar" style="display:none">
<li>
<input type="button" id="tab_btn" class="template_tabBar" value="Tab" onclick="tabClick(this)"></input>
</li>
</div>
<div id="template_tabs" style="display:none">
<div id="tabs" class="template_tabs tab_div" value="1">
<input type="text" id="txt" class="template_tabs" value="alert"></input>
<input type="button" id="btn" class="template_tabs" value="alert"></input>
</div>
</div>
</body>
CSS:
<style>
ul#menu {
padding: 0;
}
ul#menu li {
display: inline;
}
ul#menu li input {
background-color: black;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 4px 4px 0 0;
}
ul#menu li input:hover {
background-color: orange;
}
</style>
jQuery :
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script>
$tabs_prev = "";
$menu_prev = "";
$add_btn = "";
$current_tabID = "";
function tabClick(id) {
showCurrent($(id).attr('id'));
}
function addTab() {
var tabCount = parseInt($('#hidden').val()) + 1;
$('#hidden').val(tabCount);
run(tabCount);
showCurrent($('#tabs-' + tabCount).attr('id'));
}
$(document).ready(function() {
$add_btn = "<li>" + $('#template_tabBtn').html() + "</li>";
run(1);
});
function run(tabCount) {
//$tabs_prev += main($('#template_tabs'),tabCount);//alert("tabs\n"+$tabs_prev);
$menu_prev += main($('#template_tabBar'), tabCount); //alert("menu\n"+$menu_prev);
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
$('#menu').html($menu_prev + $add_btn);
logic(tabCount);
}
function main(target, tabCount) {
$htmlBackup = $(target).html();
$('.' + $(target).attr('id')).each(function() {
$(this).attr('id', $(this).attr('id') + "-" + tabCount).removeClass($(target).attr('id'));
$(this).attr('value', $(this).attr('value') + "-" + tabCount);
});
$html = $(target).html();
$(target).html($htmlBackup);
return $html;
}
function logic(tabCount) {
$('#btn-' + tabCount).click(function() {
alert($('#txt-' + tabCount).val());
});
}
function showCurrent(current_id) {
$('.tab_div').each(function() {
var id = $(this).attr('id');
var id_num = id.substr(id.lastIndexOf('-') + 1, id.length);
var current_id_num = current_id.substr(current_id.lastIndexOf('-') + 1, current_id.length);
if (id_num == current_id_num) {
$("#tabs-" + id_num).show();
$('#tab_btn-' + id_num).css({
"background-color": "orange"
});
} else {
$("#tabs-" + id_num).hide();
$('#tab_btn-' + id_num).css({
"background-color": "black"
});
}
});
}
</script>
The reason why your javascript is disappearing is because resetting the innerHTML deletes the onclick handlers on the elements. Why: the original elements are destroyed, including references to events and new elements are created.
The code responsible for this:
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
Please use jQuery's appending of an element by cloning the template tab:
$('#tabs').append($('#template_tabs').clone(true));
Append appends htmlstrings or elements to an parent element. It's a buffed up version of the documents native 'appendChild'.
clone clone the template element (makes a copy). You can do this in your function main and return it to the append function.
function main(tabCount)
{
var node = $('#template_tabs').clone(true));
//do things with the node, like setting an onclick handler, or id.
//example
node.setAttribute("id", "tab" + tabCount);
}
Removing can be done also:
function removeNode(node)
{
//provide a node via jQuery
//example: removeNode($("#tab2")) <-- now tab2 will be removed from the DOM.
node.remove();
}

Trouble using JavaScript for loop to populate an array with HTML divs

I'm trying to populate the contents of an array with the HTML from 5 different div elements using a loop. I can't get the for loop to work correctly. Any ideas?
The HTML:
<div id="person0">John</div>
<div id="person1">Kathleen</div>
<div id="person2">Cynthia</div>
<div id="person3">Eric</div>
<div id="person4">Jay</div>
<div style="width: 600px; margin: auto; padding: 15px; border: 1px solid gray; font-family: sans-serif;">
<h1>The People</h1>
<div id="result"></div>
</div>
The Javascript:
function pageLoaded(){
var list = "<ul>";
var myArray = new Array();
for(i=0; i<6; i++){
var person = "person";
var personNumber = "" + i.toString();
var divId = person.concat(personNumber);
myArray[i] = document.getElementById(divId).innerHTML;
list +="<li>"+myArray[i]+"</li>";
}
list +="</ul>";
document.getElementById("result").innerHTML=list;
}
Just change the for condition from i<6 to i<5.
You were running the loop one too many times, which meant on the sixth iteration when you did:
myArray[i] = document.getElementById(divId).innerHTML;
You were looking for an element with id of "person5", so getElementById() returned null which gave the error:
Uncaught TypeError: Cannot read property 'innerHTML' of null
...which stopped your script from completing.
Demo: http://jsbin.com/awubeq/1/edit
Here's a working solution (plus some alerts):
<html>
<head>
<title>Test</title>
<script>
function pageLoaded()
{
alert("called pageLoaded");
var list = "<ul>";
var myArray = new Array();
for(i=0; i<5; i++){
var person = "person";
var personNumber = "" + i.toString();
var divId = person.concat(personNumber);
myArray[i] = document.getElementById(divId).innerHTML;
alert("myArray[i]=" + myArray[i]);
list +="<li>"+myArray[i]+"</li>";
}
list +="</ul>";
alert(list);
document.getElementById("result").innerHTML=list;
}
</script>
</head>
<body onload="pageLoaded()">
<div id="person0">John</div>
<div id="person1">Kathleen</div>
<div id="person2">Cynthia</div>
<div id="person3">Eric</div>
<div id="person4">Jay</div>
<div style="width: 600px; margin: auto; padding: 15px; border: 1px solid gray; font-family: sans-serif;">
<h1>The People</h1>
<div id="result"></div>
</div>
</body>
</html>
If you use an iterator, you don't have to worry about knowing the size of the target of iteration.
document.getElementById('result').innerHTML =
Array.prototype.reduce.call(document.querySelectorAll('[id^=person]'),
function (prev, elem) {
return prev + '<li>' + elem.innerHTML + '</li>';
}, '<ul>') + '</ul>';
http://jsfiddle.net/ExplosionPIlls/Avfjs/1/
You are looping thru more divs than you have. If you switch it to 4, it works.
for(i=0; i<5; i++){
or
for(i=0; i<=4; i++){
Since you are practicing, I just wanted to point out that you should reconsider the markup as this is not a case for using an id attribute but for a class. The id approach, though common, is incorrect and requires more code than necessary. Here is an example with better markup, which makes using javascript with it much more straightforward.
http://jsfiddle.net/3gpe8/

Categories