in React.js data-reactid is breaking html text input? - javascript

Hi so my React component renders in the html and works with one catch.
The Catch is "data-reactid=".0.0"" this breaks the input and prevents you from being able to type in it. As soon as i remove/change this the input works again.
My React Component:
/** #jsx React.DOM */
var React = require('../../../../node_modules/react/react.js');
// react component DateBox will return a date time that updates every 50 miliseconds and appends it to a div with an id of 'date_box'
var GoogleSearchBox = React.createClass({
GetValueFromGoogleSearchInput: function(event){
var GoogleSearch = document.getElementById("google_search_input");
var UserSearchQuery = GoogleSearch.value.toString().replace(/ /g,"+");
var GET = "http://google.com/#q=" + UserSearchQuery;
window.open(GET, '_blank');
},
//rendering the html elements with the state.clock
render: function() {
return (
<div className="google_search">
<input type="text" value="" placeholder="Type here to search google" name="google_search_input" id="google_search_input">
</input>
<div>
<button id="google_search_button" onClick={this.GetValueFromGoogleSearchInput}></button>
</div>
</div>
);
}
});
//rendering with react to put onto the html
module.exports = GoogleSearchBox;
How it renders in html:
<div id="google_search_box">
<div class="google_search" data-reactid=".0">
<input type="text" value="" placeholder="Type here to search google" name="google_search_input" id="google_search_input" data-reactid=".0.0">
<div data-reactid=".0.1">
<button id="google_search_button" data-reactid=".0.1.0"></button>
</div>
</div>
</div>

Your text field is not responding to user input because you created a Controlled Component by manually setting the value prop.
An <input> with value set is a controlled component. In a controlled
<input>, the value of the rendered element will always reflect the
value prop.
If you would like to set a default value but allow the text field to respond to user input, consider setting the defaultValue prop instead.
<input type="text" defaultValue="" placeholder="Type here to search google" name="google_search_input" id="google_search_input">

Related

How to Remove Input text after submit HTML JavaScript

I have a dialog that contains inputs,
User should complete dialog inputs then click send,
After that, user can open the same dialog again and complete dialog inputs.
But when the user open the dialog again, input values remain as same from previous inputs,
How can I remove previous input values?
My Dialog:
<dialog id="main-customers">
<h2>العملاء الرئيسيون</h2>
<div>
<label for="main-customers-name">الاسم</label>
<input type="text" id="main-customers-name" placeholder="الاسم" required>
<label for="main-customers-country">الدولة</label>
<input type="text" id="main-customers-country" placeholder="الدولة" required>
<label for="main-customers-goods">سلع / بضائع</label>
<input type="text" id="main-customers-goods" placeholder="سلع / بضائع" required>
</div>
<div class="center">
<button id="main-customers-send">إرسال</button>
<button id="main-customers-cancel" onclick="closeDialog('main-customers')">إلغاء</button>
</div>
</dialog>
My JS:
document.getElementById("main-customers-send").addEventListener("click", function(){
// to remove initial value
var no_data= document.getElementById("main-customers-table-no-data");
if(no_data){
no_data.remove()
}
// END to remove initial value
var name= document.getElementById("main-customers-name");
var country= document.getElementById("main-customers-country");
var goods= document.getElementById("main-customers-goods");
document.getElementById("main-customers-table").innerHTML+=
`<tr>
<td>${name.value}</td>
<td>${country.value}</td>
<td>${goods.value}</td>
</tr>`;
let itms = document.querySelectorAll("#main-customers");
for (let itm of itms) {
if(itm.value != ""){
itm.value= ""; //it does not do the job
}
}
closeDialog("main-customers")
})
-
values remain the same as shown below:
The line let itms = document.querySelectorAll("#main-customers"); doesn't do what you think it does. It selects all the elements with the id "main-customers" (which per spec a page could only have one of).
Try let itms = document.querySelectorAll("#main-customers input[type=text]"); instead of that which will select all the children of the #main-customers element that is an input whose type is text.

JavaScript, get the value of input field on entry

