I have an input value using debounce plugin, that passing to the event. The input dom is based on an array inside looping.
At some conditions, I need to set the value that the input box to “0” from the event action after being compared with another data. How to do that?
My template code
<div class="form-group row">
<label class="col-form-label col-lg-2">QTY</label>
<div class="col-lg-10">
<div class="input-group" style="width: 300px !important">
<input
type="text"
class="form-control"
#input="CalculateItem"
v-model="item.qty"
/>
<span class="input-group-append">
<span class="input-group-text">Carton</span>
</span>
</div>
</div>
Vue method :
CalculateItem: _.debounce(function (e) {
console.log(e.target);
var totalItem = _.sumBy(this.itemList, (item) => Number(item.qty));
if(this.lineTotal<totalItem){
this.dialogOverqty = true;
e.target.value=0;
}
else{
this.lineamount = this.lineTotal - totalItem;
}
}, 500),
Have tried :
e.target.value=0; //not working
Do not change the value of the input element in the DOM. Change the data bound as v-model
To get access to correct item in the event handler, just pass the item into the handler and use $event to pass the original event data as well (if you actually need it)
<input
type="text"
class="form-control"
#input="CalculateItem($event, item)"
v-model="item.qty"
/>
Now you can change item.qty inside CalculateItem and Vue will update the content of the <input>
Also note that when creating debounced function like that, there is only one debounced function for all instances of given component - see the docs (yes, the docs are for Vue 3 but same applies to Vue 2)
Related
I am doing this for validating multiple input fields with different data intake using a generic function to which I can pass RegExp output and display the validation message or icon.
This is my HTML code
<div class="form-group">
<label for="fname" class="form-lable">First name</label>
<input type="text" id="fname" name="fname" class="form-input" required>
<div for="fname">
<span class="validation-container success"><i class="bi bi-check2"></i></span>
<span class="validation-container error"><i class="bi bi-x"></i></span>
</div>
</div>
<div class="form-group">
<label for="lname" class="form-lable">First name</label>
<input type="text" id="lname" name="lname" class="form-input" required>
<div for="lname">
<span class="validation-container success"><i class="bi bi-check2"></i></span>
<span class="validation-container error"><i class="bi bi-x"></i></span>
</div>
</div>
This is what I am doing
$('#fname').on('keyup', function () {
$('.validation-container').hide();
});
$('#lname').on('keyup', function () {
$('.validation-container').hide();
});
What it does:
It's doing that thing for both of the inputs.
$('#fname').on('keyup', function () {
$(this).parent().find('.validation-container').hide();
let check = fnameRegExp.test($(this).val());
let success = ".validation-container.success";
let wrong = ".validation-container.error";
validateInput(check, success, wrong);
});
What I am doing here is sending regex match, success as well as wrong classes to the function. If the input is not matched with the regex then it will display the div having that wrong class.
function validateInput(check, success, wrong) {
if (check) {
$(success).show();
checkAll();
} else {
$(wrong).show();
}
}
And I am calling that function on keyup for each input. what it does is, it shows validation signs (✅, ❎) for every input.
change this
<div for="fname" id="fnameValidators">
<span class="validation-container success"><i class="bi bi-check2"></i></span>
<span class="validation-container error"><i class="bi bi-x"></i></span>
</div>
$('#fname').on('keyup', function () {
$('#fnameValidators').hide();
});
Similarly make changes for last name.
TL;DR
Use
$(this).parent().find('.validation-container').hide();
To hide only the element with that class within the same container.
Longer version
$('.validation-container') searches in the whole DOM. To restrict it, you can use this selector within another element. Since you're reading the keyup event on the input, you can simply use $(this) to obtain the input object. Then go over 1 level with .parent() to select the <div class="form-group"> containing it and finally use find('.validation-container') to select the correct span you want to hide.
As one-liner:
$(this).parent().find('.validation-container').hide();
Even more dynamic
If you want to make this even more dynamic, you can avoid calling a keyup event for each separate input, and create a single function that manages all your inputs correctly.
$('.form-lable').on('keyup', function () {
var type = $(this).attr('id')
// You can use the variable type to distinguish between the two inputs
$(this).parent().find('.validation-container').hide();
});
Try this
$('#fname').on('keyup', function () {
$("div[for='fname']").find('.validation-container').hide();
});
$('#lname').on('keyup', function () {
$("div[for='lname']").find('.validation-container').hide();
});
I have a form that has multiple inputs. One input is where user can input an ID. I need to verify the ID is unique. I want to call a JavaScript function for a onchange event. However, I can't get it to trigger. I have a console.log but it never hits when I make a change in the input so I am doing something wrong.
This is the function I am trying to call on the on change
function checkUniqueID() {
console.log("here");
var $counter = 0;
var tag = document.forms["userform"]["new_id"].value;
while ($counter < $totalItems) {
}
};
<div class="six wide field">
<label for="ID">ID</label>
<input type="text" id="new" name="new_id" placeholder="ID" onchange="checkUniqueID()">
</div>
I can't even get the console.log ("here") to trigger
The onchange HTML attribute triggers when the input loses focus.
So, if you correctly have your input#new_id inside a form like this:
<form name="userform">
<div class="six wide field">
<label for="ID">ID</label>
<input type="text" id="new" name="new" placeholder="ID">
</div>
</form>
Adding an eventListener in your script file would be enough.
document.userform.new_id.onchange=function(){
alert("ID changed to: "+this.value);
};
With jQuery would be as easy as:
$("#new").change(function(){
alert("ID changed to: "+$(this).value;
}
Here is a working fiddle:
https://jsfiddle.net/edbL3kgp/
I have a form where the user can input multiple addresses, city, street+nbr and country.
For this field to be repeated I use the jquery repeater library. For the city field I want to use a selectize input field.
I am trying to repeat those 4 fields when clicking on the button, it copies everything correctly but the selectize field does not contain inputs (i guess this is because they have the same id?) but I don't know how to instantiate another selectize instance on that object.
This is my code:
HTML:
<div class="row">
<div class="form-group col-12 mb-2 address-repeater">
<div data-repeater-list="stcity">
<div class="input-group mb-1" data-repeater-item>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="companystreet"><?=lang("flow_company_street")?></label>
<input type="text" id="companystreet" class="form-control" placeholder="<?=lang("flow_company_streetname")?>" name="companystreet" required data-validation-required-message="<?=lang("flow_company_street_validation")?>">
<div class="help-block font-small-3"></div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="companystreetnumber"><?=lang("flow_company_nbr")?></label>
<input type="text" id="companystreetnumber" class="form-control" placeholder="<?=lang("flow_company_streetnbr")?>" name="companystreetnumber" required data-validation-required-message="<?=lang("flow_company_nbr_validation")?>">
<div class="help-block font-small-3"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="companycity"><?=lang("flow_company_city_or_commune")?></label>
<select id="companycity" class="companycity-select" name="companycity" autocomplete="new-password" required data-validation-required-message="<?=lang("flow_company_city_or_commune_validation")?>">
<option value="" selected><?=lang("flow_company_select_city_or_commune")?></option>
<?php
foreach ($citiesbe as $city) {
//Values are prefilled from javascript
$key = strtolower($city->name_nl) . "," . $city->zip_code;
echo "<option value=\"$key\"> $city->name_nl ($city->zip_code)</option>";
}
?>
</select>
<div class="help-block font-small-3"></div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="companycountry"><?=lang("flow_company_country")?></label>
<select id="companycountry" class="companycountry-select" name="companycountry" autocomplete="new-password" disabled>
<option value="BE" selected><?=lang("flow_company_country_belgium")?></option>
</select>
</div>
</div>
</div>
</div>
</div>
<button type="button" data-repeater-create class="btn btn-primary">
<i class="ft-plus"></i> Add new address
</button>
</div>
Javascript:
// Custom Show / Hide Configurations
$('.address-repeater').repeater({
show: function () {
$(this).slideDown();
},
hide: function(remove) {
$(this).slideUp(remove);
}
});
Since the button is not the selectize element, I don't know how to assign it to the newly created element.
Funny, I ran into a similar problem, but couldn't find a solution, so I had to work it out myself. Here's an explanation to the solution I applied to get selectize and jquery.repeater to work nicely.
First, checking through the browser console, you'll find out that selectize removes all the select options except the empty option, and uses it to populate it's own dropdown which is generated via javascript. This becomes a problem for jquery.repeater because it only repeats or creates a duplicate based on the initial page load, and not after. So, what gets repeated is the only select option left in the select element, which in this case (unfortunately) is the empty select option. Here's a pen explaining this, feel free to toggle the category targeting selectize in the select element to see for yourself.
So, here are the steps I took to get it to work nicely:
On repeating of the form (show() of the repeater instance), you'll need to delete the duplicated element completely from the DOM.
Create another select element(s) in the DOM with the preferred (or same) attributes/options.
Instantiate selectize on the newly created select element(s).
I'll suggest you add a class to the .form-group wrapper housing the .companycity-select select element. This will help to append a new select element at the exact place only, since there are other .form-group in the code. Check my solution below:
// Assuming your have the select element wrapper as <div class="form-group select-wrapper">
$('.address-repeater').reapeter({
show: function() {
$(this).slideDown();
// Remove the created element
$(this).find('.companycity-select').remove();
// Repeater rewrites your name attributes to avoid collisions within the same form,
// so we need to follow this same rule
// Get the length of the currently repeated items, to be used as the index for new elements
var count = $('div[data-repeater-item]').length;
// Create the new select element. The select name is based on the new name by repeater
var new_select_option = '<option value="" selected>Select city or community</option>';
var new_select_element = '<select id="companycity" class="companycity-select" name="stcity['+count+'][companycity]" autocomplete="new-password" required>'+new_select_option+'</select>';
// Append newly created element to DOM. Remember the new class added to the form-group?
$(this).find('.form-group.select-wrapper').append(new_select_element);
// Create a new instance of selectize on the new select element
$(this).find('.companycity-select').selectize({
// Populate your select options data via ajax,
// see docs: https://selectize.dev/docs.html
valueField: '',
labelField: '',
searchField: [],
options: []
});
}
});
Here is my main div
<div id="question-con">
<label for="ques-code">Question Setter:</label>
<input type="checkbox" id="ques-code" name="ques-code"/>
<div id="question-toggle" style="display:none;">
<div id="question-div" style="background-color:#A6A6A6;width: 350px;border: 1px solid greenyellow;margin-bottom: 10px;">
<label>Credit</label>
<input type="text" name="credit" class="credit" id="credit_0">
<label>No of Setter</label>
<input type="text" name="setter">
<label>Type</label>
<input type="text" name="type" id="type">
<label for="in-ex">Internal/External</label>
<input type="text" name="in-ex" id="">
<p class="remove" style="color:red;float: right;font-weight: bold;cursor: pointer;" >Remove</p>
</div>
</div>
<button id="btn-question" style="margin-top: 20px;margin-right: 5px; display: none;">Add</button>
</div>
In each button click, below function is triggered.I cloned the main div here, but the format of the cloned div is not like the main div.
$("#btn-question").click(function (e) {
e.preventDefault();
++question_count;
var question_clone = $('#question-div').clone();
question_clone.attr('id', question_count);
//question_clone.children().attr('id', "question_" + question_count);
question_clone.children(".credit").attr('id', "credit_" + question_count);
$('#question-toggle').append(question_clone);
$("#" + question_count + " input").val("");
});
Click here to see the image
What can i do?
You need to pass true as parameters to the clone to get its formatting too:
$('#question-div').clone(true,true);
See the .clone( [withDataAndEvents ] [, deepWithDataAndEvents ] ):
withDataAndEvents
A Boolean indicating whether event handlers and data should be copied along with the elements. The default value is false.
deepWithDataAndEvents
A Boolean indicating whether event handlers and data for all children of the cloned element should be copied. By default its value matches the first argument's value (which defaults to false).
This will only copy formatting of common classes or inline-styles that are applied to the elements but not to specific rules such as if you have #someid > a declared then copying the a element somewhere else such as #otherid a then it will not work. You need to explicitly define the css rules for them.
So I'm attempting to use my handleChange method within my React class when using a bootstrap datepicker.
<div className="col-xs-4">
<div className="input-group date_calendar">
<input className="form-control date_calendar" placeholder="Select a due date..." type="date | date: 'MM/dd/yyyy'" ref="scheduled_datetime" defaultValue={this.state.scheduled_datetime} onChange={this.handleChange}/>
<span className="input-group-btn">
<label className="btn btn-link">
<i className="fa fa-calendar text-muted"></i>
</label>
</span>
</div>
</div>
Now what I want it to do is use the Bootstrap Datepicker and whenever I click a date, it fills out the input ref and then it calls my handleChange method.
But it seems, that onChange is not what I want. onChange only is used when I'm typing the value inside the input field, and not when the input field itself just changes.
Is there any way to basically call the handleChange method whenever that input field is changed?
You need to call the handleChange function within a callback event provided by the datepicker. Use your ref in componentDidMount to both initialize and respond to these events.
componentDidMount() {
$(this.refs.scheduled_datetime).datepicker()
.on('changeDate', (e) => {
// e here contains the extra attributes
this.handleChange(e);
});
}
// render() {...}