Hi, First I am a beginner that has started a project for advanced coders. I was able to receive help and with that I almost finished my project.
To complete, I first need to finish this invoice system. The New Invoice page needs a few details done:
1. New Invoice No need to be changed to autovalue.
2. All prices need to be shown with $
3. Sum prices, tax and total amount
4. Attracting customers from the customers collection and save in the invoices.
live: https://hortiray.wixsite.com/database/fguy48-uop9l2arwq3
1) the invoiceNo number field refering to Invoices Collection number field invoiceNo need to be set to autovalue counting from 0001 to 9999. Currently it has code but line 8-11(in bold) has error: wrong spot and no function.
2)$: The existing code is not working but has worked on other pages before. Might be a different problem?
3) No code yet, I would like:
priceInput1 + priceInput2 + priceInput3 = subtotal % tax (input20)= taxamount
subtotal + taxamount = totalPriceInput
(Important that priceInput1 and priceinput2 can stay empty)
4) Existing Customer Dropdown: dropdown1 connecting to the address, suburb, state, postcode, country inputs and resetDropdownsButton
90% of the code I re-used from previous questions/mini-tutorials:
https://www.wix.com/code/home/forum/community-discussion/wix-data-dropdown-multiple-collections-and-repeater and https://www.wix.com/code/home/forum/community-discussion/dropdown-and-database
I am not sure if it works since I have an error in the code but I foresee some issues.
import wixData from 'wix-data';
$w.onReady(function () {
uniqueDropDown1();
$w('#dropdown1').onChange(dropdownHasChanged);
$w('#resetDropdownsButton').onClick(resetDropdownsButton_clicked);
});
let newInvoiceNo = await getNewInvoiceNumber();
if (!newInvoiceNo) {newInvoiceNo = 0;}
$w("#invoiceNo").text = newInvoiceNo;;
export function priceInput1_change(event, $w) {
let num = parseFloat($w("#priceInput1").value)
$w("#priceInput1").value = '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}
export function priceInput2_change(event, $w) {
let num = parseFloat($w("#priceInput2").value)
$w("#priceInput2").value = '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}
export function priceInput3_change(event, $w) {
let num = parseFloat($w("#priceInput3").value)
$w("#priceInput3").value = '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}
export function subtotal_change(event, $w) {
let num = parseFloat($w("#subtotal").value)
$w("#subtotal").value = '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}
export function taxamount_change(event, $w) {
let num = parseFloat($w("#taxamount").value)
$w("#taxamount").value = '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}
export function totalPriceInput_change(event, $w) {
let num = parseFloat($w("#totalPriceInput").value)
$w("#totalPriceInput").value = '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}
export function getNewInvoiceNo() {
return wixData.query("Invoices")
.descending("_createdDate")
.limit(1)
.find()
.then((results => {
let lastAddedItem = results.items[0];
let lastInvoiceNo = lastAddedItem.invoiceNo;
let newInvoiceNo = lastInvoiceNo++;
return newInvoiceNo;
})
}
function resetDropdownsButton_clicked(event) {
$w('#dropdown1').selectedIndex = undefined;
$w('#dropdown1').resetValidityIndication();
$w('#adressInput').value = undefined;
$w('#suburbInput').value = undefined;
$w('#stateInput').value = undefined;
$w('#postcodeInput').value = undefined;
$w('#countryInput').value = undefined;
dropdownHasChanged();
}
function uniqueDropDown1() {
wixData.query("Customers")
.limit(1000)
.find()
.then(results => {
const uniqueTitles = getUniqueTitles(results.items, 'customerName');
$w("#dropdown1").options = buildOptions(uniqueTitles);
});
}
function getUniqueTitles(items, columnKey) {
const titlesOnly = items.map(item => item[columnKey]);
let result = [];
let uniqueSet = new Set(titlesOnly);
let setIterator = uniqueSet.entries();
for (let entry of setIterator) {
let entryValue = entry[0];
if (entryValue) {
result.push(entryValue);
}
}
return result;
}
function buildOptions(uniqueList) {
return uniqueList.map(curr => {
return { label: curr, value: curr };
});
}
function dropdownHasChanged(event) {
let datasetFilter = wixData.filter();
let dropdownValue = "NoCustomerSelected";
if ($w('#dropdown1').selectedIndex >= 0 ) {
dropdownValue = $w('#dropdown1').value;
datasetFilter = datasetFilter.eq('customerName', dropdownValue);
}
$w('#dataset2').setFilter(datasetFilter)
.then(() => {
return $w('#dataset2').refresh();
})
.then(() => {
return wixData.query("Customers") // Make sure this is the correct name
.eq("customerName", dropdownValue)
.find();
})
.then((result) => {
if (result.length !== 1) {
throw Error("Internal Error? Customer record look up for " +
dropdownValue + " returned " +
result.length.toString() + "records");
}
let CustomerRecord = result.items[0];
$w('#adressInput').value = customerRecord.cycle;
$w('#suburbInput').value = customerRecord.cycle;
$w('#stateInput').value = customerRecord.cycle;
$w('#postcodeInput').value = customerRecord.cycle;
$w('#countryInput').value = customerRecord.cycle;
})
.catch((error) => {
// If we get here we have encountered an error so console.log() it for now
console.log(error.message);
});
}
Any assistance would be highly appreciated!
[@hortiray] Try using console.log() to print out the values you are getting for the various variables being calculated. It’s likely that the taxRate substring is not returning a number that can be parsed by parseFloat. I cannot help you debug line at a time without knowing what error you are getting. It is important that you spend time understanding the functions being called, what they take as parameters and what they return as results. Then check using console.log, or the browser debugger, what values are being given to a function, and what results are being returned. Get to know the MDN javascript resources https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference as well as the Wix code resources to help you. You can also get lots of good help on the w3schools javascript website. https://www.w3schools.com/js/default.asp Cheers Steve
Hi Raymond So Error #1 this is concatenation go two strings. So there needs to be a + character between the string and the string variable - change name:”element to name:”+element Error #2: if the variable taxRate has already been declared using let. The second declaration will fail because taxRate already exists. Simply delete the word ‘let’ in the second declaration :-) Steve
Hi Roi the page is https://hortiray.wixsite.com/database/fguy48-uop9l2arwq3.
@hortiray Can I suggest that you do a couple of things that might help you solve this and help the rest of us help you too :-)
1. Try writing your code so that it describes the use case you are trying to implement. What I mean by this is use function names that describe what you expect the outcome of the function to be and/or add comments to help describe this.
Put comment section before each of your functions in the code. Use it to describe what the function does and what it returns (if anything) when the function exits (e.g. on success the function returns a sorted array, on failure the function throws an exception reporting one of these errors:...).
Add other comments, for example at the start of the page, which describes how you see (your use case) the functions being used. For example:
/*************** Page Name: "name of the page" Usage: This page is loaded when <event> occurs on the site. The page is dynamic and so it is expected that the key record ID is available from the dynamicDataset currentRecord. Most elements on this page are set automatically from the dataset through Wix Editor bindings except the totals element named $w("#totals") and the average element $w('#average') which are calculated in the onReady handler. When the page is loaded the onReady function is used to initialize data that needs to be calculated from ... ***************/
2. Try to use console.log() statements at critical points where the value of your variables or arguments might be null or undefined. In these cases you may find problems due to bad values and you may need to add defensive condition testing to make sure you don't try to process these bad values. When you find a bad value you can then back track through your code to find out how the bad value occurred. I like to add log statements that reflect the function calls
function logMessage(message) { // Note the use of conditional telling me if the argument I // received is null or not console.log('logMessage('+(message?message:'null!')+')'); }
3. Add function stubs for planned functions, that do nothing, but can show how you intend to extend your code. For example
// The following function does ... function calcAvg(numberList) { console.log('TEMP TO BE WRITTEN: calcAvg called'); }
This may seem like a lot of work but it is work that you really need to do when designing your code anyway. This also helps when others try to read your code and reverse engineer it. As you do this you often have an AHHHH! moment where you see where you have an error because you have described what your function does and you realize it isn't doing that :-).
You have a lot of code as Andreas said above and the more code you have without comments the harder it becomes to understand where a problem (other than a syntax error) might be occurring. Additional data, such as info from console logs helps here.
Cheers
Steve
Hey man!
This is a more complex post so I will try to help you with some of it.
You can't have code living alone in your page code like you have with the invoice number stuff. You will need to include it inside the page onReady.
$w.onReady(function () { uniqueDropDown1(); let newInvoiceNo = await getNewInvoiceNumber(); if (!newInvoiceNo) {newInvoiceNo = 0;} $w("#invoiceNo").text = newInvoiceNo;; });
I would also recommend you when adding event handlers in Wix Code that you click the element on your page, like the dropdown and then you go to the properties panel on the right and choose under events onChange and click the + icon and it will create a stand alone function for that event handler.