I have a HTML page with an input field that the user enters a value into. The HTML code looks like this:
<div class="d-flex mg-b-0 mb-3" id="cbWrapper2">
<input type="number" name="message_average" class="form-control" id="id_message_average">
</div>
I'm trying to use JavaScript to get the value entered by the user so that I can then compare it against another value and write out the result, but I'm not sure how I collect the initial value being entered. What I have so far:
<script>
var value = document.getElementById("id_message_average").value;
console.log(value);
</script>
I'm just trying to write the value out for now so that I can tell it's working. Do I need to put it into some kind of event listener maybe when the user clicks onto another input field, or is there a way to have the script fire when a character is added?
There are indeed events to use to listen to changes in the input. One of them is called input, and you can use it like below.
The input event fires when the value of an <input>, <select>, or <textarea> element has been changed. More on MDN's doc.
var input = document.getElementById("id_message_average");
input.addEventListener("input", ()=>{
console.log(input.value)
});
<div class="d-flex mg-b-0 mb-3" id="cbWrapper2">
<input type="number" name="message_average" class="form-control" id="id_message_average">
</div>
For that you have add event listener.
let userInput = document.getElementById("id_message_average");
userInput.addEventListener("input", (e)=> {
console.log(e.target.value)
})'
You can use onClick function. If you choose onClick then you must need a button. Here is the example,
<form>
<div class="d-flex mg-b-0 mb-3" id="cbWrapper2">
<input type="number" name="message_average" class="form-control" id="id_message_average">
</div>
<button type='button' onclick="getInputValue()">Click me</button>
</form>
<script>
function getInputValue() {
var value = document.getElementById("id_message_average").value;
console.log(value);
}
</script>

How to select clicked element using querySelector

<div class="search-input" onclick="getSearch()">
<input
oninput="getPorts(value)"
type="text"
id="pick"
name="pick"
placeholder="Enter Pickup Location"
required
/>
<div class="autocom-box">
<!-- dynamic portsData map box -->
</div>
</div>
<div class="search-input" onclick="getSearch()">
<input
oninput="getPorts(value)"
type="text"
id="dest"
name="dest"
placeholder="Enter Destination"
required
/>
<div class="autocom-box">
<!-- dynamic portsData map box -->
</div>
</div>
This is Js
let searchWrapper;
let inputBox;
let suggBox;
const getSearch = () => {
searchWrapper = document.querySelector(".search-input");
console.log(searchWrapper);
inputBox = searchWrapper.querySelector("input");
console.log(inputBox);
suggBox = searchWrapper.querySelector(".autocom-box");
console.log(suggBox);
};
I am trying to get class selected based click as the class name is same (search-input) but here whichever div i click it always gets selected the 1st one. (In searchWrapper console.log it gives 1st div and its elements)
Can anyone tell me What am i doing wrong here so that i can get 2nd div and its elements if i click on 2nd div.
Two answers for you.
Using modern event handling
I suggest you don't use onxyz-attribute-style event handlers. There are multiple issues with them, but probably the most significant two are:
They can only call global functions.
The generated context for them is very complex, making it very easy to run into conflicts (for instance, if your function had the name removeChild or appendChild or in some cases submit, you wouldn't end up calling your function, you'd call a method on a DOM element instead).
Instead, look at using addEventListener. Here's an example where the event handlers are directly attached to your div elements:
<div class="search-input">
<input
oninput="getPorts(value)"
type="text"
id="pick"
name="pick"
placeholder="Enter Pickup Location"
required
/>
<div class="autocom-box">
<!-- dynamic portsData map box -->
</div>
</div>
<div class="search-input">
<input
oninput="getPorts(value)"
type="text"
id="dest"
name="dest"
placeholder="Enter Destination"
required
/>
<div class="autocom-box">
<!-- dynamic portsData map box -->
</div>
</div>
const getSearch = (event) => {
const searchWrapper = event.currentTarget;
const inputBox = searchWrapper.querySelector("input");
const suggBox = searchWrapper.querySelector(".autocom-box");
// ...
};
for (const element of document.querySelectorAll(".search-input")) {
element.addEventListener("click", getSearch);
}
I only did the div elements there, but you'd want to do the input elements as well.
You might also look at delegated event handling.
Continuing with onclick attribute
If you really want to keep using the onclick attribute, pass this into it:
<div class="search-input" onclick="getSearch(this)">
<!-- −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^ -->
this in the context generated for onxyz-attribute-style event handlers is the element the onclick attribute is on (the .search-input div in this case).
Then, in getSearch, search within that div:
const getSearch = (searchWrapper) => {
const inputBox = searchWrapper.querySelector("input");
const suggBox = searchWrapper.querySelector(".autocom-box");
// ...
};
First of all stop using inline event listeners. Use addEventListener instead. To do so, grab a list of all search input wrappers and iterate over the list, adding a click listener to each and every one.
When you have done so, the handler function automatically gets passed the event object, which contains the currentTarget property holding a reference to the element the event listener is bound to. This then allows you to find descendants of that element using querySelector on it instead of document.
To access the event object, you need to define a parameter name in your handler function. I've used event in below example, but you can name it anything you like.
let searchWrapper;
let inputBox;
let suggBox;
const getSearch = (event) => {
searchWrapper = event.currentTarget;
console.log(searchWrapper);
inputBox = searchWrapper.querySelector("input");
console.log(inputBox);
suggBox = searchWrapper.querySelector(".autocom-box");
console.log(suggBox);
};
for (const searchInput of document.querySelectorAll('.search-input')) {
searchInput.addEventListener('click', getSearch);
}
<div class="search-input">
<input type="text" id="pick" name="pick" placeholder="Enter Pickup Location" required />
<div class="autocom-box">
1. abc
</div>
</div>
<div class="search-input">
<input type="text" id="dest" name="dest" placeholder="Enter Destination" required />
<div class="autocom-box">
2. def
</div>
</div>

