read multiple inputs with backbone.js - javascript

I'm playing around with the todos.js backbone.js demo.
In the demo, they have one input text box where they take data from in the initialize function like this:
<input id="new-todo" type="text" placeholder="Todo item...">
initialize: function () {
this.input = this.$("#new-todo");
My question is, would it be possible to take the data from 3 input textboxes instead of just one?
I could try this, but this doesn't seem to scale very well:
<input id="new-todo1" type="text" placeholder="Todo item...">
<input id="new-todo2" type="text" placeholder="Todo item...">
<input id="new-todo3" type="text" placeholder="Todo item...">
initialize: function () {
this.input = this.$("#new-todo1");
this.input =+ this.$("#new-todo2");
this.input =+ this.$("#new-todo3");
Is there a better way?
Thanks

I assume you want to take the values from multiple inputs, and put them as title in a todo item. I suggest storing references to inputs in initialize with:
initialize: function () {
this.input = this.$("#new-todo");
...
}
And the createOnEntermethod should change into this:
createOnEnter: function(e) {
//concatenate the values from all inputs
var val = "";
this.input.each(function() {
val += ($(this).val());
});
if (e.keyCode != 13) return;
if (!val) return;
Todos.create({title: val});
//reset all the input elements
this.input.each(function() {
$(this).val('');
});
}
The input elements should all have the same id - "new-todo".

I am not very experienced with Backbone.js but you could use jQuery each to loop through all of the inputs and get their value.

if you have:
<input class="todo" type="text" placeholder="Todo item...">
<input class="todo" type="text" placeholder="Todo item...">
<input class="todo" type="text" placeholder="Todo item...">
then
initialize: function () {
this.$inputs = this.$(".todos");
will cache those inputs (not get the value as you said).
then
this.$inputs.each(function() {
console.log($(this).val());
});
will print their values, or you could put their values in an array like so:
var values = this.$inputs.map(function() {
return $(this).val();
});
then you can make a string out of those values with
values.join(' ');
or you can use Underscore's reduce for extra style points:
var string = _(this.$inputs).reduce(function(memo, el) {
return memo + ' ' + $(el).html();
}, '');

Related

How get the Count of Empty Input fields?

How can I check the Number of Incomplete Input fields in Particular ID, (form1, form2).
If 2 input fields are empty, in i want a msg saying something like "Incomplete Input 2"
How is it Possible to do this in JS ?
<div id="form1">
<span>Number of Incomplete Input: 2</span>
<input type="text" value="">
<input type="text" value="">
</div>
<div id="form2">
<span>Number of Incomplete Input: 1</span>
<input type="text" value="Test">
<input type="text" value="">
</div>
This is the JS, which is working, i have have multiple JS with class named assigned to each inputs and get the value, but i need to make this check all the Input fields inside just the ID.
$(document).on("click", "#form1", function() {
var count = $('input').filter(function(input){
return $(this).val() == "";
}).length;
alert(count);
});
Your html structure, especially form structure is not correct, so you should first add some submit button to form that can be clicked. Then you can add event listener on form's submission. In the event handler you should select children inputs inside the form tag using $(this).children("input"). Now you can filter them.
$(document).on("submit", "#form1", function (e) {
e.preventDefault();
var count = $(this)
.children("input")
.filter(function (input) {
return $(this).val() == "";
}).length;
alert(count);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form1">
<span>Number of Incomplete Input: 2</span>
<input type="text" value="">
<input type="text" value="">
<button type="submit">Submit</button>
</form>
This is the JS, which is working, if I have have multiple JS with class named assigned to each inputs and Im getting the value, but i have multiple JS for this to work.
How can i make this Simpler say like, when user clicks on Div, it only checks the input fields inside that div.
$(document).on("click", "#form1", function() {
var count = $('.input_field1').filter(function(input){
return $(this).val() == "";
}).length;
alert(count);
});
HTML
<div id="form1">
<span>Number of Incomplete Input: 2</span>
<input type="text" value="" class="input_field1">
<input type="text" value=""class="input_field1">
</div>
<div id="form2">
<span>Number of Incomplete Input: 1</span>
<input type="text" value="Test" class="input_field2">
<input type="text" value="" class="input_field2">
</div>
See snippet below:
It has commented and if you put some effort on it, you can have a jQuery plugin out of it.
(function () {
'use strict';
var
// this use to prevent event conflict
namespace = 'customValidation',
submitResult = true;
var
input,
inputType,
inputParent,
inputNamePlaceholder,
//-----
writableInputTypes = ['text', 'password'],
checkboxInputType = 'checkbox';
var
errorContainerCls = 'error-container';
// Add this function in global scope
// Change form status with this function
function changeFormStatus(status) {
submitResult = submitResult && status;
}
// Check if a radio input in a
// group is checked
function isRadioChecked(form, name) {
if(!form || !name) return true;
var radio = $(form).find('input[type="radio"][name="' + name.toString() + '"]:checked');
return typeof radio !== 'undefined' && radio.length
? true
: false;
}
function eachInputCall(inp, isInSubmit) {
input = $(inp);
inputType = input.attr('type');
// assume that we have a name placeholder in
// attributes named data-name-placeholder
inputNamePlaceholder = input.attr('data-name-placeholder');
// if it is not present,
// we should have backup placeholder
inputNamePlaceholder = inputNamePlaceholder ? inputNamePlaceholder : 'input';
if(!inputType) return;
// you have three type of inputs in simple form
// that you can make realtime validation for them
// 1. writable inputs ✓
// 2. checkbox inputs ✓
// 3. radio inputs ✕
// for item 3 you should write
// another `else if` condition
// but you should have it for
// each name (it was easier if it was a plugin)
// radio inputs is not good for realtime
// unchecked validation.
// You can check radios through submit event
// let make it lowercase
inputType = inputType.toLowerCase();
// first check type of input
if ($.inArray(inputType, writableInputTypes) !== -1) {
if(!isInSubmit) {
input.on('input.' + namespace, function () {
writableInputChange(this);
});
} else {
writableInputChange(inp);
}
} else if ('checkbox' == inputType) { // if it is checkbox
if(!isInSubmit) {
input.on('change.' + namespace, function () {
checkboxInputChange(this);
});
} else {
checkboxInputChange(inp);
}
}
}
// Check if an input has some validation
// (here we have just required or not empty)
function writableInputChange(inp) {
// I use $(this) instead of input
// to prevent conflict if selector
// is a class for an input
if('' == $.trim($(inp).val())) {
changeFormStatus(false);
// your appropriate message
// you can use bootstrap's popover
// to modefy just input element
// and make your html structure
// more flexible
// or
// if your inputs are in
// separate containers do
// somthing like below
inputParent = $(inp).parent();
if(!inputParent.children('.' + errorContainerCls).length) {
inputParent.append($('<div class="' + errorContainerCls + '" />').text('Please fill ' + inputNamePlaceholder));
}
} else {
changeFormStatus(true);
// I assume we have separate
// containers for each input
inputParent = $(inp).parent();
inputParent.children('.' + errorContainerCls).remove();
}
}
// Check if an checkbox is checked
function checkboxInputChange(chk) {
if(!$(chk).is(':checked')) {
changeFormStatus(false);
// if your inputs are in
// separate containers do
// somthing like below
inputParent = $(chk).parent();
if(!inputParent.children('.' + errorContainerCls).length) {
inputParent.append($('<div class="' + errorContainerCls + '" />').text('Please check ' + inputNamePlaceholder));
}
} else {
changeFormStatus(true);
// I assume we have separate
// containers for each input
inputParent = $(chk).parent();
inputParent.children('.' + errorContainerCls).remove();
}
}
$(function () {
var
form = $('#form'),
// you can change this selector with your classes
formInputs = form.find('> .input-group > input');
formInputs.each(function () {
eachInputCall(this);
});
form.submit(function () {
submitResult = true;
// check all inputs after form submission
formInputs.each(function () {
eachInputCall(this, true);
});
// Because of radio grouping by name,
// we should select them separately
var selectedGender = isRadioChecked($(this), 'gender');
var parent;
if(selectedGender) {
changeFormStatus(true);
parent = $(this).find('input[type="radio"][name="gender"]').parent();
parent.children('.' + errorContainerCls).remove();
} else {
changeFormStatus(false);
// I assume that all radios are in
// a separate container
parent = $(this).find('input[type="radio"][name="gender"]').parent();
if(!parent.children('.' + errorContainerCls).length) {
parent.append($('<div class="' + errorContainerCls + '" />').text('Please check your gender'));
}
}
if(!submitResult) {
console.log('There are errors during validations!');
}
return submitResult;
});
});
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form">
<div class="input-group">
<input type="text" name="input1" data-name-placeholder="name">
</div>
<div class="input-group">
<input type="checkbox" name="input2" data-name-placeholder="agreement">
</div>
<div class="input-group">
<input type="radio" name="gender">
<input type="radio" name="gender">
</div>
<button type="submit">
submit
</button>
</form>

jquery, attribute selector, get current attribute value

I have an input:
<input type="text" size="5" maxlength="5" decimals="2">
where "decimals" could be a value from 0 to 4.
In the onblur event, whatever number the user types in will be changed to conform, thus:
decimals="2"
User enters: 123.456
Input is changed to: 123.46
That's trivial, no problem. My question is about the most efficient way to get the value of "decimals." Ordinarily, I'd write (jquery):
$('[decimals]').blur(function(){
val = $(this).attr('decimals');
// *** do stuff with val ***
});
...but it seems to me there ought to be a more efficient way to get the value of "decimals" since we've already selected the input based on that attribute. Is there, or is my code as written the only way?
You may take a look to attributes. This is a NamedNodeMap with some functions.
If you are referring to attributes and not to custom data attributes you can do:
$(function () {
$('[decimals]').blur(function(){
var val = this.attributes.decimals.value;
var val1 = this.attributes.getNamedItem('decimals').value;
var val2 = this.getAttribute('decimals');
console.log('this.attributes.decimals.value = ' + val);
console.log('this.attributes.getNamedItem("decimals").value = ' + val1);
console.log('this.getAttribute("decimals") = ' + val);
// *** do stuff with val ***
}).trigger('blur');
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<form>
<input type="text" size="5" maxlength="5" decimals="2">
</form>
Instead if you are referring to custom data attributes:
decimals="2"
User enters: 123.456
Input is changed to: 123.46
You can do:
$(function () {
$('[data-decimals]').on('blur', function(e){
var val = +$(this).data('decimals');
var txtNumber = +this.value;
this.value = txtNumber.toFixed(2);
});
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<form>
<input type="number" size="5" maxlength="5" data-decimals="2">
</form>

Build and manipulate array based on required fields populated

I'm trying to figure out a sensible way to display and manipulate an array/list of required fields which are yet to be populated in a form - this is just so i can output this info to the user and remove each item from the list as the user goes through and populates the fields (as a sort of progress indicator). Any thoughts on how best to handle this?
I'm thinking of something along the lines of the following:
var reqFields = [];
jQuery('label.required').each(function() {
console.log(jQuery(this).text());
reqFields.push(jQuery(this).text());
});
jQuery('.custom-field').on('input', function() {
if (jQuery('.required-entry').filter(function() {
return this.value.length === 0;
}).length === 0) {
// Remove this from the list/array
} else {
}
});
On input event check the value and accordingly add/remove item in array.
var reqFields = [];
jQuery('label.required').each(function() {
console.log(jQuery(this).text());
reqFields.push(jQuery(this).text());
});
jQuery('.custom-field').on('input', function() {
if (this.value) {
// Remove this from the list/array
reqFields.splice(jQuery(this).index(),1);
// jQuery(this).index() havent tried, else just compute index some other way
} else {
// add back if cleared out
reqFields.push( jQuery('label.required').eq(jQuery(this).index()).text());
}
});
Instead of removing the entries, every time there's a change in input of the required fields, you can simply re-assign the reqFields array to the list of required fields with empty input.
var reqFields = [];
jQuery(function() {
jQuery('.requiredFields').on('input', function() {
reqFields = jQuery('.requiredFields').filter(function() {
return this.value.length === 0;
});
});
});
Check this basic example bellow using each on input to loop through all the fields with class required-entry and check the empty ones to finally append message to span #msg to inform the user which fields are required.
Hope this helps.
$('.required-entry').on('input', function() {
$('#msg').empty();
$('.required-entry').each(function() {
if ( $(this).val().length == 0 )
$('#msg').append('Field <b>'+$(this).prev('label').text()+'</b> is required.<br/>');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label class='required'>First Name</label>
<input type='text' id='first_name' name='first_name' class='required-entry' required/>
<br/>
<label class='required'>Last Name</label>
<input type='text' id='last_name' name='last_name' class='required-entry' required/>
<br/>
<label class='required'>Email Address</label>
<input type='text' id='email' name='email' class='required-entry' required/>
<hr/>
<br/>
<span id='msg'></span>

Use same function on multiple elements

I need this function to work on multiple elements in the form, right now it only works on TfDiagnosis.
How do I use it on TfDiagnosis and TfDiagnosis2 with results in TfSnowmed and TfSnowmed2?
JQUERY
$(function snowmedlist() {
$('#TfDiagnosis').on('click keyup change blur', function() {
if ($('#TfDiagnosis').val() == '[D]Anterograde amnesia (780.93)') {
$('#TfSnowmed').val(206789002);
}
if ($('#TfDiagnosis').val() == '[D]Chills with fever (780.60)') {
$('#TfSnowmed').val(206760004);
}
});
});
HTML
<input name="TfDiagnosis" type="text" id="TfDiagnosis" size="100">
<input type="text" name="TfSnowmed" id="TfSnowmed">
<input name="TfDiagnosis2" type="text" id="TfDiagnosis2" size="100" >
<input type="text" name="TfSnowmed2" id="TfSnowmed2"></td>
It's easy to work on groups of elements using class names.
<input name="TfDiagnosis" type="text" id="TfDiagnosis" class="diagnosis" size="100">
<input type="text" name="TfSnowmed" id="TfSnowmed">
js:
$('.diagnosis').on('click keyup change blur', function() {
if($(this).val() == "...") {
$(this).next().val(1.00);
}
})
This way .next() is always the next element, so you don't need to keep passing IDs around. You can then store the data outside of the function to get rid of a cluster of IF statements:
var myData = []
myData['[D]Anterograde amnesia (780.93)'] = '206789002';
myData['[D]Chills with fever (780.60)'] = '206760004';
...then substitute the look-up from the array....
$('.diagnosis').on('click keyup change blur', function() {
$(this).next().val(myData[$(this).attr(id)]);
})
You can use
$('#TfDiagnosis, #TfDiagnosis2').on('click keyup change blur', function() {
if($(this).attr('id') == 'TfDiagnosis' ){
if ($(this).val() == '[D]Anterograde amnesia (780.93)') {
$('#TfSnowmed').val(206789002);
}
if ($(this).val() == '[D]Chills with fever (780.60)') {
$('#TfSnowmed').val(206760004);
}
}else{
//Stuff to do in case it is the #TfDiagnosis2
}
});
The most efficient way to make your function work on multiple inputs is to use event delegation:
$(document).on('click keyup change blur', 'input', function() {
var value = $(this).val(); //Get the value only once
if (value == '[D]Anterograde amnesia (780.93)') {
$('#TfSnowmed').val(206789002);
}
else if (value == '[D]Chills with fever (780.60)') {
$('#TfSnowmed').val(206760004);
}
});
Which will call the function for any input on the page. You probably want to assign a class to the specific inputs you want to use like so:
HTML
<input name="TfDiagnosis" type="text" id="TfDiagnosis" class="TfInput" size="100">
<input type="text" name="TfSnowmed" id="TfSnowmed" class="TfInput">
<input name="TfDiagnosis2" type="text" id="TfDiagnosis2" class="TfInput" size="100" >
<input type="text" name="TfSnowmed2" id="TfSnowmed2" class="TfInput">
JavaScript
$(document).on('click keyup change blur', '.TfInput', function() {
var value = $(this).val(); //Get the value only once
if (value == '[D]Anterograde amnesia (780.93)') {
$('#TfSnowmed').val(206789002);
}
else if (value == '[D]Chills with fever (780.60)') {
$('#TfSnowmed').val(206760004);
}
});

adjusting default value script to work with multiple rows

I am using a default value script (jquery.defaultvalue.js) to add default text to various input fields on a form:
<script type='text/javascript'>
jQuery(function($) {
$("#name, #email, #organisation, #position").defaultvalue("Name", "Email", "Organisation", "Position");
});
</script>
The form looks like this:
<form method="post" name="booking" action="bookingengine.php">
<p><input type="text" name="name[]" id="name">
<input type="text" name="email[]" id="email">
<input type="text" name="organisation[]" id="organisation">
<input type="text" name="position[]" id="position">
<span class="remove">Remove</span></p>
<p><span class="add">Add person</span><br /><br /><input type="submit" name="submit" id="submit" value="Submit" class="submit-button" /></p>
</form>
I am also using a script so that users can dynamically add (clone) rows to the form:
<script>
$(document).ready(function() {
$(".add").click(function() {
var x = $("form > p:first-child").clone(true).insertBefore("form > p:last-child");
x.find('input').each(function() { this.value = ''; });
return false;
});
$(".remove").click(function() {
$(this).parent().remove();
});
});
</script>
So, when the page loads there is one row with the default values. The user would then start adding information to the inputs. I am wondering if there is a way of having the default values show up in subsequent rows that are added as well.
You can see the form in action here.
Thanks,
Nick
Just call .defaultValue this once the new row is created. The below assumes the format of the columns is precticable/remains the same.
$(".add").click(function() {
var x = $("form > p:first-child");
x.clone(true).insertBefore("form > p:last-child");
x.find('input:not(:submit)').defaultvalue("Name", "Email", "Organisation", "Position");
return false;
});
You should remove ids from the input fields because once these are cloned, the ids, classes, everything about the elements are cloned. So you'll basically end up with multiple elements in the DOM with the same id -- not good.
A better "set defaults"
Personally I would remove the "set defaults plugin" if it's used purely on the site for this purpose. It can easily be re-created with the below and this is more efficient because it doesn't care about ordering of input elements.
var defaults = {
'name[]': 'Name',
'email[]': 'Email',
'organisation[]': 'Organisation',
'position[]': 'Position'
};
var setDefaults = function(inputElements)
{
$(inputElements).each(function() {
var d = defaults[this.name];
if (d && d.length)
{
this.value = d;
$(this).data('isDefault', true);
}
});
};
Then you can simply do (once page is loaded):
setDefaults(jQuery('form[name=booking] input'));
And once a row is added:
$(".add").click(function() {
var x = $("form > p:first-child");
x.clone(true).insertBefore("form > p:last-child");
setDefaults(x.find('input')); // <-- let the magic begin
return false;
});
For the toggling of default values you can simply delegate events and with the help of setDefault
// Toggles
$('form[name=booking]').delegate('input', {
'focus': function() {
if ($(this).data('isDefault'))
$(this).val('').removeData('isDefault');
},
'blur': function() {
if (!this.value.length) setDefaults(this);
}
});
Fiddle: http://jsfiddle.net/garreh/zEmhS/3/ (shows correct toggling of default values)
Okey, first of all; ids must be unique so change your ids to classes if you intend to have more then one of them.
and then in your add function before your "return false":
var
inputs = x.getElementsByTagName('input'),
defaults = ["Name", "Email", "Organisation", "Position"];
for(var i in inputs){
if(typeof inputs[i] == 'object'){
$(inputs[i]).defaultvalue(defaults[i]);
}
}

Categories

Resources