empty() div + variable - javascript

I have to empty a div with an id like this
echo "<td> <div id = \" $ divbouton \ "> \ n";
I pass a variable to a function () like this
function activermedecin(numdiv,statut,nummed) {
var numdiv ;
$("divnum").empty(); // vide la div #
}
My empty () is not working !!
When I put a fixed parameter like this:
$("div_medicin").empty ();
It works
Why ??
Thank you
Stephane

If you are trying to remove a div's property then it should look something like this.
// single element
function removeProperty(selector, property){
document.querySelector(selector).removeAttribute(property);
}
// multiple elements
function removePropertys(selector, property){
document.querySelectorAll(selector).forEach(elm => elm.removeAttribute(property));
}
If you are trying to remove the actual element then it should look like this.
// first match
document.querySelector(cssSelector).remove();
// All matches
document.querySelectorAll(cssSelector).forEach(elm => elm.remove());
If you don't know how to select stuff using css selectors, here's a good cheat sheet: https://devhints.io/css

Related

How do I get a string that's the text() of an element, but with spaces added after divs?

JSFiddle here
Hi! I'm trying to output a string from the .contents().text() of an element... but with spaces between the content of each div (without changing the actual DOM).
HTML:
<!-- I don't have control over how many divs are in .myTextArea, or what text. It's really dynamic. There are also lists, etc.--tons of different types of elements. -->
<div class="myTextArea">
<div>Hey there!</div><div>I like turtles.</div><div>Do you like them?</div>
</div>
jQuery:
var myTextDescription = $(".myTextArea").contents().text();
console.log(myTextDescription);
Currently, it outputs:
Hey there!I like turtles.Do you like them?
...and this is what I want it to output: The same thing, but with spaces after the content of each div:
Hey there! I like turtles. Do you like them?
Note: Other answers on SO make you change the actual DOM (AKA, they add actual spaces after the elements on the page), and then they just grab the text() string. I don't want to change the DOM.
Also, I can't use .html() instead and try to strip away stuff, because there will be wayyyyyy too many types of elements to worry about.
JSFiddle here
You're almost there. Replace .text() with:
//get text content of all nodes
.map((i,d) => d.textContent).get()
//remove white space
.filter(t => !!t.trim())
//join the text from all nodes with a space
.join(' ');
Check out the demo below:
var myTextDescription = $(".myTextArea").contents().map((i,d) => d.textContent).get().filter(t => !!t.trim()).join(' ');
console.log(myTextDescription);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="myTextArea">
<div>Hey there!</div><div>I like turtles.</div><div>Do you like them?</div>
</div>
In case you needed to exclude text in a div, say with a class exclude you can use the :not() psedo selector like so:
... .contents(':not(".exclude")') ....
..as in the demo below:
var myTextDescription = $(".myTextArea").contents(':not(".exclude")').map((i,d) => d.textContent).get().filter(t => !!t.trim()).join(' ');
console.log(myTextDescription);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="myTextArea">
<div>Hey there!</div><div class="exclude">Please exclude this!</div><div>I like turtles.</div><div>Do you like them?</div><div class="exclude">Please exclude this too!</div>
</div>
One way to solve this is to use JavaScript's querySelectorAll method to return a list of all the DIVs in your myTextArea element. You can then run through each element in the list, get its innerText and place a space after each one:
var myTexts = document.querySelectorAll('.myTextArea > div');
var show = document.querySelector('#show');
var output = "";
for (var x = 0; x < myTexts.length; x++) {
if (output == "") { // Skip adding space before first string
output = myTexts[x].innerText;
} else { // Add space before each appended string
output += " " + myTexts[x].innerText;
}
}
show.innerText = output;
<div class="myTextArea">
<div>Hey there!</div>
<div>I like turtles.</div>
<div>Do you like them?</div>
</div>
<div id="show"></div>

I create dynamically some text area in a div. How can i get its names in javascript?

