Svelte - Binding a checkbox to toggle an input value - checkbox

Using svelte, I want to set the default value of an input based on whether a checkbox is checked or not. The input is used in a drug dosage calculation. The calculation takes an value of weight in kg (k) x the input value.
I also need to have the drug calculation results change when this input value is changed by the checkbox action or when a user changes the input value manually, which doesn't happen currently.
I have been able to implement the input value change when the checkbox is checked but not clear on how to get the calculation to recalculate when the checkbox is checked or the input value is changed manually.
I need some help in integrating the correct input value into my calculation.
Checkbox:
let yes = false;
<input type=checkbox bind:checked={yes} >
Input:
<input value={yes? item.Fdosevalue : item.dosevalue} step={item.dosestep}
min={yes ? item.Fdosemin : item.dosemin} max={yes ? item.Fdosemax : item.dosemax} >
Calculation:
Not sure how to integrate the checkbox change in this calculation.
<span bind:this={k}> {( (k * item.dosevalue)).toFixed(1)} {item.appendvol} </span>
Here is a REPL which will hopefully make it a bit clearer

You can use data binding to accomplish this:
<input bind:value={...} />
You'll just need a place to store the values:
let values = {}
And then you bind to values with a unique key.
<input bind:value={values[item.name]}/>
Make sure to initialize the values dictionary with a default values for each fluid anytime the checkbox changes:
<input type=checkbox bind:value={yes} on:change={handleChange}/>
// initialize default values
function handleChange() {
const entries = fluids.map(item => {
const defaultValue = yes ? item.dosevalue : item.Fdosevalue
return [item.name, defaultValue]
})
values = Object.fromEntries(entries)
}

Related

MUI TextField format input to show numbers and decimals

I'm trying to format the value of the input of this MUI component to show a maximum of 3 numbers following with a maximum of 2 decimals separated by a dot, e.g. 233.99, I want to store this value in a react state called value (const [value, setValue] = useState(0)).
I'm having trouble since I see a lot of approachs to achieve this, but I find it complicated to also keep track if the user already entered the first 3 numbers and not let him enter more while also keeping tack of the decimal values too, since as I said, there should be a maximum of 2 decimals.
I tried regex functions, toFixed js function, and more, but I can't make this work smoothly.
If I understood this correctly, you can achieve this with:
let inp = document.getElementById("input");
inp.addEventListener("keypress", ev => {
ev.preventDefault();
if (!/\d|\./.test(ev.key)) return;
inp.value = /^\d{0,3}(\.\d{0,2})?$/.test(inp.value + ev.key) ? inp.value + ev.key : inp.value;
// update state when value has changed
// if (inp.value != value) setValue(inp.value);
})
<input type="text" id="input">
Alternatively, you can use <input type="text" pattern="^\d{0,3}(\.\d{0,2})?$"> and input.checkValidity() to notify the user on submit.

How to show default values for text with onChange input?

I have an object that I'm passing to a state variable:
const values = [
value1:'value1',
value2:'value2',
value3:'value3',
value4:'value4'
]
const [inputValues,setInputValues] = useState(values)
I am able to modify these values as well as display them e.g:
<Text>{inputValues.value1}</Text>
<Input value={inputValues.value1} onChange={onChange} name={value1}/>
The problem is when I'm resetting the values in the input to empty strings it will reset in the text as well, leaving it blank while the input values are changed. I currently have other state variables that will display the values separately for the text, but I don't see the point since I now have two values that does the same thing:
const [value1, setValue1] = useState()
How can I modify the input values without affecting the text fields?
You can't modify the inputValues without affecting the text fields, because both values are using the same variable, you are using the same state.
...
This would be an option if your Text were to show the default value only
const values = [
value1:'value1',
value2:'value2',
value3:'value3',
value4:'value4'
]
const [inputValues,setInputValues] = useState(values)
...
//this should be taken from your values, to be static. or from another state
<Text>{values.value1}</Text>
<Input value={inputValues.value1} onChange={onChange} name={value1}/>

How to update number from an input

I am implementing a basic web app in React and I am trying to update an integer from a number type input.
The process is fairly easy but I cannot figure out how to update regarding this process,
let's say we have this hook,
const [fee, setFee] = useState(2); // default value of fee should be 2
handlerFunc() {
// ...
}
<input type="number" onChange={handerFunc} /> which should update the fee
and this <p>Fee is{fee}$</p> should increment one by one after every 500 number is entered in that number type input.
1 for the additional 500 number in the input => 3 fee.
note: The fee should stay 2 until the input number reaches 1999 and for every additional 500 types in the input, the fee should also increment by 1.
How can I implement this handler function regarding this?
Please help.
I've not tried directly if this works as expected but the logic should be this way:
Keep the fee state in synch with the input.
<input type="number" onChange={e => setFee(parseInt(e.target.value,10))} value={fee} />
then store a value in a userRef.
const calculatedFee = useRef(0);
Use useEffect to implement your logic when the fee state change:
useEffect(() => {
if(fee === 500){ // or whatever condition you need
calculatedFee.current = 500 // or a calculated amount.
}
}, [fee]);
display the calculatedFees using the ref value;
<p>{calculatedFee.current}</p>
here is a full example: https://codesandbox.io/s/laughing-star-u4o9x?file=/src/App.js

How to use Group by query in laravel?

