Meteor.js calling specific data from mongodb - mongodb

So im making this inventory website, so the forklift drivers can add or remove weight from our inventory we measure our products in weight.
So basically I need to be able to fetch the weight (in kg) from mongo db and add it to it and save it
//edit
the problem I'm having is the current code is returning "NaN kg" in html
kg is defined by a number inserted into the db and i cant seem to get the kg value without my code running into a error
The Html
<form class="add-pro">
<input type="text" class="form-control" name="namn" required="true" placeholder="Produkt Name"/>
<br />
<input type="text" class="form-control" name="id" required="true" placeholder="Produkt code"/>
<br />
<input type="number" class="form-control" placeholder="KG" name="kg" />
<input id="btnModal" type="submit" value="add" class="btn btn-primary"/>
</form>
<form class="add-data">
<input type="number" class="form-control" id="add-data-control" name="g" placeholder="how much">
<button class="glyphicon glyphicon-plus" type="submit" id="add-data-plus" aria-hidden="true"></button>
</form>
Javascript
"submit .add-data": function(event){
var g = event.target.g.value;
var x = produkter.find().fetch();
var k = kg;
produkter.update(this._id, {$set: {kg: +k + +g }});
},
Template.produkter.events({
"submit .add-pro": function(event){
var namn = event.target.namn.value;
var id = event.target.id.value;
var kg = event.target.kg.value;
produkter.insert({
namn: namn,
id: id,
kg: kg
});
return false;
},

There are a few problems with your code, see comments:
"submit .add-data": function(event){
var g = event.target.g.value;
var x = produkter.find().fetch();
// Where is kg defined?
var k = kg;
// The expression +k + +g does not compute - do you mean k+g ?
produkter.update(this._id, {$set: {kg: +k + +g }});
},
You may also be running into trouble with strings versus numbers. Even though your HTML input tag says type="number", the value will be a string, and will need to be converted to a number before saving it to the database.
I suspect you are also intending to save the value as something like "2.7 kg", which is useful for displaying the weight, but it's a bad idea, because if you do that you will need to strip off the " kg" every time you want to calculate a new value.

Related

Getting value of arbitrary form element in Google Apps Script web app

I have a Google Apps Script web app which has a form attached, for example:
<form id="form">
<input type="range" min="0" max="3" name="mb1" value="0">
<input type="range" min="0" max="3" name="mb2" value="0">
<input type="range" min="0" max="3" name="mb3" value="0">
etc...
<input id="submit" type="submit" style="display: none" onclick="this.value='Submitting ...'; google.script.run.withSuccessHandler(formSubmitted) .writeForm(this.parentNode); return false;">
</form>
The Code.gs file has a writeForm(form) function, which can access the form input values like so:
var mb1 = form.mb1;
var mb2 = form.mb2;
etc...
However, this approach is inefficient with many such inputs (I have around 80). Much better would just be to get the values when they're being processed in a loop, like so:
for(var i = 0; i <= 80; i++) {
var formItemID = "mb"+i;
console.log(form.formItemID);
}
However, this of course does not work, as it looks for form inputs with the id "formItemID". I've taken a look at some functionality of the HTMLFormElements class which should be being sent, but Apps Script doesn't seem to implement this fully, and I can't find documentation of the form.ItemName property. Is there a way to achieve this functionality without calling for each form input separately?
You could always just loop through the form elements and get the input values. This will send an array to the server.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="form" name="form">
<input class="range" type="range" min="0" max="3" value="0">
<input class="range" type="range" min="0" max="3" value="0">
<input class="range" type="range" min="0" max="3" value="0">
<br>
<input id="button" type="button" onclick="onClick()">
</form>
<script>
function onClick() {
var form = document.getElementById("form");
var vals = [];
for( var i=0; i<form.elements.length; i++ ) {
if( form.elements[i].className === "range" ) {
vals.push(form.elements[i].value);
}
}
google.script.run.getForm(vals);
}
</script>
</body>
</html>
Server side, Your form is sent as a object with key as input name and value as input values. Your form will look like:
{
mb1:0,
mb2:1,
mb3:0
}
To access the values, You can use form.mb1 as you've used or form['mb1']. To use variables as keys, always use the bracket [] notation
for(var i = 0; i <= 80; i++) {
var formItemID = "mb"+i;
console.log(form[formItemID]);//Note bracket notation
}
Or without a for loop,
var valuesArr = Object.keys(form).map(function(key){return form[key];})

get checkbox and radio button value in lift

i am trying to processing a form in lift frame work. my form is having one checkbox and radiobuttons. how could i check whether the checkbox is checked or not and the selected radio button.the following code i used to get other elements value.
the view:
<form class="lift:MySnippet?form=post">
From:<input type="text" name="source" /><br />
To: <input type="text" name="destination" /><br />
Age: <input type="text" name = "age"/><br />
Return: <input type="checkbox" name="needreturn" value="Return Ticket" /><br />
<input type="radio" name="sex" value="male" />Male<br />
<input type="radio" name="sex" value="male" />Female<br />
<input type="submit" value="Book Ticket"/>
</form>
and MySnippet scala code is:
object MySnippet {
def render = {
var from = ""
var to = ""
var age = 0
def process() {
S.notice("in process function")
}
"name=source" #> SHtml.onSubmit(from = _) &
"name=destination" #> SHtml.onSubmit(to = _) &
"name=age" #> SHtml.onSubmit(s => asInt(s).foreach(age = _)) &
"type=submit" #> SHtml.onSubmitUnit(process)
}
}
in this how could i process the checkbox and radio button. can anyone help me...thanx in advance.
Do you need to specify the choices in your HTML? If not, the easiest way is:
Return: <input type="checkbox" name="needreturn" /><br />
Sex: <input type="radio" name="sex" />
and the CSS Transform:
val radioChoices = List("male", "female")
var sex:Box[String] = None
var needReturn:Boolean = false
"#sex" #> SHtml.radio(radioChoices, sex, (resp) => sex = Full(resp)) &
"#needreturn" #> SHtml.checkbox(needReturn, (resp) => needReturn = resp)
You could replace SHtml.radio with SHtml.ajaxRadio and SHtml.checkbox with SHtml.ajaxCheckbox if you want your selection to be sent to the server every time the value is changed, instead of when the form is submitted
I believe you can also use the SHtml.onSubmit as you do above for the checkbox and radio, but I'd have to do some testing to figure out exactly how.
With regards to the radio button, you can find some information about changing the way the label is output here if you need to: https://groups.google.com/forum/?fromgroups=#!topic/liftweb/rowpmIDbQAE
Use SHtml.checkbox, SHtml.radio
By the way, the <input>-s should be SHtml.text, I think. So, they're not buttons -- they're inputs. Don't forget to check the resulting html in the web page with firebug. (You'd see that using the current code you have input=text deleted.)

Example of jQuery Mobile site with conditional/branching questions

I'm trying to create a JQM survey with branching questions--i.e. in a survey with questions 1-3, if you choose a particular answer on question 1, a question is dynamically added between questions 1 and 2.
UPDATE: I made an attempt ( https://dl.dropbox.com/u/17841063/site2/index-c1.html#page2 ) that works by matching the value of a radio button to the name of a hidden div--if there's a match, it unhides the div. The problem right now is that if you change your answer back to an option that wouldn't trigger the conditional question, it doesn't re-hide. For example, clicking No or Unsure in question A1 causes question A2 to appear, but if you then click Yes in A1, A2 still remains...
<script type="text/javascript">
// Place in this array the ID of the element you want to hide
var hide=['A2','A4'];
function setOpt()
{
resetOpt(); // Call the resetOpt function. Hide some elements in the "hide" array.
for(var i=0,sel=document.getElementsByTagName('input');i<sel.length;i++)
{
sel[i].onchange=function()
{
if(this.parentNode.tagName.toLowerCase()!='div')
resetOpt(); // Hides the elements in "hide" array when the first select element is choosen
try
{
document.getElementById(this.value).style.display='';
}
catch(e){} ; // When the value of the element is not an element ID
}
}
}
window.addEventListener?window.addEventListener('load',setOpt,false):
window.attachEvent('onload',setOpt);
function resetOpt()
{
for(var i=0;i<hide.length;i++)
document.getElementById(hide[i]).style.display='none'; // Hide the elements in "hide" array
}
</script>
Here's are the radio buttons that use the script above:
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<legend>(Question A1) A prominent accident smokes on top of the blessed reactionary?</legend>
<input type="radio" name="aaa" id="aaa_0" value="notA2" />
<label for="aaa_0">Yes</label>
<input type="radio" name="aaa" id="aaa_1" value="A2" />
<label for="aaa_1">No</label>
<input type="radio" name="aaa" id="aaa_2" value="A2" />
<label for="aaa_2">Unsure</label>
</fieldset>
</div>
<div id="A2" data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<legend>(Question A2) Does a married composite remainder the shallow whistle??</legend>
<input type="radio" name="bbb" id="bbb_0" value="" />
<label for="bbb_0">Yes</label>
<input type="radio" name="bbb" id="bbb_1" value="" />
<label for="bbb_1">No</label>
<input type="radio" name="bbb" id="bbb_2" value="" />
<label for="bbb_2">Unsure</label>
</fieldset>
</div>
If anyone has ideas about fixing this, or examples of other ways to do branching forms, I'd be very grateful!
Thanks,
Patrick
I played around a little bit with your example, removed all your plain JavaScript and added some jQuery Mobile style script, see working example here
<script>
$("input[type='radio']").bind( "change", function(event, ui) {
var mySelection = $('input[name=aaa]:checked').val();
//alert(mySelection);
if (mySelection == "A2") {
$('#A2').removeClass('ui-hidden-accessible');
} else {
$('#A2').addClass('ui-hidden-accessible');
};
});
</script>

Required attribute on multiple checkboxes with the same name? [duplicate]

This question already has answers here:
Using the HTML5 "required" attribute for a group of checkboxes?
(16 answers)
Closed 6 years ago.
I have a list of checkboxes with the same name attribute, and I need to validate that at least one of them has been selected.
But when I use the html5 attribute "required" on all of them, the browser (chrome & ff) doesn't allow me to submit the form unless all of them are checked.
sample code:
<label for="a-0">a-0</label>
<input type="checkbox" name="q-8" id="a-0" required />
<label for="a-1">a-1</label>
<input type="checkbox" name="q-8" id="a-1" required />
<label for="a-2">a-2</label>
<input type="checkbox" name="q-8" id="a-2" required />
When using the same with radio inputs, the form works as expected (if one of the options is selected the form validates)
According to Joe Hopfgartner (who claims to quote the html5 specs), the supposed behaviour is:
For checkboxes, the required attribute shall only be satisfied when one or more of the checkboxes with that name in that form are checked.
For radio buttons, the required attribute shall only be satisfied when exactly one of the radio buttons in that radio group is checked.
am i doing something wrong, or is this a browser bug (on both chrome & ff) ??
You can make it with jQuery a less lines:
$(function(){
var requiredCheckboxes = $(':checkbox[required]');
requiredCheckboxes.change(function(){
if(requiredCheckboxes.is(':checked')) {
requiredCheckboxes.removeAttr('required');
}
else {
requiredCheckboxes.attr('required', 'required');
}
});
});
With $(':checkbox[required]') you select all checkboxes with the attribute required, then, with the .change method applied to this group of checkboxes, you can execute the function you want when any item of this group changes. In this case, if any of the checkboxes is checked, I remove the required attribute for all of the checkboxes that are part of the selected group.
I hope this helps.
Farewell.
Sorry, now I've read what you expected better, so I'm updating the answer.
Based on the HTML5 Specs from W3C, nothing is wrong. I created this JSFiddle test and it's behaving correctly based on the specs (for those browsers based on the specs, like Chrome 11 and Firefox 4):
<form>
<input type="checkbox" name="q" id="a-0" required autofocus>
<label for="a-0">a-1</label>
<br>
<input type="checkbox" name="q" id="a-1" required>
<label for="a-1">a-2</label>
<br>
<input type="checkbox" name="q" id="a-2" required>
<label for="a-2">a-3</label>
<br>
<input type="submit">
</form>
I agree that it isn't very usable (in fact many people have complained about it in the W3C's mailing lists).
But browsers are just following the standard's recommendations, which is correct. The standard is a little misleading, but we can't do anything about it in practice. You can always use JavaScript for form validation, though, like some great jQuery validation plugin.
Another approach would be choosing a polyfill that can make (almost) all browsers interpret form validation rightly.
To provide another approach similar to the answer by #IvanCollantes.
It works by additionally filtering the required checkboxes by name. I also simplified the code a bit and checks for a default checked checkbox.
jQuery(function($) {
var requiredCheckboxes = $(':checkbox[required]');
requiredCheckboxes.on('change', function(e) {
var checkboxGroup = requiredCheckboxes.filter('[name="' + $(this).attr('name') + '"]');
var isChecked = checkboxGroup.is(':checked');
checkboxGroup.prop('required', !isChecked);
});
requiredCheckboxes.trigger('change');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form target="_blank">
<p>
At least one checkbox from each group is required...
</p>
<fieldset>
<legend>Checkboxes Group test</legend>
<label>
<input type="checkbox" name="test[]" value="1" checked="checked" required="required">test-1
</label>
<label>
<input type="checkbox" name="test[]" value="2" required="required">test-2
</label>
<label>
<input type="checkbox" name="test[]" value="3" required="required">test-3
</label>
</fieldset>
<br>
<fieldset>
<legend>Checkboxes Group test2</legend>
<label>
<input type="checkbox" name="test2[]" value="1" required="required">test2-1
</label>
<label>
<input type="checkbox" name="test2[]" value="2" required="required">test2-2
</label>
<label>
<input type="checkbox" name="test2[]" value="3" required="required">test2-3
</label>
</fieldset>
<hr>
<button type="submit" value="submit">Submit</button>
</form>
i had the same problem, my solution was apply the required attribute to all elements
<input type="checkbox" name="checkin_days[]" required="required" value="0" /><span class="w">S</span>
<input type="checkbox" name="checkin_days[]" required="required" value="1" /><span class="w">M</span>
<input type="checkbox" name="checkin_days[]" required="required" value="2" /><span class="w">T</span>
<input type="checkbox" name="checkin_days[]" required="required" value="3" /><span class="w">W</span>
<input type="checkbox" name="checkin_days[]" required="required" value="4" /><span class="w">T</span>
<input type="checkbox" name="checkin_days[]" required="required" value="5" /><span class="w">F</span>
<input type="checkbox" name="checkin_days[]" required="required" value="6" /><span class="w">S</span>
when the user check one of the elements i remove the required attribute from all elements:
var $checkedCheckboxes = $('#recurrent_checkin :checkbox[name="checkin_days[]"]:checked'),
$checkboxes = $('#recurrent_checkin :checkbox[name="checkin_days[]"]');
$checkboxes.click(function() {
if($checkedCheckboxes.length) {
$checkboxes.removeAttr('required');
} else {
$checkboxes.attr('required', 'required');
}
});
Here is improvement for icova's answer. It also groups inputs by name.
$(function(){
var allRequiredCheckboxes = $(':checkbox[required]');
var checkboxNames = [];
for (var i = 0; i < allRequiredCheckboxes.length; ++i){
var name = allRequiredCheckboxes[i].name;
checkboxNames.push(name);
}
checkboxNames = checkboxNames.reduce(function(p, c) {
if (p.indexOf(c) < 0) p.push(c);
return p;
}, []);
for (var i in checkboxNames){
!function(){
var name = checkboxNames[i];
var checkboxes = $('input[name="' + name + '"]');
checkboxes.change(function(){
if(checkboxes.is(':checked')) {
checkboxes.removeAttr('required');
} else {
checkboxes.attr('required', 'required');
}
});
}();
}
});
A little jQuery fix:
$(function(){
var chbxs = $(':checkbox[required]');
var namedChbxs = {};
chbxs.each(function(){
var name = $(this).attr('name');
namedChbxs[name] = (namedChbxs[name] || $()).add(this);
});
chbxs.change(function(){
var name = $(this).attr('name');
var cbx = namedChbxs[name];
if(cbx.filter(':checked').length>0){
cbx.removeAttr('required');
}else{
cbx.attr('required','required');
}
});
});
Building on icova's answer, here's the code so you can use a custom HTML5 validation message:
$(function() {
var requiredCheckboxes = $(':checkbox[required]');
requiredCheckboxes.change(function() {
if (requiredCheckboxes.is(':checked')) {requiredCheckboxes.removeAttr('required');}
else {requiredCheckboxes.attr('required', 'required');}
});
$("input").each(function() {
$(this).on('invalid', function(e) {
e.target.setCustomValidity('');
if (!e.target.validity.valid) {
e.target.setCustomValidity('Please, select at least one of these options');
}
}).on('input, click', function(e) {e.target.setCustomValidity('');});
});
});
var verifyPaymentType = function () {
//coloque os checkbox dentro de uma div com a class checkbox
var inputs = window.jQuery('.checkbox').find('input');
var first = inputs.first()[0];
inputs.on('change', function () {
this.setCustomValidity('');
});
first.setCustomValidity( window.jQuery('.checkbox').find('input:checked').length === 0 ? 'Choose one' : '');
}
window.jQuery('#submit').click(verifyPaymentType);
}

Add a unique ID to form input for total

The problem I'm having is i'm working on an invoicing system. Which uses this,
$(document).ready(function() {
$('#add').click(function() {
JQuery('#lineItems').append('<input type="text" name="description[]"
class="ui-corner-all text invDesc" />
<input type="text" name="qty[]" class="ui-corner-all text invQty" />
<input type="text" name="amount[]" class="ui-corner-all text invAmount"
title="Amount" />
<input type="hidden" name="rowTotal[]" class="row-total-input" />');
});
});
to create new line item. The hidden input named rowTotal[] is meant to hold the totals of each row so they can be added up. The Code i am using to get the row total of qty * amount is,
$(function(){
$('.row-total-input').each(
function( intIndex ){
$('.invAmount').livequery('blur', function() {
var $this = $(this);
var amount = $this.val();
var qty = $this.parent().find('.invQty').val();
if ( (IsNumeric(amount)) && (amount != '') ) {
var rowTotal = qty * amount;
$this.css("background-color", "white").parent().find(".row-total-input").val(rowTotal);
} else {
$this.css("background-color", "#ffdcdc");
};
calcProdSubTotal();
calcOrderTotal();
});
}
);
});
However it updates all the rowTotal[] input fields to the last row total so the final sum isn't correct.
I am assuming I need to create some sort of unique ID for each rowTotal[] so only the correct one is updated. I just don't know how to do it.
Thanks in advance.
Ah the problem is here:
var qty = $this.parent().find('.invQty').val();
If each row would have a distinct parent it would be fine, but all the 'rows' are contained within the same parent - #lineItems. What should help is changing your current row creation code to this:
$(document).ready(function() {
$('#add').click(function() {
JQuery('#lineItems').append('<div><input type="text" name="description[]"
class="ui-corner-all text invDesc" />
<input type="text" name="qty[]" class="ui-corner-all text invQty" />
<input type="text" name="amount[]" class="ui-corner-all text invAmount"
title="Amount" />
<input type="hidden" name="rowTotal[]" class="row-total-input" /></div>');
//notice the extra div tag that wrapps around all the input fields
});
});