This is my code to create the textarea and it works fine, but I want to know how many textarea the user creates and their names.
function createBoxEquip() {
$codEquip = $('#equipamento').val();
$nomeEquip = $('#equipamento>option:selected').text();
$novadiv = "#div"+$codEquip;
if ( !$( $novadiv ).length ) {
$("#equip_tot").append('<div class="box"name=div'+$codEquip+'id=div'+$codEquip+'></div>')
$("#div"+$codEquip).append('<span class="titulo1" name='+$codEquip+' id='+$codEquip+'> - '+$nomeEquip+'</span><span name=texto'+$codEquip+' id=texto'+$codEquip+'><br> </span>');
$("#div"+$codEquip).append('<input type="button" name=apagar'+$codEquip+' id=apagar'+$codEquip+' value="Remover" onclick="deleteBoxEquip('+$codEquip+')"><span name=texto1'+$codEquip+' id=texto1'+$codEquip+'> <br></span>');
$("#div"+$codEquip).append('<input type="text" style="width: 20px;" name=contalinhas'+$codEquip+' id=contalinhas'+$codEquip+'><span name=texto2'+$codEquip+' id=texto2'+$codEquip+'><br></span>');*/
$("#div"+$codEquip).append('<textarea style="width: 150px;" rows=12 name=numerosserie'+$codEquip+' id=numerosserie'+$codEquip+' value="'+$codEquip+' - '+$nomeEquip+'"/><span name=texto3'+$codEquip+' id=texto3'+$codEquip+'> </span>');
}
}
As long as you can pre-determine what the names of the textarea will be, for example - I've written similar code that generated a bunch of <div> tags with unique ID's, each Id was numeric, so I'd auto-generate a bunch of tags like this:
<div id="div-0">Zero</div>
<div id="div-1">One</div>
<div id="div-2">Two</div>
Because I know in advance that each div id will have the prefix div- followed by a digit which begins at 0 and increments sequentially, I can iterate through each element in a loop, and know when I've reached an undefined element:
function loopElements() {
var divPrefix = "div-";
var divNo = 0;
// Loop through all div- tags:
//
while (true) {
// The .length property will return 0 if the element
// doesn't exist...
//
if ($("#" + divPrefix + divNo.toString()).length == 0)
// This div doesn't exist, bail!
//
break;
// do something with div
divNo++;
}
}
Something like this would work, it depends on the names/id's you're creating, and if you can somehow predetermine what they should be.
hope this helps.
EDIT:
Having read your question again I think the above solution may not be what you're looking for, if not I apologise.
There are some ambiguities with your question...exactly how are these names created? Does the user choose them? Are they generated programmatically?
You should post more code and explain in greater detail.

How can I strip HTML tags that have attribute(s) from string?