this is how the data is displayed but i want
Rhugveda desai -> flowers,Sarees,Prasad
In my application i need to use group by clause . But i am getting a syntax error.Also, What should i do if i want quantity column to be multiplied by amount to get the total? My tables are inkind and inkind_items, where inkind.id is foreign key in inkind_items table as inkind_id.
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #11
of SELECT list is not in GROUP BY clause and contains nonaggregated
column
my inkind_items tabel is inkind_items
my inkind table is inkind
My query is:
$inkinds = DB::table('inkind')
->join('inkind_items', 'inkind.id', '=', 'inkind_items.inkind_id')
->select('inkind.*', 'inkind_items.*')
->groupBy('inkind_items.inkind_id')
->get();
Try using group_concat()
$inkinds = DB::table('inkind')
->join('inkind_items', 'inkind.id', '=', 'inkind_items.inkind_id')
->select('inkind.*', DB::raw('group_concat(inkind_items.name) as items'))
->groupBy('inkind_items.inkind_id')
->get();
Here I'm assuming inkind have field name and inkind_items has fields items.
You can use Laravel collection methods for that.
Just call:
$inkinds->groupBy('inkind_id');
after ->get(). Considering that inkind_id is unique column for both tables
Hi. You asked another question earlier today (about displaying an input when a particular checkbox is checked) but deleted it before I submitted my answer, so I thought I would paste the answer here instead:
Just to get you started, here is an explanation of how to use
addEventListener and createElement to achieve your desired result.
If any part of it is still unclear after studying the code and the
accompanying comments, please search for the name of the still-unclear function on
MDN.
(For example, https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName.)
// Sets `box1` to refer to the first element on the page with the class "box".
const box1 = document.getElementsByClassName("box")[0];
// Sets `container` to be the element whose id attribute has the value "container".
// (This is where our new input element, inside a new label element, will be added.)
const container = document.getElementById("container");
// Begins listening for clicks. From now on, whenever the user clicks anywhere
// on the page, our listener will call the `noticeClick` function.
document.addEventListener("click", noticeClick);
function noticeClick(event){
// Because this function's name is the second argument in
// the call to `document.addEventListener`, above, it is
// automatically called every time a 'click' event happens on the
// page (and it automatically receives that event as an argument.)
// The "target" of the event is whatever the user clicked on.
// So we set the variable `targ` to refer to this target, and we check whether:
// 1) the clicked target is our checkbox,
// 2) this click caused the checkbox to gain the "checked" attribute, and
// 3) we have not already given the checkbox the "added" class
const targ = event.target;
if(targ.id == "box1" && targ.checked && !targ.classList.contains("added")){
// If all three conditions are met, we...
// ...set two variables, `label` and `val`
const label = event.target.id;
const val = event.target.value;
// ...call the `createInput` function, passing these variables as its two arguments
createInput(label, val);
// ...give the checkbox the "added" class (so we can avoid accidentally adding it again)
targ.classList.add("added");
}
}
function createInput(newLabel, newValue){
// When the user has checked our checkbox, the `noticeClick` function
// will call this function, which receives two arguments (which we can
// see, by examining the `noticeClick` function, are two strings: the
// `id` attribute of box1 and the `value` attribute of box1.)
// We use `document.creatElement` to create an `input` element and a
// `label` element, and `document.createTextNode` to set some text
// to be used in the label (using the "newLabel" argument.)
const myInput = document.createElement("input");
const myLabel = document.createElement("label");
const myLabelText = document.createTextNode(newLabel + " ");
// We set our new `input` element's value using the "newValue" argument.
myInput.value = newValue;
// We use `appendChild` to put both the text and the input element
// inside the label, and to put the label inside `container`.
myLabel.appendChild(myLabelText);
myLabel.appendChild(myInput);
container.appendChild(myLabel);
}
// This process can be applied to multiple checkboxes on the same page
// by adding a loop inside the `noticeClick` function, where the string
// "box1" should be replaced with a variable that can refer to the id of a
// different checkbox's `id` for each iteration of the loop.
<label>
<input type="checkbox" id="box1" class="box" value="value1" />
Label for box1
</label>
<hr />
<div id="container"></div>

updating ng-model from ng-value directive

I have a situation where I have couple of readonly fields in the form like with others to show the problem
You can see the las two inputs are readonly and they are calculated inputs where total debit is calculated by totalDebit function on $scope and total credit is calculated by totalCredit() function on the $scope. The problem is inputs only reflect ng-model values which is zero for both inputs and does not take value from calculating functions. A simplified controller is
app.controller('myController', ['$scope' ,function($scope){
$scope.credit = 0;
$scope.debit = 0;
$scope.debitSum = 0;
$scope.creditSum = 0;
$scope.totalCredit = function(){
return $scope.credit + 200; //just to show that it is calculated field
}
$scope.totalDebit = function(){
return $scope.debit + 200; //just to show that it is calculated field
}
}]);
If you remove ng-model directive from readonly inputs they will assume their values from totalDebit and totalCredit functions respectively. But I want them to use values from functions and also update $scope properties of totalDebit and totalCredit. Here is the plunker for this code
Should not be answer here (Why the ng-value is not doing what expected):
ngValue
Binds the given expression to the value of <option> or input[radio], so that when the element is selected, the ngModel of that element is set to the bound value.
And that is not our case...
Because, the ngValue is triggered on CHANGE. When we select radio or some option in the <select>
So, ng-value is not the proper setting in this scenario.
We can adjust it like this:
<input name="totalDebit" value="{{totalDebit()}}" readonly="" />
<input name="totalCredit" value="{{totalCredit()}}" readonly="" />
See updated plunker

Resources