Text input from jquery not working - javascript

Hi I have a script that appends a set of constant string to a textarea it works fine if I click the button first but as soon as I input text on the textarea, the button does not append the constant string on the textarea if clicked again
here is my code for the click event:
$("#apply").on("click",function() {
var orange = $("#agent_option").val(),
lock = $("#agent_disallowed").val();
$("#textareaFixed").html(orange + " " + lock );
});
and Here is my html form:
<label for="agent_option" class="control-label">User-Agent :</label></div>
<div class="col-md-6">
<select id="agent_option" class="form-control input-sm">
<option value="all">All</option>
<option value="banana">Banana</option>
<option value="apple">Apple</option>
<option value="melon">Melon</option>
<option value="lynx">Lynx</option>
<option value="liger">Liger</option>
</select>
</div>
<div class="row">
<div class="col-md-4">
<label for="ax_disallowed" class="control-label">Disallow :</label></div>
<div class="col-md-6">
<input class="form-control input-sm" id="ax_disallowed" type="text" value="<?=ax_default_disallow;?>">
</div>
</div>
<div class="row">
<div class="col-md-4">
<button id="apply" class="btn btn-default">Register Player</button>
</div>
This is my textarea:
<form method="post" class="form-login">
<div class="form-group">
<textarea name="new_config" class="form-control" id="textareaFixed" cols="60" rows="16"><?=file_get_contents($open); ?></textarea>
</div>
</form>
please help me I tried google it but found irrelevant results. you guys are my only hope now :(

Change .html(...) to .val(...)
$("#apply").on("click",function() {
var orange = $("#agent_option").val(),
lock = $("#ax_disallowed").val();
$("#textareaFixed").val(orange + " " + lock );
});

You need to use append() instead of html()
Please try $("#textareaFixed").append(orange + " " + lock ); if you want to add the new text after the previous one.
If you use html(), it replaces the old stuff with the new one.

There isn't any input named as "agent_disallowed", you need to use correct id.
$("#apply").on("click",function() {
var orange = $("#agent_option").val();
var lock = $("#ax_disallowed").val();
$("#textareaFixed").html(orange + " " + lock );
});

Related

How to make a dropdown autocomplete navigable by keyboard

Here, I have a nice autocomplete dropdown that, given a city typed by the user, the page will show all possible city-state-country triplets. For example the name Guadalajara would suggest
Guadalajara de Buga, Valle del Cauca Department, Colombia
Guadalajara, Castilla La Mancha, Spain
and
Guadalajara, Jalisco, Mexico
The code works perfectly from both the backend and the frontend, the only problem left is that the autosuggest drop down menu will only work with the mouse and not with the keyboard. The Up and Down arrow keys will not allow to navigate through the most appropriate choice and pressing esc doesn't cancel the menu.
I tried everything and I have no idea about what is missing to make this work with the keyboard as well. I would like to find a solution with pure vanilla JavaScript and that would involve the least possible changes in the rest of working code. Here the entire code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vanilla Javascript Cities Test</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma#0.8.2/css/bulma.min.css">
</head>
<body id="body">
<div class="title has-text-centered" id="main"></div>
<section id="form" class="section" onclick="clearCities()">
<div class="container">
<h1 class="title">Vanilla Cities Javascript</h1>
<!-- Row for City, State and Country -->
<div id="location">
<div class="field">
<div class="control">
<div id="cities-dropdown" class="dropdown">
<div class="dropdown-trigger">
<input name="cities" id="cities" onkeyup="getCities()" maxlength="50" class="input" type="text" placeholder="Enter a city" aria-haspopup="true" aria-controls="dropdown-menu3" -autocomplete="off" required
>
</div>
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
<div id="cities-dropdown-content" class="dropdown-content">
<!-- content -->
<a class="dropdown-item"></a>
</div>
</div>
</div> Clear
</div>
<span class="is-size-7 has-text-info">(If your location doesn't appear immediately, try to type slower).</span>
</div>
<!-- City Field -->
<div class="field">
<div class="control">
<input name="city" id="city" class="input" type="text" placeholder="City" required>
</div>
</div>
<!-- State Field -->
<div class="field">
<div class="control">
<input name="state" id="state" class="input" type="text" placeholder="State" required>
</div>
</div>
<!-- Country Field -->
<div class="field">
<div class="control">
<input name="country" id="country" class="input" type="text" placeholder="Country" required>
</div>
</div>
</div>
</div>
</section>
</body>
<script>
function getCities(){
var inputCity = document.getElementById('cities').value;
const city = changeCase(inputCity);
if(city.length <= 2){
return false;
}
// Create request to get cities locations
var request = new XMLHttpRequest();
request.addEventListener("load", transferComplete);
request.open("GET", "/cities/?cityname=" + city);
request.send();
// Called when transfer is complete
function transferComplete(event){
//alert(event.srcElement.response);
locations = JSON.parse(event.srcElement.response);
// Return false if no matching city was found
if(locations.length == 0){
return false;
}
// Append choices
dropContent = document.getElementById('cities-dropdown-content');
dropContent.innerHTML = "";
for (var i = 0; i < locations.length; i++) {
var link = document.createElement("a");
link.setAttribute("onclick", "setCity(" + JSON.stringify(locations[i].name) + "," + JSON.stringify(locations[i].state) + "," + JSON.stringify(locations[i].country) + ")");
link.setAttribute("class", "dropdown-item");
link.innerHTML = locations[i].name + ", " + locations[i].state.name + ", " + locations[i].country.name
dropContent.append(link);
}
document.getElementById("cities-dropdown").classList.add("is-active");
}
// document.getElementById("products-list").innerHTML = html;
}
function setCity(city, state, country){
document.getElementById('cities').value = city+', '+state.name+', '+country.name;
document.getElementById('city').value = city;
document.getElementById('state').value = state.name;
document.getElementById('country').value = country.name;
document.getElementById('cities-dropdown-content').innerHTML = "";
document.getElementById("cities-dropdown").classList.remove("is-active");
}
function clearCities(){
document.getElementById('cities-dropdown-content').innerHTML = "";
document.getElementById("cities-dropdown").classList.remove("is-active");
}
function deleteEntry(e){
e.preventDefault();
document.getElementById('cities').value = '';
}
function changeCase(inputCity){
return inputCity
.replace(/([a-z])([A-Z])/g, function (allMatches, firstMatch, secondMatch) {
return firstMatch + " " + secondMatch;
})
.toLowerCase()
.replace(/([ -_]|^)(.)/g, function (allMatches, firstMatch, secondMatch) {
return (firstMatch ? " " : "") + secondMatch.toUpperCase();
}
);
}
var eraser = document.getElementById("clear");
eraser.addEventListener('click', deleteEntry);
</script>
I hope to find the simpler and least invasive solution to complete a code that just have this left.
I would change your dropdown and input to the semantic html datalist element:
<label for="ice-cream-choice">Choose a flavor:</label>
<input list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice" />
<datalist id="ice-cream-flavors">
<option value="Chocolate">
<option value="Coconut">
<option value="Mint">
<option value="Strawberry">
<option value="Vanilla">
</datalist>
Then both search and keyboard accessibility should work more or less out of the box.
If you really don't want to do that, you have to attach event listeners (vanilla js) to the different elements of your dropdown and input field and write a rather long thing to be able to tab or arrow key your way down and up and back into the search field. I would say it's too much work compared to the reward.
Better to use some time to css-animate the datalist so it behaves a bit smoother and style it neatly.

Cloning a div and getting specific id's value in the div

I have a html that will allow me to add or remove numbers of rows(divs) and a button that allows me to read through that number of rows(divs)
so the rows is as follow
<div id="mainContent">
<div id="StaffRow" class="WorkItemRow row" display:none;">
<div id="selections">
<select class="form-control">
<option value=""></option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<div>
Name
</div>
<div>
<input id="MemberName" type="text" value="">
</div>
<div>
Mail
</div>
<div>
<input type="text" id="Mail" value="">
</div>
</div>
I've managed to clone the row as such
$('#ButtonAddStaff').click(function (e) {
counters++;
$("#StaffRow").clone(true).attr('id', "#StaffRow" + staffCount).appendTo("#mainContent");
$(".WorkItemRow").last().css('display', '');
});
but now the problem is i cant seem to iterate over the staffrow created and get the datas.
I've tried getting the data as such but it returns me undefined
for (let i = (counters- 1) ; i >= 0; i--) {
if (counters!= 1)
var nameData= document.getElementById('StaffRow' + i).children("#MemberName").val();
nameData= document.getElementById('StaffRow' + i);
list.push(nameData);
}
any idea where i should be looking to accomplish what i wanted to?
so what i wanna do is iterate over the created staffrow that is created after pressing the button and getting the values of membername in each of the row
I think your problem is here:
.attr('id', "#StaffRow" + staffCount)
When you do that, you actually set an id with the sharp. The second parameter of this function is not a kind a selector. Then you do a document.getElementById without this sharp.
You should use:
.attr('id', "StaffRow" + staffCount)
Maybe the following will help a bit, please let me know if you need more help.
This code does not rely on id's but uses a user defined attribute called x-role to indicate what role this element has in your program.
document.querySelector('#ButtonAddStaff').addEventListener(
"click",
function (e) {
const newRow = document.querySelector("#StaffRow").cloneNode(true);
//remove the id, no 2 same id's should be the same in dom
newRow.removeAttribute("id");
//set the x-role attribute, could set it on the hidden first but
// have to use .slice(1) when getting all the rows in getAllStaffRows
newRow.setAttribute("x-role","staffrow");
//show the row
newRow.style.display="";
document.querySelector("#mainContent").append(newRow);
}
);
//keep going to parent until we reach document or until function passed in
// returns true
const getParentUntil = fn => el => {
if(el===document.body){
return false;
}
if(fn(el)){
return el;
}
//keep calling itself until we find the correct parent
// or until we reach document
return getParentUntil(fn)(el.parentElement);
}
//remove handler
document.getElementById("mainContent").addEventListener(
"click",
e=>{
if(e.target.getAttribute("x-role")==="remove"){
const staffRow = getParentUntil(x=>x.getAttribute("x-role")==="staffrow")(e.target);
if(staffRow){
staffRow.remove();
}
}
}
)
document.querySelector('#logdata').addEventListener(
"click",
function (e) {
console.log(
JSON.stringify(
getAllStaffRows(),
undefined,
2
)
)
}
);
const getAllStaffRows = () =>
//get all html elements that have x-role attribute of staffrow
Array.from(document.querySelectorAll(`[x-role='staffrow']`))
//map the row elements into objects that contain the input values
.map(
row=>({
//find the element with x-role attribute that has a membername value
name:row.querySelector(`[x-role='membername']`).value,
//do this for selections and mail as well
selection:row.querySelector(`[x-role='selections']`).value,
mail:row.querySelector(`[x-role='mail']`).value
})
);
<input type="button" value="add" id="ButtonAddStaff">
<input type="button" value="log values" id="logdata">
<div id="mainContent">
<div id="StaffRow" class="WorkItemRow row" style="display:none;">
<div>
<select class="form-control " x-role="selections">
<option value=" "></option>
<option value="1 ">1</option>
<option value="2 ">2</option>
<option value="3 ">3</option>
</select>
</div>
<div>
Name
</div>
<div>
<input x-role="membername" type="text " value=" ">
</div>
<div>
Mail
</div>
<div>
<input type="text " x-role="mail" value=" ">
</div>
<div>
<input type="button" x-role="remove" value="remove">
</div>

Is there a way to simplify this into only a few lines of jQuery

I am trying to display input values of a form into their corresponding div/p tags. So whenever a user starts typing into an input field, that value will be written in the input box as well as in a p tag else where on the page.
I have my jQuery looking at every individual form field and displaying that info to an assigned p tag. Is there a way to write this code so I do not have to create multiple lines of code for each form field?
Write now it is checking for if there is a change in the form, and then seeing if the field has a value and if so displaying the information in the p tag, if not it makes the p tag empty.
He is what I have working now.
$('#webform-client-form-1').on('change',function(e){
/* Distributor Name INPUT */
var distributorNameInput=$('#edit-submitted-distributor-name').val();
if( !$("#edit-submitted-distributor-name").val() ) {
$(".distributor-name p").html("");
} else {
$(".distributor-name p").html("<strong>Distributor Name</strong> <br/>" + distributorNameInput);
};
/* Year INPUT */
var YearInput=$('#edit-submitted-year').val();
if( !$("#edit-submitted-year").val() ) {
$(".year p").html("");
}else {
$(".year p").html("<strong>Year</strong> <br/>" + YearInput);
};
/* General Information INPUT */
var generalinfoInput=$('#edit-submitted-general-information').val();
if( !$("#edit-submitted-general-information").val() ) {
$(".general-info").html("");
}else{
$(".general-info").html("<h2>General Information</h2> <p>" + generalinfoInput + "</p>");
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<form enctype="multipart/form-data" action="/" method="post" id="webform-client-form-1" accept-charset="UTF-8">
<p>
<label>Distributor Name*</label>
<input type="text" id="edit-submitted-distributor-name" name="submitted[distributor_name]" value=" " size="60" maxlength="128" class="form-text required">
</p>
<p>
<label for="edit-submitted-year">Year*</label>
<select id="edit-submitted-year" name="submitted[year]" class="form-select">
<option value="2015" selected="selected">2015</option>
<option value="2016">2016</option>
</select>
</p>
</form>
<div class="preview" id="preview">
<div class="distInfo">
<div class="distributor-name">
<p><strong>Distributor Name</strong> <br>Text will go here</p>
</div>
<div class="year">
<p><strong>Year</strong> <br>2015</p>
</div>
</div>
</div>
Instead of using IDs you can use classes and data attributes to pass input target element:
$(document).ready(function() {
$(document).on('change input paste', '.input', function() {
$($(this).data('target')).text($(this).val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="input" data-target="#text-input" />
<select class="input" data-target="#select-input">
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
</select>
<hr/>
<div id="text-input"></div>
<div id="select-input"></div>
you probably meaning something like inline if
/* Distributor Name INPUT */
var distributorNameInput = $('#edit-submitted-distributor-name').val();
$(".distributor-name p").html( distributorNameInput ? "<strong>Distributor Name</strong> <br/>" + distributorNameInput : "");
/* Year INPUT */
var YearInput = $("#edit-submitted-general-information").val();
$(".year p").html( YearInput ? "<strong>Year</strong> <br/>" + YearInput: "");
/* General Information INPUT */
var generalinfoInput = $('#edit-submitted-general-information').val();
$(".general-info").html( generalinfoInput ? "<h2>General Information</h2> <p>" + generalinfoInput : "");
The syntax for an inline if is
condition ? true code: false code
You can create an array of objects and iterate over it. This is great if you are thinking on adding new elements, because you will only need to add them to the array.
$('#webform-client-form-1').on('change',function(e){
var elements=new Array(
{valueToCheck:'edit-submitted-distributor-name',className:'distributor-name', label: 'Distributor Name'},
{valueToCheck:'edit-submitted-year',className:'distributor-name', label: 'Distributor Name'},
{valueToCheck:'edit-submitted-distributor-name',className:'distributor-name', label: 'Distributor Name'},
);
//check'em
elements.forEach(function(element){
var myValue=$("#"+element.valueToCheck).val();
$("."+element.className+" p").html( myValue ? "<strong>"+element.label+"</strong> <br/>" + myValue: "");
});
}

add/remove multiple input fields

<div class="form-inline">
<div class="form-group col-lg-4">
<label>Select Item:</label>
<div id="field1">
<select class="form-control" name="item_1">
<?php if($item !=0){foreach ($item as $list_item){?>
<option value="<?php echo $list_item['item'];?>">
<?php echo $list_item[ 'item'];?>
</option>
<?php }}else {?>
<option value="">No Items Available</option>
<?php }?>
</select>
</div>
</div>
<div class="form-group col-lg-2">
<label>Quantity:</label>
<div id="field2">
<input type="number" min="1" class="form-control input-md" name="quantity_1" />
</div>
</div>
<div class="form-group col-lg-3">
<label>Cost(per piece):</label>
<div id="field3">
<input type="number" min="1" class="form-control input-md" name="cost_1" />
</div>
</div>
<div class="form-group col-lg-3" style="margin-top:25px">
<div id="field4">
<button id="addmore" onclick="add();" class="btn add-more" type="button">+</button>
</div>
</div>
</div>
I have these three fields('item, quantity and cost') and these three fields are added incrementally on clicking + button but i am having removing these buttons on - click.
I simply need these three input fields to be added at one click and remove these fields on one click as well. also these fields name should be incremented.
<script>
function add() {
i++;
var div1 = document.createElement('div');
div1.innerHTML = '<select class="form-control" name="item_' + i + '"> <option value=""></option></select>';
document.getElementById('field1').appendChild(div1);
var div2 = document.createElement('div');
div2.innerHTML = '<input type="number" min="1" class="form-control input-md" name="quantity_' + i + '" />';
document.getElementById('field2').appendChild(div2);
var div3 = document.createElement('div');
div3.innerHTML = '<input type="number" min="1" class="form-control input-md" name="cost_' + i + '" />';
document.getElementById('field3').appendChild(div3);
var div4 = document.createElement('div');
div4.innerHTML = '<button id="remove" onclick="remove_btn(this)" class="btn remove" type="button">-</button>';
document.getElementById('field4').appendChild(div4);
}
</script>
There are several issues:
Avoid putting blobs of HTML in your javascript, put your HTML in the HTML file.
Avoid IDs, particularly when they will certainly be duplicated. Duplicate IDs are illegal. Only the first one can be found with a lookup.
Avoid concatenating together strings of text to generate your HTML. It is a too easy to make a mistake and put an XSS vulnerability in your code that way.
(function($) {
"use strict";
var itemTemplate = $('.example-template').detach(),
editArea = $('.edit-area'),
itemNumber = 1;
$(document).on('click', '.edit-area .add', function(event) {
var item = itemTemplate.clone();
item.find('[name]').attr('name', function() {
return $(this).attr('name') + '_' + itemNumber;
});
++itemNumber;
item.appendTo(editArea);
});
$(document).on('click', '.edit-area .rem', function(event) {
editArea.children('.example-template').last().remove();
});
$(document).on('click', '.edit-area .del', function(event) {
var target = $(event.target),
row = target.closest('.example-template');
row.remove();
});
}(jQuery));
.hidden { display: none; }
.formfield { float: left; }
.example-template { clear: left; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hidden">
<div class="example-template">
<div class="formfield"><input placeholder="Name" name="name"></div>
<div class="formfield"><input placeholder="Addr" name="addr"></div>
<div class="formfield"><input placeholder="Post" name="post"></div>
<div class="formfield"><button class="del">-</button></div>
</div>
</div>
<div class="edit-area">
<div class="controls">
<button class="add">+</button>
<button class="rem">-</button>
</div>
</div>
This works by first grabbing the row template out of the hidden div element, and storing it in a variable. Each time it needs to make a new row, it clones the template and updates it. It updates it by adjusting the name element as required, appending "_" and a number. Once it has customized this copy of the template, it appends it to the edit area.
You can remove elements with a reference to the parent using similar syntax with the following:
var childElement = document.getElementById("myChildElement");
document.getElementById("myElement").removeChild(childElement);
Similar to what is described here: http://www.w3schools.com/js/js_htmldom_nodes.asp
Also, consider a toggle on the CSS style property: "display: none;"

show or hide div depending on dynamic value in combo box jquery

I have a combobox called select_person ={typeA, typeB}.
When an option is chosen I want to show other combobox has_id={has_id, has_no_id}
Now depending on value chosen in typeA or typeB and depending on that has_id or has_no_id I want to show (or keep hidden) the respective div.
So If the registry happens to have an id and is typeA I will show only an input field, but if is typeA and has no ID i will display 3 input fields, same for typeB.
to do so I am doing something like:
$(function () {
$('#select_person').change(function () {
$('#has_id').show();
if ($('#select_person').val() == 'typeA') {
$("#has_id").append("<option>" + $("#typeA_has_id").val() + "</option>");
$("#has_id").append("<option>" + $("#typeA_has_no_id").val() + "</option>");
}
if ($('#select_person').val() == 'typeB') {
$("#has_id").append("<option>" + $("#typeB_has_id").val() + "</option>");
$("#has_id").append("<option>" + $("#typeB_has_no_id").val() + "</option>");
}
});
});
$(function () {
$('#has_id').change(function () {
$('.persons').hide();
$('#' + $(this).val()).show();
});
});
});
and html
<Select id="select_person">
<option value="0">Select person</option>
<option value="typeA">typeA</option>
<option value="typeB">typeB</option>
</Select>
<Select id="has_id" style="display:none"></Select>
<div id="person1" class="persons" style="display:none">
<div class="form-left">Type A has id *</div>
<input type="text" id="name" name="name" class="form-input"
/>
</div>
<div id="person1" class="persons" style="display:none">
<div class="form-left">Type A has No id *</div>
<input type="text" id="id" name="id" class="form-input"
/>
<input type="text" id="name" name="name" class="form-input"
/>
<input type="text" id="address" name="address" class="form-input"
/>
</div>
<div id="person2" class="persons" style="display:none">
<div class="form-left">Type B has id *</div>
<input type="text" id="nameB" name="nameB" class="form-input"
/>
</div>
<div id="person2" class="persons" style="display:none">
<div class="form-left">Type B has No id *</div>
<input type="text" id="idB" name="idB" class="form-input"
/>
<input type="text" id="nameB" name="nameB" class="form-input"
/>
<input type="text" id="addressB" name="addressB" class="form-input"
/>
</div>
but isnot working, could you help me out? here is the jsfiddle
you have extra }); at the end of the document...
you have two ids with a same name person1..which is invalid HTML markup.. either remove it..and use classes
updated from your comment
i have created this example fiddle..reading your comment not sure if this is what you want.. but i am sure this will get you started
fiddle here
See what is happening in your code and html markup:
Your markup is invalid since it used same ids for multiple elements on same page.
Its also not clear how would you determine to put values in $("#typeA_has_id").val().
and you had a }); extra closing at the end as mentioned in other answers as well.
and if you want to put some values in the option list of your $('#has_id') then you can try with this one.
$("<option/>").val('a').text('a').appendTo("#has_id");
Although i have done something if you would like to see:
FIDDLE
changed html:
<div id="person-A-withID" class="persons" style="display:none"></div>
<div id="person-A-withoutID" class="persons" style="display:none"></div>
<div id="person-B-withID" class="persons" style="display:none"></div>
<div id="person-B-withoutID" class="persons" style="display:none"></div>
jQuery:
$(function () {
$('#has_id').show();
$('#select_person').change(function () {
$('.persons').hide();
if ($('#select_person').val() == 'typeA') {
$("#has_id").html('');
$("<option/>").val('0').text('--Choose Type A--').appendTo("#has_id");
$("<option/>").val('person-A-withID').text('person-A-withID').appendTo("#has_id");
$("<option/>").val('person-A-withoutID').text('person-A-withoutID').appendTo("#has_id");
}
if ($('#select_person').val() == 'typeB') {
$("#has_id").html('');
$("<option/>").val('0').text('--Choose Type B--').appendTo("#has_id");
$("<option/>").val('person-B-withID').text('person-B-withID').appendTo("#has_id");
$("<option/>").val('person-B-withoutID').text('person-B-withoutID').appendTo("#has_id");
}
});
$('#has_id').change(function () {
$('.persons').hide();
$('#' + $(this).val()).show();
});
});
One minor mistake : }); extra
http://jsfiddle.net/LEfbX/1/
$(function () {
$('#has_id').change(function () {
$('.persons').hide();
$('#' + $(this).val()).show();
});

Categories