I have alot of data, that i can check, useing checkbox. when I 'Submit', and want to see all the data i checked, i get redirected to the result page. But lets say i choose to only check 1 element the URL is: http://XXX.xxx/Test/TestResults?ID%5B%5D=2728
this is okay, but lets say i choose to see 10 elements the URL is LONG:
http://XXX.xxx/Test/TestResults?ID%5B%5D=2728&ID%5B%5D=2726&ID%5B%5D=2727&ID%5B%5D=2725&ID%5B%5D=2724&ID%5B%5D=2723&ID%5B%5D=2722&ID%5B%5D=2721&ID%5B%5D=2720&ID%5B%5D=2719
and the problem is that if i choose to see 100 elements, the URL will become so long that the site can alert me with: 'Submitted URI too large!'
is there any way only to show the id number, and not the ID[] (ID%5B%5D)?
The ID[] is the ID%5B%5D part, and then the id number will be added to it.
echo "<input type = 'checkbox' name = 'ID[]' class = 'checkbox' value = '".$testjobids[$count]."'/>";
/*this is in another .php file where i get the ID*/
$SelectedTestjobids = $_GET['ID'];
Link is shorter
After useing _POST, i got this: http://XXX.xxx/Test/TestResults
Problem
The only problem i have now is that i can't link this site to anyone, because there isn't attached anything else but the site in the URL. Is there a way to make a uniqe number after the http://XXX.xxx/Test/TestResults, so it's possible to share the link and it stills shows the same data?
If you can't use a post request for some reason, you could copy the values you want and submit them as a more compact string, either manually or by adding the string to another form element before submitting.
Of course, your server code would have to know what to do with the comma-separated string when it receives it.
This example uses a hidden <textarea> element to hold the values:
// Identifies HTML elements
const
boxes = document.querySelectorAll(".box"),
area1 = document.getElementById("area1"),
btn1 = document.getElementById("btn1"),
div1 = document.getElementById("div1");
// Calls `submitCheckboxValuesAsText` when the button is clicked
btn1.addEventListener("click", submitCheckboxValuesAsText);
// Defines `submitCheckboxValuesAsText`
function submitCheckboxValuesAsText(){
// Puts checked values in the textarea
updateTextarea();
// Copies the text from the textarea
const text = area1.value;
// Clears the demo div
div1.innerHTML = "";
// Formats the copied text within the demo div
if(text){
div1.innerHTML = "Imagine this gets sent to your server:<br /><br />" +
"<span class='grey'>" + text + "</span>";
}
}
// Defines `updateTextarea`
function updateTextarea(){
area1.value = [...boxes] // `[...boxes]` converts `boxes` to a proper Array
.filter(box => box.checked) // Makes a new Array of just the checked boxes
.map(box => box.value) // Makes a new Array with the values of those boxes
.join(","); // Makes a string from the array, separated by commas
}
label{ margin-right: 15px; }
#btn1{ margin: 20px 5px; }
.grey{ background-color: #DDDDDD; padding: 2px 5px; }
<label><input type="checkbox" class="box" value="val1" /><span>box1</span></label>
<label><input type="checkbox" class="box" value="val2" /><span>box2</span></label>
<label><input type="checkbox" class="box" value="val3" /><span>box3</span></label>
<textarea id="area1" hidden></textarea>
<div><button id="btn1">Submit</button></div>
<div id="div1"></div>
(If you wanted to avoid submitting manually, you should probably populate the hidden field before the user clicks Submit, such as by using document.addEventListener("change", updateTextarea);.
You would also want to change the button to <input type="submit" />.)
Related
I am dynamically converting a list of options to a series of radio buttons. One of the values that is in the option has a literal quote mark.
<option value="6\" tall">
When I loop through each option, pull the a value $(this).val(); then I build a string for the radio button:
rb="input id=\"CTRL"+fld+"_"+cnt+"\" name=\""+fld+"\" type=\"radio\" "+ sel+" value=\"" +val+ "\"" +valCaption";
If I debug and break on this, the string is created correctly, but when I insert the element, the literal in the value is lost and the result is:
<input id="CTRLText1_3" name="Text1" type="radio" value="Rev 6" tall"="">
I cannot escape the value because then the value doesn't actually match what is being returned by the original select list.
Any ideas how I can create this radio button?
In HTML \" doesn't mean literal quote, it just means backslash followed by a double-quote. In HTML to produce a quote character when you need to, you use HTML Entities and the specific entity for a double quote is: ".
<input value=""To be or not to be"">
\" is the escape code for a double quote when that string is parsed by the JavaScript runtime, not the HTML parser.
So, value="6\" doesn't contain a literal quote. It contains 6\. The quote after the \ is the closing quote for the value attribute which causes tall" to remain as invalid HTML that the HTML parser just ignores. When you pull the value of the input, you would only get 6\.
You stated that the string gets created correctly, but it doesn't. Look closely at the end of what you say you are getting;
<input id="CTRLText1_3" name="Text1" type="radio" value="Rev 6" tall"="">
tall"="" is invalid HTML.
To do what I think you are after, you should use single quotes for the HTML attribute and then the double quote can be properly stored for JavaScript to extract later. You won't need any escaping:
console.log(document.querySelector("option").value);
<option value='6" tall'>
More info:
I tried building the radio buttons with an empty "value" attribute:
<input type="radio" value="">
The option tag actually looks like this:
<option value="6\" tall">
As I loop through my options I put the values into an array. Then after I add the HTML for the radio buttons to the page, I loop through the array and add the value to the attribute of the radio button.
for(x=0;x<arrVals.length; x++){
$("#CTRL"+fld+"_"+x).attr("value",arrVals[x]);
}
The end result, though is this:
<input id="CTRLText1_1" name="Text1" type="radio" value="Rev 6" tall">
The = sign has been escaped with """ While this is closer, it unfortunately is not the same. The original value in the option tag does not match the end-result value of the radio button.
Quotes in HTML
There's two easy ways to avoid conflicting quotes:
Instead of using double quotes in the HTML, use single quotes.
<option value='6" tall'>6" tall</option>
<option> will default to its text content if value is not assigned.
<option>7" tall</option>
Strings
The use of complex literal strings with concatenated variables are a little more manageable if you alternate between double and single quotes:
// Literal string concatenation syntax: '+VAR+'
let literalString = '<input id="'+ID+'" type="radio">';
Template literals interpolate variables and expressions:
// Template literal interpolation syntax: ${VAR}
let templateLiteral = `<input id="${ID}" type="radio">`;
I prefer the use of template literals for longer complex strings and literal strings for short simple strings.
Demo
The following demo collects all values into an array then creates a simple radio button then adds the attributes and values to it using simple JavaScript property assignment and the array of values. The use of htmlStrings is very error prone consider the alternative presented in demo.
Note: details are commented in demo
// Define counter
let i = 0;
// Delegate click event to button.add
$('.add').on('click', function(e) {
// Increment counter
i++;
/*
.map() will collect all .data and return their values
.get() will place all of the values into an array
V is an array of values
*/
let V = $('.data').map(function() {
return $(this).val();
}).get();
// Checking V array
console.log(JSON.stringify(V));
// Append a radio button to fieldset.box
$('.box').append(`<input type='radio'>`);
/*
- Reference the last radio button
- Dereference the last radio button from a jQuery Object
to a JavaScript DOM Node by suffixing [0] to it.
- The reason for dereferencing is to be able to use
simple plain JavaScript properties
*/
const rad = $('.box :radio:last')[0];
/*
Values are referenced by index from the V array
The attributes are set by property assignments
*/
rad.id = 'CTRL' + V[0] + '_' + i;
rad.name = V[0];
rad.value = V[1] + ' ' + V[2];
// Checking the radio button HTML
console.log(rad.outerHTML);
});
/*
This function just demonstrates what each radio button's
value is when rendered as HTML
*/
$('#formA').on('change', function(e) {
if ($(e.target).is(':checked')) {
$('#view').html($(e.target).val());
}
});
:root,
body {
font: 400 3vw/1.45 Consolas
}
select,
input,
button {
display: inline-block;
font: inherit;
height: 3ex;
line-height: 1;
width: 10ch;
margin-bottom: 8px;
padding: 0 2px;
vertical-align: middle
}
select {
padding: 2px 2px 4px 2px;
width: 12ch;
}
button {
padding: 0px 3px 5px;
line-height: 1.25;
width: 6ch;
cursor: pointer
}
#view {
color: tomato
}
<form id='formA'>
<input id='fld' class='data' value='Text1'>
<input id='val' class='data' value='Rev'>
<select id='valCaption' class='data'>
<option value='6" tall'>6" tall</option>
<option>7" tall</option>
</select>
<button class='add' type='button'>ADD</button>
<fieldset class='box'>
<output id='view'></output><br>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
Thank you for everyone's suggestions. I did find the problem. I actually had to first collect the values from the options, then build the radio buttons with a blank value attribute and add that to the page. Then loop back through and just the $(fieldid).val(value) to set the values.
The other issue with saving the value then putting our page back into edit mode and the value not being re-selected. The ultimate problem is a bug in the core of the software where its not correctly comparing the stored value to the value in the list.
I'm trying to create a simple HTML page that presents a user with several options via checkboxes. I need to generate a string, stored in a variable that I can use on the page when a button is clicked, which will vary based on which boxes are checked.
The string will be a URL ("http://example.com/index.htm&term=") and will need to have additional text appended to it for each checkbox that is checked.
For example, if only a single box, say box1, is checked the string "box1" should be appended to the URL variable to look like "http://example.com/index.htm&term=box1"
If, however more than one box is checked, say box2 and box3 are checked, then the string "box2%20OR%20box3" should be appended to the URL string.
I'm pretty sure this can be done with JavaScript but I have no experience with it and would appreciate some guidance/examples.
Instead of storing it in a variable, I would recommend calling a function that builds the link when the button is pressed. If you really wanted to put it in a variable though, you would set up an event listener for the change event for each checkbox, and call the function to update the variable each time one of the checkboxes is checked or unchecked.
function checkboxUrl(checkboxes) {
const
url = `http://example.com/index.html`,
checkedArray = [];
for (let checkbox of checkboxes) {
if (checkbox.checked) checkedArray.push(checkbox);
};
const checkboxString = checkedArray.map(checkbox => checkbox.value).join(`%20OR%20`);
return url + (checkboxString ? `?term=` + checkboxString : ``);
}
let checkboxes = document.querySelectorAll(`input[type='checkbox']`);
label {
display: block;
}
<label><input type='checkbox' value='box1'>box1</label>
<label><input type='checkbox' value='box2'>box2</label>
<label><input type='checkbox' value='box3'>box3</label>
<button onclick='console.log(checkboxUrl(checkboxes))'>Get URL</button>
If you use Jquery you can do something like this:
<input type="checkbox" id="box1">
<input type="checkbox" id="box2">
<button type="button" id="myButton">Submit</button>
<script>
$(document).ready(function(){
$('#myButton').click(function(){
var url = 'www.myurl.com/index.html&term=';
var checkboxList = [];
var params = '';
$(':checkbox:checked').each(function(){
checkboxList.push($(this).attr('id'));
});
params = checkboxList.join('%'); //will output "box1%box2"
url += params //www.myurl.com/index.html&term=box1%box2
window.location.href = url;
});
});
</script>
I've created a datalist that shows the saved data of the user when he/she closed the program. I wanted the datalist to only show when the user clicks on the dropdown arrow (or the input box) and hides when the user starts typing. I've tried:
Creating an oninput event in the hopes that the datalist will hide when user starts typing.
Hiding datalist by using datalist.style.display = none;
Trying the codes written here: Avoid filtering of datalist items in an input element (Although it does not work in my case because I need to use pure JS)
Help is appreciated, thanks.
Edit:
Here is my code:
<div style="top:60px;position:absolute;z-index:2" id="speechBox">
<input id ="userText" name="userText" type="text" list = 'talk-list' oninput = "hideList()"></input>
<span class = "dropdown" title = "Saved Talk"><datalist id = 'talk-list'></datalist></span>
<button id="speakText" class="toolbutton" title="Speak"></button>
<hr>
</div>
<script>
function hideList() {
var hiddenList = document.getElementById("talk-list");
hiddenList.style.display = none;
}
</script>
Note: The datalist is not empty. I have an external script that adds infinite amount of options to datalist.
One way you can do this is to chage the datalist id when there is a value in input. If there is no value then change the id back so that they can choose the options in the datalist rather than type a new one.
function hideList(input) {
var datalist = document.querySelector("datalist");
if (input.value) {
datalist.id = "";
} else {
datalist.id = "talk-list";
}
}
<input id ="userText" name="userText" type="text" list = 'talk-list' oninput="hideList(this)"></input>
<span class = "dropdown" title = "Saved Talk"><datalist id = 'talk-list'><option>Apple</option><option>Ball</option><option>Calculator</option><option>Donkey</option></datalist></span>
<button id="speakText" class="toolbutton" title="Speak">Speak</button>
I doubt you can replace how the <datalist> element behaves. If I were you, I'd just make my own datalist made out of divitis. The sample below still has ways to go, but this should get you started in case you want to go this path.
The 3rd solution you mentioned in your post is not really a direct solution to your datalist problem. Instead it suggests a separate library that can render a datalist-like ui element, which turns out to be something from jQuery. What I'm suggesting is exactly like that, except you're gonna write your own.
function hideList() {
const list = document.querySelector("#talk-list");
list.style.display = "none";
}
function showList(){
const list = document.querySelector("#talk-list");
list.style.display = "block";
}
#talk-list{ border: 1px solid #ccc; display: none; }
button{display: block}
<div style="top:60px;position:absolute;z-index:2" id="speechBox">
<input id ="userText" name="userText" type="text" list = 'talk-list' oninput = "hideList()" onclick="showList()"></input>
<div id = 'talk-list'>
<div value="foo">foo</div>
<div value="bar">bar</div>
</div>
<button id="speakText" class="toolbutton" title="Speak">Submit</button>
</div>
I have an input form which looks like this:
<input type="number" value="0.00" step="0.05">
I found the step function which technically solves my increment problem changing it to 0.05 instead of the default 1. I have however not found a solution where I can change the increment without changing the valid inputs.
The input can take any number but the most common values will be in increments of 0.05. Is there a work-around for this? A solution using JavaScript is also more than welcome.
Thank you very much!
EDIT:
Adding nonvalidateto the html form-tag solved this for me. Now pressing the buttons use the increments I want but when I need to specify more accurately than the steps the form still accepts the values.
<form action="/run" novalidate>
<input type="number" value="0.00" step="0.05">
<input type="submit">
</form>
Using novalidate in the form tag will get rid of the validation for the whole form but keep the increments implemented by step.
Update
"I did add nonvalidate to the form tag. It let's me do what I want as of now but it might not be the best solution."
If you don't want your form "compromised" by novalidate, then have 2 forms:
Form A [No action or method]
All user interaction and calculations are here.
All inputs can be modified without worrying about built-in validation from the form.
Form B [Set action and method optional target]
The submit button resides within
Add a hidden input for each value on Form A you want to submit and ensure each has a name attribute and value.
Any client-side validation should be done here.
With that setup you'll need an event like onbeforesubmit so the values of Form A can transfer over to Form B before it submits to the server. Unfortunately I don't think it exist as a standard, but to emulate it is simple:
formA.onsubmit = b4Submit;
function b4Submit(event) {
hidden_Input_In_FormA.value = number_Input_With_Crazy_Step_In_FormA.value
return true;
}
So this contrived example shows an event handler that gets the value from one form then stores it in the other form. Next it continues by submitting whatever data it has. This is due to the callback returning true, should false be returned, the callback function itself dies and so does the submit event along with it.
The Demo has been updated to do what was just described above. Note: there are no novalidate attributes in use. The second form (Form B or form#tx) is sending text from a hidden input as far as it's concerned. A number like -103.002684109 is not valid if it's from an <input type='number'> but from a text or hidden input, it is just text (although I believe the actual data in most form controls is actually a string not a number).
"The input can take any number but the most common values will be in increments of 0.05. Is there a work-around for this? A solution using JavaScript is also more than welcome."
You can change any attribute you want on any tag AFAIK. Programatically the syntax is simple with Plain JavaScript:
Object.property = "string"
Object: a referenced <element> tag
property: when you reference an standard attribute like a property it's becomes a property.
string: the value must be a string
Here's a basic way of changing a standard attribute programmatically:
var obj = document.querySelector('a');
obj.href = "https://google.com"; //
The following Demo uses:
Document.Forms
HTMLFormElement.elements
HTMLFormControlsCollection
Dot Notation
Demo
Demo can send to a live test server the response is sent to an iframe to view
var ui = document.forms.ui;
var tx = document.forms.tx;
var u = ui.elements;
var x = tx.elements;
var D = u.digit;
var C = x.cache;
var lo = u.min;
var hi = u.max;
var inc = u.step; // I think this what you specificly
var t = u.type;
var chg = u.change;
chg.onclick = chgAttr;
tx.onsubmit = cacheVal;
function chgAttr(e) {
D.min = lo.value;
D.max = hi.value;
D.step = inc.value;
D.type = t.value;
}
function cacheVal(e) {
C.value = D.value;
return true;
}
body {
font: 400 16px/1.5 'Consolas'
}
#digit {
margin-right: 15px;
}
input,
output,
button,
select,
option,
label {
display: inline-block;
font: inherit
}
select {
padding: 3px 5px
}
[type='submit'] {
float: right;
}
<!doctype html>
<html>
<head>
<title></title>
<meta charset='utf-8'>
<style></style>
</head>
<body>
<form id='ui' oninput='out.value = digit.value'>
<fieldset>
<legend>Click Button to Change Input</legend>
<input id='digit' min='' max='' step='' type='number'>
<button id='change' type='button'>CHANGE</button>
<output id='out' for='digit'></output>
</fieldset>
<fieldset>
<legend>Attribute Adjustments</legend>
<input id='min' min='-2147483648' max='2147483648' type='number' placeholder='min'>
<input id='max' min='-2147483648' max='2147483648' type='number' placeholder='max'>
<input id='step' type='number' placeholder='step'>
<label for='type'>Type:
<select id='type'>
<option>number</option>
<option>text</option>
<option>range</option>
<option>hidden</option>
<option>color</option>
<option>time</option>
</select>
</label>
</fieldset>
</form>
<form id='tx' action='https://httpbin.org/post' method='post' target='response'>
<input id='cache' name='cache' type='hidden'>
<input type='submit'>
</form>
<iframe src='about:blank' name='response'></iframe>
<script></script>
</body>
</html>
reposting for simplicity. i want to have the text users enter into an input to replace the label text of another form's input. Additionally, the form is a plugin which doesn't let me attach an id to the specific label tag of the text i want to change. how can i do this, in vanilla javascript please.
the input users put text into:
<input class="charInput" id="name1" type="text" onKeyUp="change1(this)" >
the form label i want to change the text in (p.s: cant use the class(not unique to this label), cant add id):
<div id="frm_field_53_container" class="frm_form_field form-field frm_top_container">
<label class="frm_primary_label" for="field_inputactor1">
TEXT TO REPLACE
<span class="frm_required"></span>
</label></div>
Maybe it is not the best solution, but it is a solution that works in Firefox and Chrome (not tested under IE)
findLabelToChange = function() {
var div = document.getElementById("frm_field_53_container");
return div.querySelector("label");
};
customizeText = function(text) {
return text + ' <span class="frm_required"></span>';
};
change1 = function() {
var label = findLabelToChange();
var text = document.getElementById("name1").value;
label.innerHTML = customizeText(text);
};
you can see a example in this feedle
http://jsfiddle.net/HAK5X/1/
Here is a fiddle.
It is one line of code.
http://jsfiddle.net/te3jv/6/
function change1(myInput){
document.getElementById('frm_field_53_container').querySelector("label").innerHTML =myInput.value;
}
Alternatively add <span class="frm_required"></span> to the end of HTML reassignment to keep your empty (but required?) span.