How can I remove the 'Currently' in the HTML withouting deleting other texts
<div class="group if-description-margin">
Currently: <--- Remove this text
images/header-dots.png
<input type="checkbox" name="profile_picture-clear" id="profile_picture-clear_id">
<input type="file" name="profile_picture" accept="image/*" id="id_profile_picture">
<p> But don't remove this </p>
<label for="id_profile_picture">Profile Picture</label>
</div>
You can use a regexp and the innerHTML:
const textContainer = document.querySelector('.group')
const btn = document.getElementById('remove')
const removeText = (el, regexp) => {
const oldHTML = el.innerHTML
const newHTML = oldHTML.replace(regexp, '')
return newHTML
}
const regexp = /Currently:/g
btn.addEventListener('click', function() {
textContainer.innerHTML = removeText(textContainer, regexp)
})
<div class="group if-description-margin">
Currently: <!-- Remove this text -->
images/header-dots.png
<input type="checkbox" name="profile_picture-clear" id="profile_picture-clear_id">
<input type="file" name="profile_picture" accept="image/*" id="id_profile_picture">
<p> But don't remove this </p>
<label for="id_profile_picture">Profile Picture</label>
</div>
<button id="remove">REMOVE THE TEXT</button>
You can use the DOM to your advantage. If you have a reference to the parent Div, you can use the childNodes property (https://www.w3schools.com/jsref/prop_node_childNodes.asp) of it. It only returns the HTML elements, and not the text nodes. You could write a pretty simple function that loops through the childNodes to rebuild the innerHTML and by happy side-effect, it would leave out the text nodes.
If you want specific text nodes removed, you can use the children property (https://www.w3schools.com/jsref/prop_element_children.asp) which includes both the text nodes and the html elements. Then you still loop through the children and just add logic to decide if you add it back in to the innerHTML.
Edit: Adding a link to my test page...
https://highdex.net/StackOverflow/DOMHelper.htm
Edit 2: further explanation
I ended up using only the childNodes collection. And instead of clearing and rebuilding, I just removed text nodes (or text nodes that match the criteria). The second function has a lot more variable assignment than necessary, but I broke it up during debugging so I could more easily see values being used. It should be cleaned up, but won't hurt your understanding of it. One last thing to mention is that decrementing the counter in the for loop MUST be done that way. It avoids trying to access an index that might no longer exist if you try removing things from the beginning first.
Related
I have a loop of button elements that are outputted with a while loop from data called from a MySQL database via PHP.
A user can add a button to this list and I want to add the new button and it's associated HTML using the prepend() method on the parent element, so it appears at the top of the list.
I know how to do this in various stages using createElement and adding class names and attribute names, but wondered if there is a simpler way of doing it using a template literal of the required HTML?
I've seen plenty of examples using parentElement.innerHTML(variableName), where variableName is the template literal, but these button elements illustrated below are inside a loop, and want I to prepend the newly created button to the parent .board-list element shown in the HTML.
When a new board name is submitted, a fetch() post request happens in the background to update the database, but I need to create a new element with JavaScript so this shows instantly to the user.
At the moment the template literal newButton is added to the HTML inside quote marks as a string of text, not as HTML DOM elements.
JavaScript
// added into the template literal below
const newBoardName = document.querySelector('.input-title').value;
const newButton = `
<button class="board-list-item full-width" name="board-name" type="submit">
<span>${newBoardName}</span>
<span class="add-icon flex">+</span>
</button>
`
document.querySelector(".board-list").prepend(newButton);
HTML
<div class="board-list">
// buttons outputted from the database appear here
</div>
<form>
<input class="input-title">
<button name="new-board-name">New Board Name</button>
<form>
I think a simple solution is to use .innerHTML, here is an example:
// added into the template literal below
const newBoardName = document.querySelector('.input-title').value;
const newButton = `
<button class="board-list-item full-width" name="board-name" type="submit">
<span>${newBoardName}</span>
<span class="add-icon flex">+</span>
</button>
`
let boardList = document.querySelector(".board-list");
boardList.innerHTML = newButton + boardList.innerHTML;
<div class="board-list">
// buttons outputted from the database appear here
</div>
<form>
<input class="input-title" value="user1">
<button name="new-board-name">New Board Name</button>
<form>
This is simply to answer your question, although it is not the best solution, so I do not see it recommended.
The solution to this was using the insertAdjacentHTML method. The question/answer given in one of the comments helped me on this, but I don't think it is a duplicate question, and the question linked to has an overly complicated answer IMHO.
// added into the template literal below
const newBoardName = document.querySelector('.input-title').value
const newButton = `
<button class="board-list-item full-width" name="board-name" type="submit">
<span>${newBoardName}</span>
<span class="add-icon flex">+</span>
</button>
`
// insert using 'afterbegin' to add as the first child element
document.querySelector(".board-list").insertAdjacentHTML('afterbegin', newButton)
This is my .cshtml code :
<div class="col-xs-4 col-md-2">
<div class="form-group">
<input asp-for="FileName" type="hidden" class="hdnFileName" />
<input type="file" asp-for="UploadFile" accept=".csv" />
<button id="btnUpload" class="btn btn-tertiary btnFileSelect" type="button">Browse</button>
</div>
</div>
I need the id of the FileName on click of the upload button.
Script :
$(".btnFileSelect").each(function () {
var btnId = $(this).attr("id");
//The below code is not working and throwing an undefined value.
//Tried .closest() which is not working either.
var fileName = $(this).prev('.hdnFileName').attr('id');
})
Variable fileName is showing undefined.
What do I change? Is it being a hidden field the issue?
prev doesn't scan, it will only ever return a jQuery object for the previous element (if the selector matches) or an empty one (if it doesn't). From the documentation:
Get the immediately preceding sibling of each element in the set of matched elements. If a selector is provided, it retrieves the previous sibling only if it matches that selector.
(jQuery's set-based nature makes that slightly less clear than it could be, but basically you'll get the immediately-previous element if it matches, or none if it doesn't.)
If you want to scan, use .prevAll().eq(0). Or in this case, I'd probably use siblings:
var fileName = $(this).siblings('.hdnFileName').attr('id');
(I'm assuming something at some point adds an id to that element, since it doesn't have one in the markup you've shown.)
As you can see, my HTML contains multiple references to '0'. I need to change these to '1'.
However, my jQuery isn't working.
jQuery(".create-new-location").click(function() {
jQuery("#header-logo").html().replace(/\[0\]/g, '['+(1)+']');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header-logo" class="header-title location-header-0 title-edit-header" data-row-id="location-header-0" title="Location name (for your reference)">
<div class="input-selection title-edit-header">
<div class="text-input">
<input class="option_textbox col-sm-12 change-width title-edit" placeholder="Location name (for your reference)" value="" type="text" name="bp_theme_options[social][map][locations][0][location_name]">
</div>
</div>
<div class="open-block pencil-edit" data-row-id="location-header-0"></div>
</div>
You have to set the html like this
jQuery(".create-new-location").click(function() {
var the_html = jQuery("#header-logo").html().replace(/\[0\]/g, '['+(1)+']');
jQuery("#header-logo").html(the_html);
});
But this is not a good practice!!
When you need to change only the attribute of an <input>, why change the whole #header-logo, right? When you re-draw html like this, you risk losing event-handlers binded to the elements you have just re-drawn.
jQuery(".create-new-location").click(function() {
var elements = jQuery("#header-logo").find('input[name]'); /*all input with name*/
elements.each(function(el){
var the_name = el.attr('name').replace(/\[0\]/g, '['+(1)+']');
el.attr('name', the_name);
});
});
Regexing the html is never a good idea.
As you can see, my HTML contains multiple references to '0'. I need to change these to '1'.
The approach you used, and even the accepted answer here, will not modify the containing div with id="header-logo" which contains several of these references. Moreover, there are significant issues with simply replacing existing dom elements with freshly regexed ones in validation cases (as in, this may break your validation).
The approach you should use is to specifically target the attributes that contain these references, and then only modify those. Here is a general approach which looks in all attributes and modifies the occurrence of [0 (0 being the value of before) into [1 (1 being the value of after) as well as modifying the occurrence of -0 (before = 0) to -1 (after =1).
This will prevent removing any existing event handlers from the elements, as well as a number of other issues associated with regexing straight html and then replacing the dom element with the that result.
$.fn.indexUpdate = function(before,after){
$("*",this).add(this).each(function(){
$(this.attributes).each(function(){
this.value = this.value.replace(new RegExp('\\b\\-'+before+'\\b','g'), '-'+after);
this.value = this.value.replace(new RegExp('\\['+before, 'g'), '['+after);
});
});
};
$("#header-logo").indexUpdate(0,1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header-logo" class="header-title location-header-0 title-edit-header" data-row-id="location-header-0" title="Location name (for your reference)">
<div class="input-selection title-edit-header">
<div class="text-input">
<input class="option_textbox col-sm-12 change-width title-edit" placeholder="Location name (for your reference)" value="" type="text" name="bp_theme_options[social][map][locations][0][location_name]">
</div>
</div>
<div class="open-block pencil-edit" data-row-id="location-header-0"></div>
</div>
This statement jQuery("#header-logo").html().replace(/\[0\]/g, '['+(1)+']'); retrieve the html inside the element that have id as header-logo and replace every 0 inside the html string with 1 But it doesn't assign the modified string again to the element So you may want to use following code.
jQuery("#header-logo").html(jQuery("#header-logo").html().replace(/\[0\]/g, '['+(1)+']'));
Try this:It will replace all existence of '0' with '##'
$(".create-new-location").click(function() {
$("#header-logo").html().replace(/0/gi, '##')
});
I'm just trying to do this from the chrome console on Wikipedia. I'm placing my cursor in the search bar and then trying to do document.activeElement.innerHTML += "some text" but it doesn't work. I googled around and looked at the other properties and attributes and couldn't figure out what I was doing wrong.
The activeElement selector works fine, it is selecting the correct element.
Edit: I just found that it's the value property. So I'd like to change what I'm asking. Why doesn't changing innerHTML work on input elements? Why do they have that property if I can't do anything with it?
Setting the value is normally used for input/form elements. innerHTML is normally used for div, span, td and similar elements.
value applies only to objects that have the value attribute (normally, form controls).
innerHtml applies to every object that can contain HTML (divs, spans, but many other and also form controls).
They are not equivalent or replaceable. Depends on what you are trying to achieve
First understand where to use what.
<input type="text" value="23" id="age">
Here now
var ageElem=document.getElementById('age');
So on this ageElem you can have that many things what that element contains.So you can use its value,type etc attributes. But cannot use innerHTML because we don't write anything between input tag
<button id='ageButton'>Display Age</button>
So here Display Age is the innerHTML content as it is written inside HTML tag button.
Using innerHTML on an input tag would just result in:
<input name="button" value="Click" ... > InnerHTML Goes Here </input>
But because an input tag doesn't need a closing tag it'll get reset to:
<input name="button" value="Click" ... />
So it's likely your browsers is applying the changes and immediatly resetting it.
do you mean something like this:
$('.activeElement').val('Some text');
<input id="input" type="number">
document.getElementById("input").addEventListener("change", GetData);
function GetData () {
var data = document.getElementById("input").value;
console.log(data);
function ModifyData () {
document.getElementById("input").value = data + "69";
};
ModifyData();
};
My comments: Here input field works as an input and as a display by changing .value
Each HTML element has an innerHTML property that defines both the HTML
code and the text that occurs between that element's opening and
closing tag. By changing an element's innerHTML after some user
interaction, you can make much more interactive pages.
JScript
<script type="text/javascript">
function changeText(){
document.getElementById('boldStuff').innerHTML = 'Fred Flinstone';
}
</script>
HTML
<p>Welcome to Stack OverFlow <b id='boldStuff'>dude</b> </p>
<input type='button' onclick='changeText()' value='Change Text'/>
In the above example b tag is the innerhtml and dude is its value so to change those values we have written a function in JScript
innerHTML is a DOM property to insert content to a specified id of an element. It is used in Javascript to manipulate DOM.
For instance:
document.getElementById("example").innerHTML = "my string";
This example uses the method to "find" an HTML element (with id="example") and changes the element content (innerHTML) to "my string":
HTML
Change
Javascript
function change(){
document.getElementById(“example”).innerHTML = “Hello, World!”
}
After you clicked the button, Hello, World! will appear because the innerHTML insert the value (in this case, Hello, World!) into between the opening tag and closing tag with an id “example”.
So, if you inspect the element after clicking the button, you will see the following code :
<div id=”example”>Hello, World!</div>
That’s all
innerHTML is a DOM property to insert content to a specified id of an element. It is used in Javascript to manipulate DOM.
Example.
HTML
Change
Javascript
function FunctionName(){
document.getElementById(“example”).innerHTML = “Hello, Kennedy!”
}
On button Click, Hello, Kennedy! will appear because the innerHTML insert the value (in this case, Hello, Kennedy!) into between the opening tag and closing tag with an id “example”.
So, on inspecting the element after clicking the button, you will notice the following code :
<div id=”example”>Hello, Kennedy!</div>
Use
document.querySelector('input').defaultValue = "sometext"
Using innerHTML does not work on input elements and also textContent
var lat = document.getElementById("lat").value;
lat.value = position.coords.latitude;
<input type="text" id="long" class="form-control" placeholder="Longitude">
<button onclick="getLocation()" class="btn btn-default">Get Data</button>
Instaed of using InnerHTML use Value for input types
I'm iterating over a div using :
Can I access a hidden parameter in this div within the iteration ?
<DIV>
<div id="myDiv" <input type="hidden" name="Language" value="English"> />
</DIV>
$('#myDiv div.id').each(function() {
//access a hidden parameter of the current div here
});
You can use one of the following methods:
$('#myDiv div.id').each(
function(){
parameter = $(this).attr('data-hidden-parameter');
/* or:
parameter = $(this).data('hidden-parameter');
*/
});
The first parameter = $(this).attr('data-hidden-parameter') requires the following structure:
<div class="id" data-hidden-parameter="value"><!-- other stuff --></div>
Whereas the latter works with getting/setting with the data() method of jQuery:
$(selector).data('hidden-parameter','value'); // sets
$(selector).data('hidden-parameter'); // gets
If you mean retrieving text, or other content/attributes, from a hidden element that's a child of the div.id element, with mark-up such as:
<div class="id">
<input type="hidden" value="somethingOrOther" />
<span style="display: none;">Some text in a hidden element</span>
</div>
You could retrieve that value with:
$('#myDiv div.id').each(
function(){
parameter = $(this).find('input:hidden').val();
/* or:
parameter = $(this).find('span').text();
});
Note your jQuery selector implies you're iterating over a number of elements, based on the class of those elements, while your class-name, id, implies you're trying, instead, to search based on the id of an element. This might be pseudo-code to demonstrate your approach, but please don't use a class-name of id. It's perfectly valid, but it's terribly confusing. Albeit this is simply my own, personal, objection and response.
Edited, to supply a more targeted answer, by amending one of the above suggestions with an appropriate selector:
var parameter = $('#myDiv').find('input:hidden[name="Language"]').val();
References:
attr().
data().
find().
:hidden selector.
text().
val().
your html code is invalid: if you mean
<div id="myDiv"><input type="hidden" name="Language" value="English"></div>
this will target your input
$('#myDiv input[type="hidden"]')
You cannot put a tag inside another tag (or, in HTML or HTML-compatible XHTML, use self-closing tag syntax on a div). Your HTML is invalid and subject to whatever error recovery parsers care to put it though.
If you had, for instance:
<div id="myDiv">
<div class="id">
<input type="hidden" name="Language" value="English">
</div>
</div>
Then you could do:
$('#myDiv div.id').each(function(index, element) {
var foo = $(element).find('input').val()
});
… but you are probably better off using data-* and jQuery's data() method