Javascript closest selector but for sibling [duplicate] - javascript

This question already has answers here:
Implement siblings() in vanilla javascript
(5 answers)
Closed 8 months ago.
I have this html:
<form action="/action_page.php">
<label for="qsearch">Qsearch</label>
<input id="search1" type="search" value="" name="s">
<br>
<label for="num">Num</label>
<input type="number" value="" name="Num">
<br>
<label for="a">A</label>
<input type="text" value="" name="a">
<br>
<label for="a">B</label>
<input type="text" value="" name="b">
<input type="submit">
</form>
<script>
console.log( document.getElementById("search1").closest("input[type='text']") );
</script>
I want to get the next text input closest to search input without knowing the ID. But i can't seems to use closest()
What is the correct way to do it using vanilla javascript?

closest looks up in the DOM. In your case input#search1 is fist element in the DOM. You may try a recursive function like this and check if the element have next sibling. If it has next sibling and matches the type then return it else call the recursive function
function getNextSibling(elem, selector) {
let sibling = elem.nextElementSibling;
// check if the element have next sibling
while (sibling) {
if (sibling.matches(selector)) {
return sibling;
}
sibling = sibling.nextElementSibling;
}
};
const x = document.getElementById("search1")
.nextElementSibling;
console.log(getNextSibling(x, "input[type='text']"))
<form action="/action_page.php">
<label for="qsearch">Qsearch</label>
<input id="search1" type="search" value="" name="s">
<br>
<label for="num">Num</label>
<input type="number" value="" name="Num">
<br>
<label for="a">A</label>
<input type="text" value="" name="a">
<br>
<label for="a">B</label>
<input type="text" value="" name="b">
<input type="submit">
</form>

Related

How can I show and hide the form in HTML page?

I have an html form which is supposed to appear only after clicking a submit button. I have added simple JavaScript to display the same on click.
Intention is show the update form on click of the button above it. Can anyone help me out to find what I did wrong?
function showForm() {
alert('Form has been submitted');
document.getElementByClass(UpdateForm - section).style.display = 'block';
}
.UpdateForm-section.hidden {
display: none;
}
<input type="submit" name="delete" class="button-1" value="Update" onclick="showForm();" />
<br><br><br>
<!-- Update details form here -->
<div>
<form action="" method="post" class="UpdateForm-section">
<label>Car Name</label>
<input type="text" value="" name="ev_name" placeholder="Model name"><br>
<label>Manufacturer</label>
<input type="text" value="" name="ev_manufacturer" placeholder="Brand name"><br>
<label>Year</label>
<input type="number" value="" name="ev_year" placeholder="YYYY"><br>
<label>Battery size</label>
<input type="number" value="" step="any" name="ev_battery" placeholder="Capacity in Kwh"><br>
<label>Range</label>
<input type="number" value="" name="ev_range" placeholder="Range in Km"><br>
<label>Cost</label>
<input type="number" value="" name="ev_cost" placeholder="Price in €"><br>
<label>Power</label>
<input type="number" value="" name="ev_power" placeholder="Power in Kw"><br>
<br>
<input type="submit" id="update_submit" value="Update details" name="submit_button" />
</form>
</div>
Try the below changes in your code.
In CSS:
remove .hidden from .UpdateForm-section.hidden
In JS:
use querySelector instead of getElementByClass and wrap the name of the class in quotes.
Wokring code:
function showForm() {
alert('Form has been submitted');
document.querySelector('.UpdateForm-section').style.display = 'block';
}
.UpdateForm-section {
display: none;
}
<input type="submit" name="delete" class="button-1" value="Update" onclick="showForm();" />
<br><br><br>
<!-- Update details form here -->
<div>
<form action="" method="post" class="UpdateForm-section">
<label>Car Name</label>
<input type="text" value="" name="ev_name" placeholder="Model name"><br>
<label>Manufacturer</label>
<input type="text" value="" name="ev_manufacturer" placeholder="Brand name"><br>
<label>Year</label>
<input type="number" value="" name="ev_year" placeholder="YYYY"><br>
<label>Battery size</label>
<input type="number" value="" step="any" name="ev_battery" placeholder="Capacity in Kwh"><br>
<label>Range</label>
<input type="number" value="" name="ev_range" placeholder="Range in Km"><br>
<label>Cost</label>
<input type="number" value="" name="ev_cost" placeholder="Price in €"><br>
<label>Power</label>
<input type="number" value="" name="ev_power" placeholder="Power in Kw"><br>
<br>
<input type="submit" id="update_submit" value="Update details" name="submit_button" />
</form>
</div>
I suggest you to have the following approach: define a desired style when your element will be shown:
.UpdateForm-section { // here we set the default style of the div -> not displayed
display: none;
}
.UpdateForm-section.active { // here the CSS selector is stronger, so it will override the previous statement
display: block;
}
Then in your javascript, you just add the "active" class to the element when you want it to show:
function showForm() {
alert('Form has been submitted');
document.querySelector(".UpdateForm-section").classList.add('active'); // Prefer to use an id to select an unique element to avoid miss coding
}
You just need to save your form in a variable, and you can easyly change it after it. You will need to remove .hidden from your css.
You need to use form[0], because when you make getElementsByClassName, you are getting an array:
function showForm() {
alert('Form has been submitted');
var form = document.getElementsByClassName("UpdateForm-section");
form[0].style.display = 'block'
}