I have a question and answer website like SO. Also I have a textarea and a preview under it (exactly the same as SO). I use a markdown library to converts some symbols to HTML tags. For example that JS library replaces ** with <b>. Ok all fine.
Now I need to escape HTML tags that have attribute. I can do that by PHP like this:
<?php
$data = <<<DATA
<div>
<p>These line shall stay</p>
<p class="myclass">Remove this one</p>
<p>But keep this</p>
<div style="color: red">and this</div>
</div>
DATA;
$dom = new DOMDOcument();
$dom->loadHTML($data, LIBXML_HTML_NOIMPLIED);
$xpath = new DOMXPath($dom);
$lines_to_be_removed = $xpath->query("//*[count(#*)>0]");
foreach ($lines_to_be_removed as $line) {
$line->parentNode->removeChild($line);
}
// just to check
echo $dom->saveHtml($dom->documentElement);
?>
I'm not sure code above is the best, but as you see (in the fiddle I've linked) it works as expected. I mean it removes nodes that are at least one attribute. Now I need to do that by JS (or jQuery) (I need this for that textarea preview simulator). Anyway how can I do that? Do I need regex?
You could do something like this:
$('.myTextArea *').each(function(){
if (this.attributes.length)
$(this).remove();
});
JSFIDDLE
It's not the most efficient, but if it's just a textarea preview it should be fine. I'd recommend running it as little as possible though. As far as I know there is no selector (jQuery or otherwise) that would otherwise do this...so you have to make the JS do the work.
Edit based on comment:
To not remove the element, just the surrounding tag, do something like this:
$('.myTextArea *').each(function(){
if (this.attributes.length)
this.outerHTML = this.textContent;
});
JSFIDDLE
The JavaScript element.attributes property returns a live NamedNodeMap of a tags attributes and their values. For example...
HTML
<div class=".cls" id="id" title="divtitle">
<!-- content ... -->
</div>
JavaScript
var div = document.getElementById('id');
var attr = div.attributes;
console.log(attr);
/* =>
NamedNodeMap [class="cls", id="id", title="divtitle"]
*/
This can be used to filter selected items - something like this for your example...
/* return an array from querySelectorAll */
var paras = Array.prototype.slice.call(
document.querySelectorAll('div p')
);
/* loop through paras */
paras.forEach(function(p) {
/* 'p' = each element in 'paras' */
/* get attributes of 'p' */
var attr = p.attributes;
/* only check elements with attributes */
if (attr.length != 0) {
/* loop through attributes */
Object.keys(attr).forEach(function(a) {
/* apply conditional */
if (attr[a].name === 'class' && attr[a].value === 'myclass' ||
attr[a].name === 'style' && attr[a].value === 'color: red;') {
/* remove element ('p') */
p.parentElement.removeChild(p);
}
});
}
});
Because a NamedNodeMap is a type of Object I used Object.keys(obj) to return an array of keys, and then looped over them to determine the attribute's .name and .value properties.
EDIT: In light of comment above
If you just want to remove the attributes then you can drop the condition above, like so...
paras.forEach(function(p) {
var attr = p.attributes;
if (attr.length != 0) {
Object.keys(attr).forEach(function(a) {
p.removeAttribute(a);
});
}
});
See:
NamedNodeMap
Element.attributes
Array.prototype.slice
Array.prototype.forEach
Object.keys
Element.removeAttribute

dynamic class select in javascript

I want to write a function in jquery using handlebars. where name of html and class where it has to be appended will be pass dynamically.
Basically i need something like this :
var pageTemplate="";
function addTempl(){
var renderedPage = pageTemplate(pageName);
$("#Class_id").empty();
$("#Class_id").append( renderedPage );
}
this Class_name and pageName will be dynamically passed to this function from another main function where it will be called.
Issue is i can pass pageName as it is javascript thing but how to do same for Class_name. beacuse if I append '#' and "" it is not coming.
please let me know if my problem is still unclear.
class is denoted by . and id is denoted by #
updated
$("#"+Class_id).empty();
$("#"+Class_id).append( renderedPage );
in one line
$("#"+Class_id).empty().append( renderedPage );
If I understood correctly, you want to use dynamic selector based on passed parameter. You can do something like:
function doSomething(className) {
var selector = "#" + className; // # for id, . for class
$(selector).empty();
$(selector).append(something);
}
Optimized version would be:
function doSomething(className) {
var x = $("#" + className); // # for id, . for class
x.empty();
x.append(something);
}
Optimized = you look for the element in DOM only once
Try this in order to select class use dot .
$("#"+Class_id).empty();
$("#"+Class_id).append( renderedPage );

How to change text inside span with jQuery, leaving other span contained nodes intact?

