Hi I have two sets of code. The first one was made by a nice person on this site, and generates a random letter based on the selections checkboxed by the user.
The second is one I found online. It allows you to turn image links into checkboxes that can be checked and unchecked.
I am trying to combine these two codes so that I can have the program generate a random image (instead of a letter) based on an array of images (again instead of letters) that the user checkboxes. In short, I'm trying to get something like the first set of code that uses images instead of letters.
Then, the final thing I'm trying to do is add a range slider like so (https://www.w3schools.com/code/tryit.asp?filename=GJ5U82DC2JX9) underneath each image. I want the user to be able to use the slider to "weight" the frequency of each checked image in the final randomization (with a range of 0 to 10).
Here is the first program in running form:
https://www.w3schools.com/code/tryit.asp?filename=GJ5TXX8V9B7L
Here is the second program in running form:
https://www.w3schools.com/code/tryit.asp?filename=GJ5TXEQM6HVI
I have tried intuitively copying and pasting from one set to the other, but I cant seem to get it even close to working the way I'd like. As for the weighting part, I am at a loss.
Thank you for any and all help, and if this is beyond the scope of help for this site I apologize.
Like that?
HTML Code:
<div id="formMatrix">
<ul>
</ul>
<input id="randomSubmit" type="submit" value="Randomize">
</div>
<div id="result">
<br />
<br />
</div>
JS Code:
function updateTextInput(val, i) {
document.getElementById('textInput-' + i).value = val;
}
document.addEventListener("DOMContentLoaded", function() {
//put your image's links
var images = ["http://townandcountryremovals.com/wp-content/uploads/2013/10/firefox-logo-200x200.png", "http://www.thebusinessofsports.com/wp-content/uploads/2010/10/facebook-icon-200x200.png", "http://tech21info.com/admin/wp-content/uploads/2013/03/chrome-logo-200x200.png"];
const form = document.getElementById("formMatrix");
const submitBtn = document.getElementById("randomSubmit");
const textResult = document.getElementById("result");
for (var i = 0; i < images.length; i++) {
form.getElementsByTagName('ul')[0].innerHTML += ("<li><input type='checkbox' id='chk-" + i + "' /><label for='chk-" + i + "'><img id='img-" + i + "' src='" + images[i] + "'/><div class='ranges'><input type='range' id='range-" + i + "' min='0' max='10' value='0' onchange='updateTextInput(this.value, " + i + ");' /><input type='text' disabled='disabled' id='textInput-" + i + "' value='0'/></div></label></li>");
}
// We check the values on the submit click
submitBtn.addEventListener("click", function(e) {
// Prevent it from *actually* submitting (e.g. refresh)
e.preventDefault();
// Grab *all* selected checkboxed into an array
const items = document.querySelectorAll("#formMatrix input:checked");
// Checking if it's not empty
if (items.length > 0) {
var array_items = [];
// Convert object to array
for (var i = 0; i < items.length; i++) {
array_items.push(items[i]);
}
// Add items by freq
for (var i = 0; i < array_items.length; i++) {
var n = parseInt(document.getElementById('textInput-' + array_items[i].id.split('-')[1]).value);
for (var j = 0; j < n; j++) {
array_items.splice(i + 1, 0, array_items[i]);
}
i = (i + n);
}
// Setting a random index from items[0] to items[items.length]
var imgid = ('img-' + array_items[Math.floor(Math.random() * array_items.length)].id.split('-')[1]);
textResult.innerHTML = ("<label><img id='imgResult' src='" + document.getElementById(imgid).src + "'/></label>");
} else {
// If not, we alert
alert("Please choose at least 1 image");
}
});
});
DEMO:
https://jsfiddle.net/pr0mming/vfam3g05/31/
What I really don't understand is the slide part, do you mean that each image can have a "weighting" number, which means that the larger the number, the more frequent it should be output?
UPDATE 1:
The simplest way I saw was to temporarily work the array of selected images, then, if the weight is 10, 10 more images will be inserted into the array respecting the order and it will be chosen randomly.
UPDATE 2:
Last changes: https://jsfiddle.net/pr0mming/vfam3g05/33/
Related
Goal: Show a label, and input value from a different div and display it in a different section
I have a div that dynamically generates a set of input fields, and I am trying to then display that input fields value and their corresponding labels in a different section.
For example:
Step 1 - User enters in the number 5 into an input field.
Step 2 - There are 5 input fields created (based on value entered from step 1). Those input fields are labeled #1, #2, #3, etc... all the way to #5 or whatever number the user entered in Step 1.
Step 3 - User is presented with a new HTML section that lists off the labels (#1, #2, #3, etc.) and next to the labels is the value the user entered for those corresponding input fields.
Here is the code created for Step 2:
<label>#' + count + '</label>
<input type="number" name="length_field" value="" class="form-control length_field" />
Then, I need some javascript/jquery to take the labels and their corresponding input values and display then something like this:
<p>[LABEL #1] <span>[LABEL #1 INPUT VALUE]</span></p>
<p>[LABEL #2] <span>[LABEL #2 INPUT VALUE]</span></p>
<p>[LABEL #3] <span>[LABEL #3 INPUT VALUE]</span></p>
Etc...
For step 2 you need to check the value of your length_field input and create that many inputs by JavaScript. Set some helper ID and CLASS attributes so you can get values later.
For step 3 use that attributes to get input field values and set them as result div's html.
$(document).on('change', '#length_field', function() {
var inputsCount = parseInt($(this).val());
$('#inputsWrapper').html('');
$('#result').html('');
for (var i = 1; i <= inputsCount; i++) {
// Create custom input with label
var tempInput = document.createElement('input');
tempInput.setAttribute('name', i);
tempInput.setAttribute('id', i);
tempInput.setAttribute('class', 'customInputs');
var tempInputLabel = document.createElement('label');
tempInputLabel.setAttribute("for", i);
tempInputLabel.innerHTML = 'Input #' + i + ": ";
$('#inputsWrapper').append(tempInputLabel);
$('#inputsWrapper').append(tempInput);
// Create corresponding value presenter in result div
var resultRow = document.createElement('p');
resultRow.setAttribute('id', 'result-' + i);
resultRow.innerHTML = 'Label #' + i + ':';
$('#result').append(resultRow);
}
});
$(document).on('keyup', '.customInputs', function() {
var id = $(this).attr('id');
var inputValue = $(this).val();
$('#result-' + id).html('Label #' + id + ': <span> ' + inputValue + '</span>');
});
#inputsWrapper input {
display: block;
margin-bottom: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="length_field">Enter the number of inputs you want:</label>
<input type="number" name="length_field" id="length_field" />
<br/>
<div id="inputsWrapper">
</div>
<hr>
<div id="result">
</div>
This is really quick'n'dirty but it works.
I'm using a for-loop in both steps, in the first step the for-loop is generating the input fields and outputting them after.
In the second step I'm saving the html of the resulting paragraphs in a variable, because I can't override the document, because my wanted values are in the input fields.
The on keypress listener is optional and ensures that you don't have to press the Submit button with your mouse ;)
If I could help you i would appreciate if you could mark this answer as accepted.
let number = 0;
$(document).on("click", "#step1", function() {
number = $("input").val();
if (number > 0) {
let html = "", i;
for (i = 1; i <= number; i++) {
html += "<label for='input_" + i + "'>#" + i + "</label>: <input type='text' id='input_" + i + "'><br>";
}
html += "<button id='step2'>Submit</button>"
$("body").html(html);
}
})
$(document).on("click", "#step2", function() {
let html = "", i;
for (i = 1; i <= number; i++) {
html += "<p>Label #" + i + ": <span>" + $("#input_" + i).val() + "</span></p>";
}
$("body").html(html);
})
$(document).on('keypress', function(e) {
if (e.which == 13) {
$("button").trigger("click");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" placeholder="Number of fields">
<button id="step1">Submit</button>
After dynamic table creation, I created a jQuery function that allows the user to copy chosen entries' input values into a staging area via buttons. The values are cloned successfully, but after each button click, the parsley validation error message
"This value should be a valid integer."
appears for every input in the table. Why is the validation perceiving an invalid number entered into the input, and how can this error message be avoided?
Also, there is a button that copies a group of inputs to a staging area, and after that click, the parsley validation error message does not appear. Can anyone see why the single copy would generate the validation message and the group copy would not? The only differences I see are that the validation-triggering code: 1) is called when a class member is clicked as opposed to an ID; and 2) uses the .closest(), .children(), and .eq() methods to navigate the table as opposed to using only IDs to reference table elements. Thanks very much in advance!
The dynamic table row creation in a loop after an AJAX call:
var row = $('<tr></tr>');
var idCell = $('<td></td>').append($('<input type="submit" class="btn btn-info contractToOffer" value="Add To Contracts">'));
row.append(idCell);
idCell = $('<td class="text-center" id="contractID' + data[i].ContractID + '"></td>').append(data[i].ContractID);
row.append(idCell);
idCell = $('<td class="text-center"></td>').append(Number(Number(data[i].ContractPrice) + Number(data[i].ContractMargin)).toFixed(2));
row.append(idCell);
idCell = $('<td class="text-center"><input id="contractValue' + data[i].ContractID + '" value="' + Number(Number(data[i].ContractPrice) + Number(data[i].ContractMargin)).toFixed(2) + '" step="0.01" class="contractInput" type="number" name="quantity" min="1" max="50000"></td>').append();
row.append(idCell);
Moving function that generates validation message:
$("#contractPanel").on("click", ".contractToOffer", function () {
var $offerContractOne = $("#OfferContract1"),//In staging area
$offerPriceOne = $(".price1"),//Also in staging area
$movingContract = 0,
$movingPrice = 0.00,
$oCells = $(this).closest('tr').children('td');
$movingContract = $oCells.eq(1).text();
$movingPrice = $("#contractValue" + $movingTerm.toString()).val();
$offerContractOne.val($movingTerm);//Staging area
$offerPriceOne.text($movingPrice);//Also staging area
});
And finally, the group copying that doesn't generate any message via a "standardOffers" button, which I would also like the single-copy code to do:
$("#contractPanel").on("click", "#standardOffers", function () {
var $oContractOne = $("#OfferContract1"),
$oPriceOne = $(".price1"),
$oContractTwo = $("#OfferContract2"),
$oPriceTwo = $(".price2"),
$oContractThree = $("#OfferContract3"),
$oPriceThree = $(".price3"),
$oContractFour = $("#OfferContract4"),
$oPriceFour = $(".price4"),
$oContractFive = $("#OfferContract5"),
$oPriceFive = $(".price5"),
//The preceding are in the staging area
$standardPrice = 0.00
for (var i = 1; i < 6; i = i + 1) {
if ($("#contractID" + i).length > 0) {
$standardPrice = $("#contractValue" + i.toString()).val();
if (i == 1) {
$oContractOne.val(i.toString());
$oPriceOne.text($standardPrice);
}
else if (i == 2) {
$oContractTwo.val(i.toString());
$oPriceTwo.text($standardPrice);
}
else if (i == 3) {
$oContractThree.val(i.toString());
$oPriceThree.text($standardPrice);
}
else if (i == 4) {
$oContractFour.val(i.toString());
$oPriceFour.text($standardPrice);
}
else {
$oContractFive.val(i.toString());
$oPriceFive.text($standardPrice);
}
}
}
});
Building on top of my comment:
You have 2 options:
event.preventDefault();
this will:
Cancels the event if it is cancelable, without stopping further propagation of the event.
Source
2nd Option:
event.stopPropagation();
this will:
Prevents further propagation of the current event in the capturing and bubbling phases.
Source
I have the following JS code which use's local storage to display the 'name' and 'age' entered previously:
This HTML code currently displays the date, time, name and age of a person in a table. how can i pass these values to be displayed in a HTML form as labels instead of in that table?
HTML only bringing back the start time, name and age aren't being displayed:
<div id="history_list"></div>
<div id="name"> </div>
<div id="age"></div>
JS:
function loadHistoryList() {
for(var i = numberOfHistory; i >= 1; i--) {
var historyData = new historyElement(db.getItem(i.toString()));
if(historyData === null) {
console.error('error');
continue;
}
$('#history_list').append(historyData.startTime);
$('#name').append(historyData.name);
$('#age').append(historyData.age);
}
}
instead of
var div = '<div id="history_element"><div id="element_title">' + historyData.startDate + ' ' + historyData.startTime + '</div><table>';
var div = '<div id="name"><tr><td>name: </td><td>' + historyData.name+ '</td></tr>';
var div = '<div id="age"><tr><td>age: </td><td>' + historyData.age+ '</td></tr>';
div += '</table></div>';
$('#history_list').append(div);
$('#name').append(div);
$('#age').append(div);
Do this:
$('#history_list').append(historyData.startTime);
$('#name').append(historyData.name);
$('#age').append(historyData.age);
In short: you can (and should in this case) simply add the desired value to the container (the DIV, Form field, or whatnot)
those three lines starting witn var div (...) are overwriting each previous line, but that is a side note.
Overall, you should read up more on JavaScript and/or JQuery.
To populate the form field First you have to add a form element like input field
HTML
<div id="history_list">
</div>
<input type="text" id="name" name="name">
JS
function loadHistoryList() {
for(var i = numberOfHistory; i >= 1; i--) {
var historyData = new historyElement(db.getItem(i.toString()));
if(historyData === null) {
console.error('error');
continue;
}
$('#name').val(historyData.name);
}
}
I have this fiddle which is having user tab.In user tab ,there are three fields which accepts name,mobile and email.When a user fills all the three and hits add button then a row is inserted.Now i want to make the new added row editable.This means that I want to keep 2 bootstrap buttons edit and delete.So if delete is pressed then the entire row will be deleted and if edit is pressed then the entire will be editable where user can change the mobile number,name and email.Can any body please tell me how to do.
This js code adds new rows
$('#btn1').click(function () {
if ($(".span4").val() != "") {
$("#mytable").append('<tr id="mytr' + val + '"></tr>');
$tr=$("#mytr" + val);
$tr.append('<td class=\"cb\"><input type=\"checkbox\" value=\"yes\" name="mytr' + val + '" unchecked ></td>');
$(".span4").each(function () {
$tr.append("<td >" + $(this).val() + "</td>");
});
var arr={};
name=($tr.find('td:eq(1)').text());
email=($tr.find('td:eq(2)').text());
mobile=($tr.find('td:eq(3)').text());
arr['name']=name;arr['email']=email;arr['mobile']=mobile;
obj[val]=arr;
val++;
} else {
alert("please fill the form completely");
}
This question is so specific to the OP scenario, so i will try to make the answer a bit more general.
I'm no expert here, but it seems you already capture the user's input and cloned it when they click Add to a new td. Therefore from what I understood is that you need to edit/delete the data from the new created td.
We have a table that contains several fields. We want to apply the following action on them
1- Add
2- Edit
3- Delete
Maybe this isn't the best practice, in short, my approach for this was to insert two spans for each data value:
One hidden that contains an input text field (inputSpan).
Another just contains plain text value (dataSpan).
Whenever you want to edit, dataSpan (just a data container) will disappear and inputSpan (text input field) appears instead enabling you to edit the text field. Once you edit and click Save the data in the text field will be cloned to replace the data in dataSpan. So basically dataSpan is just a reflection to inputSpan text field.
Here is an updated demo:
JSFiddle >> FullView Fiddle
I suggest for readability purposes, you break your code down into small function, it will make life easier, just sayin. So here general logic for your idea:
deleteRow = function (trID) {
// delete code goes here, remove the row
$(trID).remove();
}
manageEdit = function (tdNo) {
if ($("#edit-btn" + tdNo).html() === "Edit") {
$("#save-btn" + tdNo).show();//show save button
$("#edit-btn" + tdNo).html("Cancel");//change edit to cancle
editRow(tdNo);//call edit function
} else if ($("#edit-btn" + tdNo).html() === "Cancel") {
$("#save-btn" + tdNo).hide();//hide save button
$("#edit-btn" + tdNo).html("Edit");//change back edit button to edit
cancelEditRow(tdNo);
}
}
editRow = function (tdNo) {
$(".inputSpan" + tdNo).show();//show text input fields
$(".dataSpan" + tdNo).hide();//hide data display
}
cancelEditRow = function (tdNo) {
//looop thru 3 input fields by id last digit
for (var i = 0; i < 3; i++) {
//get input span that contain the text field
var inputSpan = $("#inputSpan" + tdNo + "-" + i);
//get the data span that contain the display data
var dataSpan = $("#dataSpan" + tdNo + "-" + i);
//text field inside inputSpan
var textField = inputSpan.find('input:text');
inputSpan.hide();//hide input span
textField.val(dataSpan.html());//take original data from display span and put it inside text field to cncle changes.
dataSpan.show();//show data span instead of edit field
}
}
saveRow = function (tdNo) {
//same as edit, but we reverse the data selection.
for (var i = 0; i < 3; i++) {
var inputSpan = $("#inputSpan" + tdNo + "-" + i);
var dataSpan = $("#dataSpan" + tdNo + "-" + i);
var textField = inputSpan.find('input:text');
inputSpan.hide();
dataSpan.html(textField.val());//take data from text field and put into dataSpan
dataSpan.show();
}
$("#edit-btn" + tdNo).html("Edit");//change text to edit
$("#save-btn" + tdNo).hide();//hide same button.
}
Here where I add the spans:
var tdCounter = 0;
$(".span4").each(function () {
var tid = val+"-"+tdCounter;
$tr.append("<td id='#mytd"+tid+"'>
<span id='inputSpan"+tid+"' class='inputSpan"+val+"' style='display:none'>
<input type='text' id='#input"+tid+"' value='"+ $(this).val() + "' /></span>
<span id='dataSpan"+tid+"' class='dataSpan"+val+"'>"+$(this).val()+"</td>");
tdCounter++;
});
Here I just append the buttons to call the functions, each button works for it's own row:
$tr.append("<td><botton id='edit-btn" + val + "' class='btn' onclick=manageEdit('" + val + "');>Edit</botton></td>");
$tr.append("<td><botton style='display:none' id='save-btn" + val + "' class='btn' onclick=saveRow('" + val + "');>Save</botton></td>");
$tr.append("<td><botton id='delete-btn" + val + "' class='btn' onclick=deleteRow('" + trID + "');>Delete</botton></td>");
Below is a sample function, it wont do everyhing you need, but it shows the jquery functions and one possibility how to do it. I only enabled editing name field, and deleting.
You would have to add other fields, + copy id data for the input.
js Fiddle
window.deleteRow = function (tar) {
$(tar).parent().remove();
}
window.editRow = function (tar) {
var row = $(tar).parent(),
cells, name;
cells = row.find("td");
name = $(cells.get(1)).text();
$(cells.get(1)).text('');
$(cells.get(1)).append('<input type="text" value="' + name + '">');
}
window.saveData = function() {
var data = {};
data.name = "some name";//get this from your input
data.email= "some email";//get this from your input
data.phone= "some phone";//get this from your input
$.get("http://yourphpsite.com", data, function(data, status) {
//data contains your server response
if (data.somepositiveservermessage) {
$("#user_notification_field").text("data saved");
$("#user_notification_field").show();
});
}
I am currently doing a school project where I have to use javascript to create a page where a user can key in multiple numbers from an input box.
After each number is entered there is a add button which then shows the number in another box below the input. So each number is displayed vertically down the page.
From there I need two more buttons. The first one to calculate which will add the numbers together and work out the average. The second one will clear the array to start again.
I believe I am ok with the last two buttons. What I am unsure of is how should the user input create the dynamic array which will then be displayed in the page. I have been able to get a single number input but I am missing the next step so the next number entered will dispay and allow me to build an array from which the calculations can be performed.
Please try this I think it will work for you
JAVA SCRIPT :
<script type="text/javascript">
var arr = new Array();
function addNum()
{
var temp = document.getElementById('a').value;
arr.push(temp);
document.getElementById('a').value = "";
getAvg();
}
function getAvg()
{
var sum = 0;
for(var i = 0; i < arr.length; i++){
sum += parseInt(arr[i]);
}
var avg = sum/arr.length;
document.getElementById('sum').value = sum;
document.getElementById('avg').value = avg;
}
function clearAll()
{
arr.length = 0;
document.getElementById('a').value = "";
document.getElementById('sum').value = "";
document.getElementById('avg').value = "";
}
</script>
HTML:
<table>
<tr><td><input type="text" id="a"></td>
<td>Sum :<input type="text" id="sum"></td>
<td>Avg :<input type="text" id="avg"></td></tr>
<tr><td><input type="button" value="add" onclick="addNum()"></td>
<td><input type="reset" value="reset" onclick="clearAll()"></td></tr>
</table
Easiest way would be to loop over the inputs showing the numbers and add each number that way, rather than trying to maintain an array that is updated from the first input.
Stick the displaying input elements into a container with an id, then you can do something simple like:
var container = document.getElementById("container-id"),
inputs = container.children,
total;
for (var x = 0, y = inputs.length; x < y; x++) {
total += parseInt(inputs[x].value, 10);
}
alert(total) //do something way better than alert!