I've been searching for a solution on this but haven't been able to find anything I can understand.
I'm working on the piece of code below - I have simplified the output for ease of reading.
function CreateMsg() {
var MsgDOM = document.getElementById("MSG");
MsgDOM.innerHTML = '<p>calculation.value</p><li>How you view God or a Higher Power: ' + document.forms[0].godview.value + '<\/li><li>How you view your life in general: ' + document.forms[0].lifeview.value + '<\/li><li>How you approach life: ' + document.forms[0].level.value + '<\/li><li>What your inner voice and internal thoughts are busy with: ' + document.forms[0].emotion.value + '<\/li><li>How you are most likely to tackle challenges: ' + document.forms[0].process.value + '<\/li><li>The lessons (mirrors) you are currently working with: ' + document.forms[0].lessons.value + '<\/li>';
}
I have everything working fine so far, but I need to do a calculation that reads the 6 values that the output display is picking up.
The value has to be read, and then replaced from an array - the same array applies to all six variables.
So the output value for each of the elements in the output is one of a number of fixed text values, usually a number. So if the value is 1, for example, I want it to replace that value with a 2. If it's 2, then replace it with 4, etc. There's a string of about 20 values, but they are common to all six numbers I need to calculate.
Then I want it to take those six values and add them together, and print them to the output display where it says calculation.value.
That should be reasonably easy to do, something like this should be what you're looking for!
function CreateMsg() {
var MsgDOM = document.getElementById("MSG");
let fieldsToRead = ["godview", "lifeview", "level", "emotion", "process", "lessons"];
let inputArray = fieldsToRead.map((fieldName) => {
return Number(document.forms[0][fieldName].value);
});
console.log(inputArray);
// This determines how we map input fields to output fields.
// We can add more elements as needed.
let inputOutputMap = {
0:0,1:2,2:4,3:6,4:8,5:10,6:12
};
// You can perform your calculations here!!
let result = inputArray.reduce((total, input) => {
total += (inputOutputMap[input] || 0);
return total;
}, 0);
MsgDOM.innerHTML = '<p>Calculation.value</p><li>How you view God or a Higher Power: ' + document.forms[0].godview.value + '<\/li><li>How you view your life in general: ' + document.forms[0].lifeview.value + '<\/li><li>How you approach life: ' + document.forms[0].level.value + '<\/li><li>What your inner voice and internal thoughts are busy with: ' + document.forms[0].emotion.value + '<\/li><li>How you are most likely to tackle challenges: ' + document.forms[0].process.value + '<\/li><li>The lessons (mirrors) you are currently working with: ' + document.forms[0].lessons.value + '<\/li><br><h3>Calculation total: ' + result + '</h3>';
}
CreateMsg();
<html>
<body>
<form>
Godview:<br>
<input type="text" name="godview" value="1"><br>
Lifeview:<br>
<input type="text" name="lifeview" value="2"><br>
Level:<br>
<input type="text" name="level" value="3"><br>
Emotion:<br>
<input type="text" name="emotion" value="4"><br>
Process:<br>
<input type="text" name="process" value="5"><br>
Lessons:<br>
<input type="text" name="lessons" value="6"><br>
</form>
<div>
<br>
<br>
<div id="MSG">
</div>
</body>
</html>
hi
I go through code acording the requirement bellow is the solved code
can sum the values from the array
<!DOCTYPE HTML>
<html>
<head>
</head>
<body onload="">
<form>
<input type="text" id="godview" value="" />
<input type="text" id="lifeview" value="" />
<input type="text" id="level" value="" />
<input type="text" id="emotion" value="" />
<input type="text" id="process" value="" />
<input type="text" id="lessons" value="" />
</form>
<div>
<input type="button" id="btnsend" value="save" onclick="return CreateMsg();" />
</div>
<div id="MSG">
</div>
<script>
function CreateMsg() {
var arr = [];
var godv = document.forms[0].godview.value;
var lifv = document.forms[0].lifeview.value;
var levelv = document.forms[0].level.value;
var emotionv = document.forms[0].emotion.value;
var processv = document.forms[0].process.value;
var lessonsv = document.forms[0].lessons.value;
arr.push(godv);
arr.push(lifv);
arr.push(levelv);
arr.push(emotionv);
arr.push(processv);
arr.push(lessonsv);
alert(arr);
var MsgDOM = document.getElementById("MSG");
MsgDOM.innerHTML = '<p>calculation.value</p><li>How you view God or a Higher Power: ' + document.forms[0].godview.value + '<\/li><li>How you view your life in general: ' + document.forms[0].lifeview.value + '<\/li><li>How you approach life: ' + document.forms[0].level.value + '<\/li><li>What your inner voice and internal thoughts are busy with: ' + document.forms[0].emotion.value + '<\/li><li>How you are most likely to tackle challenges: ' + document.forms[0].process.value + '<\/li><li>The lessons (mirrors) you are currently working with: ' + document.forms[0].lessons.value + '<\/li>';
}
</script>
</body>
</html>
Related
I have a django form with an inline formset and I'd like to give the user the ability to add/remove the fields 'approach_type' and 'approach_number'
This a snippet of the form:
<div class="form-group">
<div class="input-group-sm">
<label class="text-muted">Approaches</label>
<div class="form-control pl-4 pt-2">
<div class="row form-row">
<input type="hidden" name="approach_set-TOTAL_FORMS" value="1" id="id_approach_set-TOTAL_FORMS" /><input type="hidden" name="approach_set-INITIAL_FORMS" value="0" id="id_approach_set-INITIAL_FORMS" /><input type="hidden" name="approach_set-MIN_NUM_FORMS" value="0" id="id_approach_set-MIN_NUM_FORMS" /><input type="hidden" name="approach_set-MAX_NUM_FORMS" value="1000" id="id_approach_set-MAX_NUM_FORMS" />
<input type="hidden" name="approach_set-0-id" id="id_approach_set-0-id" />
<div class="col pr-5>"><select name="approach_set-0-approach_type" class="form-control" id="id_approach_set-0-approach_type">
<option value="" selected>---------</option>
<option value="ILS">ILS</option>
<option value="CATII">CAT II</option>
<option value="CATIII">CAT III</option>
</select></div>
<div class="col pr-5>"><input type="number" name="approach_set-0-number" min="0" class="form-control" id="id_approach_set-0-number" /> </div>
<div class="input-group-append">
<button class="btn btn-success add-form-row">+</button>
</div>
<!-- <div class="col pr-5>"><input type="checkbox" name="approach_set-0-DELETE" class="form-control" id="id_approach_set-0-DELETE" /></div> -->
</div>
and here is the JS from this tutorial:
https://medium.com/#taranjeet/adding-forms-dynamically-to-a-django-formset-375f1090c2b0
<script type='text/javascript'>
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>');
return false;
}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;
}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;
});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;
});
</script>
This line is the current problem:
var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
I'm sorry but I only know a very little bit of JS.
So as you pointed out in your comment the problem is that $(this).attr('name') is returning undefined. It looks like for some reason your query is also returning the button, which if you look at the jquery documentation makes a little sense... although i dont know if I would consider a button an input automatically but they do. I'm also not 100% sure what you want this to be doing, but to solve this issue you can either wrap that chunk of code in an if block checking if the name attr is undefined or not, changing your query on the inputs to be stricter, or filter down the list you are running over. Here is a codepen that I think is working as intended, but again, didn't read the whole meium article so no promises. the relevant part is here:
newElement.find(':input')
.filter(function(){
return $(this).attr('name');
})
.each(function(){
...
})
the filter function is essentially saying filter out all results where the name attribute is undefined.
let me know if this does what you're hoping for! good luck learning Javascript! I promise its more fun that what you're currently dealing with. especially if you start using ES6
On my form I am trying to have specific output fields and their strings output as Title Case. May be worth noting, this form outputs to results on the same page. Here's a Fiddle demo of my form.
As you can see from it I have 3 input categories Name, City and Words, for this example I am trying to implement the Title Case script to just the 'Name" and City" output strings without it effecting the "Words" category. As I don't want to convert an ongoing sentence to Title Case.
I found a lot of discussion here on how to convert to title case. However I am having difficulty implementing this in to my form as I am still new to JavaScript. All the examples show the script, but not how to implement it in a form.
I was playing around with Greg Dean's top answer to try and target the specific inputs like so...
toTitleCase = function(str)
{
var name = document.getElementById('name');
var city = document.getElementById('city');
return str.replace(/\w\S*/g, function(txt){return
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
However this does not seem to be working.
Here's the HTMl:
<form>
<input type="text" class="text" id="name" placeholder="Name">
<br>
<input type="text" class="text" id="city" placeholder="City">
<br>
<textarea type="textarea" id="words" placeholder="Words" cols="70" rows="6">
</textarea>
<br>
<input type="button" value="Combine" onclick="convert()">
<br>
<div class="wrap"><span id="CharCountLabel1" class="counter"></span>
<textarea type="textarea" name="output" id="output" cols="70" rows="10"
maxlength='' placeholder="Output"></textarea>
</div>
<br>
<button type="reset" onclick="ResetForm();" value="Reset
form">Reset form</button>
</form>
And the rest of the script:
function convert() {
var name = document.getElementById("name").value;
var city = document.getElementById("city").value;
var words = document.getElementById("words").value;
//input = wordwrap(input, 70, true);
var output = "";
if(!document.getElementById("name").disabled){
output += "Name: " + name + "\n";
}
if(!document.getElementById("city").disabled){
output += "City: " + city + "\n";
}
if(!document.getElementById("words").disabled){
output += "The words are... " + words + "\n";
}
document.getElementById("output").value = output;
}
CharacterCount = function(output,FieldToCount){
var myField = document.getElementById(output);
var myLabel = document.getElementById(FieldToCount);
var Chars = myField.length;
if(!Chars){Chars = "" ; };
var remainingChars = Chars + myField.value.length
myLabel.innerHTML = remainingChars+""+Chars
}
setInterval(function(){CharacterCount('output','CharCountLabel1')},55);
How do I target the script to just the specified input fields? Please no jQuery, just JavaScript solutions.
While you have a fully-function toTitleCase() function, you're never actually calling it. All you need to do is run your name and city variables through your toTitleCase function when you go to output them to the page:
if (!document.getElementById("name").disabled) {
output += "Name: " + toTitleCase(name) + "\n";
}
if (!document.getElementById("city").disabled) {
output += "City: " + toTitleCase(city) + "\n";
}
To prevent the words from also being transformed, simply don't pass that variable to the function:
if (!document.getElementById("words").disabled) {
output += "The words are... " + words + "\n";
}
A working demo of this can be seen here.
Hope this helps! :)
So this is what the page looks like currently:
The first one is hardcoded in and then the rest are added/removed by the buttons. The first one can also be added and removed from the buttons. I want to call a jquery function when the dropdown is changed to change the type from textbox/radiobutton (and text)/checkbox (and text) etc.
Currently it only works on the first Question/Answer and only works if it is the original and not dynamically created. I'm not sure why that is.
Here is how the Q/A's are created and removed
$("#addButton").click(function () {
if (counter > max_fields) {
alert("Only " + max_fields + " Questions allowed");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<label>Question #' + counter + ' : </label>' +
'<input type="text" name="textbox' + counter +
'" id="questionbox' + counter + '" value="" />' +
' <select id="choice'+ counter +'"><option>Type</option><option>Radio Button</option><option>Text Box</option><option>Check Box</option></select>' +
'<button id = "remove' + counter + '">Remove</button>' +
'<br/><label>Answer #' + counter + ' : </label>' +
'<div id="Answers' + counter + '">' +
'Option 1: <input type="text" id="answerbox' + counter +
'1" name="answerbox' + counter + '" value="" />' +
'<br/>Option 2: <input type="text" id="answerbox' + counter +
'2" name="answerbox' + counter + '" value="" />' +
'<br/>Option 3: <input type="text" id="answerbox' + counter +
'3" name="answerbox' + counter + '" value="" />' +
'<br/>Option 4: <input type="text" id="answerbox' + counter +
'4" name="answerbox' + counter + '" value="" /></div>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
$("#removeButton").click(function () {
if (counter == 1) {
alert("No more textbox to remove");
return false;
}
counter--;
$("#TextBoxDiv" + counter).remove();
});
This is how I tried to get it to change types
$('#choice1').change(function () {
var selected_item = $(this).val()
var searchEles = document.getElementById("Answers1").children;
alert(searchEles.length);
for(var i = 0; i < searchEles.length; i++) {
$('#answerbox1' + i).attr('type', selected_item);
//alert(searchEles.length);
}
});
The web page code is as follows
<input type='button' value='Add Question' id='addButton'/>
<input type='button' value='Remove Question' id='removeButton'/>
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
<label>Question #1 : </label>
<input type='text' id='questionbox1'/>
<select id="choice1" onchange="$('#choice').val('id');"> //this on change was added and currently does nothing it seems.
<option value="">Type</option>
<option value="radio">Radio Button</option>
<option value="text">Text Box</option>
<option value="checkbox">Check Box</option>
</select>
<button id="remove1">Remove</button>
<br/><label>Answer #1 : </label>
<div id="Answers1">
Option 1: <input type="text" id='answerbox11' name='answerbox1' value="" />
<br/>Option 2: <input type="text" id='answerbox12' name='answerbox1' value="" />
<br/>Option 3: <input type="text" id='answerbox13' name='answerbox1' value="" />
<br/>Option 4: <input type="text" id='answerbox14' name='answerbox1' value="" />
</div>
</div>
</div>
I tried to do something like onchange and then get the ID and go from there but that didn't work. I know it doesn't match the back end jquery name.
TL;DR
I don't know how to dynamically write the jQuery function to work
for all of them.
I don't know why even if I hardcode it to #choice1 it will work
when its first created but not if i remove and add it even though it
has the same exact values. I think it might MAYBE have to do with
for loop, because the alert doesn't even trigger the second time
around.
You could try
$(document).on("change", ".selector", function(){
//do something
});
//Edit
Add to the select element class for example select-option and a tag that will hold the select's counter
//JS
...'<select id="choice'+counter+'" class="select-option" number="'+counter+'">'...
and then your on change function would look something like
$(document).on("change", ".select-option", function(){
//do something
var selected_type = $(this).attr('value');
var ans_number = $(this).attr('number');
$("#answerbox"+ans_number).children('input').attr('type', selected_type);
});
I hope this will help :)
For dynamically added elements use
$(selector).on("change", callback)
If element is dynamic then Jquery will not bind directly as
$('#choice1').change(function (){});
But for that you need to call same function with some static element.
For Ex:
$(".listingDiv").find('#choice1').change(function (){});
or
$(document).find('#choice1').change(function (){});
and it will work. try it.
When elements will be aded dynamically, best practice is to delegate the handler(s). Put your handler on the containing div or window/document
.
First
<select id="choice1" onchange="$('#choice').val('id');"> //this on change was added and currently does nothing it seems.
This is one reason your never be called. If you bind an event listener to an element, you should not write the actual JS code inside the element.
Second
Bind your listener like this:
$('#choice1').on("change", function () {
var selected_item = $(this).val()
var searchEles = document.getElementById("Answers1").children;
alert(searchEles.length);
for(var i = 0; i < searchEles.length; i++) {
$('#answerbox1' + i).attr('type', selected_item);
//alert(searchEles.length);
}
});
I'm Having a bit of an issue. I'm using JavaScript to inset HTML into a webpage along with an event handler for the onblur event. It looks like this:
return '<input id = "txtIn" type="text" value=" ' + dateTime + '" onblur= "submitManualDate(document.getElementById("txIn").value(), 2, 3);" />';
I'm getting a syntax error. However, the following works perfectly fine:
return '<input id = "txtIn" type="text" value=" ' + dateTime + '" onblur= "submitManualDate(1, 2, 3);" />';
Any idea what I'm missing?
Using " inside "(double quoted) expression will break the string.
It's better to pass this as an argument as you should not have multiple elements with same id attributes in a document.
Try this example:
(function() {
var input = '<input type="text" value="5" onblur= "submitManualDate(this, 2, 3);" />';
document.getElementById('parent').innerHTML = input;
})();
function submitManualDate(elem, j, k) {
alert(elem.value + ' ' + j + ' ' + k);
}
<div id='parent'></div>
Fiddle here
I am starting to learn javascript and I have a small project work complete. I would like to take the information from a form and create an ics file for 3 single events - an original date, a 5 day event, a 20 day event. Below is the entire html and javascript code. This will be an internal file, it won't go online.
So far i've been able to create the form and an alert box that pulls the information presented. I would like to keep it scrictly javascript and not jQuery - as that is beyond my skill level and comprehension.
Thank you so much friends. .
<form>
<fieldset>
<legend>NUMC Information</legend>
Handler: <select>
<option value = "Ronald" >Ronald</option>
<option value = "Thomas">Thomas</option>
<option value = "Elizabeth">Elizabeth</option>
</select>
</fieldset>
</form>
<br>
<fieldset>
<legend>FOIL Contact</legend>
<form>
First name:<br>
<input type="text" id="firstname">
<br>
Last name:<br>
<input type="text" id="lastname">
<br>
Email:<br>
<input type="email" id="email">
<br>
Phone:<br>
<input type="text" id="phone">
</form>
</fieldset>
<br>
<div class="origin-event" >Origin Event">
<form id="eventForm">
<fieldset>
<legend>New FOIL Calendar Event</legend>
<legend>FOIL Origin Date</legend>
<fieldset>
<div>
Title: <input type="text" id="summary" >
<br><br>
Origin Date: <input type="date" id = "originDate"/>
<br>
</div>
</fieldset>
<br>
<legend>FOIL 5 Day Reminder</legend>
<fieldset>
<div>
5 Day Reminder Date: <input type="date" id = "5dayDate"/>
<br>
</div>
</fieldset>
<br>
<legend>FOIL 20 Day Reminder</legend>
<fieldset>
<div>
20 Day Reminder Date: <input type="date" id = "20dayDate"/>
<br>
</fieldset>
<br>
Description:
<br>
<textarea id="description" name="description"></textarea>
<br>
Location:
<br>
<input value="New York" id="location">
</div>
</fieldset>
</form>
</div>
<br>
<div class = "buttons">
</div>
<div class="wrap">
<button type="button" onclick="getValue()">Create Origin Date Noficiation</button></a>
<br>
</div>
<script>
function getValue()
{
var title= "Title: " + document.getElementById("summary").value;
var description = "Description: " + document.getElementById("description").value;
var location = "Location: " + document.getElementById("location").value;
var originalDate = "Origin Date: " + document.getElementById( "originDate").value;
var FiveDay = "Five Day: " + document.getElementById( "5dayDate").value;
var TwentyDay = "Twenty Day: " + document.getElementById( "20dayDate").value;
alert(title + "\n" + description + "\n" + location + "\n" + originalDate + "\n" + FiveDay + "\n" + TwentyDay);
}
</script>
I found a possible solution at https://github.com/nwcell/ics.js and https://github.com/matthiasanderer/icsFormatter but its just blowing my mind how to manipulate it to fit my needs.
Thoughts?
Thanks everyone for your help.
I have completely the project.
The sample page can be found here: https://dl.dropboxusercontent.com/u/25536938/FOIL%20Reminder.html
The code I came up with was:
<script>
// Demo
// access text property of selected option
var val = "Contact Name: " + sel.options[sel.selectedIndex].text;
function createEvent() {
var cal_single = ics();
var cal = ics();
var sel = document.forms['form'].elements['category'];
// value property of select list (from selected option)
var val = sel.value;
// access text property of selected option
var val = "Handler: " + sel.options[sel.selectedIndex].text;
var FiveDaysubject = document.getElementById("summary").value + " (Five Day Reminder)";
var TwentyDaysubject = document.getElementById("summary").value + " (Twenty Day Reminder)";
var foilFirst = " Contact First Name: " + document.getElementById("firstname").value;
var foilLast = " Contact Last Name: " + document.getElementById("lastname").value;
var foilEmail = " Contact Email: " + document.getElementById("email").value;
var foilPhone = " Contact Phone: " + document.getElementById("phone").value;
var originalDate = new Date(form.originDate.value);
originalDate.setDate(originalDate.getDate() + 1);
var FiveDayDate = new Date(form.FiveDay.value);
FiveDayDate.setDate(FiveDayDate.getDate() + 1);
var TwentyDayDate = new Date(form.TwentyDay.value);
TwentyDayDate.setDate(TwentyDayDate.getDate() + 1);
var description = val + foilFirst + foilLast + foilEmail + foilPhone + " Description: " + document.getElementById("description").value + " Origin Date: " + originalDate;
var location = "New York";
cal_single.addEvent(FiveDaysubject, description, '', FiveDayDate, FiveDayDate);
cal.addEvent(TwentyDaysubject, description, '', TwentyDayDate, TwentyDayDate);
cal_single.download(FiveDaysubject);
cal.download(TwentyDaysubject);
}
</script>
The original ics.js was a good initiative, but the original has some critical flaws.
There are several forks that solved at least major output problem: Time doesn't show up if minutes and seconds are 0, which looks like a duplicate of Lacking Minute Issue, both totally ignored by the original author.
Specifically, I liked this fork https://github.com/connorbode/ics.js based on having multiple contributors and some pull requests and merges in its history.
You cannot do this purely in Javascript. You'd need some help from the server to make a file.
But you could try using a library called Downloadify and see if that will do it for you!
Cheers!