React.js - How do I uniquely identify a field within a dynamically generated component?

I am currently creating a form that has an unknown number of sensor fields within it. I've gotten the front end working beautifully. However, now I want to grab the user info out of those dynamically generated component fields and I can't figure out how. Here is where I'm generating the components:
{this.state.sensors.map((item, i) => (
<UpdateSensorInfo
key={i}
sensorName={item.sensorName}
sensorLowerLimit={item.sensorLowerLimit}
sensorUpperLimit={item.sensorUpperLimit}
/>
))}
And here is the actual component itself:
import React, { Component } from "react";
import "./updateSensorInfo.css";
class UpdateSensorInfo extends Component {
render() {
return (
<div>
<div className="sensorInfoFrame">
<div className="sensorFieldBody">
<label className="sensorTextFieldLabel">Sensor Name:</label>
<input
type="text"
name="text"
placeholder=""
className="sensorTextField"
defaultValue={this.props.sensorName}
required
/>
</div>
<div className="sensorFieldBody">
<label className="sensorTextFieldLabel">Sensor Upper Limit:</label>
<input
type="number"
name="text"
placeholder=""
className="sensorTextField"
defaultValue={this.props.sensorUpperLimit}
required
/>
</div>
<div className="sensorFieldBody">
<label className="sensorTextFieldLabel">Sensor Lower Limit:</label>
<input
type="number"
name="text"
placeholder=""
className="sensorTextField"
defaultValue={this.props.sensorLowerLimit}
required
/>
</div>
</div>
</div>
);
}
}
export default UpdateSensorInfo;
I would like to uniquely identify each text field within each generated component. How can I do this?
For anyone who has a similar situation, I have found a solution that works. There is a way to use the key that is created for each of the components within each component. use the following as an id or name for the input element:
id={`${this._reactInternalFiber.key}-additionalNameHere`}
This uses the key and will allow you to loop over the inputs within the components.

React accessing children in form

I can not really access my dynamically generated children in a component. I found some cases on the internet, it seems like a common problem but nothing i could properly relate to or it was not really well documented so i got more confused.
I have a form which has a button and every time a press the button, subform is added to the form.
render: function() {
var prop_forms = [];
for(var i = 1; i <= this.state.count; i++){
prop_forms.push(<App.Form.Property reference={i}/>);
}
return(
<div>
<h2>New model</h2>
<form className="form" callback={this.submited}>
<label>Name:</label>
<input type="text" ref="name" className="fancy_input" required/>
<label><input type="checkbox" ref="include_endpoints"/> Include basic endpoints</label>
<h3>Properties <a onClick={this.add_property}><span className="glyphicon glyphicon-plus"></span></a></h3>
{prop_forms}
<button className="btn" onClick={this.submited} type="button">Add model to the canvas</button>
</form>
</div>
);
}
every time a click a button, this.state.count is incremented so I get one more App.Form.Property component. I am passing the i variable so i can use it in my ref parameter in the App.Form.Property component.
render: function(){
var input_ref = "property_"+this.props.reference+"_input";
var select_ref = "property_"+this.props.reference+"_select";
return(
<div className="property_form">
<input className="fancy_input" ref={input_ref} type="text" placeholder="Property name..."/>
<select className="fancy_select" ref={select_ref}>
<option value="string">String</option>
<option value="integer">Integer</option>
<option value="double">Double</option>
</select>
</div>
);
}
My problem is that when i submit the form, I can not access the children via ref. I can only address name and include_endpoints but nothing from the App.Form.Property component.
Add a function getSubmitData in your form component that encapsulates the children from the outer element

Categories