Handle multiple dropdown lists with VueJS - vue.js

I am new at VueJs and I want to create a form. It contains questions with category and rate. My target is to take the rate of each question and his category, and all questions from category 'F' will have scoreF (which will occur from the sum of rates) and all questions from category 'H' will have a scoreH. Here is my job till now. Thank you in advance for your help!
https://codepen.io/dparanou/pen/zYGPexa
<select v-bind:id="question.id" #change="onChange($event, question.id, question.category)">
<option disabled selected>--</option>
<option v-for="n in question.answers" :value="n">{{n}}</option>
</select>
<span>Score F: {{fScore}}</span>
<span>Score H: {{hScore}}</span>
And here is my JS file
data: {
fScore: 0,
hScore: 0,
},
methods: {
onChange(event, id, cat) {
num = event.target.value;
console.log("id: "+ id + ", category: " + cat + ", score: " + num);
if(cat == "F") {
this.fScore += num;
console.log(this.fScore);
} else {
this.hScore += num;
}
}
}

It had only to convert the event into Integer!
onChange(event, id, cat) {
var num = parseInt(event.target.value);
if(cat == "F") {
this.fScore += num;
} else {
this.hScore += num;
}
}

Related

How Can I Add Website Decimal Quantity in Odoo

I Have a custom module website_decimal_quantity. after installing this module, In the website shop cart, when the user clicks on the + or - button to adjust quantity, It should add or deduct .1 value from it. i find out that a function onclickaddcartjson in the sale.variantmixin is responsible for the button click.i tried to extend the onclickaddcartjson function that present in the website_sale.website_sale. but it does not work.
Thanks For the Attention
My code is like :
publicWidget.registry.WebsiteSale.include({
onClickAddCartJSON: function (ev) {
ev.preventDefault();
var $link = $(ev.currentTarget);
var $input = $link.closest('.input-group').find("input");
var min = parseFloat($input.data("min") || 0);
var max = parseFloat($input.data("max") || Infinity);
var previousQty = parseFloat($input.val() || 0, 10);
var quantity = ($link.has(".fa-minus").length ? -0.1 : 0.1) + previousQty;
var newQty = quantity > min ? (quantity < max ? quantity : max) : min;
if (newQty !== previousQty) {
$input.val(newQty).trigger('change');
}
return false;
},
_changeCartQuantity: function ($input, value, $dom_optional, line_id, productIDs) {
_.each($dom_optional, function (elem) {
$(elem).find('.js_quantity').text(value);
productIDs.push($(elem).find('span[data-product-id]').data('product-id'));
});
$input.data('update_change', true);
this._rpc({
route: "/shop/cart/update_json",
params: {
line_id: line_id,
product_id: parseInt($input.data('product-id'), 10),
set_qty: value
},
}).then(function (data) {
$input.data('update_change', false);
var check_value = parseFloat($input.val());
if (isNaN(check_value)) {
check_value = 1;
}
if (value !== check_value) {
$input.trigger('change');
return;
}
if (!data.cart_quantity) {
return window.location = '/shop/cart';
}
wSaleUtils.updateCartNavBar(data);
$input.val(data.quantity);
$('.js_quantity[data-line-id='+line_id+']').val(data.quantity).text(data.quantity);
if (data.warning) {
var cart_alert = $('.oe_cart').parent().find('#data_warning');
if (cart_alert.length === 0) {
$('.oe_cart').prepend('<div class="alert alert-danger alert-dismissable" role="alert" id="data_warning">'+
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> ' + data.warning + '</div>');
}
else {
cart_alert.html('<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> ' + data.warning);
}
$input.val(data.quantity);
}
});
},
_onChangeCartQuantity: function (ev) {
var $input = $(ev.currentTarget);
if ($input.data('update_change')) {
return;
}
var value = parseFloat($input.val());
if (isNaN(value)) {
value = 1;
}
var $dom = $input.closest('tr');
// var default_price = parseFloat($dom.find('.text-danger > span.oe_currency_value').text());
var $dom_optional = $dom.nextUntil(':not(.optional_product.info)');
var line_id = parseInt($input.data('line-id'), 10);
var productIDs = [parseInt($input.data('product-id'), 10)];
this._changeCartQuantity($input, value, $dom_optional, line_id, productIDs);
},
})
The change that I made is in _onclickaddcartjson; change the line
var quantity = ($link.has(".fa-minus").length ? -0.1 : 0.1) + previousQty;
and in _changeCartQuantity, change the check_value into:
var check_value = parseFloat($input.val())
And in _onChangeCartQuantity, change the value into:
var value = parseFloat($input.val()).
Even if I made these changes in source file without my custom module, the quantity increase or decrease by .1. But it automatically turns into an integer value. That means when I click on the + button, the value changes to 1.1, but it immediately changes to 1. Also, if I click on the - button, it will changes to 2.9 from 3, then it changes to 2 as its value. If anybody has an idea about this please share. Thanks for the attention.
Yes, it 's possible as the type of the underlying field in model SaleOrderLine is Float. And in website_sale/models/sale_order.py : int(sum(order.mapped('website_order_line.product_uom_qty'))) needs to be reülaced by: sum(order.mapped('website_order_line.product_uom_qty')):
class SaleOrderLine(models.Model):
_name = 'sale.order.line'
product_uom_qty = fields.Float(string='Quantity', digits='Product Unit of Measure', required=True, default=1.0)
#api.depends('order_line.product_uom_qty', 'order_line.product_id')
def _compute_cart_info(self):
for order in self:
order.cart_quantity = sum(order.mapped('website_order_line.product_uom_qty'))
order.only_services = all(l.product_id.type in ('service', 'digital') for l in order.website_order_line)
The underlying python method to add quantity is located in addons module website_sale/models/sale_oder.py :
def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs):
""" Add or set product quantity, add_qty can be negative """
self.ensure_one()
product_context = dict(self.env.context)
product_context.setdefault('lang', self.sudo().partner_id.lang)
SaleOrderLineSudo = self.env['sale.order.line'].sudo().with_context(product_context)
...
...which is called by 2 methods in website_sale/controllers/main.py :
#http.route(['/shop/cart/update'], type='http', auth="public", methods=['GET', 'POST'], website=True, csrf=False)
def cart_update(self, product_id, add_qty=1, set_qty=0, **kw):
AND
#http.route(['/shop/cart/update_json'], type='json', auth="public", methods=['POST'], website=True, csrf=False)
def cart_update_json(self, product_id, line_id=None, add_qty=None, set_qty=None, display=True):
"""This route is called when changing quantity from the cart or adding
a product from the wishlist."""
"""This route is called when adding a product to cart (no options)."""
This controller method cart_update_json is called in sale/.../js/variant_mixin.js by:
onClickAddCartJSON: function (ev) {
ev.preventDefault();
var $link = $(ev.currentTarget);
var $input = $link.closest('.input-group').find("input");
var min = parseFloat($input.data("min") || 0);
var max = parseFloat($input.data("max") || Infinity);
var previousQty = parseFloat($input.val() || 0, 10);
var quantity = ($link.has(".fa-minus").length ? -1 : 1) + previousQty;
var newQty = quantity > min ? (quantity < max ? quantity : max) : min;
if (newQty !== previousQty) {
$input.val(newQty).trigger('change');
}
return false;
},
...where: var quantity = ($link.has(".fa-minus").length ? -1 : 1) + previousQty; shows us that is incremented +1 oder -1
That s why you need to override this function in website_sale/.../website_sale.js to integrate:
var $parent = $(ev.target).closest('.js_product');
var product_id = this._getProductId($parent);
if product_id == yourspecificproductid
var quantity = ($link.has(".fa-minus").length ? -0.1 : 0.1) +
previousQty;
else
var quantity = ($link.has(".fa-minus").length ? -1 : 1) +
previousQty;
When quantity input value is changed automatically, it might be caused by parseInt($input.val()) in _onChangeCartQuantity in the file: website_sale.js:
_onChangeCartQuantity: function (ev) {
var $input = $(ev.currentTarget);
if ($input.data('update_change')) {
return;
}
var value = parseFloat($input.val() || 0, 10);
if (isNaN(value)) {
value = 1;
}
var $dom = $input.closest('tr');
// var default_price = parseFloat($dom.find('.text-danger > span.oe_currency_value').text());
var $dom_optional = $dom.nextUntil(':not(.optional_product.info)');
var line_id = parseInt($input.data('line-id'), 10);
var productIDs = [parseInt($input.data('product-id'), 10)];
this._changeCartQuantity($input, value, $dom_optional, line_id, productIDs);
},

