HTML Form Concatenate Inputs into One Field (with GET) - html

Long story short:
<form action="example.com/" method="get">
<input type="hidden" name="q" value="one,two,">
<input type="text" name="q">
</form>
The goal is that, when the user inputs e.g. "three", the website
example.com/?q=one,two,three
is called, instead of example.com/?q=one,two,&q=three.
A solution without JavaScript would be ideal, but I suspect that's not possible.
Thank you so much!

If you don't mind using an array then you can try using this solution
<form action="example.com/" method="GET">
<input type="hidden" name="q[]" value="one">
<input type="hidden" name="q[]" value="two">
<input type="text" name="q[]">
<input type="submit" name="submit">
</form>
this way you will get an array of values on submit then you can handle it on server side. But if you just still want to use your method then Javascript is required. With javascript you can get formdata then append the user input to the form then send it using ajax.

Yes, it's not possible without using Javascript as far I know.
it's better if you handle this at the backend.
But, if you really want to do at the front-end, you can do as follows (With vanilla Javascript).
document.addEventListener("DOMContentLoaded", function(){
let form = document.getElementById('form');
let query = '';
let valueObj = {};
if(form){
form.addEventListener('submit', (e) => {
e.preventDefault();
let exceptinput = ['submit','reset','button','file','image'];
let allElem = e.srcElement;
if(allElem.length > 0){
createValueObj(allElem, valueObj, exceptinput).then(data => {
console.log(data);
query = serialize(data);
window.location = 'http://www.example.com/?' + query;
}).catch(err => {
console.log(err);
})
}
});
}
let serialize = (obj) => {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
let insertValueToObj = (key, value, obj) => {
if(obj[key]){
obj[key] = obj[key]+','+ value;
}else{
obj[key] = value;
}
return obj;
}
let createValueObj = (arr, obj, exceptinput) => {
return new Promise((resolve, reject)=>{
for (let index = 0; index < arr.length; index++) {
let isProperInput = exceptinput.includes(arr[index].type);
if(!isProperInput) {
let key = arr[index].name;
let value = arr[index].value.trim();
obj = insertValueToObj(key, value, obj);
}
if(index == (arr.length -1)){
resolve(obj);
}
}
});
}
});
thanks.

Related

pass function to input onChange and then set it in state reactjs?

I just cannot figure out how to do this.
This function works to split the string of the input ID.
function func() {
// Original string
let str = urlInput.value
// Splitting up the string
let array = str.split(".com/");
let joined = array[0]+".com/embed/"+array[1];
document.write(joined);
console.log("function happened")
}
I am trying to pass it through onChange and then set it in state but the function isn't being passed onChange?
{
currentAccount ? (<textarea
placeholder={spotifyLink}
type="url"
id="urlInput"
onChange={e => {{func}; setMessageValue(e.target.value)}}/>) : null
}
What am I doing wrong? How do I pass the function and then setState after the function has split the user input string onChange?
You can make use of controlled components. With this approach, the input value is controlled by a state. It promotes single source of truth, you can read more here.
CODE -
function TextAreaComponent() {
const [messageValue, setMessageValue] = useState('');
const splitString = (str) => {
// Splitting up the string
let array = str.split(".com/");
let joined = array[0]+".com/embed/"+array[1];
return joined;
}
const handleOnChange = (event) => {
const { value } = event.target;
const splittedString = splitString(value);
setMessageValue(splittedString);
}
return (
<textarea
// placeholder={spotifyLink}
// id="urlInput"
type="url"
value={messageValue}
onChange={handleOnChange}
/>
);
}

how to filter data that pulling from backend in angular

I have input where I user can search/type a data and I'm wondering how I can make the user ONLY able to search what was already provided from the backend and forbid them from creating new data.
so in my backend I've "Chart" and "Map" words and I figuring out a way to make the user able to search only this. If I user type other than this and press enter, nothing will happen.
Right now, if the user type other text than this two and press enter, it create a new data and push it to the backend.
I don't want to hard code like this (input == "Chart" || input == "Map") since we will be adding more data in the backend later.
super <= data type like "Chart and Map"
<div>
<input matInput #input [formControl]="tagCtrl" [matAutocomplete]="auto" [matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" (matChipInputTokenEnd)="add($event,null)">
</div>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let tag of filteredSuperTags | async" [value]="tag">
{{tag}}
</mat-option>
</mat-autocomplete>
tagCtrl = new FormControl();
superTags: Tag[] = [];
filteredSuperTags: Observable<String[]>;
allsuperTags: Array<Tag> = [];
allSuperTagNames: Array<String> = new Array<String>();
add(event: MatChipInputEvent, event1: MatAutocompleteSelectedEvent): void {
if (event1 == null) {
const input = event.input;
const value = event.value;
this.tagService.addTag(this._workspace.guid, 'workspace', value).subscribe((tag) => console.log("added", tag));
this.snackbar.open(input.value + " has been added as super tag.", " ", { duration: 2500 });
if ((value || '').trim()) {
if (this.allSuperTagNames.find((f) => f.toUpperCase() === value.toUpperCase()))
{this.superTags.push({ tag: value.trim(), type: TagType.super }); } }
// Reset the input value
if (input) {
input.value = '';
}
this.tagCtrl.setValue(null);
}
else {
const input = event1.option;
const value = event1.option.value;
this.tagService.addTag(this._workspace.guid, 'workspace', value).subscribe((tag) => console.log("added", tag));
this.snackbar.open(input.value + " has been added as super tag.", " ", { duration: 2500 });
if ((value || '').trim()) {
if (this.allSuperTagNames.find((f) => f.toUpperCase() === value.toUpperCase()))
{this.superTags.push({ tag: value.trim(), type: TagType.super }); } }
if (input) {
input.value = '';
}
this.tagCtrl.setValue(null);
}
}
any recommendation or help will be really appreciated.
Your backend was adding the option no matter what because you were calling the service before verifying if the value existed. If its a form, its super weird to call the backend everytime you select something in a typeahead. In my opinion it should be done once when everything is filled properly or on some kind of submit event.
I just moved the service call inside the verification and removed a if that was only used to assign the input and the value but was duplicating about 10 lines. Now you have an if assigning the value and then followed by the content of the previous if.
add(event: MatChipInputEvent, event1: MatAutocompleteSelectedEvent): void {
const input = event.input;
const value = event.value;
if (event1 === null) {
input = event.input;
value = event.value;
else {
input = event1.option;
value = event1.option.value;
}
if ((value || '').trim()) {
if (this.allSuperTagNames.find((f) => f.toUpperCase() === value.toUpperCase()))
{
this.superTags.push({ tag: value.trim(), type: TagType.super });
this.tagService.addTag(this._workspace.guid, 'workspace', value).subscribe((tag) => console.log("added", tag));
this.snackbar.open(input.value + " has been added as super tag.", " ", { duration: 2500 });
}
}
// Reset the input value
if (input) {
input.value = '';
}
this.tagCtrl.setValue(null);
}

Angular (keyup) event not detecting only # symbol

Im trying to implement search bar using angular (keyup) event.And i have file name like
base #,
base $,
base 1,
base #,
base 2,
when i search base # or base $ or base 1 in the search bar it filters fine. but when i search base # it dont filter base # it filter all file name with base.
here is the code below which i have coded
My html:
<input type="search" class="form-control" placeholder="Search file" (keyup)="onSearch($event)" [(ngModel)]='searchKeywords'>
my js code:
onSearch(event: any) {
const keywords = event.target.value;
if (keywords && keywords.length > 2) {
const apiURL =`abc/thg/hjy?filter[file.name]=${keywords}`;
this.api.get(apiURL).subscribe((data: any) => {
console.log(data);
this.topics = data.list;
if (this.trigger) {
this.trigger.openMenu();
}
});
} else {
this.topics = [];
this.trigger.closeMenu();
}
}
Now I'm able to pass # .
onSearch(event: any) {
const keywords = event.target.value;
const params: any = {};
if (keywords && keywords.length > 2) {
params['filter[translations.title]'] = keywords;
const options = {
search: params
};
const apiURL = `abc/thg/hjy`;
this.api.get(apiURL, options).subscribe((data: any) => {
console.log(data);
this.topics = data.list;
if (this.trigger) {
this.trigger.openMenu();
}
});
} else {
this.topics = [];
this.trigger.closeMenu();
}
}
I notice that you have an missing in the HTML markup.
<input type="search" class="form-control" placeholder="Search file" (keyup)="onSearch($event)" [(ngModel)]="searchKeywords">
Then, in the .ts file:
onSearch(event: any) {
...
}
I think the value is getting set ok in apiURL in the line:
const apiURL =`abc/thg/hjy?filter[file.name]=${keywords}`;
I think the problem is the following line, where you are passing the # (hashtag) without URL encoding it.
Try swapping out the hashtag with %23 before you use it in the next line - your get request.
See: How to escape hash character in URL

Keydown is trigger before onChange on <input/>

I have a requirement that after typing certain content in an tag, pressing enter will do search function.
It running well normally like:
<input
onChange={this.onInputChange}
onKeyPress={this.onSearch}
/>
onInputChange = (e) => {
console.log(2);
this.setState({
searchText: e.target.value
})
}
onSearch = (e) => {
console.log(1);
if (e.which === 13) {
search(this.state.searchText); // some search api ...
}
}
But if user Enter really quickly, like 0.1s, the this.state.searchText is not get updated properly.
This is not just caused by setState is async method, but the onKeyPress is trigger before onChange.
is there any idea to deal with this issue?
So I can't really understand why you use two separate functions.
First of all, if you only use searchText for the two functions you could just do:
HTML
<input
onKeyPress={this.onKeyPress} />
JS
onKeyPress = e => {
if(e.which === 13) {
// Send Query
search(e.target.value);
}
}
And even if you needed searchText somewhere else you could just do:
onKeyPress = e => {
let value = e.target.value;
if(e.which === 13) {
// Send Query
search(value);
} else this.setState({searchText: value});
}
If I missed something please tell me ^^
<input
onChange={this.onInputChange}
onKeyDown={this.onSearch}
/>
onInputChange = (e) => {
this.setState({
searchText: e.target.value
})
}
onSearch = (e) => {
if (e.keyCode === 13) {
search(this.state.searchText); // some search api ...
}
}
<input
ref={(input) => this.selectVal = input}
onKeyPress={(e) => e.which === 13 ?this.onSearch():''}
/>
onSearch = () => {
console.log("value",this.selectVal.value);
// search(this.input.current.value); // some search api ...
}
try this way

Input format smpte-timecode

Whats the best way to set the input format when using smpte-timecode?
<Input
placeholder="In"
autoFocus={true}
onChange={e => this.onChange(e)}
type="time"
step="00.01"
pattern="^(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)$"
style={{fontSize: "16px", width: "100%"}}/>
)}
onChange = (element, frameRate) => {
const { form } = this.props;
const keys = form.getFieldValue('keys');
keys.forEach(function (value) {
var inTc = Timecode(form.getFieldValue('1-in'), 25); // errors
console.log(inTc.toString());
});
This keeps resulting in the following
Error: Timecode string expected as HH:MM:SS:FF or HH:MM:SS;FF