Hi, I want to post data in a repeater manually so that I can have chance to approve or reject the data before is published live. This data is being collected in a form and submitted to the database collection and then displayed in a repeater on another page. I want to prevent this automatic functionality and do it manually when I consider it appropriate(approving and rejecting data). I appreciate any help, kind regards. Thank you.
Instead of connecting your Repeater to a dataset, you can manually query the database, and then set the Repeater data . Since this is manual, you have control over when you set the Repeater’s data. You will also need to handle the Repeater items manually, so you will need to include an onItemReady() handler.
I hope this helps,
Yisrael
Hi Yisrael thank you a lot for your help I appreciate it. The problem is that sometimes I can have 10 or 20 requests from all the clients that submitted data to the live database. The repeater is a directory web app so it must display data from the database all the time. These 10 - 20 requests have to be approved before can be displayed in the directory and very possible I wont have time to approve them all at once.
What I was thinking is to create 2 databases, a database where the submissions will be received but not posted to the directory and a second database that is posting automatically with a dataset to the directory. So if this works fine all I need to figure out is how to connect this first database with the second database to send data to the second database when I approve the data in the first database. I appreciate any suggestions and help on how to connect these 2 databases. Kind regards.
Hi Scene -
Wanted to offer 2 possible ways to do what you are describing:
Option #1:
What you may be able to do is to have 2 separate Collections within 1 Database. Where the 2nd Collection is essentially a copy of the 1st Collection’s structure (i.e. same amount of fields). You would then only connect your Repeater to the 1st Collection to display the “approved” directory listings. You could then create a separate “Add Directory Listing” page. Where a user would submit the entry to the 2nd Collection. Then you have another, administrative screen that you review and approve/disapprove the submitted listings. When you approve the listings, it would copy the listing in Collection #2, to Collection #1 and delete the entry in Collection #2.
Option #2:
You could use the same Collection in the same Database, but add an extra “Boolean” field called say “Approved”. Then on your repeater that displays the Live and approved directory listings, you could apply a “Filter” to the Dataset whereby you only show records from that dataset in the repeater that had been approved. You would however need a separate “Admin” type screen whereby you could have a separate listing of all the newly submitted listings that have not been approved yet. On this second screen, you would add a Filter that would only display listings that were not approved yet.
I believe Option #2 will be the more straightforward way to implement. But it is up to you. Below the steps & some code that may help for Option #1.
Steps & Code for Option #1:
- Add a new Collection (i.e. named “DirectoryListingSubmitted”) with the same fields as Collection #1.
- Add a button to the current page where you have the Repeater displaying the Live/Approved directory listings. This button you could name “btnAddNewListing”.
- Add a new page, let’s say it is called “addDirectoryListing” (aka “add-directory-listing” is the Page listing URL in the Page’s SEO properties)
- On the new page, submit the Data to the “DirectoryListingSubmitted” Collection.
- Create another page that is a copy your current Directory Listing page. Add an “Approve” button to the repeater. Then add an “onClick” event to that button whereby you copy the data from the current item of the repeater to the live collection (say it is called “DirectoryListingLive”). Then delete the entry in the “DirectoryListingSubmitted”. Refresh the page.
CODE for “ADD NEW LISTING” Page
// For full API documentation, including code examples, visit Velo API Reference - Wix.com
import wixData from ‘wix-data’;
import wixLocation from ‘wix-location’;
$w.onReady( function () {
//TODO: write your page related code here…
});
export function btnSubmit_click(event, $w) {
//Add your code for this event here:
let toInsert = {
“company”: $w(‘#txtCompany’).value,
“address”: $w(‘#txtAddress’).value,
“phone”: $w(‘#txtPhone’).value,
“email”: $w(‘#txtEmail’).value
};
wixData.insert("DirectoryListingSubmitted", toInsert)
.then( (results) => {
let item = results; //see item below
wixLocation.to(“/directory-listing-submitted”);
} )
. catch ( (err) => {
console.log(err);
} );
}
CODE for “DIRECTORY LISTING SUBMITTED” Page
// For full API documentation, including code examples, visit Velo API Reference - Wix.com
import wixData from ‘wix-data’;
import wixLocation from ‘wix-location’;
$w.onReady( function () {
//TODO: write your page related code here…
});
export function btnApprove_click(event, $w) {
//Add your code for this event here:
let toInsert = {
“companyName”: $w(“#txtCompany”).text,
“address”: $w(“#txtAddress”).text,
“phone”: $w(“#txtPhone”).text,
“email”: $w(“#txtEmail”).text
};
console.log("company - "+ $w("#txtCompany").text);
console.log("address - "+ $w("#txtAddress").text);
console.log("phone - " + $w("#txtPhone").text);
console.log("email - "+ $w("#txtEmail").text);
wixData.insert("DirectoryListingLive", toInsert)
.then( (results) => {
let item = results; //see item below
wixData.remove("DirectoryListingSubmitted", event.context.itemId)
.then( (results2) => {
wixLocation.to("/directory-listing-live");
} )
. **catch** ( (err) => {
console.log(err);
} );
} )
. **catch** ( (err) => {
console.log(err);
} );
}
Hope this helps. Code is tested.
Nick
Hi Nick, I highly appreciate such a effort to help with this. Option 2 is brilliant! I had in mind to create option 1 very similar as you explained but Option 2 is definitely brilliant, it works very good. Thanks a lot have a good day.
Hi Scene - Glad Option 2 worked for you!
Best,
Nick
Hi Nick, there is only one thing that is causing my trouble with option 2, I’m using a user input element that I programmed to retrieve information from the database collection(a filter in the dataset that runs when a user input data in the user input element), as soon as I type the data of any unproved request(boolean field) that is in the database collection the data is displayed to the repeater so this boolean is working but my piece of code is removing the filter I’m thinking to use an if statement before the query something like if(wixData.approved == true){run the user input filter }else{load again the boolean filter “approved”} or something like that, but I’m not sure how to specify this approved field.
In other words my search functionality(below) resets the boolean filter and dataset stops filtering by this boolean so I need to prevent it some how.
My code is:
import wixData from ‘wix-data’;
// For full API documentation, including code examples, visit Velo API Reference - Wix.com
$w.onReady( function () {
//TODO: write your page related code here…
});
let debounceTimer;
export function iTitle_keyPress(event, $w) {
//Add your code for this event here:
if (debounceTimer){
clearTimeout(debounceTimer);
debounceTimer = undefined;
}
debounceTimer = setTimeout(() => {
filter($w(‘#inputusertitle’).value);
}, 200)
}
let lastFilterTitle;
function filter(title){
if (lastFilterTitle !== title){
$w(‘#dataset2’).setFilter(wixData.filter().contains(‘name’, title));
lastFilterTitle = title;
}
}
// this part uses the dropdown menu to filter by state
let debounceTimer2;
export function dropstates_change(event, $w) {
//Add your code for this event here:
if (debounceTimer2){
clearTimeout(debounceTimer2);
debounceTimer2 = undefined;
}
debounceTimer2 = setTimeout(() => {
filterStates($w(‘#dropstates’).value);
},200)
}
let lastFilterTitle2;
function filterStates(statevalue){
if (lastFilterTitle2 !== statevalue){
$w(‘#dataset2’).setFilter(wixData.filter().contains(‘state’, statevalue));
lastFilterTitle2 = statevalue;
}
}
I appreciate any suggestions. Kind regards.
Hi Scene -
You’ll most likely want to add another condition to the Filter (you actually can have more than 1). Here is an example to try:
$w(‘#dataset2’).setFilter( wixData.filter()
.contains(‘name’, title)
.eq(‘myBoolField’, true)
);
Hopefully something like this works for you.
Best,
Nick
Hi Nick, eq() seems to work good. Thanks a lot I really appreciate it.
Great. Glad to hear.
Nick
Hi Nick, do you have any idea how can I add more search filters to the code that I share above, I tried eq() but eq() is a method and can not be used more than once for the same time I guess. I need to create a piece of code that can search on all the columns of the collection at the same time. I appreciate any suggestion.
Hi Scene - Have you tried the following?
$w(’ #dataset2 ').setFilter( wixData.filter()
.contains(‘name’, title)
.eq(‘myBoolField’, true)
.eq(‘myField2’, field2Value)
);
Note, not sure what the precise limitation on the number of clauses you can add to a new Filter. But the process of adding them is the same as the previous ones. You just have to remember to close the filter clauses inside of the " ); " - (i.e. ending parenthesis and semi-colon.)
Is this what you were looking for?
Hi Nick, I was actually trying exactly that, I had no errors in the grammar of the language. But if I add more than one eq() to the chain the total search functionality stops working. As soon as I delete the eq() everything start to work again. I’m also using http://jshint.com/ to make sure things are right with my syntax and grammar; Here is the piece of code for that part:
let lastFilterTitle;
function filter(title){
if(lastFilterTitle !== title){
$w('#dataset2').setFilter(wixData.filter().contains('name', title)
.eq('pendingapproval', true).eq('company', title).eq('address', title));
lastFilterTitle = title;
}
}
Thanks for everything!
Maybe try changing from “.eq” to “.contains” where you are using the title field .
As is, looks like title can exist anywhere in the ‘name’ field. While title must exist as an exact match in both the ‘company’ and ‘address’ fields.
let lastFilterTitle; function filter(title){ if (lastFilterTitle !== title){ $w(’ #dataset2 ').setFilter(wixData.filter(). contains (‘name’, title) .eq(‘pendingapproval’, true). contains (‘company’, title). contains (‘address’, title)); lastFilterTitle = title; } }
Hi Nick, I was trying that as well but it does the same, is not working with more than one contain(). Also I had a look to the database collection to make sure to use the right key values.
I appreciate your help, thanks a lot!!!
Hi Scene - Alright, maybe you can try the following code. Added a few “.or” clauses. Seems that without the “.or” clauses each “.contains” is, in essence, requiring that the “title” exist somewhere in each field.
Hopefully this will do the trick!
//---------------START OF CODE-----------------------//
let lastFilterTitle;
function filter(title){
if(lastFilterTitle !== title){
$w(‘#dataset2’).setFilter(wixData.filter()
.eq(‘pendingapproval’, true)
.or(
.contains(‘name’, title)
)
.or(
.contains(‘company’, title)
)
.or(
.contains(‘address’, title)
) );
lastFilterTitle = title;
}
}
Hi Nick I appreciate your effort. This is not working for me but I’m programming a workaround I just can not have a search functionality that finds values on different columns only one column at the time. I’m using a page with the typical wix input elements with 6 dropdown menus and I have been trying to pass 6 input values, one on each column so is 6 columns each one with a value so I have 6 columns and my search code can not search on all the 6 columns, but I can create a string with all the values and only 1 column, Doing this, I can use my base code to search for content inside the string.
I’ve been programming this, I already have a dataset that is sending the data from my input elements to the database collection.
And for each dropdown input element(I have 6 elements) I created a change value event so when the value changes trigger a function so I have 6 functions and also I have an empty array. I created another function that is called from each one of the 6 functions and push() the value of the dropdown menus into the empty array, then using an if statement I check when the array.length is smaller or equals to 6 I run toString() to transform it to string and when and then I send it to a textbox input element like this: $w(‘#textbox’).value = ‘my array transformed to string’; then my plan was that the user click the submit button and the dataset was going to send this string with the values from the dropdown menus to my database collection.
But is not sending the value from this: $w(‘#textbox’).value = ‘my array transformed to string’
All the other values are sent and stored in my database collection except the dropdown menus
I debugged the array and the string transformation with console.log and everything is looking good.
All I need to know how can I send this data to the collection when the submit button is clicked.
Perhaps is a JSON object? or something like that? which is not being accepted in the collection?
Or perhaps I’m not putting the data in the right property of the textbox or the right method?
Thanks a lot!!!
This is my code:
// For full API documentation, including code examples, visit http://wix.to/94BuAAs
$w.onReady(function () {
//TODO: write your page related code here...
});
// this list takes all the programs selected by user, that are going to the database
let list_programs = [];
/* this set of functions take the values from the dropdown menus and add them as parameters
to the functions that are going to be used with the array list_programs */
export function program1_change(event, $w) {
//Add your code for this event here:
programsPush($w('#program1').value);
}
export function program2_change(event, $w) {
//Add your code for this event here:
programsPush($w('#program2').value);
}
export function program3_change(event, $w) {
//Add your code for this event here:
programsPush($w('#program3').value);
}
export function program4_change(event, $w) {
//Add your code for this event here:
programsPush($w('#program4').value);
}
export function program5_change(event, $w) {
//Add your code for this event here:
programsPush($w('#program5').value);
}
export function program6_change(event, $w) {
//Add your code for this event here:
programsPush($w('#program6').value);
}
/* this function take parameters with the values of each drop down menu
and append it to the empty arrway list_programs */
function programsPush(programvalue){
list_programs.push(programvalue);
if(list_programs.length <= 6){ transformToString();}
}
// this function transform to string and send the info to the textbox
function transformToString(){
let programs_string = list_programs.toString();
$w('#textBox3').value = programs_string;
}
Hi Nick, I’ve solved everything using something like $w(‘#mysetdata’).setFieldValue(‘myfield’, string)
Thanks a lot for all your help and effort I really appreciate it.
Glad you got it working.