Javascript: Validating if form entries are already submitted to proceed - javascript

so I´m working with this: A form where user(workID and name) submits a claim with a date, positioID=secuence. User may have more than 1 secuence and claims are done with one or more dates. So a user may have a claim for 6/7/2017 and secuence=22. Also user may submit a claim with same date (6/7/2017) with secuence=9. User may even submit 2 diferent dates, with different secuences.
Need to validate if user has already submitted a claim for a Date, and secuence. So claims are not duplicated and an alert is triggered if it is already claimed.
To work this out: I´m doing a table/matrix where each secuence is assigned to a date already submitted. The objective is to get many date objects with each assigned secuence. So next entry is compared.
So first step:
claimList.get({workID: $rootScope.workID}, function(response) {
listByDate = [];
var validateList = response.body;
validateList.forEach(function(response){
listByDate.push({
key1: 'date',
key2: 'Secuence',
value1: response.date,
value2: response.secuence
});
}
BUilding this matrix is quite difficult
next step would be a foreach and conditional.

I will assume that data you're trying to store in is inside an object:
data = { date: x, sequence: y }
and data that you have already stored is inside an Array called dataList;
You should just check dataList for those values, if you can't find them it means you're safe and you can proceed by publishing a different and unique entry.
You should code something like the following
var occupiedSlot = dataList.find(
function(elementOfDataList) {
return elementOfDataList.date === data.date
}
);
if(occupiedSlot) alert('You've already published an entry for this date!');
If you need to publish more entries, you can repeat this script inside a function for every entry that you need to check.

Related

How to output the firebase snapshot in reverse order?

I am trying to get the latest 3 data from the database and display them in reverse order in the HTML page.
Code:
var refForevent = database.ref('/events/post');
refForevent.orderByChild("intro").limitToLast(3).on('child_added', function(snapshot){
var eventlist = []
eventlist.push(snapshot)
console.log(eventlist)
eventlist.reverse()
document.getElementById("event1date").innerHTML = moment(eventlist[0].intro).format("MMM Do YYYY");
document.getElementById("event1title").innerHTML = eventlist[0].title;
document.getElementById("event2date").innerHTML = moment(eventlist[1].intro).format("MMM Do YYYY");
document.getElementById("event2title").innerHTML = eventlist[1].title;
document.getElementById("event3date").innerHTML = moment(eventlist[1].intro).format("MMM Do YYYY");
document.getElementById("event3title").innerHTML = eventlist[1].title;
})
Output: Output that I am getting
Database:
I see that the field intro contains a date.
Here is one solution:
Take the value of this field
Remove the hyphen separators (e.g. from 2020-12-10 you get the number 20201210)
Multiply this number by -1
Store the resulting value in another field
Sort on this field
Alternatively (and more elegant...), use the date to create a Timestamp, multiply it by -1 and use it as explained above, i.e. store the resulting value in another field and sort on this field.
Since you're listening to the child_added event, your function gets called with each post node that matches the query in the order in which Firebase returns them. So your eventlist will only ever contain one node at a time.
To reverse the items, you can either get Firebase to return the values in reverse order, as Renaud suggest (I'll also link some answers below), or you can listen to all results in once go and then reversing client-side (as your code already seem to be trying). The latter would look something like:
var refForevent = database.ref('/events/post');
refForevent.orderByChild("date").limitToLast(3).on('value', function(results){
var eventlist = []
results.forEach(function(snapshot) {
eventlist.push(snapshot.val())
});
eventlist.reverse()
console.log(eventlist);
...
})
So this:
Listens to the value event, instead of child_added, so that it gets all matching child nodes in one go.
If then loops over the results, adding them to the array,
It calls .val() on each child snapshot, to get the value from it.
For more on descending sorting, also see:
Display posts in descending posted order (the oldest I could find describing the trick with negative values)
firebase -> date order reverse (with many more links from there)
Sorting in descending order in Firebase database

Storing multiple data entries into a javascript object?

In my program I have to prompt the user to enter customer info.
The information includes first name, last name, phone number, and grocery items (separate each array by a comma).
The prompt keeps asking user for info until user presses cancel or enters nothing.
ex:
peter,pho,123-324-2333, beans,carots,cereal
karen,smite,122-333-1223, milk,pudding
Each time the user enters input, I need to create an object to store the info, and each object needs a property grocery item. So I assume it goes something like this.
cust = prompt("enter customer info");
while(cust != null){
var array1 = cust.split(',');
var customer = {
custinfo:array1.slice(0,3),
items:array1.slice(3,array1.length)
}
cust = prompt("enter");
}
This works for the first customer, but how do I store many entries, I don't know how much customers the user will enter. I tried creating an array of objects, if that makes any sense , like customer[], but it didn't work.I split them into arrays for later use in my homework. Also how do I make the prompt run until user enters nothing?
If you want an ordered list of items, use an Array. You can combine this with a for loop. Here is an example
function ask_questions(questions) {
var answers = [],
i,
ans;
for (i = 0; i < questions.length; ++i) { // for infinite loop, `while (true) {`
ans = prompt(questions[i] || 'enter'); // default question
if (!ans) break; // cancel or blank ends questioning
answers[i] = ans; // do what you want with the data given
}
return answers;
}
The function ask_questions takes an Array (say arr) and prompts the user arr.length times, then returns the results of the prompts as another Array
var qs = ['enter customer info', null, 'enter2']; // null will cause message "enter"
qs.length = 4; // undefined will cause message "enter"
ask_questions(qs); // ["foo", "bar", "baz", "fizz"]
However, is this really the best data structure for you? You may do better with an Object which has useful property names rather than indices and ask them for specific pieces of data such as their name and address rather than leaving it up to them. If you leave it all up to them you could end up with their pet's life story and their favourite colour etc or even nothing at all.
Finally, prompt isn't a good UX, use <input> or <textarea>s in your final revision

CRM 2011 Bulk Edit form : how to update some of the form fields with different values for each record record?

Currently I am dealing with a problem while using bulk edit functionality. I am trying to achieve the below. I also have given the code below.
On the bulk edit form , select values from the 2 option sets.
On the change event of the value2 , it calls a javascript function.
In the function,I am fetching all the records selected for bulk edit ,using window.dialogArguments, into a variable.
Now in the for loop, I fetch the records one by one and then for each record I do the following:
a. For each record, using both optionset values seleted and some more values from the current record data, it checks conditions and decides the set of final values to be set.
b. It tries to set these final values for some (let say 5 ) of the fields available on the bulk edit form, for that particular record using OData update.
It is executing the loop, fetching the records, assigning it to the entity object, executing OData call and updating the values selected in step 1 (i.e. optionset values) , which are same for all the records.
For those 5 fields it should set the values as per the conditions and final value set retrieved from step b.
Instead of that, it is setting 5 field values for all records equivalent to the values retrieved from the step b , for the last record.
What I am suspecting is, at the end just before closing the bulk edit form, it is over-writing those 5 fields values for all the records with same values ( which is by deafult functionality of the bulk edit, I understand).
How I can prevent this last overwriting of the data values and keep the values I updated using OData previously?
I am kind of stuck with this now. Any help is really appreciated.
Below is the sample code :
if (Xrm.Page.ui.getFormType() == 6) {
var records = window.dialogArguments;
for(i=0; i<records.length;i++){
// oDataEndpointUrl Fetch
var requestResultsOpp= fetchData(...);
var optionset1 = Xrm.Page.getAttribute("optionset1").getValue();
var optionset2 = Xrm.Page.getAttribute("optionset2").getValue();
if (requestResultsOpp != null) {
var case_value = requestResultsOpp.field;
var entityObject = new Object();
/* Check values from optionset and perform some condition checks */
if (some condition ) {
switch (case_value) {
case 3 /* XYZ */:
case 4 /* ABCD */:
case 5 /* PQR */:
if (optionset1 == 1 && optionset2 == 11)
Set the 5 fields values
if (optionset1 == 1 && optionset2 == 12 )
Set the 5 fields values
break;
default:
if (optionset1 == 2 && optionset2 == 12 )
Set the 5 fields values
break;
}
}
entityObject.optionset1 = {Value: optionset1};
entityObject.optionset2 = {Value: optionset2};
entityObject.Field1 = {Value: field1};
entityObject.Field2 = {Value: field2};
entityObject.Field3 = {Value: field3};
entityObject.Field4 = {Value: field4};
entityObject.Field5 = {Value: field5};
// oDataEndpointUrl update
updateRecordSync("entityName", record[i] , entityObject);
}
}
}
The short answer is no, you can execute javascript on a bulk edit form (OData assumes javascript in CRM). The good news is that you can execute exactly that logic within a plugin, which will execute as expected for a bulk edit. Within plugins, you can use pre and post entity images to compare before and after values, so you have a huge amount of flexibility as to what logic you want to perform.
Your question is a bit confusing as to the final desired result, but if you want to roll back the transaction (not update the values), then you can throw an InvalidPluginExecutionException for whichever records you don't want to update, or just let the execution complete to allow the update to persist.

Taffydb dynamic like 'and' query

I recently started working with taffydb. Assuming I have this as my data
db= TAFFY([
{OrderNo:'prod1',range: 3,description:'one two'},
{OrderNo:'prod2',range: 2,description:'one two three'},
{OrderNo:'prod3',range: 2,description:'one three two'},
{OrderNo:'prod4',range: 6,description:'one two four three'},
{OrderNo:'prod5',range: 5,description:'three'},...
if I wanted to write a query to find all records with "one two" and "three" I'd do something like
db({description:{likenocase:"one two"}},{description:{likenocase:"three"}}).get()
this would return products 2 and 4. Unfortunately I can't figure out how to do this with a dynamic query that will have an unknown number of variables to search for. I'm doing this to let the user search for their own supplied words.
Anyone got any ideas?
As a precursor, this will not be the best answer to your problem. But it will work. :)
So the user will have the option of searching a database with an "unknown number of variables". Let's add a maximum amount of variables--perhaps 10?
Now we catch all the user's search variables in an array:
// Create a dynamic array
var userSearchVars = [];
// Fill the array from 10 HTML input type=text fields
// You can fill your array however you fancy. This is just one example!
$("#myForm input[type=text]").each(function() {
userSearchVars.push( $(this).val());
}
// Note: by default an empty input will return the empty string: ""
Using your code snippet, just query the database with the array:
db(
{description:{likenocase:userSearchVars[0]}},
{description:{likenocase:userSearchVars[1]}},
{description:{likenocase:userSearchVars[2]}},
{description:{likenocase:userSearchVars[3]}},
{description:{likenocase:userSearchVars[4]}},
{description:{likenocase:userSearchVars[5]}},
{description:{likenocase:userSearchVars[6]}},
{description:{likenocase:userSearchVars[7]}},
{description:{likenocase:userSearchVars[8]}},
{description:{likenocase:userSearchVars[9]}}
).get()
Adapting #Jacob-IT's answer so that its dynamic. Used Taffy for the first time tonight and just discovered you can pass an array of objects as the query argument.
// Create a dynamic array
var userSearchVars = [];
// Fill the array from 10 HTML input type=text fields
// You can fill your array however you fancy. This is just one example!
$("#myForm input[type=text]").each(function() {
// This is my edit - push the whole query on to the array.
userSearchVars.push({description:{likenocase: $(this).val() }});
}
// Then pass the whole query array in...
db( userSearchVars ).get()
Tested the above - and it worked for me.
You can do it like this
let items = [];
items.push({description:{likenocase:"one two"}});
items.push({description:{likenocase:"three"}});
db(...items).get()

How to change result position based off parameter in a mongodb / mongoose query?

So I am using mongoose and node.js to access a mongodb database. I want to bump up each result based on a number (they are ordered by date created if none are bumped up). For example:
{ name: 'A',
bump: 0 },
{ name: 'B',
bump: 0 },
{ name: 'C',
bump: 2 },
{ name: 'D',
bump: 1 }
would be retreived in the order: C, A, D, B. How can this be accomplished (without iterating through every entry in the database)?
Try something like this. Store a counter tracking the total # of threads, let's call it thread_count, initially set to 0, so have a document somewhere that looks like {thread_count:0}.
Every time a new thread is created, first call findAndModify() using {$inc : {thread_count:1}} as the modifier - i.e., increment the counter by 1 and return its new value.
Then when you insert the new thread, use the new value for the counter as the value for a field in its document, let's call it post_order.
So each document you insert has a value 1 greater each time. For example, the first 3 documents you insert would look like this:
{name:'foo', post_order:1, created_at:... } // value of thread_count is at 1
{name:'bar', post_order:2, created_at:... } // value of thread_count is at 2
{name:'baz', post_order:3, created_at:... } // value of thread_count is at 3
etc.
So effectively, you can query and order by post_order as ASCENDING, and it will return them in the order of oldest to newest (or DESCENDING for newest to oldest).
Then to "bump" a thread in its sorting order when it gets upvoted, you can call update() on the document with {$inc:{post_order:1}}. This will advance it by 1 in the order of result sorting. If two threads have the same value for post_order, created_at will differentiate which one comes first. So you will sort by post_order, created_at.
You will want to have an index on post_order and created_at.
Let's guess your code is the variable response (which is an array), then I would do:
response.sort(function(obj1, obj2){
return obj2.bump - obj1.bump;
});
or if you want to also take in mind name order:
response.sort(function(obj1, obj2){
var diff = obj2.bump - obj1.bump;
var nameDiff = (obj2.name > obj1.name)?-1:((obj2.name < obj1.name)?1:0);
return (diff == 0) ? nameDiff : diff;
});
Not a pleasant answer, but the solution you request is unrealistic. Here's my suggestion:
Add an OrderPosition property to your object instead of Bump.
Think of "bumping" as an event. It is best represented as an event-handler function. When an item gets "bumped" by whatever trigger in your business logic, the collection of items needs to be adjusted.
var currentOrder = this.OrderPosition
this.OrderPosition = currentOrder - bump; // moves your object up the list
// write a foreach loop here, iterating every item AFTER the items unadjusted
// order, +1 to move them all down the list one notch.
This does require iterating through many items, and I know you are trying to prevent that, but I do not think there is any other way to safely ensure the integrity of your item ordering - especially when relative to other pulled collections that occur later down the road.
I don't think a purely query-based solution is possible with your document schema (I assume you have createdDate and bump fields). Instead, I suggest a single field called sortorder to keep track of your desired retrieval order:
sortorder is initially the creation timestamp. If there are no "bumps", sorting by this field gives the correct order.
If there is a "bump," the sortorder is invalidated. So simply correct the sortorder values: each time a "bump" occurs swap the sortorder fields of the bumped document and the document directly ahead of it. This literally "bumps" the document up in the sort order.
When querying, sort by sortorder.
You can remove fields bump and createdDate if they are not used elsewhere.
As an aside, most social sites don't directly manipulate a post's display position based on its number of votes (or "bumps"). Instead, the number of votes is used to calculate a score. Then the posts are sorted and displayed by this score. In your case, you should combine createdDate and bumps into a single score that can be sorted in a query.
This site (StackOverflow.com) had a related meta discussion about how to determine "hot" questions. I think there was even a competition to come up with a new formula. The meta question also shared the formulas used by two other popular social news sites: Y Combinator Hacker News and Reddit.

Categories

Resources