In my C# MVC app, I have a series of textboxes that are generated as such...
#foreach (object item in items)
{
#Html.TextBox(....)
}
The rendered result is a series of text boxes that look like this....
<input class="item-quantities valid" data-bomid="1939" data-rid="2054" id="AddedItemIDs_1939_" name="AddedItemIDs[1939]" onchange="ChangeItemQuantity(156,78)" onkeypress="return isNumberKey(event)" type="text" value="7" aria-invalid="false">
<input class="item-quantities valid" data-bomid="1940" data-rid="1055" id="AddedItemIDs_1940_" name="AddedItemIDs[1940]" onchange="ChangeItemQuantity(159,90)" onkeypress="return isNumberKey(event)" type="text" value="1">
Now, I need a javascript / jquery function in which I can capture three values:
bomid
rid
the new value of the textbox
I am just fine capturing the value when the textbox loses focus (tab out, etc.)
I have tried this (WITHOUT onchange="ChangeItemQuantity()" in the textbox), but for some reason I can never get this event to fire. Plus, I'd rather NOT do it this way, because then I am forced to be rigid on what classes I assign to the textboxes....
$(function () {
$('.item-quantities.valid').change(function () {
var value = $(this).val();
var bomid= $(this).data('bomid');
var rid= $(this).data('rid');
});
});
And I have tried this (WITH onchange="ChangeItemQuantity(159,90)" in the textbox). I would RATHER do it this way, as it allows me to be flexible with the classes in the text box...
function ChangeItemQuantity(bomid, rid) {
// no idea how I would capture the value here.
}
Add another argument to the function to pass the element in and get it's value:
onchange="ChangeItemQuantity(156,78, this)"
function ChangeItemQuantity(bomid, rid, el) {
alert(el.value)
}
You could fetch the attribute's value like this,
function getValues(){
var actual=$(this).value;
var bomid=$(this).attr('bomid');
var rid=$(this).attr('rid');
}
Related
I have written this code which detects if there is a value populated in productName field using javascript and then it parses and auto-populate the input field quantity. My code only works if productName field is populated through javascript code and fails to register keyboard inputs if I use onChange
I want to detect in both scenarios i.e javascript and keyboard, how do I detect using the keyboard in this code?
const input = document.getElementById('productName');
const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(input), 'value');
Object.defineProperty(input, 'value', {
set: function(t) {
console.log('Input value was changed programmatically');
descriptor.set.apply(this, arguments);
document.getElementById("quantity").value=t
},
get: function() {
return descriptor.get.apply(this);
}
});
var i=0;
function changeInput(){
/* console.log(document.getElementById('productName').value) */
document.getElementById("productName").value=i++;
}
<input type="text" id="productName" name="productName" placeholder="product name">
<input type="text" id="quantity" name="quantity" placeholder="quantity">
<button onclick="changeInput()">Change</button>
Since I am a beginner in Javascript, a comment by #epascarello helped me, and this was quite easy with binding the input element:
document.getElementById("productName").addEventListener("input",(event)=>{
document.getElementById("quantity").value= document.getElementById("productName").value;
})
html:
<label>Label1</label><br>
<input type="text" name="first" onclick="somefunc()"><br>
<label>Label2</label><br>
<input type="text" name="second"><br>
Javascript:
function somefunc() {
var second = document.getElementsByName('second')[0];
second.disable = true;
}
When I click the first input the second is disabled (that was what I want), but when I type something into the first input field, then delete it, the second is still disabled. Is there a way so I can enable it again?
I couldn't find an other event which can solve this.
You can listen to the keyup event on the first input box and check the value of first input box for enabling or disabling second input.
<label>Label1</label><br>
<input type="text" name="first" onkeyup="somefunc()"><br>
<label>Label2</label><br>
<input type="text" name="second"><br>
<script>
function somefunc() {
var first = document.getElementsByName('first')[0];
var second = document.getElementsByName('second')[0];
if(first.value){
second.disabled = true;
}else{
second.disabled = false;
}
}
</script>
Seems you have missed enabling textbox here. If you can see in previous reply, you just need to re-enable textbox into same state as it was before.
I'm using jquery autocomplete.In my case I have multiple autocomplete textbox and hidden field on my page.
e.g
<input class='myclass' type='text'> </input>
<input class='.emp_num_hidden' type='hidden'> </input>
<input class='myclass' type='text'> </input>
<input class='.emp_num_hidden' type='hidden'> </input>
and so on...
so when I fire change event on hidden field then it is raised multiple time
below is my code:
$(".myclass").each(function() {
var $empName= $(this);
var $empNumber = $empName.next('input:hidden');
//things to do
//Setting variable e.g url...
$empName.autocomplete(url,{
//code...
}).result(function(event,data,formatted)
{
$empNumber.val(formatted).change();
});
});
In above code $empNumber holds the hidden field which is used to store autocomplete value i.e in this case when
we select any text from autocomplete then that selected employees number will get store in hidden field.
Based on this hidden field value I want to do ajax call which will return full details of the employee based on his
employee number.
So I have written hanldler to change event of the hidden field as below.
$(.emp_num_hidden).on('change',function (
)};
here 'emp_num_hidden' is the class of the hidden field.
Please suggest how can I prevent multiple event on hidden field change.
This is done using the $(this) object. Since the change event has a target, it will only be effecting one element. The callback function is being executed on this element, this. For example:
$(".emp_num_hidden").on('change', function (e){
alert($(this).val());
});
What will happen is that an alert window will be shown when the hidden field is changed, containing the employee number from only that hidden field. You will also notices there are a few fixes to your code.
Personally, I would make use of both id and class attributes on your objects. This gives you wide scope and narrow scope to your selectors.
Example:
HTML
<input class='myclass' type='text' id='entry-txt-1' />
<input class='emp_num_hidden' type='hidden' id='hide-txt-1' />
<input class='myclass' type='text' id='entry-txt-2' />
<input class='emp_num_hidden' type='hidden' id='hide-txt-2' />
jQuery
$(function(){
var $empName, $empNumber;
$(".myclass").each(function(key, el) {
$empName= $(el);
$empNumber = $empName.next("input[type='hidden']");
// things to do
// Setting variable e.g url...
$empName.autocomplete(url, {
//code...
}).result(function(e, d, f){
$empNumber.val(f).change();
});
});
$(".emp_num_hidden").on('change', function(e){
var empId = $(this).attr("id");
var $employeeNumberField = $("#" + empId);
// Do the needful...
});
});
Taking this a bit further, you may want to consider making use of data attributes. You may also want to look at select event for Autocomplete. Something like:
$(function(){
$(".myclass").autocomplete({
source: url,
select: function(e, ui){
$(this).val(ui.item.label);
$(this).data("emp-number", ui.item.value);
$.post("employeedata.php", { n: ui.item.value }, function(data){
$("#empData").html(data);
});
return false;
}
});
});
This assumes that url returns an array objects with label and value properties. This would add the Employee Number as a data-emp-number attribute to the field that the user was making a selection from. The label being their Employee Name, and the value being their Employee Number. You could also use this callback to show all the other employee data based on Employee Number.
A working example: https://jsfiddle.net/Twisty/zmevd0r0/
Here is the working demo of what I want to achieve. Just enter some value in input and you might get what I want to achieve. (Yes, I got it working but stay on..)
But it fails when multiple keys are pressed together.
What I am trying :
I have screen which contains few enabled and few disabled input elements. Whenever user updates any value in editable input element, I want to update disabled input which had same value with user updated value.
HTML :
<input value="foo" /> // When User updates this
<br/>
<input value="bar">
<br/>
<input value="Hello">
<br/>
<input value="World">
<br/>
<input value="foo" disabled> // this should be updated
<br/>
<input value="bar" disabled>
<br/>
<input value="foo" disabled> // and this also
<br/>
<input value="bar" disabled>
<br/>
<input value="Happy Ending!">
<br/>
I tried this which I think will save me from multiple_clicks_at_a_time
JS:
$(":input:not(:disabled)").keyup(function () {
// Get user entered value
var val = this.value;
// Find associated inputs which should be updated with new value
siblings = $(this).data("siblings");
$(siblings).each(function () {
// Update each input with new value
this.value = val;
});
});
$(function () {
$(":input:not(:disabled)").each(function () {
// Find inputs which should be updated with this change in this input
siblings = $(":input:disabled[value=" + this.value + "]");
// add them to data attribute
$(this).data("siblings", siblings);
});
});
But I am not able to pass the selectors to keyup function and invoke .each on it.
PS:
My previous completely different try, working with single_click_at_a_time but I felt that I am unnecessarily traversing the DOM again and again so dropped this
$(":input").keypress(function () {
$(this).data("oldVal", this.value);
});
$(":input").keyup(function () {
var oldVal = $(this).data("oldVal");
$(this).data("newVal", this.value);
var newVal = $(this).data("newVal");
$("input:disabled").each(function () {
if (this.value == oldVal) this.value = newVal;
});
});
I would group those inputs first and bind a handler for enabled elements to apply to the group. See below,
var grpInp = {};
$(":input").each(function () {
if (grpInp.hasOwnProperty(this.value)) {
grpInp[this.value] = grpInp[this.value].add($(this));
} else {
grpInp[this.value] = $(this);
}
});
$.each(grpInp, function (i, el) {
el.filter(':enabled').keyup(function () {
el.val(this.value);
});
});
DEMO: http://jsfiddle.net/fjtFA/9/
The above approach basically groups input element with same value, then filters them based on :enabled and bind a handler to apply it to the group.
// Find associated inputs which should be updated with new value
siblings = $(this).data("siblings", siblings);
No. The .data method called with two arguments does not get, but set the data (and returns the current selection). Also, you should make your variables local:
var siblings = $(this).data("siblings");
Working demo
I have multiple textboxes with set character limits that together make up a code. There is value in the boxes being separated for a variety of reasons. I want to be able to paste a complete code in the first textbox and have it automatically populate all the textboxes. Is there a way to do this in javascript or a jquery library for this case?
Currently I'm using jQuery autotab on each textbox and I'd prefer to keep that functionality.
DEMO
Use the onpaste event to capture the data from the user's clipboard. Then take that data and produce an array appropriate for your inputs. Then set those values using .val()
JS
$(function(){
// get first input element
pastable = document.getElementById('pastable');
// listen for the user to paste
pastable.onpaste = function(e){
// retrieve paste data as an array split to each 3 characters (3 dots below in regex)
var inputArray = e.clipboardData.getData('text/plain').match(/.../g);
// loop over input fields
$('input').each(function(i){
// place data from paste
$(this).val(inputArray[i]);
});
};
});
HTML
<input type='text' id="pastable" maxlength="3"/>
<input type='text' maxlength="3" />
<input type='text' maxlength="3" />
You can certainly do this in JS. I don't know about a library to do it for you through. Shooting from the hip here but maybe something like this:
Example HTML
<input type='text' data-auto-pop='true' data-group='1' data-char-limit='3'/>
<input type='text' data-auto-pop='true' data-group='1' data-char-limit='3'/>
<input type='text' data-auto-pop='true' data-group='1' data-char-limit='4'/>
Example JS
$("input[data-auto-pop='true']").change(function () {
var $this = $(this), val = $this.val();
if ($this.data("char-limit") > val.length) {
return;
} else {
var setVal = function() {
$this.val(val.slice(0, $this.data("char-limit"));
val = val.slice($this.data("char-limit"));
};
setVal();
while ($this.closest("input[data-group='"+$this.data("group")+"']") && val.length > 0) {
$this = $this.closest("input[data-group='"+$this.data("group")+"']");
setVal();
}
}
}
Probably has some mistakes in it but you should get the idea.