Vuejs counter condition not working when value is reset

I'm trying to implement a datepicker where you flick through the months.
The objective is to reset the month counter when it reaches -1 or 11.
Counting up, it works just fine, but counting down it does not reset the value once it reaches -1 and I don't understand why.
<template>
<div id="app">
<button #click="count(1)">Count up</button>
<button #click="count(-1)">Count down</button>
<button #click="reset">reset</button>
<div>Value: {{ value }}</div>
</div>
</template>
methods: {
reset(){ this.value = 5 },
count(num) {
var x = this.value + num;
console.log(x)
if (x < 0) {
this.value = 11;
}
if (x > 11) {
this.value = 0;
} else {
this.value = x;
}
}
},
data() {
return {
value: 5,
};
},
Here's the code sandbox
Update your code to
if (x < 0) {
this.value = 11;
} else if (x > 11) {
this.value = 0;
} else {
this.value = x;
}
And it will work :)
The reason is that for now when the value is less than 0 it enters the first condition (if (x < 0)) and then it still enters the else so this.value is set to x.

How to select from the database within a option that is filled with JavaScript

I'm new to razor page
I have an edit page - that it has 2 selection tags
1 - "MissionTime" and the other - "MissionDay".
The choices in MissionDay vary according to the choice of MissionTime.
In terms of JavaScript it works great! On the Create page it works really well.
Also on the edit page it works well on the part of the JavaScript.
The problem is when the database has information () but it does not select according to the value in the database.
<div class = "col-sm-4">
<label asp-for = "Mission.MissionTime" class = "control-label"> </label>
<select id = "MissionTime" asp-for = "Mission.MissionTime">
<option value = "0">
with no
</option>
<option value = "1">
Every day
</option>
<option value = "7">
once a week
</option>
<option value = "30">
once a month
</option>
<option value = "365">
Once a year
</option>
</select>
</div> <div class = "col-sm-4">
<label asp-for = "Mission.MissionDay" class = "control-label"> </label>
<select id = "MissionDay" asp-for = "Mission.MissionDay">
<option value = "0">
with no
</option>
</select>
</div>
Code JavaScript -
<script>
$ (document) .ready (function () {
missionTime ();
$ ("#MissionTime"). Change (function () {
missionTime ();
});
$ ("#MissionDay"). Change (function () {
var d = new Date ();
var val = $ (this) .val ();
if (val == "Sunday") {
d.setDate (d.getDate () + ((7 - d.getDay ())% 7 + 0)% 7);
} else if (val == "Monday") {
d.setDate (d.getDate () + ((7 - d.getDay ())% 7 + 1)% 7);
} else if (val == "Tuesday") {
d.setDate (d.getDate () + ((7 - d.getDay ())% 7 + 2)% 7);
} else if (val == "Wednesday") {
d.setDate (d.getDate () + ((7 - d.getDay ())% 7 + 3)% 7);
} else if (val == "Thursday") {
d.setDate (d.getDate () + ((7 - d.getDay ())% 7 + 4)% 7);
}
else if (val == "startMonth") {
d.setMonth (d.getMonth () + 1, 1);
}
else if (val == "middleMonth") {
// if 15th of current month is over move to next month
// need to check whether to use> = or just> ie on 15th Jun
// if you want 15 Jun then use> else if you want 15 Jul use> =
var dt = d.getDate ();
d.setDate (15);
if (dt> = 15) {
d.setMonth (date.getMonth () + 1);
}
d.setHours (23, 59, 59, 0);
}
else if (val == "endMonth") {
d.setMonth (d.getMonth () + 1);
d.setDate (0);
}
else if (val == "firstYear") {
d = new Date (new Date (). getFullYear () +1, 0, 1);
}
else if (val == "lastYear") {
d = new Date (new Date (). getFullYear (), 11, 31);
}
var dd = String (d.getDate ()). padStart (2, '0');
var mm = String (d.getMonth () + 1) .padStart (2, '0'); // January is 0!
var yyyy = d.getFullYear ();
d = yyyy + '-' + mm + '-' + dd;
document.getElementById ("firstDate"). value = d;
}
);
function missionTime () {
var val = $ ("# MissionTime"). val ();
if (val == "1") {
$ ("#MissionDay"). Html ("<option value = '0'> without </option>");
today ();
} else if (val == "7") {
$ ("#MissionDay"). Html ("<option value = 'Sunday'> Sunday </option> <option value = 'Monday'> Monday </option> <option value = 'Tuesday'> Tuesday < / option> <option value = 'Wednesday'> Wednesday </option> <option value = 'Thursday'> Thursday </option> ");
var d = new Date ();
d.setDate (d.getDate () + ((7 - d.getDay ())% 7 + 0)% 7);
var dd = String (d.getDate ()). padStart (2, '0');
var mm = String (d.getMonth () + 1) .padStart (2, '0'); // January is 0!
var yyyy = d.getFullYear ();
d = yyyy + '-' + mm + '-' + dd;
document.getElementById ("firstDate"). value = d;
} else if (val == "30") {
. / option> ");
var d = new Date ();
d.setMonth (d.getMonth () + 1, 1);
var dd = String (d.getDate ()). padStart (2, '0');
var mm = String (d.getMonth () + 1) .padStart (2, '0'); // January is 0!
var yyyy = d.getFullYear ();
d = yyyy + '-' + mm + '-' + dd;
document.getElementById ("firstDate"). value = d;
} else if (val == "365") {
$ ("#MissionDay"). Html ("<option value = 'firstYear'> beginning of year </option> <option value = 'lastYear'> end of year </option>");
} else if (val == "0") {
$ ("#MissionDay"). Html ("<option value = '0'> without </option>");
today ();
}
}
function today () {
var today = new Date ();
var dd = String (today.getDate ()). padStart (2, '0');
var mm = String (today.getMonth () + 1) .padStart (2, '0'); // January is 0!
var yyyy = today.getFullYear ();
today = yyyy + '-' + mm + '-' + dd;
document.getElementById ("firstDate"). value = today;
}
});
</script>
The code works great!
The problem is that I can not get the data in the "MissionDay"
I guess this is because first the page takes data from the database and only then does it run the script. Anyone have any tips on how to solve this problem?
Best regards
The problem is when the database has information () but it does not select according to the value in the database.
Please note that the option(s) that you generate on JavaScript client could not be available when the Select Tag Helper is rendered. Therefore it does not set default selected option based on the data passed through Mission.MissionDay.
To achieve your requirement of setting the default selected option based on the stored MissionDay, you can try to store the data in a hidden field, then set the selected option in JavaScript code, like below.
Add a hidden field with id="hf_missionDay"
<label asp-for="Mission.MissionDay" class="control-label"> </label>
<input type="hidden" id="hf_missionDay" value="Mission.MissionDay" />
<select id="MissionDay" asp-for="Mission.MissionDay">
<option value="0">
with no
</option>
</select>
Set selected option based on the data store in hidden field
$(document).ready(function() {
missionTime();
SetSelectionOfMissionDay();
//...
//your code logic here
//...
SetSelectionOfMissionDay function
function SetSelectionOfMissionDay() {
var mday = $("#hf_missionDay").val();
$("select#MissionDay option[value='" + mday + "']").attr("selected", true);
//or
//$("select#MissionDay").val(mday);
}

Creating dynamic number of select based on entered textbox value

I have a javascript which when a user enters a number to textbox,the script generates that much number of textboxes dynamically.But what i need is to create is select's instead of textboxes with options retrieved from mysql database.
the javascript for creating textbox is given below,
<script type="text/javascript" >
$(document).ready(function () {
$("#stops").change(function () {
var count = $("#holder input").size();
var requested = parseInt($("#stops").val(), 10);
if(requested == 0 && count > 0){
location.reload();
}
$("#title").html("Stop Codes");
if (requested > count) {
for (i = count; i < requested; i++) {
var $ctrl = $('<input/>').attr({
type: 'text',
name: 'text' + i,
placeholder: "Enter stop " +(i+1) +" airport code"
});
$("#holder").append($ctrl);
}
} else if (requested < count) {
var x = requested - 1;
$("#holder input:gt(" + x + ")").remove();
}
});
});
HTML generated textboxes here
<td id="holder"></td>

dojo.connect / dojo.hitch scope problem?

I have a programmer class that populates a ul with project names and checkboxes - when a checkbox is clicked a popup dialog is supposed to show with the programmers id and the project name. dojo.connect is supposed to setup onclick for each li but the project (i) defaults to the last value (windows). Any ideas why this is happening?
...
projects: {"redial", "cms", "android", "windows"},
name: "Chris",
id: "2",
constructor: function(programmer) {
this.name = programmer.name;
this.id = programmer.id;
this.projects = programmer.projects;
},
update: function(theid, project) {
alert(theid + ", " + project);
},
postCreate: function() {
this.render();
// add in the name of the programmer
this.programmerName.innerHTML = this.name;
for(var i in this.projects) {
node = document.createElement("li");
this.programmerProjects.appendChild(node);
innerNode = document.createElement("label");
innerNode.setAttribute("for", this.id + "_" + i);
innerNode.innerHTML = i;
node.appendChild(innerNode);
tickNode = document.createElement("input");
tickNode.setAttribute("type", "checkbox");
tickNode.setAttribute("id", this.id + "_" + i);
if(this.projects[i] == 1) {
tickNode.setAttribute("checked", "checked");
}
dojo.connect(tickNode, 'onclick', dojo.hitch(this, function() {
this.update(this.id, i)
}));
node.appendChild(tickNode);
}
},
Just found out that extra parameters can be attached to the hitch:
dojo.connect(tickNode, 'onclick', dojo.hitch(this, function() {
this.update(this.id, i)
}));
should be:
dojo.connect(tickNode, 'onclick', dojo.hitch(this, "update", this.id, i));
Why are you calling this.render()? Is that your function or the widget base (i.e. already in the lifecycle)? For good measure make sure to call this.inherited(arguments); in postCreate.
My guess would be that tickNode is not in the DOM yet for the connect to work. Try appending the checkbox before you setup the connect. The last one is being fired because it is being held on by reference. You can try something like this instead:
for(var i = 0; i < this.projects.length; i++) {
var p = this.projects[i];
node = document.createElement("li");
this.programmerProjects.appendChild(node);
innerNode = document.createElement("label");
innerNode.setAttribute("for", this.id + "_" + p);
innerNode.innerHTML = p;
node.appendChild(innerNode);
tickNode = document.createElement("input");
tickNode.setAttribute("type", "checkbox");
tickNode.setAttribute("id", this.id + "_" + p);
if(i == 0) { //first item checked?
tickNode.setAttribute("checked", "checked");
}
node.appendChild(tickNode);
dojo.connect(tickNode, 'onclick', function(e) {
dojo.stopEvent(e);
this.update(this.id, p);
});
}
I would consider looking into dojo.create as well instead of createElement as well. Good luck!
Alternatively, and I think it's cleaner, you can pass the context into dojo.connect as the third parameter:
dojo.connect(tickNode, 'onclick', this, function() {
this.update(this.id, i);
});