I have one large form that is separated into different sections with divs. Each section is within the same form (bigform) and I need to make sure only one section is enabled/editable at a time. And if the user changes sections after entering data into one section, all data would be cleared from the old section before disabling it. The ideal way for me is to have something like this:
<form>
<select name="selector">
<option>Choose Which Div To Enable</option>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
</select>
</form>
<form name="bigform">
<div id="1">
<input type="text">
<select name="foo">
<option>bar</option>
<option>bar</option>
</select>
</div>
<div id="2">
<input type="text">
<select name="foo">
<option>bar</option>
<option>bar</option>
</select>
</div>
<div id="3">
<input type="text">
<select name="foo">
<option>bar</option>
<option>bar</option>
</select>
</div>
</form>
When the user selects option "Two" in the selector form, all form elements in DIVs 1 and 3 would be disabled. I've searched the web for hours but I cannot find a solution. What's the best method to achieve this?
I found this code online that does "almost" what I want but not quite. It 'toggles' the form elements in the given element (el). What I'm trying to do is sort of the opposite of this.
<form>
<select name="selector" onChange="toggleDisabled(document.getElementByID(this.value))>
<option>Choose Which Div To Enable</option>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
</select>
</form>
<script>
function toggleDisabled(el){
try {
el.disabled = el.disabled ? false : true;
}
catch(E){}
if (el.childNodes && el.childNodes.length > 0) {
for (var x = 0; x < el.childNodes.length; x++) {
toggleDisabled(el.childNodes[x]);
}
}
}
</script>
A way to solve it without using a scripting library such as jQuery:
function disableFormFields(container, isDisabled) {
var tagNames = ["INPUT", "SELECT", "TEXTAREA"];
for (var i = 0; i < tagNames.length; i++) {
var elems = container.getElementsByTagName(tagNames[i]);
for (var j = 0; j < elems.length; j++) {
elems[j].disabled = isDisabled;
}
}
}
<select name="selector" onchange="partiallyDisableForm(this)">
<!-- give every option a numeric value! -->
<option value='0'>Choose Which Div To Enable</option>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
</select>
function partiallyDisableForm(selector) {
// don't forget to give your form the ID "bigform"
var form = document.getElementById("bigform");
var parts = form.getElementsByTagName("DIV");
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
// give your form parts the ID "formpart_1" through "formpart_3"
if (part.id.match(/^formpart_\d+$/)) {
// you must implement what to do if selector.value is 0
var isDisabled = (part.id != "formpart_" + selector.value);
disableFormFields(part, isDisabled);
}
}
}
When the user selects option "Two" in the selector form, all form elements in DIVs 1 and 3 would be disabled. So when user submits "bigform", only the values inside div 2 would be submitted.
No. the form will always be submitted as a whole, regardless of what elements were disabled in UI.
If you want to submit only one set of form items, create a separate form for each set.
Its not possible to prevent some input elements from submittng, and it might be safer/easier to do the selective saving on the server side, as it would stop erroneous results being saved if JS broke/was compromised.
You could disable the elements not being submitted and maybe change their name attributes to ensure the values weren't used by the server.
You could also assign a name/value to a submit button, and parse this on the server-side. It would be trivial to use Javascript to set a value n the submit button to tell the server side to only the the required buttons.
So you have N sections with id's 1..N, and you want only section i to be active?
If you put it in that wording, I would code it somewhat like this - mind: my jQuery is not that strong, I'm merely pseudo-jQuerying:
function enable( element, sensitive ) {
//recursively disable this node and it's children
element.disabled = !sensitive;
if( element.childNodes ) {
for( var i = 0; i != element.childNodes.length; ++i ) {
enable( element.childNodes[i], sensitive );
}
}
}
// this function should rely on the structure of your document
// it ought to visit all sections that need to be enabled/disabled
function enableSection( i ) {
$("#bigform > div").each( function( index, element ) {
enable( element, index==i );
});
}
$("#sectionselector").change( function( ) {
// find value of active section
var activesection = $("#sectionselector").value; // or the like
enableSection( activesection );
} );
Related
I'm trying to select a drop-down value using js. In my case, I need to select "DRAW PORTRAIT" drop-down option after the plugin loads.
I tried two methods but I'm not getting anywhere. This is a part of the frontend found in Bookly WordPress plugin. I added an id id="category" to the dropdown so that I can select a value.
HTML:
<div class="bookly-js-chain-item bookly-table bookly-box" style="display: table;">
<div class="bookly-form-group">
<label>Service Type</label>
<div>
<select id="categorydraw" class="bookly-select-mobile bookly-js-select-category">
<option value="">Select category</option>
<option value="6">DRAW PORTRAIT</option>
<option value="7">DRAW DUMMY FIGURE</option>
<option value="8">DESIGN WAX SCULPTURE</option></select>
</div>
</div>
</div>
Method 01
document.getElementById("categorydraw").value = "DRAW PORTRAIT";
Method 02
var objSelect = document.getElementById("categorydraw");
setSelectedValue(objSelect, "DRAW PORTRAIT");
function setSelectedValue(selectObj, valueToSet) {
for (var i = 0; i < selectObj.options.length; i++) {
if (selectObj.options[i].text== valueToSet) {
selectObj.options[i].selected = true;
return;
}
}
}
Please see the full code where the js doesn't work: https://jsfiddle.net/3z5hcv62/
I would really appreciate if someone can correct my cranky code. Thanks in advance!
One line of jQuery will allow you to select the item necessary:
$('#categorydraw option[value="7"').prop("selected", true);
https://jsfiddle.net/fLc1p5mq/
Edit: In order to activate on a WordPress page load, use:
jQuery( document ).ready(function() {
jQuery('#categorydraw option[value="7"').prop("selected", true);
});
First, i want to make sure. Do you want to select the value of the dropdown or set the value to the dropdown?. Maybe this will help your problem.
HTML
<!-- I set the "categories" id to the dropdown -->
<select class="bookly-select-mobile bookly-js-select-category" id="categories">
<option value="">Select category</option>
<option value="1">Cosmetic Dentistry</option>
<option value="2">Invisalign</option>
<option value="3">Orthodontics</option>
<option value="4">Dentures</option>
</select>
<p>
Selected value: <strong id="selected"></strong>
</p>
JavaScript
var dropdown = document.getElementById('categories');
var datas = [];
var select = 3;
/* Get value with text from dropdown */
for(var i=0;i<dropdown.options.length;i++) {
datas.push({
id: dropdown.options[i].value,
text: dropdown.options[i].text,
});
}
/* For set the value */
dropdown.value = select; // after page loaded,, default value will selected is "Orthodontics"
/* For select current value with the text */
var dataSelected = datas[select];
document.getElementById('selected').innerHTML = "ID: "+dataSelected.id+", TEXT: "+dataSelected.text;
The result will show like this https://jsfiddle.net/65jnzLko/1/
You can improve that code. Like selecting datas by id of the dropdown value.
Or if you just want to set the value for your dropdown, you can do this
// using pure js
document.getElementById('yourdropdown').value = 3 // or other values
// using jquery
$("#yourdropdown").val(5) // 5 can replace with other values
We are using a html quiz application that does not contain a total field for dropdowns/select elements. I would like to insert a html div total that captures ALL select elements with values while using click to capture changes. I've found pieces of my solution while searching but can't seem to put them all together. I don't have the ability to insert the eventlistener into the html directly.
What I have so far. Feel like im close but receiving x[i] not defined.
var x = document.getElementsByTagName("select");
var i = 1;
sum = 0;
for (i; i < x.length; i++) {
x[i].addEventListener("click", function(){
sum += Number(x[i].value);
});
}
All dropdowns are in the same repeated class:
<select class="qm_SELECT_sel"><option value=""></option>
you getting x[i] as undefined because click even is bind with all of the select element but while firing click event in i it always passes the last valid of i
for example : if you have 3 dropdowns then it will click event with 3 of them but while clicking any dropdown it always passes 3.
to ignore this u had to kept that event bind to saperate function and pass element as a parameter to that function in this way value of each i is maintained
var x = document.getElementsByTagName("select");
var i = 1;
sum = 0;
for (i; i < x.length; i++) {
bindSelectClick(x[i]);
}
function bindSelectClick(elem){
elem.addEventListener("click", function(){
sum += Number(elem.value);
});
}
As per Your comment the finale answer is
$('.qm_SELECT_sel').change(function(){
var sum=0;
$('.qm_SELECT_sel option:selected').each(function(){
sum =Number(sum)+Number($(this).val());
});
$('#total_filed').val(sum);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="1as" class="qm_SELECT_sel">
<option value="" >select 1 </option>
<option value="1" >1 </option>
<option value="2" >2</option>
</select>
<select name="2asa" class="qm_SELECT_sel" >
<option value="" >select 2 </option>
<option value="1" >1 </option>
<option value="2" >2</option>
</select>
<input name="input_field" id="total_filed" >
The reason I would like to do this, is that it will be situational. If a user is logged in, they will see drop downs. If not, they will see a list of text. Ideally just plain text, but I don't know if that's possible, so I was thinking I could convert the <select> to checkboxes and hide the check boxes with CSS.
Basically we don't want a user who isn't logged in to feel they can select anything, because they won't be able to order and this could lead to frustration. But we would still like them to view what options are available for each product as unselectable text. If there is a better way to do this than what I'm thinking, I'd be grateful for suggestions. For now, this is what I've patched together, but it's not changing the select to checkboxes.
I grabbed some code from here to use as a starting point: http://www.w3schools.com/jsref/met_element_setattribute.asp
Also, I can't grab the < select > by id, because this will be on all < select >'s.
<select id="unique_id" class="unique_class" data-attribute_name="unique_attribute_name" name="unique_name">
<option value="" selected="selected">Choose an option</option>
<option class="attached enabled" value="516">5/16"</option>
<option class="attached enabled" value="38">3/8"</option>
</select>
Javascript:
function myFunction() {
document.getElementsByTagName("SELECT")[0].setAttribute("type", "checkbox");
}
Here is a fiddle: https://jsfiddle.net/d4qdekom/
This should convert your select to checkboxes, provided there is an HTML element with an id of "container" to append the new checkboxes.
This is the HTML
<select id="unique_id" class="unique_class" data-attribute_name="unique_attribute_name" name="unique_name">
<option value="" selected="selected">Choose an option</option>
<option class="attached enabled" value="516">5/16"</option>
<option class="attached enabled" value="38">3/8"</option>
</select>
<div id="container"></div>
The JavaScript function to transform the select to checkboxes below
function myFunction() {
var select = document.getElementById('unique_id');
var container = document.getElementById('container');
var i;
for (i = 0; i < select.length; i++) {
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.name = 'option';
checkbox.id = 'randomId' + i;
checkbox.value = select.options[i].text;
var label = document.createElement('label')
label.htmlFor = 'randomId' + i;
label.appendChild(document.createTextNode(select.options[i].text));
container.appendChild(checkbox);
container.appendChild(label);
}
}
You can then go ahead and remove the select from the DOM. I guess all these should be made easier with JQuery
This is an update using getElementsByTagName:
var selects = x.getElementsByTagName('SELECT'); // this is a node list
for (var i = 0; i < y.length; i++) {
var select = selects[i]; // this is a single select element
// You can call the above function on each select here...
}
This is a working jsFiddle
I hope this helps.
If I am understanding your goal correctly, you can just put div's in and hide/show or enable/disable the div's depending on if the user is logged in or not. So wrap your select up in a div and just toggle that.
This would avoid trying to change the html by simply showing/hiding or enabling/disabling what you want the user to see.
Good afternoon!
I am building a contact form in Contact Form 7 in Wordpress. And I need a functionality where one of the form fields is a number selector (for example, 1-10) and I need the number that is selected to be calculated and drop down the number of fields to be inputted.
I'll try to explain the best I can. So if someone types in the 4...I need a drop down of four input fields.
I have looked for some jquery script for this functionality, but I'm basically at a deadend. If anyone has any suggestions, I would much appreciate it!
Here's an option using jQuery (jsFiddle)
HTML
Number of inputs:
<select class="numInputs" onChange="buildInputs(this);">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<div class="inputs"></div>
Javascript (jQuery)
$(document).ready(function () {
// set onchange event for the select box.
$('.numInputs').change(function () {
// clear any inputs added to the div.
$('.inputs').empty();
// get number of inputs to add from select box.
var num = $('.numInputs option:selected').text();
// build the inputs.
for (var i = 1; i <= num; i++) {
$('<input type="text"/><br/>').appendTo('.inputs');
}
})
});
You would use javascript, I wrote a simple sample for you. I haven't ever worked with wordpress, but this just works on it's own, and I would think you should be able to just put it in.
Javascript
<script type="text/javascript">
function thing(){
var num = document.getElementById("number").value; //Get the number out of the number field
document.getElementById("select").innerHTML = ''; //Get rid of the placeholder, or the old ones
for (var i = 0; i < num; i++){
var newOpt = document.createElement('option');
newOpt.innerHTML = i; //It'll just have a dropdown for 0 to the number
newOpt.value = i;
document.getElementById("select").appendChild(newOpt);
}
}
</script>
HTML
<form>
Number: <input type="number" name="number" id="number" onblur="thing();">
<select id="select">
<option value="no">Enter a number first</option>
</select>
<input type="submit" value="Submit">
</form>
Also, instead of using onblur, you could use onkeyup or something. onblur is for when it loses focus.
So I've got an input field that I'm trying to populate using two separate drop-down menus. I've got it working with a single drop-down currently, but I'm unable to do two. Here's an example of what I'm trying to accomplish:
<select type="text" id="make">
<option value="">- select one -</option>
<option value="chevy">Chevy</option>
</select>
<select type="text" id="model">
<option value="">- select one -</option>
<option value="silverado">Silverado</option>
</select>
<input type="text" id="input" value="" />
So the value of the text input should be 'Chevy Silverado' if both fields are selected. Here's the script that I've got so far:
$(function(){
$('select#make').bind('change', function(){
$('input#input').val($(this).val());
});
});
Which works great for one drop down, but obviously does nothing for the other. Any ideas? I've tried a few solutions that I'd found with absolutely no success. Thanks for looking!
Big thanks to those of you who answered my question! With your guidance I was able to get the below code working for me perfectly. Note that I DID add an additional class to my select boxes
$(function(){
var $makemodel = $('.makemodel');
$('.makemodel').on('change',function(){
$('#input').val($makemodel.eq(0).val()+' '+$makemodel.eq(1).val());
});
});
No problem! Please forgive the length of this answer, it offers multiple options depending on whether you place greater importance on code readability vs efficiency. It will only make marginal differences in speed but hopefully it shall inspire you to think of speed in your overall code!
Easy solution:
$('#make,#model').on('change',function(){
$('#input').val($('#make').val()+' '+$('#model').val());
});
More efficient:
Give your selects a class:
<select type="text" id="make" class="MakeModel">
<option value="">- select one -</option>
<option value="chevy">Chevy</option>
</select>
<select type="text" id="model" class="MakeModel">
<option value="">- select one -</option>
<option value="silverado">Silverado</option>
</select>
<input type="text" id="input" value="" />
And then select on the class:
$('.MakeModel').on('change',function(){
$('#input').val($('#make').val()+' '+$('#model').val());
});
Giving it a class just makes it slightly easier for the parser to query only one selector rather than two.
Most efficient:
Use the appropriate .eq() values and caching instead of querying the ID selectors again:
var $makemodel = $('.MakeModel');
$makemodel.on('change',function(){
$('#input').val($makemodel.eq(0).val()+' '+$makemodel.eq(1).val());
});
This means the select items do not need to be requeried since all the objects of .MakeModel are contained within the function under the cached $makemodel and you can just specify the object order number to reference a specific one.
jsFiddle to show what I mean here
Additional notes:
Notice the use of .on rather than .bind, which is the more correct syntax for modern jQuery applications.
Also, using tagnames before ID or class will actually make your selectors less efficient, as the parser needs to verify the ID/class is associated with the tag, rather than just grabbing the ID (which should be unique anyway) or class name (which should be appropriately isolated in its naming).
Simple solution:
$(function() {
$('#make, #model').on('change', function() {
var makeCurr = $('#make').find(":selected");
var madelCurr = $('#model').find(":selected");
var make = (makeCurr.val() != '') ? makeCurr.text() : '';
var model = (madelCurr.val() != '') ? madelCurr.text() : '';
$('input#input').val(make + ' ' + model);
});
});
View Example
I'd suggest amending the HTML somewhat, to group the select elements within a single parent, and binding, using on(), the change event to that element:
<form action="#" method="post">
<fieldset>
<select type="text" id="make">
<option value="">- select one -</option>
<option value="chevy">Chevy</option>
</select>
<select type="text" id="model">
<option value="">- select one -</option>
<option value="silverado">Silverado</option>
</select>
<input type="text" id="input" value="" />
</fieldset>
</form>
With the jQuery:
$('fieldset').on('change', function(){
var self = $(this);
$('#input').val(function(){
return self.find('select').map(function(){ return this.value; }).get().join(' ');
});
});
JS Fiddle demo.
Modifying further, to use a class to identify the summary element (the text-input into which the value will be inserted) reduces the reliance on known elements, and allows for more general-purpose code:
$('fieldset').on('change', function(){
var self = $(this);
self.find('.summary').val(function(){
return self.find('select').map(function(){ return this.value; }).get().join(' ');
});
});
JS Fiddle demo.
And a non-jQuery, plain-JavaScript approach to the same solution (albeit only works in those browsers that support document.querySelector()/document.querySelectorAll() and addEventListener()):
function summarise(container, what, sumClass) {
var els = container.querySelectorAll(what),
sumTo = container.querySelector(sumClass),
vals = [];
for (var i = 0, len = els.length; i < len; i++) {
vals.push(els[i].value);
}
sumTo.value = vals.join(' ').trim();
}
var fieldsets = document.querySelectorAll('fieldset');
for (var i = 0, len = fieldsets.length; i < len; i++) {
fieldsets[i].addEventListener('change', function(){
summarise(this, 'select', '.summary');
}, false);
}
JS Fiddle demo.