I have the following HTML snippet:
<span class="target">Change me <a class="changeme" href="#">now</a></span>
I'd like to change the text node (i.e. "Change me ") inside the span from jQuery, while leaving the nested <a> tag with all attributes etc. intact. My initial huch was to use .text(...) on the span node, but as it turns out this will replace the whole inner part with the passed textual content.
I solved this with first cloning the <a> tag, then setting the new text content of <span> (which will remove the original <a> tag), and finally appending the cloned <a> tag to my <span>. This works, but feels such an overkill for a simple task like this. Btw. I can't guarantee that there will be an initial text node inside the span - it might be empty, just like:
<span class="target"><a class="changeme" href="#">now</a></span>
I did a jsfiddle too. So, what would be the neat way to do this?
Try something like:
$('a.changeme').on('click', function() {
$(this).closest('.target').contents().not(this).eq(0).replaceWith('Do it again ');
});
demo: http://jsfiddle.net/eEMGz/
ref: http://api.jquery.com/contents/
Update:
I guess I read your question wrong, and you're trying to replace the text if it's already there and inject it otherwise. For this, try:
$('a.changeme').on('click', function() {
var
$tmp = $(this).closest('.target').contents().not(this).eq(0),
dia = document.createTextNode('Do it again ');
$tmp.length > 0 ? $tmp.replaceWith(dia) : $(dia).insertBefore(this);
});
​Demo: http://jsfiddle.net/eEMGz/3/
You can use .contents():
//set the new text to replace the old text
var newText = 'New Text';
//bind `click` event handler to the `.changeme` elements
$('.changeme').on('click', function () {
//iterate over the nodes in this `<span>` element
$.each($(this).parent().contents(), function () {
//if the type of this node is undefined then it's a text node and we want to replace it
if (typeof this.tagName == 'undefined') {
//to replace the node we can use `.replaceWith()`
$(this).replaceWith(newText);
}
});
});​
Here is a demo: http://jsfiddle.net/jasper/PURHA/1/
Some docs for ya:
.contents(): http://api.jquery.com/contents
.replaceWith(): http://api.jquery.com/replacewith
typeof: https://developer.mozilla.org/en/JavaScript/Reference/Operators/typeof
Update
var newText = 'New Text';
$('a').on('click', function () {
$.each($(this).parent().contents(), function () {
if (typeof this.tagName == 'undefined') {
//instead of replacing this node with the replacement string, just replace it with a blank string
$(this).replaceWith('');
}
});
//then add the replacement string to the `<span>` element regardless of it's initial state
$(this).parent().prepend(newText);
});​
Demo: http://jsfiddle.net/jasper/PURHA/2/
You can try this.
var $textNode, $parent;
$('.changeme').on('click', function(){
$parent = $(this).parent();
$textNode= $parent.contents().filter(function() {
return this.nodeType == 3;
});
if($textNode.length){
$textNode.replaceWith('Content changed')
}
else{
$parent.prepend('New content');
}
});
Working demo - http://jsfiddle.net/ShankarSangoli/yx5Ju/8/
You step out of jQuery because it doesn't help you to deal with text nodes. The following will remove the first child of every <span> element with class "target" if and only if it exists and is a text node.
Demo: http://jsfiddle.net/yx5Ju/11/
Code:
$('span.target').each(function() {
var firstChild = this.firstChild;
if (firstChild && firstChild.nodeType == 3) {
firstChild.data = "Do it again";
}
});
This is not a perfect example I guess, but you could use contents function.
console.log($("span.target").contents()[0].data);
You could wrap the text into a span ... but ...
try this.
http://jsfiddle.net/Y8tMk/
$(function(){
var txt = '';
$('.target').contents().each(function(){
if(this.nodeType==3){
this.textContent = 'done ';
}
});
});
You can change the native (non-jquery) data property of the object. Updated jsfiddle here: http://jsfiddle.net/elgreg/yx5Ju/2/
Something like:
$('a.changeme3').click(function(){
$('span.target3').contents().get(0).data = 'Do it again';
});
The contents() gets the innards and the get(0) gets us back to the original element and the .data is now a reference to the native js textnode. (I haven't tested this cross browser.)
This jsfiddle and answer are really just an expanded explanation of the answer to this question:
Change text-nodes text
$('a.changeme').click(function() {
var firstNode= $(this).parent().contents()[0];
if( firstNode.nodeType==3){
firstNode.nodeValue='New text';
}
})
EDIT: not sure what layout rules you need, update to test only first node, otherwise adapt as needed

Categories