How can I get the value of a textarea after input but not in same div with jQuery? I tried to do the foreach and find methods. I need to get the value and assign to JS object.
<div id="txtall">
<div class="subdiv">
<input type = "text" value = "firstInput" class= "subinput">
</div>
<textarea class="textarea" class="subTextarea"> firsttextareavalue </textarea>
<div class="subdiv">
<input type = "text" value = "secondInput" class= "subinput">
</div>
<textarea class="textarea" class="subTextarea" /></textarea>
<div class="subdiv">
<input type = "text" value = "thirdInput" class= "subinput">
</div>
<textarea class="textarea" class="subTextarea" />second may be empty</textarea>
<div class="subdiv">
<input type = "text" value = "forthInput" class= "subinput">
</div>
<textarea class="textarea" class="subTextarea" />last text area value</textarea>
When I click a button I need to get value.
$('#txtall').find('.subinput').each(function() {
console.log(this.value);
console.log($(".subtextarea",this).val());
});
The output needs to be:
firstInput
firsttextareavalue
secondInput
(this should be empty)
thirdInput
second may be empty
forthInput
last text area value
I also have to assign value to JS object.
function newObject(input,textarea)
{
this.input = input;
this.textarea = textarea;
}
var list = [];
$('#txtall').find('.subinput').each(function() {
var obj_1 = new newObject();
obj_1.input = this.value;
obj_1.textarea = $(".subtextarea",this).val();
list.push(obj_1);
});
By the way, I need to use this and I can't assign a different id or class to each input or textarea.
The textarea comes after the input, so it's the next() element from the parent .subdiv
$('#txtall').find('.subinput').each(function() {
console.log( this.value );
console.log( $(this).closest('.subdiv').next('.subtextarea').val() );
});
When you do $(".subtextarea",this) it's the same as $(this).find(".subtextarea"), which will only find descendants, and inputs don't have descendants.
Note that your HTML is invalid, you can only have the class attribute once, and you shouldn't be closing the textareas twice
There's also no reason to create instances here, and you can just map the elements
var list = $('#txtall').find('.subinput').map(function() {
return {
input : this.value,
textarea : $(this).closest('.subdiv').next('.subTextarea').val()
}
}).get();
console.log(list)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="txtall">
<div class="subdiv">
<input type="text" value="firstInput" class="subinput">
</div>
<textarea class="textarea subTextarea"> firsttextareavalue </textarea>
<div class="subdiv">
<input type="text" value="secondInput" class="subinput">
</div>
<textarea class="textarea subTextarea"></textarea>
<div class="subdiv">
<input type="text" value="thirdInput" class="subinput">
</div>
<textarea class="textarea subTextarea">second may be empty</textarea>
<div class="subdiv">
<input type="text" value="forthInput" class="subinput">
</div>
<textarea class="textarea subTextarea">last text area value</textarea>
</div>
Use .next() to get to the next element after the parent DIV.
function newObject(input, textarea) {
this.input = input;
this.textarea = textarea;
}
$("#button").click(function() {
var list = [];
$('#txtall').find('.subinput').each(function() {
var input = this.value;
var textarea = $(this).closest(".subdiv").next(".subTextarea").val();
var obj_1 = new newObject(input, textarea);
list.push(obj_1);
});
console.log(list);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="txtall">
<div class="subdiv">
<input type="text" value="firstInput" class="subinput">
</div>
<textarea class="subTextarea"> firsttextareavalue </textarea>
<div class="subdiv">
<input type="text" value="secondInput" class="subinput">
</div>
<textarea class="subTextarea" /></textarea>
<div class="subdiv">
<input type="text" value="thirdInput" class="subinput">
</div>
<textarea class="subTextarea" />second may be empty</textarea>
<div class="subdiv">
<input type="text" value="forthInput" class="subinput">
</div>
<textarea \class="subTextarea" />last text area value</textarea>
</div>
<button id="button">Click me</button>
$('#txtall').find('.subinput').each(function() {
console.log( this.value );
console.log( $(this).closest('.subdiv').next('textarea').val() );
});
Try this Code use $(this).parent().next().val(); it will get the textarea next to the parent of input.
function newObject(input,textarea)
{
this.input = input;
this.textarea = textarea;
}
var list = [];
$('#txtall').find('.subinput').each(function() {
var obj_1 = new newObject();
obj_1.input = this.value;
obj_1.textarea = $(this).parent().next().val();
list.push(obj_1);
});
Working Fiddle
Related
I have a form with 3 fields:
<form id="book-form">
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" placeholder="Enter a title">
</div>
<div class="form-group">
<label for="author">Author</label>
<input type="text" name="author" class="form-control" placeholder="Enter the author of the book">
</div>
<div class="form-group">
<label for="isbn">ISBN#</label>
<input type="text" name="isbn" class="form-control" placeholder="Enter the book isbn">
</div>
<button type="submit" class="btn btn-primary btn-block">Add Book to store</button>
</form>
Here are I am retrieving the value of these fields that I will insert in their respective span in the html.
const title = document.getElementsByName('title')[0].value
const author = document.getElementsByName('author')[0].value
const isbn = document.getElementsByName('isbn')[0].value
Now I have three span tags where the value of these form fields are suppose to be inserted.
<span class="title">// the value of title</span>
<span class="author">// the value of author</span>
<span class="isbn">// the value of isbn</span>
Now I have a function that checks if the retrieve from the fields of the form is not empty(null) if that is the case I want to remove the span that is was suppose to be in the dom.
function insertMe(fieldValue) {
if (fieldValue === "") {
// How to remove the span that it was suppose to go
} else {
return fieldValue
}
}
It's not clear how you're calling insertMe, and the name of that function is misleading because you're only removing elements, not adding them.
I'd approach it this way.
When the button is clicked/onSubmit call the function and use querySelectorAll to target all the inputs by class. Iterate over them and if the value is an empty string remove the span whose class matches the name of the input, otherwise set the text content of the span to the input value.
const button = document.querySelector('button');
button.addEventListener('click', handleClick, false);
function handleClick() {
const inputs = document.querySelectorAll('.form-control');
inputs.forEach(({ name, value }) => {
const el = document.querySelector(`span.${name}`);
if (el && !value) {
el.remove();
} else {
el.textContent = value;
}
});
}
<input type="text" class="form-control" name="title" placeholder="Enter a title">
<input type="text" class="form-control" name="author" placeholder="Enter an author">
<input type="text" class="form-control" name="isbn" placeholder="Enter an ISBN number">
<button>Click</button>
<br/><br/>
<span class="title">Title</span><br/>
<span class="author">Author</span><br/>
<span class="isbn">ISBN</span><br/>
I have a form for which I should write validation logic.
Let's say there's an input field like this.
<div class="group1"><label>Product code</label> <input id="code" name=""code" type="text" class="control1"></div>
If I want to make it a required field how do I write the logic?
I don't have access to the CSS files. But there's an input like this which I can use which has a red outline.
<div class="group1 row has-error">
<div><input type="text" class="control1"></div>
</div>
I have to give the code in JavaScript or jQuery.
Get an element and set true on required property.
const input1 = document.getElementById('code');
input1.required = true;
const input2 = document.querySelector('div.group1>div>input.control1');
input2.required = true;
<form>
<div class="group1"><label>Product code</label>
<input id="code" name="code" type="text" class="control1">
</div>
<div class="group1 row has-error">
<div>
<input type="text" class="control1">
</div>
</div>
<input type="submit">
</form>
I think this is what you need
$("#formSubmit").submit(function(e) {
e.preventDefault();
var error_text = "<div class='text-danger error_val'>Cannot be empty</div>"
var data = $("#formSubmit").serializeArray();
var allInputs = $("#formSubmit input");
for(var i=0; i<data.length; i++){
if(data[i].value.length == 0){
$(".group1").addClass('has-error');
var errorDiv = $(allInputs)[i].closest('.has-error');
$(error_text).insertAfter( errorDiv );
}
}
});
.has-error input{
border: 1px solid #f00;
}
.text-danger{
color:#f00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formSubmit">
<div class="group1 row">
<label>Product code</label>
<input id="code" name="code" type="text" class="control1" >
</div>
<button type="submit" id="submitButton">Save</button>
</form>
I know it`s too late but you can use these functions to make an input required/optional
function makeFieldRequired(element, elementName) {
let jqueryObj = $(element);
jqueryObj.attr('title', `${elementName} is required`);
jqueryObj.attr('required', 'true');
if (jqueryObj.closest("form").length)
refreshFormValidtion(jqueryObj.closest("form"));
}
function makeFieldOptional(element) {
let jqueryObj = $(element);
jqueryObj.removeAttr('required');
jqueryObj.removeAttr('title');
if (jqueryObj.closest("form").length)
refreshFormValidtion(jqueryObj.closest("form"));
}
function refreshFormValidtion(form) {
$(form).removeData("validator").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse($(form));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I'm trying to create new fields like the first field in this form by clicking on an image, but the fields are spawning below the button to submit and I don't understand why. The behavior I'm looking for is for the new fields to spawn above the button.
Here's my code
<div id="title">
<h1>Monthly Run Operations Assessment</h1>
</div>
<div class="row">
<div class="col-20" id="row-one">
<label for="name">1. </label>
</div>
<div class="col-60">
<input type="text" id="op" name="op" placeholder="Insert operation here">
</div>
<div class="col-20" id="symbol">
<img src="file:///C:/Users/user/Downloads/plus-circle-solid.svg" id="add">
</div>
</div>
<div id="submit">
<input type="submit" value="Submit">
</div>
</div>
This is the function:
var element = document.getElementById("add");
element.onclick = function() {
console.log("woot");
var ele = document.getElementsByClassName("row")[0];
var clone = ele.cloneNode(true);
var newDiv = document.createElement("div");
document.body.appendChild(clone);
}
appendChild, as its name suggests, always appends the new element -- that is, it adds it to the end. What you want is insertBefore:
document.body.insertBefore(clone, ele);
One way to handle this is to wrap your form in a container and append to it :
var element = document.getElementById("add");
element.onclick = function() {
// console.log("woot");
var ele = document.getElementsByClassName("row")[0];
var clone = ele.cloneNode(true);
var newDiv = document.createElement("div");
document.querySelector('#container').appendChild(clone);
}
<div id="title">
<h1>Monthly Run Operations Assessment</h1>
</div>
<div id="container">
<div class="row">
<div class="col-20" id="row-one">
<label for="name">1. </label>
</div>
<div class="col-60">
<input type="text" id="op" name="op" placeholder="Insert operation here">
</div>
<div class="col-20" id="symbol">
<img src="file:///C:/Users/user/Downloads/plus-circle-solid.svg" id="add">
</div>
</div>
</div>
<div id="submit">
<input type="submit" value="Submit">
</div>
</div>
I combined the above answers to achieve the expected behavior.
var element = document.getElementById("add");
element.onclick = function() {
// console.log("woot");
var ele = document.getElementsByClassName("row")[0];
var clone = ele.cloneNode(true);
var newDiv = document.createElement("div");
document.querySelector('#container').insertBefore(clone, ele);
}
I am trying to loop through the form which has label inside random elements and check if the label matches with the given label name and if matches, I am adding a class to that element. But I am not able get it working, how can I do this?
Here's what I have tried.
Form which has labels inside random elements like div
<form id="grtform">
<div id="section-1">
<lable>Currency type</lable>
<input type="text" name="currencyType">
</div>
<div id="section-2">
<lable>Currency rate</lable>
<input type="text" name="currencyRate">
</div>
<lable>Currency of country</lable>
<input type="text" name="currencyCountry">
<div id="section-3">
<div class="formData">
<lable>Currency due</lable>
<input type="text" name="currencyDue">
</div>
</div>
</form>
Jquery code:
$("#grtform").each(function(){
var matchLable = "Currency due"
var lable = $(this).find('label').text();
if(matchLable == lable){
$(this).addClass('matchFound');
}
});
You need loop through lables, not against form
$("#grtform lable").each(function(){ // selecting all labels of form
var matchLable = "Currency type"
var lable = $(this).text(); // changed here too
if(matchLable == lable){
$(this).addClass('matchFound');
}
});
In above code, this refers to currently iterating label.
After trimming a bit
$("#grtform lable").each(function(){ // selecting all labels of form
if($(this).text() == "Currency type"){
$(this).addClass('matchFound');
}
});
You can also use following way :-
var allLables = document.querySelectorAll("#grtform lable");
for(var i = 0; i < allLables.length; i++){
var matchLable = "Currency type";
var lable = allLables[i].innerText; // changed here too
if(matchLable == lable){
allLables[i].classList.add("matchFound");
}
}
<form id="grtform">
<div id="section-1">
<lable>Currency type</lable>
<input type="text" name="currencyType">
</div>
<div id="section-2">
<lable>Currency rate</lable>
<input type="text" name="currencyRate">
</div>
<lable>Currency of country</lable>
<input type="text" name="currencyCountry">
<div id="section-3">
<div class="formData">
<lable>Currency due</lable>
<input type="text" name="currencyDue">
</div>
</div>
</form>
I have several div tags with the class of opt that have an input and button element inside them. I am trying to create a function that will take the value from the input tag and when you click the button, the next input and button field will pop up and ask you to enter different information, while the previous input and button tags will hide itself. However, the function is not working here is the jsfiddle.
HTML
<div id="container">
<div class="opt active"> <input type="text" placeholder ="Enter Name"name="name"> <button>OK</button>
</div>
<div class="opt">
<input type="text" placeholder ="Enter Age" name="age"> <button>OK</button>
</div>
<div class="opt">
<input type="text" placeholder ="Enter Race" name="race"> <button>OK</button>
</div>
<div class="opt">
<input type="text" placeholder ="Enter Sex" name="sex"> <button id="done">Done</button>
</div>
</div>
Javascript
function init(){
var opt = document.getElementsByClassName('opt');
var num = 0;
var prop = [];
var propVal = [];
for (var i = 0 ; i < opt.length; i++)
{
opt[i].querySelector('input').value = "";
}
opt[num].querySelector('button').onclick = function()
{
prop[num] = opt[num].querySelector('input').name;
propVal[num]= opt[num].querySelector('input').value;
opt[num].className = "opt";
opt[num+1].className ="opt active";
console.log(prop +" "+ propVal);
num++;
};//button function
}
init();
You need bind the click handlers in the loop as well. You also don't need to use parallel arrays to store the properties when you could use an object instead.
Make sure that there is a "next input" before trying to change the class of the next one.
var opt = document.getElementsByClassName('opt'),
num = 0, prop = {};
function nextInput() {
var input = opt[num].querySelector('input');
prop[input.name] = input.value;
console.log(prop);
opt[num].className = "opt";
if (num + 1 < opt.length) {
opt[num + 1].className = "opt active";
num++;
} else {
// submit?
}
}
for (var i = 0; i < opt.length; i++) {
opt[i].querySelector('input').value = "";
opt[i].querySelector('button').onclick = nextInput;
}
.opt { display: none }
.opt.active { display: block }
<div id="container">
<div class="opt active">
<input type="text" placeholder="Enter Name" name="name">
<button>OK</button>
</div>
<div class="opt">
<input type="text" placeholder="Enter Age" name="age">
<button>OK</button>
</div>
<div class="opt">
<input type="text" placeholder="Enter Race" name="race">
<button>OK</button>
</div>
<div class="opt">
<input type="text" placeholder="Enter Sex" name="sex">
<button id="done">Done</button>
</div>
</div>