I am trying to implement automatically HTML using form value.
When user enter the information in the form, the JS will create the correspond HTML for him.
For example.
<div class="row" id="1">
<div class="form-group col-lg-2">
<select class="form-control" name="tag">
<option value="p" selected>p</option>
<option value="br">br</option>
</select>
</div>
<div class="form-group col-lg-2">
<select class="form-control" name="class">
<option value="Day" selected>Day</option>
<option value="BlockTime">BlockTime</option>
<option value="BlockTitle">BlockTitle</option>
<option value="Session">Session</option>
<option value="Person">Person</option>
<option value="Firm">Firm</option>
</select>
</div>
<div class="form-group col-lg-7">
<textarea class="form-control" rows="3" name="content"></textarea>
</div>
<div class="form-group col-lg-1">
<input type="button" class="btn btn-default" onclick="addLine()" value="Add">
</div>
</div>
The user selected P, Day, Test message, and the press "Add" button, the button will call function addLine(). The main part is below, I didn't make it right.
var currentTag = currentLine.find("select[name='tag'] option:selected").text();
var currentClass = currentLine.find("select[name='class'] option:selected").text();
var currentText = currentLine.find("textarea").val();
var new_content = $("<currentTag></currentTag>").addClass(currentClass).html(currentText);
Now the currentTag will get the value "p", currentClass will get "Day", currentText do get "Test message", this has been done.
This is what I want, the jQuery creates HTML code like this:
<p class="Day">Test message</p>
And I want to store the HTML code to a variable called new_content. ...
If you have a container for these elements, you could just append them to it:
First you want to set your new line as a variable:
var newElements = [];
var i = 0; //Make an index counter so you can use it later if you want to. This is optional
/* Do your selection script */
var htmlElement = "<" + currentTag + " class='" + currentClass + "'>" + currentText + "</" + currentTag + ">";
newElement.push(htmlElement, i);
$('.container').append(htmlElement);
i++; //increment your i to create an index
/* Make sure all of this is inside your selection script. */
Related
I have a form, where a user can select between different options inside a few dropdown fields. Depending on the user selection, the values will be displayed inside a span field next to the dropdown field.
Now I would like to count all those values inside the span fields, so that I can display a total amount at the end of the form before it will be submitted.
Here is a part of my form:
<form name='formname_form' action='./index.php' method='post' class='formname-form' id='formname-form'>
<div class="row" id='save_prices'>
<div class="col-lg-8 offset-lg-2 col-md-10 offset-md-1 col-sm-12">
<div class="form-inline">
<label class="form-icon">
<figure>
<img src="../assets/images/symbol-1.png" alt="/">
</figure>
</label>
<div class="form-group">
<select name="field_a" id="field_a" onchange="CalcDiscount()">
<option value="0,00">Option A?</option>
<option value="6,17">Yes</option>
<option value="0,00">No</option>
</select>
</div>
<div class="amount-wrap-3">
<span>€ <span id='field_a_price' class='prices'></span></span>
</div>
</div>
<div class="form-inline">
<label class="form-icon">
<figure>
<img src="../assets/images/symbol-2.png" alt="/">
</figure>
</label>
<div class="form-group">
<select name="field_b" id="field_b" onchange="CalcDiscount()">
<option value="0,00">Option B</option>
<option value="17,50">Yes</option>
<option value="0,00">No</option>
</select>
</div>
<div class="amount-wrap-3">
<span>€ <span id='field_b_price' class='prices'></span></span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 offset-lg-2 col-md-10 offset-md-1 col-sm-12">
<div class="total-amount">
Total Price
<div class='price'><span id='total_price' class="total_price"></span> €</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-12">
<div class="form-inline">
<input name='submit' type='submit' id='submit' value='Save' class='btn btn-form-indiv'/>
</div>
</div>
</div>
</form>
And here is my javascript part:
<script>
// Get references to the objects you need (<select> and <span>)
var field_a = document.getElementById('field_a');
var field_a_price = document.getElementById('field_a_price');
var field_b = document.getElementById('field_b');
var field_b_price = document.getElementById('field_b_price');
// When the list value changes, set the innerHTML of the <span>
field_a.onchange = function() {
field_a_price.innerHTML = this.value;
};
field_b.onchange = function() {
field_b_price.innerHTML = this.value;
};
var priceList = $('#save_prices').find('.prices');
var totalPrice = 0;
$.each(priceList, function(i, price){
totalPrice += parseInt($(price).text())
});
$('.total_price').text(totalPrice);
</script>
Does anyone have an idea what I am doing wrong? The value inside my span with the class total_price stays always 0. I assume that is has something to do with my onChange methods that I am using?
Problem
The total from the 2 select boxes are not appearing in the Total Price area.
Solution
Create a function and call it to fire off on the onchange event when a new value is selected in the selection boxes.
Example
// Get references to the objects you need (<select> and <span>)
var field_a = document.getElementById('field_a');
var field_a_price = document.getElementById('field_a_price');
var field_b = document.getElementById('field_b');
var field_b_price = document.getElementById('field_b_price');
// When the list value changes, set the innerHTML of the <span>
field_a.onchange = function() {
field_a_price.innerHTML = this.value;
// Calling new function
updateTotal();
};
field_b.onchange = function() {
field_b_price.innerHTML = this.value;
// Calling new function
updateTotal();
};
// New function
function updateTotal() {
var p = $('.prices').map(function () { return $(this).text(); }).get();
var totalPrice = 0;
$.each(p, function( index, value ) {
totalPrice = totalPrice + value;
$('.total_price').text(totalPrice);
});
}
Summary
I am not sure what you are attempting to do with the values considering they have commas.
To directly address your question, when your code is ran the reason the values are always empty is because all the code only runs on page load. When you change the selection box values only the code in the onchange was being ran. By adding a function that is called each time a selection is made we can populate the array from the class list returned with JQuery.
I'm currently able to append HTML and remove the right appended HTML, but when I add more of that HTML it is appended with the same id so the functionality if I want to show or hide a certain div element, is not working.
This is the code that i append and remove:
$(".adRowOutdoor").click(function(){
var newTxt = $('<div class="add-row-outdoor row width-100 padding-left-15"> <div class="form-group col-md-4"> <label for="state" class="control-label">Type</label> <div class="sg-select-container"> <select id="choose-outdoor"> <option disabled="">Choose type</option> <option value="Undercover walkway">Undercover walkway</option> <option value="Oval">Oval</option> <option value="Swimming Pool">Swimming Pool</option> <option value="Outdoor Basketing Court">Outdoor Basketing Court</option> <option value="other">Other</option> </select> </div> </div><!-- end col --> <div id="choose-outdoor-is-hidden" class="form-group col-md-4" style="display: none;"> <label for="other-textfield" class="control-label">Other</label> <input type="text" class="form-control form-input-field" name="other-textfield" value="" required="" placeholder=""> <span class="help-block"></span> </div> <div class="col-md-2 remove-btn-audit form-space-top-35"> <button class="btn btn-add-waste removeOutdoor"><i class="fa fa-minus-circle o-btn-add" aria-hidden="true"></i>Remove</button> </div> </div><!-- row audit -->');
$(".row-outdoor-container").append(newTxt);
});
$("body").on('click' , '.removeOutdoor' , function(){
var curRow = $(this).parents('div.add-row-outdoor');
curRow.remove();
});
An image how it looks is:
What I want now is to hide and show a div element with a text field on the selection of the certain div with a unique id that I want to generate.
I'm able to show that text field only for the first element, but not for other appended HTML.
$('#choose-outdoor').change(function (e) {
var val = $("option:selected", this).val()
if (val == 'other') {
$('#choose-outdoor-is-hidden').show();
}
// Hide complete sub type div
else {
$('#choose-outdoor-is-hidden').hide();
}
});
JsFiddle of my code is here
Change id to classes so basically make choose-outdoor and choose-outdoor-is-hidden as your classes on the same elements.
Then use event delegation as the elements are dynamically created:
$('.row-outdoor-container').on("change", '.choose-outdoor', function (e) {
var val = $(this).val();
$el = $(this).closest(".add-row-outdoor").find('.choose-outdoor-is-hidden');
if (val == 'other') {
$el.show();
}
else {
$el.hide();
}
});
Updated fiddle
I'm just a beginner I want to create button for remove clone but I can't.
This is my code but it isn't work. Please help me to know where did I wrong.
PS. Sorry for my poor English
HTML
<div class="docu">
<div class="row">
<div class="col-sm-2"></div>
<div class="col-lg-7" id="Freport" name="Freport">
<div class="input-group">
<div class="input-group-btn">
<select name="tell" id="tell" class="btn btn-default dropdown-toggle">
<option value="0"></option>
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
</select>
</div><!--End row-->
<input type="text" class="form-control" aria-label="..." placeholder="...">
</div><!-- /btn-group -->
</div><!-- /input-group -->
<div class="col-sm-1">
<button type="submit" id="btnClonereport"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span></button>
<button type="submit" id="btnDelreport"><span class="glyphicon glyphicon-minus-sign" aria-hidden="true"></span></button>
</div>
<div id="container4">
</div>
JS This is my script I can clone but I can't remove clone.
<script type="text/javascript">
$(function () {
$("#btnClonereport").bind("click", function () {
var index = $("#container4 select").length + 1;
//Clone the DropDownList
var fre = $("#Freport").clone();
var fre2 = $("#orand").clone();
//Set the ID and Name
fre.attr("id", "Freport_" + index);
fre.attr("name", "Freport_" + index);
fre2.attr("id", "orand_" + index);
fre2.attr("name", "orand_" + index);
//[OPTIONAL] Copy the selected value
var selectedValue = $("#Freports option:selected").val();
fre.find("option[value = '" + selectedValue + "']").attr("selected", "selected");
var selectedValue = $("#orands option:selected").val();
fre2.find("option[value = '" + selectedValue + "']").attr("selected", "selected");
//Append to the DIV.
$("#container4").append(fre2);
$("#container4").append(fre);
$("#container4").append("<br /><br />");
});
$("#btnDelreport").bind("click", function(){
$(this).closest("#container4").remove();
});
});
</script>
So you want to remove all form clones? Try this for your delete button action:
EDIT: If you want to remove the last occurance, that makes things much simpler.
$("#btnDelreport").bind("click", function(){
$('#container4').children('.col-lg-7').last().remove();
});
I have a multistep form in my project, the first step of which has a javascript extend field function where a user can add additional fields. If the user goes to the next step, the data is of course stored in Session until final submission. However, the extended form will not be remembered. If the user goes back from next step the additional field and its data is not displayed, worse still, if the data in the additional field is invalid, the user won't see it, as the message is displayed underneath the disappeared field (I'm using Cakephp default validation).
Is there a way, like storing the setting in session, to make it stay?
var counter = 0;
function moreFields(val1, val2, val3) {
counter++;
var newField = document.getElementById(val1).cloneNode(true);
newField.id = '';
newField.style.display = 'block';
var newFields = newField.querySelectorAll('[name], [id], [for], [data-display]');
for (var i=0;i<newFields.length;i++) {
var theNames = newFields[i].name
if (theNames)
newFields[i].name = "data[" + val3 + "][" + counter + "][" + theNames + "]";
var theNames2 = newFields[i].id;
if (theNames2)
newFields[i].id = theNames2 + counter;
console.log(newFields[i].id);
var theNames3 = newFields[i].htmlFor;
if (theNames3)
newFields[i].htmlFor = theNames3 + counter;
//console.log(newFields[i].htmlFor);
var theNames4 = newFields[i].dataset.display;
if (theNames4)
newFields[i].dataset.display = theNames4 + counter;
console.log(newFields[i].dataset.display);
}
var insertHere = document.getElementById(val2);
insertHere.parentNode.insertBefore(newField,insertHere);
}
<span id="readroot" style="display: none">
<div class="row">
<div class="col-lg-6">
<div class="form-group required">
<label for="Student1Grade">Grade</label>
<select name="grade" data-display="#display_student_1_grade" class="form-control" id="Student1Grade" required="required">
<option value="">Please Select</option>
<option value="1">Grade 1</option>
<option value="1">Grade 2</option>
</select>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label for="Student1Gender">Gender</label>
<select name="gender" data-display="#display_student_1_gender" class="form-control" id="Student1Gender">
<option value="1">Male</option>
<option value="2">Female</option>
</select>
</div>
</div>
</div>
<input class="btn btn-default" type="button" value="Remove" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" /><br /><br />
</span>
<span id="writeroot"></span>
<input class="btn btn-default" type="button" onclick="moreFields('readroot', 'writeroot', 'Student')" value="Add Field" />
You need to implement either sessionStorage or localStorage for your page.
localStorage - stores data with no expiration date
sessionStorage - stores data for one session (data is lost when the browser tab is closed)
Here I am just posting sample code for your help through which u can do your desire task. You just need to follow the logical concept from below code and implement in your code.
There is a sample also which is only containing id but you can implement it in other way which can full fill your task.
click here
I have a rather long complicated form to be used to record field data. One section of the form requires the ability to add a "Field Blank" section with no data recorded AND the ability to add a duplicate section where everything (including the data from the field blank section) is duplicated. The only different thing that would change on the duplicate would be the SampleID
The field blank script
<script>
var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('readroot').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
var theName = newField[i].name
if (theName)
newField[i].name = theName + counter;
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields,insertHere);
}
</script>
The duplicate script
<script>
$(document).ready(function(){
var template_index=0;
$("#add_FieldDup").click(function(){
template_index++;
$(this).parent().before($("#template").clone().attr("id","template" + template_index));
$("#template" + template_index).css("display","inline");
$("#template" + template_index + " :input").each(function(){
$(this).attr("name",$(this).attr("name") + template_index);
$(this).attr("id",$(this).attr("id") + template_index);
});
$("#remove_Dup" + template_index).click(function(){
$(this).closest("fieldset").remove();
});
});
});
</script>
My form
<h3>Water Samples</h3>
<fieldset id="template"> <!--for the duplicate-->
<div id="template"> <!--for the duplicate-->
Sample ID: <input type="text" id="SampleID" name="SampleID"></div>
<div class="_40" data-role="controlgroup" data-mini="true" data-type="horizontal">
<label> Collection Method</label><br />
<input type="radio" id="radGrab" value="grab" name="Collection" />
<label for="radGrab">Grab</label>
<input type="radio" id="radEWI" value="EWI" name="Collection" />
<label for="radEWI">EWI</label>
</div>
<fieldset> <!--For the field blank-->
<div id="readroot" class="hidden"> <!--For the field blank-->
QA Sample ID:<input type="text" id="QASampleID" name="QASampleID">
<div class="_30" data-role="controlgroup" data-mini="true" data-type="horizontal">
<label>Collection Method</label><br />
<input type="radio" id="radGrab1" value="Grab" name="Collection1" />
<label for="radGrab1">Grab</label>
<input type="radio" id="radEWI1" value="EWI" name="Collection1" />
<label for="radEWI1">EWI</label></div>
</div>
<label class="analysis-label" for="analysis">Analyte:</label>
<select class="analysis" id="analysis" name="analysis" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "TN">TN</option>
<option value = "TP,NO2+3">TP,NO2+3</option>
</select>
<label class="preserve-label" for="preserve">Preserved</label>
<select class="select_preserve" id="preserve" name="preserve" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "HNO3">HNO₃</option>
<option value = "H2SO4">H₂SO₄</option>
</select>
<label class="cool-label" for="cool">Cooled</label>
<select class="select_cool" id="cool" name="cool" data-iconpos="left" data-icon="grid">
<option>Select</option>
<option value = "Ice">Ice</option>
<option value = "Frozen">Frozen</option>
<option value = "None">None</option>
</select>
</div> <!--Fieldblank-->
</fieldset> <!--Fieldblank -->
<hr /><span id="writeroot"></span>
</div> <!--duplicate template-->
</fieldset> <!--duplicate template-->
<button type="button" data-theme="b" data-icon="plus" id="moreFields" onclick="moreFields()">ADD FIELD BLANK</button>
<button type="button" data-theme="b" data-icon="plus" id="add_FieldDup">ADD FIELD DUP</button>
I got the duplicate to work (when the field blank wasn't hidden) but I cannot get the field blank to work. Any assistance would be greatly appreciated!
You should extract your javascript from your dom, put it in separate js and make function work in any of this blocks, create class="template" block and inside give any needed interaction buttons and inputs classes so there can exist multiple parent elements with same inside structure... then cloning does not get in a way of your interaction logic.
In js go like:
$(document).ready(function() {
$(".template .interaction_button_one").on('click', function(){
//... here you go traversing like
$(this).parents('.template').find('.some_important_div').show();
})
});
Notice .on(), this is delegation, and it will give same interaction bindings to all of your elements.