I'm trying get a form to fill in inputs automatically when a user puts in information in the footage field which should then be plugged into an equation with JQuery and then the answer should be output in postQuantity. Since the user can add inputs the form is set up that each footage should go with a corresponding postQuantity signified by its suffix number. So that footage2 should be used to find postQuantity2 and 3 for 3 and so on. The problem is that only the first field is automatically filling in and that anytime a different footage class is changed nothing happens. Any insight on where I went wrong and advice on how to fix it will be greatly appreciated! Thanks! Here is a JSFiddle - http://jsfiddle.net/gv0029/TwH5n/
HTML:
<form>
<fieldset id="fence">
<div class="inputFence">
<fieldset class="fenceDescripton">
<legend><strong>Fence Description</strong></legend>
<label>Footage<input name="footage_1" class="footage" /></label>
<select name="fenceHeight_1" class="fenceHeight">
<!--got rid of "select" from the value. not needed at all-->
<option value="">Select Fence Height</option>
<!--got rid of the ids completely. the numbers from the values are all you need-->
<option value="6">6 Ft.</option>
<option value="8">8 Ft.</option>
</select>
</fieldset>
<fieldset class="post">
<legend><strong>Post Type</strong>
</legend>
<label>Post Quantity:
<input type="postQuantity" name="postQuantity_1" class="postQuantity" value="" />
</label>
<select name="postMeasurements_1" class="postMeasurements">
<option value="">Select Post Measurements</option>
<option value="23/8 x .065 x 8">2 3/8 x .065 x 8</option>
<option value="23/8 x .095 x 8">23/8 x .095 x 8</option>
</select>
</fieldset>
</div>
</fieldset>
<div>
<input type="button" id="btnAddFence" value="Add Another Fence" />
<input type="button" id="btnDelFence" value="Remove Fence" />
</div>
</form>
JS:
//Quantity for Posts
$("[class^='footage']").bind('keypress keydown keyup change', function(){
var footage = parseFloat($(this).val(),10);
var total = '';
var parts = $(this).attr('name').split("_");
var fenceNumber = parts[1];
if(!isNaN(footage)){
total = Math.ceil(footage /7);
$(":input[name='postQuantity_" + fenceNumber + "'" + ']').val(total.toString());
} else {
$(":input[name='postQuantity_" + fenceNumber + "'" + ']').val("");
}
});
//Dynamic Fence Input Fields
$('#btnAddFence').click(function () {
// create the new element via clone()
var newElem = $('.inputFence:last').clone();
// insert the new element after the last "duplicable" input field
$('.inputFence:last').after(newElem);
// enable the "remove" button
$('#btnDelFence').removeAttr('disabled');
//get the input name and split into array (assuming your clone is always last)
var parts = $('.fenceHeight:last').attr('name').split("_");
//change the second element of the array to be one higher
parts[1]++;
//join back into a string and apply to the new element
$('.fenceHeight:last').attr('name', parts.join("_"));
//do the same for other two inputs
parts = $('.postQuantity:last').attr('name').split("_");
parts[1]++;
$('.postQuantity:last').attr('name', parts.join("_"));
parts = $('.postMeasurements:last').attr('name').split("_");
parts[1]++;
$('.postMeasurements:last').attr('name', parts.join("_"));
parts = $('.footage:last').attr('name').split("_");
parts[1]++;
$('.footage:last').attr('name', parts.join("_"));
// business rule: you can only add 5 names
//if (newNum == 5)
//$('#btnAdd').attr('disabled','disabled');
});
$('#btnDelFence').click(function () {
//remove the last inputFence
$('.inputFence:last').remove();
// if only one element remains, disable the "remove" button
if ($('.inputFence').length == 1) $('#btnDelFence').attr('disabled', 'disabled');
});
$('#btnDelFence').attr('disabled', 'disabled');
I think you want somethign like this:
http://jsfiddle.net/TwH5n/3/
the line I changed was:
$(document.body).on('keydown', '[class^="footage"]'
this binds the event to all future '[class^="footage"]' elements
ideally you would not do this on body since its not efficient. find a closer parent, or attach the event to each clone upon creation.
The jsfiddle is wrong
Anyway, you are using .bind method which is bind event handlers to currently existing elements. You can use .live method which is working for selector instead of elements, but this is deprecated in version 1.7, and removed in 1.9
As of http://api.jquery.com/bind/
For more flexible event binding, see the discussion of event
delegation in .on() or .delegate().
Hope this helps
P.S. Right example without using deprecated methods
$('form').on('keypress keydown keyup change',"[class^='footage']", function(){});
http://jsfiddle.net/TwH5n/7/
Related
Goal: Have a select whose option have nested structure when user clicks on the select, but when user selects an option the option should be displayed "normally" (ie with no leading spaces).
Attempted solution using JS and Jquery: My JS is far from sophisticated so I apologize in advance :)
I attempted to use .on("change") and .on("click") to change the selected option value (by calling .trim() since I achieve the "nested" structure with ). I'm also storing the original value of the selected option because I want to revert the select menu to its original structure in case the user selects another option.
The problem: The function registered for .on("click") is called twice, thus the select value immediately resets itself to its original value.
I suspect there is a much, much easier solution using CSS. I will be happy to accept an answer that will suggest such solution.
JSFiddle: https://jsfiddle.net/dv6kky43/9/
<form>
<select id="select">
<option value=""></option>
<option value="a"> a</option>
<option value="b"> b</option>
</select>
</form>
<textarea id="output"/>
var orig;
var output = $("#output");
output.val("");
function onDeviceSelection(event){
output.val(output.val() + "\nonDeviceSelection");
var select = event.target;
orig = select.selectedOptions[0].text;
select.selectedOptions[0].text = select.selectedOptions[0].text.trim()
}
function resetDeviceSelectionText(event) {
output.val(output.val() + "\nresetDeviceSelectionText");
var select = event.target;
if (orig !== undefined){
select.selectedOptions[0].text = orig;
}
}
$("#select").on("change", onDeviceSelection);
$("#select").on("click", resetDeviceSelectionText);
If you are already using jQuery, why not utilize data function to store the original value. This way you will also be able to specify different nest levels.
(function($){
$(document).on('change', 'select', function(event) {
$(this).find('option').each(function(index, element){
var $option = $(element);
// Storing original value in html5 friendly custom attribute.
if(!$option.data('originalValue')) {
$option.data('originalValue', $option.text());
}
if($option.is(':selected')) {
$option.html($option.data('originalValue').trim());
} else {
$option.html($option.data('originalValue'));
}
})
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<select id="select">
<option value=""></option>
<option value="a"> a</option>
<option value="b"> b</option>
</select>
</form>
Once caveat I see is, the selected option will appear trimmed on the list as well, if dropdown is opened after a previous selection has been made:
Will it still work for you?
Instead of keeping the state of the selected element i would simply go over all options and add the space if that option is not selected:
function onDeviceSelection(event){
// Update textarea
output.val(output.val() + "\nonDeviceSelection");
// Higlight the selected
const {options, selectedIndex} = event.target;
for(let i = 0; i < options.length; i++)
options[i].innerHTML = (i === selectedIndex ? "":" ") + options[i].text.trim();
}
$("#select").on("change", onDeviceSelection);
Note that you need to use innerHTML to set the whitespace...
I have array of select dom and input textbox . On blur event of input(of perticular index) want to set the element in select dom value of same index.
My bind is working but after each blur event for different input box it is retiurning 0.
I am not able to set the select value i.e. (drop down)as per given index
JSFiddle
My code is following.
$(document).ready(function (){
var i =1;
$('#addme').on('click', function(){
var test = '<tr class="employee"><td><input type="text" id="emp_id['+i+']" /></td><td><select id="emp_name['+i+']" '
test += '<option value="-1" >Please Select </option><option value="e0001" >James Smith</option><option value="e0002" >Roger Sm</option>'
test +='<option value="e0003" >Elina Lobo</option></select></td></tr>'
$('#addme').after(test);
i++;
});
$(".employee input").live('blur',function(){
var inputIndex = $(this).index();
var inputValue = $(this).val();
alert("Input Index is :" + inputIndex + ' and value is ' + inputValue);
$('#emp_name[inputIndex]').each(function(){
if(this.value == inputValue){
$('#emp_name[inputIndex]').val($(this).val());
return false;
}
alert("Please iput valid value");
$('#emp_name[inputIndex]').val('-1');
});
});
});
</script>
<table />
<tr class="employee">
<td><input class="employee" type="text" id="emp_id[0]" /></td>
<td><select id="emp_name[0]" name="emp_name">
<option value="-1" >Please Select </option>
<option value="e0001" >James Smith</option>
<option value="e0002" >Roger Sm</option>
<option value="e0003" >Elina Lobo</option>
</select></td>
</tr>
<input type="button" id="addme" value="ADD ME"/>
</body>
</html>
You would need to delegate the events as you are adding the elements dynamically on the click of the button..
So $(".employee input").live('blur',function(){
should look something like this
$(staticContainer).on('blur',".employee input", function(){
staticContainer is the element that is already in the DOM when the elements are bound with the element.
Closer the container better the performance.
Also you have multiple issues with your code..
It is a better idea to append the rows to the table, so that the selector returns the right element inside the table.
$('#addme').after(test);
Supposed to be
$('table').append(test);
Next this selector does not replace the index value
$('#emp_name[inputIndex]')
supposed to be
$('#emp_name[' + inputIndex + ']')
Lastly the way you are accessing the indexes is completely wrong.
You are trying to get the current input with respective to the other elements . So
var inputIndex = $(this).index();
supposed to look like
var inputIndex = $('input').index(this); // which will give the right value.
Check Fiddle
First,jQuery .Index() means find the index of e's all siblings,not the index of the selector field,if you want to do so,you need a selector parameter.
So
var inputIndex = $(this).index();
should change to
var inputIndex = $(this).index(".employee input");
then your index part will work fine.
Second,I actually don't understand your blur event code part.You said you want to set the same index of select dom,why you compare the value?And you use the jQuery attribute selector and I didn't see any match element.I guess you try to select all select doms,and you try to alert on loop?I don't think it's a good idea.
I think you should rebuild this part,it has no logic and very hard to read now.
i have checked this link Set radio button 'checked' in jquery based on ID However, seems not very suitable for me. This is my code
<label for="basic" class="basic">Gender:</label>
<fieldset data-type="horizontal" data-role="controlgroup" data-mini="true">
<input type="radio" name="gender" id="radio-mini-1" value="Male" checked="checked" />
<label for="radio-mini-1">Male</label>
<input type="radio" name="gender" id="radio-mini-3" value="Female" />
<label for="radio-mini-3">Female</label>
</fieldset>
and
<label for="select-choice-min" class="select">Living Place:</label>
<select name="select-choice-min" id="livingPlace" data-mini="true">
<optgroup label="AAA">
<option value="123">123</option>
<option value="456">456</option>
</optgroup>
<optgroup label="BBB">
<option value="789">789</option>
<option value="246">246</option>
</optgroup>
</select>
May I ask how to set the default value? Thanks.
My json return is something like this:
[{"data":{"id":"8","livingPlace":"789","gender":"Female"}}]
UPDATED
For the living Place, I found that when I use $("#livingPlace").val(data[0].data.livingPlace); it can actually get the value in the selector, when I click the selector, it can show me the correct value, however, when the page is loaded, without clicking the selector, it just show the first value in the selector, i.e 123 in the example above
$.getJSON('http://mydomain.com/getmyDetail.php?user_name='+localUsername+'&role='+localRole+'&jsoncallback=?', function(data) { // the javascripts are located here
$('#livingPlace').val(data[0].data.livingPlace).find('[value="' + data[0].data.livingPlace + '"]').attr('selected', 'selected');}
I did in this way, is there any problem?
Setting select is just like input with jQuery:
$('#livingPlace').val(789); // select menu is easy
Your radio buttons are a little more verbose:
$('input[name="gender"][value="Female"]').attr('checked', 'checked');
Let me explain that long selector.
input - looks for an <input> tag
[name="gender"] - looks for tags with an attribute "name" set to "gender"- this grabs both radio buttons.
[value="Female"] - This is where we narrow down to the radio button with a value of Female.
After selecting the 'female' radio button, we set the "checked" attribute to "checked". We could also set it to true. Um, the browser automatically unchecks the other radio buttons.
Put with your data, here is one solution:
http://jsfiddle.net/hRqZP/1/
var json = '[{"data":{"id":"8","livingPlace":"789","gender":"Female"}}]';
var data = JSON.parse(json)[0].data; // get 'data' out of json.
$('#livingPlace').val(data.livingPlace); // select menu is easy
$('input[name="gender"][value="' +
data.gender +
'"]'
).attr('checked', 'checked');
Edit: I don't know what browser you are using, but I noticed that val() didn't set "selected=selected" on the option. In Chrome it displayed the correct value, though.
Anyway, I updated it so that it sets selected=selected, too:
http://jsfiddle.net/hRqZP/2/
var json = '[{"data":{"id":"8","livingPlace":"789","gender":"Female"}}]';
var data = JSON.parse(json)[0].data; // get 'data' out of json.
$('#livingPlace').
val(data.livingPlace).
find('[value="' + data.livingPlace + '"]').
attr('selected', 'selected');
$('input[name="gender"][value="' +
data.gender +
'"]'
).attr('checked', 'checked');
Edit: For jQuery.mobile the select menu may need to refresh:
$('#livingPlace').
val(data.livingPlace).
find('[value="' + data.livingPlace + '"]').
attr('selected', 'selected').
end().
selectmenu('refresh', true);
I don't care about the content in the form, just want to add a new set of them every time I click add. I will however be adding some conditional fields. But with that in mind, do I actually need to iterate ids? And is the clone event the best way to handle this?
<div id="wrapper">
<div id="condition-1">
<select id="trigger-1" class="trigger">
<option value="0">Select...</option>
<option value="1">View Count</option>
<option value="2">Comment Count</option>
</select>
<select id="operator-1" class="operator">
<option value="0">Select...</option>
<option value="1">Is Greater Then</option>
<option value="2">Less Than</option>
</select>
<div id="input-1" class="input">
<input id="number-1"></input>
</div>
</div>
<div id="add-1" class="add">Add more</div>
I've been digging through a lot of examples of jQuery .clone() ,have not been able to apply any examples to a structure like this. My goal is to add a new set of form elements every time I click "Add more". I don't care if it clones the actual content, just want to clone and then iterate the id's appropriately.
I tried using something similar to:
var cur_num = 1;
var cloned = $("#condition-" + cur_num).clone(true, true).get(0);
++cur_num;
cloned.id = "condition-" + cur_num; // Change the div itself.
$(cloned).find("*").each(function(index, element) { // And all inner elements.
if(element.id)
{
var matches = element.id.match(/(.+)_\d+/);
if(matches && matches.length >= 2) // Captures start at [1].
element.id = matches[1] + "-" + cur_num;
}
});
$(cloned).appendTo($("#condition-wrapper"));*/
The above block of code will clone and append the block I want. But as it iterates the first condition id to #condition-2, every block after is coming up #condition-2 and I have no idea how to change the children of condition-1 to trigger-2 operator-2. Any help is appreciated, thank you!
try this
$(function(){
$('.add').bind('click',function(){
var $this=$(this),
$cloned=$this.prev().clone(),
re=/(\d+)$/,
counter=1,
cid=$cloned.attr('id').replace(re,function(n){
return counter+=parseInt(n);
});
$cloned.attr({id:cid})
.find('[id]')
.each(function(i,o){
var iid=$(o).attr('id').replace(re,counter);
$(o).attr({id:iid});
})
.end()
.insertBefore($this);
});
})
I'm somewhat new to jQuery. I'm pretty sure this is possible, but I'm not quote certain how to code this.
What I'm looking to do is to use a dropdown with selections that represent ranges (e.g. if someone were searching for bedrooms, the dropdown selctions would look like "0-2", "3-5", "6+"). Then when someone chooses a selection, two hidden fields would by dynamically filled. One field with the minimum of the range, and the other field with the maximum of the range.
Here is an example of how I'm trying to structure this:
<select id="bedrooms" class="dropdown">
<option>Bedrooms</option>
<option></option>
<option value="1">0-2</option>
<option value="2">3-5</option>
<option value="3">6+</option>
</select>
<input type="hidden" name="bedrooms-from" value=''>
<input type="hidden" name="bedrooms-to" value=''>
I suppose the values of each option could change, I wasn't sure what the best way to approach that would be.
I haven't actually run this, but I think it should work:
$("#bedrooms").change(function ()
{
// Get a local reference to the JQuery-wrapped select and hidden field elements:
var sel = $(this);
var minValInput = $("input[name='bedrooms-from']");
var maxValInput = $("input[name='bedrooms-to']");
// Blank the values of the two hidden fields if appropriate:
if (sel.val() == "") {
minValInput.val("");
maxValInput.val("");
return;
}
// Get the selected option:
var opt = sel.children("[value='" + sel.val() + "']:first");
// Get the text of the selected option and split it on anything other than 0-9:
var values = opt.attr("text").split(/[^0-9]+/);
// Set the values to bedroom-from and bedroom-to:
minValInput.val(values[0]);
maxValInput.val((values[1] != "") ? values[1] : 99999999);
});
$("select").on("change", function() {
$("form").append( /* <input type='hidden'> tag here */ );
});