jQuery: select id by matching only part of its name [duplicate]

This question already has an answer here:
jQuery: Finding partial class name [duplicate]
(1 answer)
Closed 2 years ago.
In my code I've got pleny of inputs with the following pattern:
<input type="text id="Order_Products_0_quantity" value="0">
<input type="text id="Order_Products_1_quantity" value="1">
<input type="text id="Order_Products_2_quantity" value="2">
etc
The only difference between them is the number in the middle which stands for their place in the row. Is it possible to somehow match all of them and select their values with jQuery?
The correct way to do this would be:
<input type="text" data-order-qty="0" class="Order_Products_quantity" value="0">
<input type="text" data-order-qty="1" class="Order_Products_quantity" value="1">
<input type="text" data-order-qty="2" class="Order_Products_quantity" value="2">
You can then retrieve the element like so:
$(".Order_Products_quantity[data-order-qty=2]");
Or fetch the order qty like so:
$(".Order_Products_quantity").eq(1).attr('data-order-qty');
Here's more info on using custom attributes:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
You can try using Attribute Starts With Selector [name^="value"].
Demo:
$('[id^=Order_Products_]').each(function(){
console.log(this.value);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="Order_Products_0_quantity" value="0">
<input type="text" id="Order_Products_1_quantity" value="1">
<input type="text" id="Order_Products_2_quantity" value="2">
Attribute selectors to the rescue:
Attribute Starts With Selector [name^=”value”]
Attribute Ends With Selector [name$=”value”]
var inps = $('input[id^="Order_Products_"][id$="_quantity"]')
console.log(inps.map(function () { return +this.value }).get())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="Order_Products_0_quantity" value="0">
<input type="text" id="Order_Products_1_quantity" value="1">
<input type="text" id="Order_Products_2_quantity" value="2">
<input type="text" id="Order_Products_0_foo" value="4">
<input type="text" id="Order_Products_1_foo" value="5">
<input type="text" id="Order_Products_2_foo" value="6">
It would be better to add a class, but this selector will work.

getElementById() returns null on first element

The following code is my simple registration form. The problem is that alert(elements[0].value) displays undefined instead of the value of name (which is the first element of my form). However, if I try to execute alert(elements[1].value), it displays the value of name without any problem. Any ideas?
<html>
<body>
<form name="register" id="register" method="POST" action="this-file.php">
<fieldset>
<legend><span style="color:red; font-size:20px">
Register</span></legend><br>
<label for="firstname">First name<span style="color:red;">*</span></label>
<input type="text" name="firstname" id="firstname" placeholder="Peter"
autofocus required><br><br>
<label for="lastname">Last name<span style="color:red;">*</span></label>
<input type="text" name="lastname" id="lastname" placeholder="Parker"
required><br><br>
<label for="password">Password<span style="color:red;">*</span></label>
<input type="password" name="password" id="password" required><br><br>
<label for="favfood">Favorite food<span style="color:red;">*</span></label>
<select name="favfood" id="favfood" required>
<option value="" selected>(none)</option>
<option value="chicken">Chicken</option>
<option value="pizza">Pizza</option>
<option value="pasta">Pasta</option>
<option value="hamburger">Hamburger</option>
<option value="steak">Steak</option>
</select>
<p>Gender<span style="color:red;">*</span></p>
<ul>
<li>
<input type="radio" name="gender" id="male" value="male" required>
<label for="male">Male</label>
</li>
<li>
<input type="radio" name="gender" id="female" value="female" required>
<label for="female">Female</label>
</li>
</ul>
</fieldset><br>
<input type="submit" value="Register" name="register">
<input type="reset" value="Clear form" name="clear"><br><br>
</form>
<script type="text/javascript">
var form = document.getElementById('register');
var elements = form.elements;
form.noValidate = true;
form.addEventListener('submit', function (event) {
alert(elements[0].value); //displays "undefined" -- why?
for (var i = 0; i < elements.length; i++) {
if (elements[i].hasAttribute("required")) {
if (!elements[i].checkValidity()) {
event.preventDefault();
alert('Please, fill in every required field.');
form.reset();
elements[0].focus();
break;
}
}
}
}, false);
</script>
</body>
</html>
The first element in the elements collection is the <fieldset>. It doesn't have a name or a value.
(Yes, I know it doesn't really make sense for elements to include fieldsets, but it does).
Test the value of theelement.tagName to see if you are dealing with an input/select/textarea before trying to run your validation routine on it.

Simple generate button with html and javascript and save after finish

I try to generate a simple button by HTML and JavaScript. Unfortunately, I don't know how to it with JavaScript to catch to value from input range HTML to apply for button. How could I use JavaScript to catch value from HTML range?
this is my html code:
<form name='frm'>
<div id="div">
<label>
Width:
<input type="text" id="MyText"/>
<input type="range" id="MyRange" oninput="myfunc()"/>
</label><br/>
<label>
Height:
<input type="text" id="height"/>
<input type="range" id="heights" oninput="myfunc()"/><br/>
</label><br/>
<label>
Background:
<input type="text" id="bdg"/>
<input type="color" id="background"/>
<!--/* <input type="range"/>
<input type="imge" name="imge"/>*/-->
</label><br/>
<label>
Radius:
<input type="text" name="rad" id="Radius"/>
<input type="range" name="rad" id="Rd"/><br/>
</label><br/>
<label>
Margin:
<input type="text" name="margin" id="margin"/><br/>
</label><br/>
<label>
Padding:
<input type="text" name="padding" id="padding"/><br/>
</label><br/>
<label>
Box-shadow:
<input type="text" name="shadow" id="shadow"/><br/>
</label><br/>
</div>
<div id="div">
<label>
Color:<br/>
<input type="text" name="col" id="color"/>
<input type="color" id="colors"/><br/>
</label>
<label>
Border-width:<br/>
<input type="text" name="bdwidths" id="bw"/>
<input type="range" id="bdw"/><br/>
</label>
<label>
Border-style:<br/>
<input type="number" name="bdstyle" id="bdstyle"/><br/>
</label>
<label>
Border-color:<br/>
<input type="number" name="bdcol" id="bdcolor"/>
<input type="color" id="color"/><br/>
</label>
<label>
Text-align:<br/>
<input type="number" name="aligns" id="ta"/><br/>
</label>
<label>
Font-size:<br/>
<input type="number" name="font" id="font"/>
<input type="range" id="font-size"/><br/><br/>
</label>
<label>
<input type="button" value="save change" onclick="save()"/>
</label>
</div>
</form>
My Button
To trigger the javascript function you need to listen for changes/events.
This is using the oninput attribute. This will trigger/call the javascript function myfunc each time the range has a new input.
This is now using id attributes, not name attributes.
document.getElementById('') Is used to target the element
document.getElementById('').value is used to target the elements value.
function myfunc(){
//Assign a variable to the MyRange element.
var MyVariable= document.getElementById('MyRange');
//Target the MyText input and change the value to the value of MyVariable.
document.getElementById('MyText').value=MyVariable.value+'px';
//Target MyBtn's style - width
document.getElementById('MyBtn').style.width=MyRange.value+'px';
}
Width:<input type="text" id="MyText"/><br/>
<input type="range" id="MyRange" oninput="myfunc()"/>
<button id="MyBtn">My Button</button>
If you don't understand any of the source code please leave a comment below and I will explain it line by line for you so you understand how this works. It's better to understand how something works rather than copy/paste and hope for the best.
Javascript should be placed inside of script tags
<script type="text/javascript">
//Place Javascript Here....
</script>
I hope this helps. Happy coding!
Give the element an ID so you can access it:
<input type="range" id="widthrange" name="widths"/>
Then in your Javascript, you can do:
var width = document.getElementById("widthrange").value;

How to wrap two elements into one div?

I have a problem with wrapping two elements: label and input into one div. Can you help me how to do it right ? Thank you very much.
Example:
<label><label>
<input>
<label></label>
<input>
Should be:
<div data-role="fieldcontain">
<label><label>
<input>
</div>
<div data-role="fieldcontain">
<label><label>
<input>
</div>
Jquery:
$('input[type="text"]').prev().andSelf().wrap('<div data-role="fieldcontain">');
HTML:
<label>Name: </label>
<input type="text" name="name" id="name" value="" />
<label>Surname: </label>
<input type="text" name="surname" id="surname" value="" />
You need to loop through each input then club the input and the label and use .wrapAll() like
$('input[type="text"]').each(function () {
$(this).prev().addBack().wrapAll('<div data-role="fieldcontain">');
})
Demo: Fiddle

Categories