how can i copy a html element to a string correctly. I use metroui, version 4. They have a special input class where a X popsout with a click you can delete the value that you entered in the input.
https://metroui.org.ua/input.html
When i copy the html element to a var this X does nothing, but when i define a var with the string and append this, it works. When i get it with the element id, there is already injected the javascript code from metro js, because i use this data-role="input", then metroui js do some things. How can i get the same string as it would be with var div ? The pure html like it shows in editor? Or isnt this possible because jquery can only read the dom? So that i can read this pure html
<span id="section-one-a1">
<div class="p_scnt" id="p_scnt" name="p_scnt">Test 1</div>
<input value="val1" id="val1" type="text" data-role="input" />
</span>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css">
<script src="https://cdn.metroui.org.ua/v4/js/metro.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(function(){
$('#addScnt').on('click', function() {
var div = $('<span id="section-one-a1">'+
'<div class="p_scnt" id="p_scnt" name="p_scnt">Test 1</div>'+
'<input value="val1" id="val1" type="text" data-role="input" />'+
'</span>');
//console.log(div);
var newdiv = $('#section-one-a1').prop('outerHTML').replace(/(\r\n|\n|\r|\t)/gm,"");
console.log(newdiv)
var test = $(newdiv);
$(div.appendTo("#p_scents"));
return false;
});
});
</script>
</head>
<body id="main">
<ul id="test">
<li>
new
</li>
</ul>
<div id="p_scents">
<span id="section-one-a1">
<div class="p_scnt" id="p_scnt" name="p_scnt">Test 1</div>
<input value="val1" id="val1" type="text" data-role="input" />
</span>
</div>
</body>
</html>
I did it this way no, perhaps not nicely, but works. Remove the elements and attributes that the MetroUI JS injected in the html when data-role is input, then it works. When it goes to the dom with appendto the metroui JS injected the new ones.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css">
<script src="https://cdn.metroui.org.ua/v4/js/metro.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(function(){
$('#addScnt').on('click', function() {
var div1 = $('<span id="section-one-a1">'+
'<div class="p_scnt" id="p_scnt" name="p_scnt">Test 1</div>'+
'<input value="val1" id="val1" type="text" data-role="input" />'+
'</span>');
//console.log(div);
var newdiv = $('#section-one-a1').clone().html().replace(/(\r\n|\n|\r|\t)/gm,""); // string
var replace = newdiv.replace('<div class="input">',''); // replace input
replace = replace.replace('data-role-input="true"',''); // replace data-role-input
replace = '<span id="section-one-a1">'+replace+'</span>';
var div = $(replace); // to object
div.find(".button-group").remove(); // remove button-group
//console.log(test)
$(div.appendTo("#p_scents"));
return false;
});
});
</script>
</head>
<body id="main">
<ul id="test">
<li>
new
</li>
</ul>
<div id="p_scents">
<span id="section-one-a1">
<div class="p_scnt" id="p_scnt" name="p_scnt">Test 1</div>
<input value="val1" id="val1" type="text" data-role="input" />
</span>
</div>
</body>
</html>
Related
I know this is a basic questions, but I am working on making a dynamic form and was having a bit of trouble figuring out how to delete elements that share the same class. I have looked around on the web and other posts for a means to accomplish this, but still was unable to figure it out.
I am new to this so I apologize for the basic question. Below, I have pasted the relevant code and my attempt at this. Would anyone be able to assist me?
var ingCounter = 1;
var dirCounter = 1;
var limit = 10;
function addIngredient(divName){
if (ingCounter == limit) {
alert("You have reached the add limit");
}
else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<div class='ingredientSet'><input class='ingredientInput' type='text' name='ingredients[]'><button class='deleteIngredientButton' type='button' onClick='removeElement('directionSet');'>X</button></div>";
document.getElementById(divName).appendChild(newdiv);
ingCounter++;
}
}
function addDirection(divName){
if (dirCounter == limit) {
alert("You have reached the add limit");
}
else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<div class='directionSet'><input class='directionInput' type='text' name='directions[]'><button class='deleteDirectionButton' type='button'>X</button></div>";
document.getElementById(divName).appendChild(newdiv);
dirCounter++;
}
}
function removeElement(elementId) {
// Removes an element from the document
var element = document.getElementById(elementId);
element.parentNode.removeChild(element);
}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Homemade</title>
<!-- Required program scripts -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<!-- Style Sheets-->
<link rel="stylesheet" href="/styles/navBarStyle.css">
<link rel="stylesheet" href="/styles/myRecipesStyle.css">
<link rel="stylesheet" href="/styles/createRecipeStyle.css">
<link rel="stylesheet" href="/styles/errorMessageStyle.css">
</head>
<body>
<!-- Background image -->
<img id="background" src="/images/foodBackground.jpg" alt="">
<div id="newRecipeContainer">
<div id="closeButtonContainer">
<div id="backButton"><a id="back" href="/recipes/myRecipes">← My Recipes</a></div>
</div>
<form id="createRecipeForm" action="/recipes/createRecipe" method="POST" enctype="multipart/form-data">
<label id="formSubHeading">Create Your Homemade Recipe</label>
<%- include('../_partial/_messages'); -%>
<div id="recipeNameContainer">
<label id="recipeNameLabel">Title</label>
<input id="recipeNameInput" type="text" name="recipeName">
</div>
<div id="recipeImage">
<label id="recipeImageLabel">Add An Image of Your Meal</label>
<input id="recipeImageInput" type="file" accept="image/*" name="recipeImage"/>
<label id="recipeImageInputLabel" for="recipeImageInput" name="recipeImage">Choose A File</label>
</div>
<div id="recipeDescription">
<label id="recipeDescriptionLabel">Description</label>
<textarea id="recipeDescriptionInput" name="recipeDescription" cols="30" rows="10" maxlength="2000"></textarea>
</div>
<div class="ingredientsContainer">
<label id="ingredientsLabel">Ingredients</label>
<button id="addIngredientButton" type="button" onClick="addIngredient('allIngredients');">Add Another Ingredient</button>
<div id="allIngredients">
<div class="ingredientSet">
<input class="ingredientInput" type="text" name="ingredients[]">
</div>
</div>
</div>
<div class="directionsContainer">
<label id="directionsLabel">Directions</label>
<button id="addDirectionButton" type="button" onClick="addDirection('allDirections');">Add Another Direction</button>
<div id="allDirections">
<div class="directionSet">
<input class="directionInput" type="text" name="directions[]">
</div>
</div>
</div>
<div id="createRecipeButtonContainer">
<button id="createRecipeButton" type="submit">Create Recipe</button>
</div>
</form>
</div>
</body>
<!-- Required scripts to run app -->
<script src="/controls/newRecipeControl.js"></script>
<script src="/controls/errorMessageControl.js"></script>
</html>
Thanks for any help.
In your code you are using getElementById but there is no id called directionSet its a class.
You can simply use parentElement and remove to remove the newly added dynamic inputs by calling an onClick function.
In the onClick function removeElement() - this refers to the elements we have clicked and it will remove from the form.
var ingCounter = 1;
var dirCounter = 1;
var limit = 10;
function addIngredient(divName) {
if (ingCounter == limit) {
alert("You have reached the add limit");
} else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<div class='ingredientSet'><input class='ingredientInput' type='text' name='ingredients[]'><button class='deleteIngredientButton' type='button' onClick='removeElement(this);'>X</button></div>";
document.getElementById(divName).appendChild(newdiv);
ingCounter++;
}
}
function addDirection(divName) {
if (dirCounter == limit) {
alert("You have reached the add limit");
} else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<div class='directionSet'><input class='directionInput' type='text' name='directions[]'><button class='deleteDirectionButton' onClick='removeElement(this);' type='button'>X</button></div>";
document.getElementById(divName).appendChild(newdiv);
dirCounter++;
}
}
function removeElement(elementId) {
// Removes an element from the document
elementId.parentElement.remove()
}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Homemade</title>
</head>
<body>
<!-- Background image -->
<div id="newRecipeContainer">
<div id="closeButtonContainer">
<div id="backButton"><a id="back" href="/recipes/myRecipes">← My Recipes</a></div>
</div>
<form id="createRecipeForm" action="/recipes/createRecipe" method="POST" enctype="multipart/form-data">
<label id="formSubHeading">Create Your Homemade Recipe</label>
<div id="recipeNameContainer">
<label id="recipeNameLabel">Title</label>
<input id="recipeNameInput" type="text" name="recipeName">
</div>
<div id="recipeImage">
<label id="recipeImageLabel">Add An Image of Your Meal</label>
<input id="recipeImageInput" type="file" accept="image/*" name="recipeImage" />
<label id="recipeImageInputLabel" for="recipeImageInput" name="recipeImage">Choose A File</label>
</div>
<div id="recipeDescription">
<label id="recipeDescriptionLabel">Description</label>
<textarea id="recipeDescriptionInput" name="recipeDescription" cols="30" rows="10" maxlength="2000"></textarea>
</div>
<div class="ingredientsContainer">
<label id="ingredientsLabel">Ingredients</label>
<button id="addIngredientButton" type="button" onClick="addIngredient('allIngredients');">Add Another Ingredient</button>
<div id="allIngredients">
<div class="ingredientSet">
<input class="ingredientInput" type="text" name="ingredients[]">
</div>
</div>
</div>
<div class="directionsContainer">
<label id="directionsLabel">Directions</label>
<button id="addDirectionButton" type="button" onClick="addDirection('allDirections');">Add Another Direction</button>
<div id="allDirections">
<div class="directionSet">
<input class="directionInput" type="text" name="directions[]">
</div>
</div>
</div>
<div id="createRecipeButtonContainer">
<button id="createRecipeButton" type="submit">Create Recipe</button>
</div>
</form>
</div>
</body>
</html>
I'm developing a web page by means of which user will add questions and answers. To add a new question the user clicks on the button and new div is added to container.
The problem is that when a new text-area is added, the text written in the other text-areas is removed.
View of filled text-area before clicking the button
View of text-area after clicking the button
Code:
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
const template = '<form class="eachtest">' +
'<textarea id="question" rows="4" cols="80" placeholder="Sual"></textarea>' +
'<br><strong> A </strong> ' +
'<textarea class="answer" rows="4" cols="80" placeholder="Cavab"></textarea><br>' +
'</form>';
function on_click() {
document.querySelector('.container').innerHTML += template;
}
</script>
</head>
<body>
<div class="container"></div>
<button id="add" type="button" name="button" onclick="on_click()">add</button>
</body>
</html>
innerHTML rebuild the whole content. Try the following:
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
const template = '<form class="eachtest"><textarea id="question" rows="4" cols="80" placeholder="Sual"></textarea><br><strong> A </strong> <textarea class="answer" rows="4" cols="80" placeholder="Cavab"></textarea><br></form>';
function on_click() {
document.querySelector('.container').insertAdjacentHTML('beforeend', template);
}
</script>
</head>
<body>
<div class="container">
</div>
<button id="add" type="button" name="button" onclick="on_click()">add</button>
</body>
</html>
For more info on innerHTML, click here
As you should avoid using inline JS and CSS, I propose you the following:
Create a hidden div id="template" in your HTML,
Use JS to append its content after your container when you click the "add" button.
I also changed your id="question" to class="question" as you can add multiple ones.
const template = document.querySelector('#template').innerHTML;
var container = document.querySelector('.container');
document.querySelector('#add').onclick = function() {
container.insertAdjacentHTML('beforeend', template);
}
#template {
display: none;
}
<html lang="en" dir="ltr">
<body>
<div class="container"></div>
<button id="add" type="button" name="button">Add</button>
<div id="template">
<form class="eachtest"><textarea class="question" rows="4" cols="80" placeholder="Sual"></textarea><br> <strong> A </strong><textarea class="answer" rows="4" cols="80" placeholder="Cavab"></textarea><br></form>
</div>
</body>
</html>
Hope it helps.
Use Jquery append() :D
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
const template = '<form class="eachtest"><textarea id="question" rows="4" cols="80" placeholder="Sual"></textarea><br><strong> A </strong> <textarea class="answer" rows="4" cols="80" placeholder="Cavab"></textarea><br></form>';
function on_click() {
$('.container').append(template)
}
</script>
</head>
<body>
<div class="container">
</div>
<button id="add" type="button" name="button" onclick="on_click()">add</button>
</body>
</html>
I'm trying to inject into the header of a page(JQM) a title by using Javascript.
I also want to enable a Subscription feature so I need to insert the button via Javascript aswell. However, whenever I inject it, it's getting messy.
I want the button to align with the title, and I want the title in the middle of the header.
Here's a picture to demonstrate how it looks right now
and I want it to align perfectly, with no line-breaks at all(like it has now)
Im using these lines to insert the button and the title(JS):
document.getElementById("forum_name").innerHTML = fName;
document.getElementById("subscribe_btn").innerHTML = " <a href='#' class='ui-btn'>Unsubscribe</a>";
And Im using these lines in the HTML File:
<div data-role="header"><span style="display:inline;" id="subscribe_btn"></span><center><div id="forum_name" style="display:inline-block"></div></center></div>
With JQM you can do it following way:
var subscribeText = "Subscribe", unsubscribeText = "Unsubscribe";
function changeSubscription() {
var choiche = $('input[name=rg-subscription]:checked'),
value = choiche.val(),
label = choiche.parent().text();
$("#toggleSubscription").toggleClass("ui-screen-hidden", value == "no-subscription");
if (value == "no-subscription") {
$("#toggleSubscription").text(subscribeText);
}
var pageId = $(":mobile-pagecontainer").pagecontainer("getActivePage").prop("id");
$("#" + pageId + " [data-role='header'] h1").text(label);
}
$(document).on("pagecreate", "#page-1", function(e) {
$("input[name='rg-subscription']").change(changeSubscription);
$("#toggleSubscription").on("vclick", function(e) {
$(this).text($(this).text() === subscribeText ? unsubscribeText : subscribeText);
});
$("#injectButton").click(injectButton);
});
$(document).on("pagebeforeshow", "#page-1", function(e, ui) {
changeSubscription();
});
function injectButton() {
$("#toggleSubscription").off();
var html = [
'<button id="toggleSubscription" ',
'class="ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all">',
'Subscribe',
'</button>'
].join("");
$("#toggleSubscription").remove();
$("#page-1 [data-role='header']").prepend(html).enhanceWithin();
$("#toggleSubscription").on("vclick", function(e) {
$(this).text($(this).text() === subscribeText ? unsubscribeText : subscribeText);
});
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js"></script>
</head>
<body>
<div id="page-1" data-role="page">
<div data-role="header">
<h1>Header</h1>
</div>
<div role="main" class="ui-content" id="page-1-content">
<fieldset data-role="controlgroup" data-mini="true">
<input name="rg-subscription" id="rc-subscription-0" value="no-subscription" checked="checked" type="radio">
<label for="rc-subscription-0">no subscription</label>
<input name="rg-subscription" id="rc-subscription-1" value="alt-binaries-mp3" type="radio">
<label for="rc-subscription-1">alt.binaries.mp3</label>
<input name="rg-subscription" id="rc-subscription-2" value="alt-binaries-linux" type="radio">
<label for="rc-subscription-2">alt.binaries.linux</label>
<input name="rg-subscription" id="rc-subscription-3" value="alt-binaries-games" type="radio">
<label for="rc-subscription-3">alt.binaries.games</label>
</fieldset>
<button id="injectButton" class="ui-btn ui-btn-inline ui-mini ui-corner-all">Inject "Subscribe" Button</button>
</div>
</div>
</body>
</html>
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 8 years ago.
I'm new to JavaScript and JQuery, and I'm trying to figure out why my function doesn't get called when I press the button. My only clue is that the Firefox Console is showing TypeError: document.getElementById(...) is null. I found this example, which says "document.write will overwrite the entire DOM if it's called after the document has finished being parsed" and that's why it's happening. I took a look at my code, and I moved the button into my div tag and it's still happening. I also tried moving the button into it's own div tags. Compiler didn't seem to like syntax when I tried adding html tags where the button is. I'm not sure what I'm supposed to do to fix this.
I'm following this example for the function call on button click. Hopefully I'm applying it ok to my project.
This is my code:
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>jQuery Michele Project</title>
<link href="css/skins/polaris/polaris.css" rel="stylesheet">
<link href="css/skins/all.css" rel="stylesheet">
<link href="css/demo/css/custom.css" rel="stylesheet">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="js/jquery-1.11.0.js"></script>
<script type="text/javascript" src="js/jquery.ui.core.js"></script>
<script type="text/javascript" src="js/jquery.ui.widget.js"></script>
<script src="js/icheck.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.input').iCheck({
checkboxClass:'icheckbox_polaris',
radioClass:'iradio_polaris',
increaseArea:'10%'
});
});
</script>
<script type="text/javascript">
// Returns an array with values of the selected (checked) checkboxes in "frm"
function getSelectedChbox(frm) {
// JavaScript & jQuery Course - http://coursesweb.net/javascript/
var selchbox = []; // array that will store the value of selected checkboxes
// gets all the input tags in frm, and their number
var inpfields = frm.getElementsByTagName('input');
var nr_inpfields = inpfields.length;
// traverse the inpfields elements, and adds the value of selected (checked) checkbox in selchbox
for(var i=0; i<nr_inpfields; i++) {
if(inpfields[i].type == 'checkbox' && inpfields[i].checked == true)
selchbox.push(inpfields[i].value);
}
return selchbox;
}
document.getElementById('btntest').onclick = function() {
var selchb = getSelectedChbox(this.form);
alert(selchb);
}
</script>
<style type="text/css">
ul {list-style-type: none}
img {padding-right: 20px; float:left}
#infolist {width:500px}
</style>
</head>
<body>
<form>
<div class="skin skin-line">
<div class="arrows">
<div class="top" data-to="skin-flat"></div>
<div class="bottom" data-to="skin-polaris"></div>
</div>
</div>
<div class="skin skin-polaris">
<div class="arrows">
<div class="top" data-to="skin-line"></div>
<div class="bottom" data-to="skin-futurico"></div>
</div>
<h3>Select Items for Column Headings</h3>
<dl class="clear">
<dd class="selected">
<div class="skin-section">
<h4>Live</h4>
<ul class="list">
<li>
<input tabindex="21" type="checkbox" id="polaris-checkbox-1">
<label for="polaris-checkbox-1">Checkbox 1</label>
</li>
<li>
<input tabindex="22" type="checkbox" id="polaris-checkbox-2" checked>
<label for="polaris-checkbox-2">Checkbox 2</label>
</li>
<li>
<input type="checkbox" id="polaris-checkbox-3" >
<label for="polaris-checkbox-3">Checkbox 3</label>
</li>
<li>
<input type="checkbox" id="polaris-checkbox-4" checked >
<label for="polaris-checkbox-4">Checkbox 4</label>
</li>
</ul>
</div>
<script>
$(document).ready(function(){
$('.skin-polaris input').iCheck({
checkboxClass: 'icheckbox_polaris',
radioClass: 'iradio_polaris',
increaseArea: '20%'
});
});
</script>
//$('#checkbox').prop('checked')
</dd>
</dl>
</div>
<div id="loading">
<input type="button" value="Click" id="btntest" />
</div>
</form>
</body>
</html>
The issue is you assign the click handler before the element is available in the DOM. To resolve, you should wrap it in a DOM ready function:
$(function(){
document.getElementById('btntest').onclick = function() {
var selchb = getSelectedChbox(this.form);
alert(selchb);
}
});
Note: $(function(){ ... }); is a shortcut for $(document).ready(function(){ ... });
You're running document.getElementById('btntest') before that element exists. Put this script after your button on the page, not before it:
<script>
document.getElementById('btntest').onclick = function() {
var selchb = getSelectedChbox(this.form);
alert(selchb);
}
</script>
I thought that adding a DOM element as context to a JQuery method would restrict the method to looking ONLY at that element and its descendants instead of the entire document. If this is the case...
Why does this:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<script type="text/javascript">
$(document).ready(function() {
var contextElem = document.getElementById("row1");
$("img").closest(".drow", contextElem).each(function(index, elem) {
console.log("Context Element: " + elem.tagName + " " + elem.className
+ " " + elem.id);
});
});
</script>
</head>
<body>
<h1>JQuery Closest Example</h1>
<form method="post">
<div id="oblock">
<div class="dtable">
<div id="row1" class="drow">
<div class="dcell">
<img src="cell11.png"/><label for="cell11">Cell 1 1:</label>
<input name="cell11Value" value="0" required>
</div>
<div class="dcell">
<img src="cell12.png"/><label for="cell12">Cell 1 2:</label>
<input name="cell12Value" value="0" required >
</div>
</div>
<div id="row2"class="drow">
<div class="dcell">
<img src="cell21.png"/><label for="cell21">Cell 2 1:</label>
<input name="cell21Value" value="0" required>
</div>
<div class="dcell">
<img src="cell22.png"/><label for="cell22">Cell 2 2:</label>
<input name="cell22Value" value="0" required >
</div>
</div>
</div>
</div>
<div id="buttonDiv"><button type="submit">Save</button></div>
</form>
</body>
</html>
J
Result in this in the console:
Context Element: DIV drow row2
Instead of this:
Context Element: DIV drow row1
???
Passing in a context means jQuery will look for your selector as a descendent of context. In your case, your selector and context are the same element.