Ok, so I have a kind of weird problem that I need ideas on how to solve.
I have a vb.net web application that points to a sql database. There's a table with a primary key that is an auto-incremented integer.
When a user adds an object to this table, it doesn't currently check to see if the "First Name" and "Last Name" already exist in one of the datarows. The desired addition to the functionality is as follows:
1)When the user submits the form, check the table to see if such a record already exists.
1.1)If the record doesn't exist proceed with the insert.
2)If that record does exist, display a warning to the user that such a record exists
2.1)The warning should have two buttons, "Continue" and "Cancel"
2.1.1)If the user clicks "Continue" go ahead and add the duplicate record
2.1.2)If the user clicks "Cancel" stop the insert.
I'm still relatively new to web development (a little over a year of experience). I am looking for the "correct" way to do this. The aspect of this task that is making it hard for me is that I have to run the query, and then possibly display and alert (javascript probably). I'm not sure how to display an alert in the middle of the server side validation.
Any ideas or comments are appreciated!
Thanks!
If you wouldn't allow insertion of duplicates, you could just create unique index in your database. However, what you can do now is to get the count of records in the database, where firstname and lastname equals to inserted.
In case of normal SQL it would look like
SELECT COUNT(recordID) WHERE firstName = #firstName AND lastName = #lastName;
Or it could look even easier with Entity Framework. Anyway, your question was about "displaying alert in the middle of server side validation". Think about it differently. Think about it as about two checks.
Add another control to your input form, an invisible checkbox near the Submit button. It should contain the expression about user's agreement to insert duplicate record.
Once you detect, that record is duplicate, interrupt the validation, and make checkbox visible, but Submit button - disabled. When user checks the checkbox, Submit button should become visible again.
Now, since you are going through the same validation again, you have to take your checkbox into equation - if it is visible and checked, you don't have to check for record duplication anymore, and just submit the record. If you need to re-use that input form, don't forget to uncheck the checkbox and make it invisible once again.
What you want to do here is add a confirm parameter or something like that to your method, like this:
' This is just pseudocode; I'm guessing you can translate it to
' whatever web framework you're using
Sub InsertRecord(ByVal name() As String, Optional ByVal confirm As Boolean = False)
If DuplicateRecord(name) And Not confirm
' Here's where you would render the page with a confirmation dialog
RenderViewToRequestConfirmation()
Return
End
DoInsertRecord(name)
RenderViewAfterRecordInserted()
End
Then under normal circumstances, from your front end you would submit a request that would call this method without the confirm parameter. In the case of duplicate records, the server would render a response with a dialog requesting confirmation. If the user clicked 'Yes' (or whatever), then the front end would send the same request but this time with the necessary request params to set confirm to True.
In terms of web requests, this process might look like:
| Request Data | Response |
|------------------------------------------|------------------------|
| { "name": "M Webster" } | Page w/ confirm dialog |
| { "name": "M Webster", "confirm": true } | Success page |
The route that I went is a little confusing... even now that I have it working, but i'll explain it here in case it makes sense to someone else who can better explain it later.
I wrote a function in the code behind that calls the function that checks the database for a duplicate record, but I added these two lines of code above the function declaration:
<System.Web.Services.WebMethod()>
<System.Web.Script.Services.ScriptMethod()>
Then, I wrote a JavaScript function that grabs the value from the Textbox and passes the value to that function in the code behind. This is made possible by those two lines above the function declaration in the code behind and by using the PageMethods object. The actual call from the JavaScript would look like this:
PageMethods.FunctionName(parameter, function(returnValueFromOtherFunction){
....function stuff
});
Then I assigned the JavaScript function to the onBlur event in the Textbox.
Thanks for the help guys, but I think this is the best way to solve my problem.
Related
So i've been asked to remake some registration forms. The way its supposed to work is, that an interpreter chooses X amount of languages in the first select box. Then based on the selections of languages, the user must specify from which languages they can translate from/to.
I want to store this data in a key/value array, with the key being "LanguageFrom" and Value being another array, of "LanguagesTo". This is how i have solved this:
function btnTest() {
var fromArray = $('.freelancerLanguagesFrom').map(function() {
return $(this).val();
}).get();
var toArray = $('.freelancerLanguagesTo').map(function() {
return $(this).val();
}).get();
var tempArray = {};
tempArray[fromArray] = toArray;
}
This method is being called with an "onclick" function in the html part. The user should specify which languages he can translate to for each of the chosen languages in the first box,
I am aware that this probably isn't the ideal approach, but im still an inexperienced developer, and i'd love to hear your take on another approach.
Now comes my problem:
1) How do i make it so the array wont overwrite the existing array with each button click, and instead just add to the array?
2) How do i process this array on the server side (php), so that i can store the values in my database?
3) Is it possible to skip the flow where the user has to press the save(gem) button after each language he has chosen?
edit: Question 1 and 3 are now solved, my only problem is accessing the array i made in js, on the php side
1) tempArray exists only in the scope of the btnTest() function. Declare it outside (in the global scope), initialize it as {} and don't reset it every time you click the button. The way you get the fromArray variable may require some tweaking depending on whether the "from" list can accept a multiple selection or not.
2) Ajax may help. Create a php endpoint to receive the request and call it using ajax. You can work on the array using JSON. Send your data using JSON.stringify(tempArray) and read it using json_decode() in your php script, or simply set the request headers as "application/json" to have it done automatically for you.
3) I personally wouldn't automate this process. Let's say I have 4 languages, Italian, English, French and Chinese.
I have selected a desirable state of languages I can handle:
Italian -> English, French
But I also know how to translate French in Italian so I click, in the from list, French, and I get
French -> English
Which is an undesirable state, for me, because I don't know how to do that. Especially if I were to select many languages, I'd get, inbetween 2 states I want to save, an indefinite amount of states I don't want to save.
If you still want to do so, you need to move the even listener from the button to the list(s), with the onchange event.
I'd also suggest you do your event binding trough jQuery, if you aren't already.
Hope this helped.
I'm working on some functionality that sends out notification emails. There may or may not be a contact specified. So when I initially set up the mail merge, this is what I'm doing:
var template = nlapiCreateEmailMerger(_TEMPLATE_ID);
template.setEntity("customer", customerId);
if (!isEmpty(contactID)) {
template.setEntity("contact", contactID);
}
Because there may or may not be a contact specified, in my email template I have Freemarker in place to check to see if a contact is there. If so, it adds their first and last name. If not, it adds the "companyname" value from the customer record. This is what I have:
<#if contact.id?has_content>${contact.firstName} ${contact.lastName}<#else>${customer.companyName}</#if>
The issue that I'm having is that when a contact is added, it displays the contact name just fine. However, if no contact is added, the conditional statement fails completely. Nothing shows up at all, even if "companyname" has a value. I've tried the following, but the conditional statement always resolves to false:
<#if contact?has_content>${contact.firstName} ${contact.lastName}<#else>${customer.companyName}</#if>
I've tried seeing what's going on, and if I place all of the values outside of the conditional statement, I get values when I expect them, and blank space when I expect it. So I know there is no issue with the data itself, as far as I can tell.
I know I can get around this by creating two separate templates and picking the correct one in the script, but that becomes trouble when having to make changes and I'd prefer to only have one template to maintain.
So, I suppose the real question is, what is the appropriate value to use in the condition statement that works whether or not a contact record is added?
Ok, I had an epiphany and solved the issue. In hindsight, it was pretty obvious. Here's what I did.
I basically created a variable, and set it to be the "companyname" value. Then, if there was a contact, assign it the contact's name. Here's the code:
<#assign greeting = customer.companyName>
<#if contact.id?has_content><#assign greeting = contact.firstName + " " + contact.lastName></#if>
${greeting},<br />
I hope this helps someone else.
I have a series of various fields on a Dynamics CRM 2011 form. I'm using javascript to carry out various checks. One of these is setting particular fields to "required" to prevent the user saving the form until the field is assigned a value. (Making them mandatory)
Xrm.Page.data.entity.attributes.get("new_FieldA1").setRequiredLevel("required");
However, some of my fields are radio buttons. The above code doesn't seem to work correctly for these. I think a Yes/No selection of "No" is seen as null anyway. Which means if "No" is selected, I still get a message "You must provide a value for FieldA1".
Can anyone suggest a work around so "No" is allowed?
Thanks.
To check mandatory fields, (if particular fields are completed on the form) the user selects a radio button as the last option at the bottom of the form ("Mark this form as complete?") When Yes is selected, the following function carries out some basic checks:
function FormSaveAlert()
{
if (Xrm.Page.getAttribute("new_formcompleted").getValue() == true)
{
if (confirm("Are you sure this form is complete? \n Once saved, this form cannot be modified again.") == false)
{
Xrm.Page.getAttribute("new_formcompleted").setValue(false);
}
else
{
var HF1 = Xrm.Page.getAttribute("new_hf1field");
HF1.setRequiredLevel("required");
if (HF1.getValue()==null) {HF1.setValue(false);}
//Xrm.Page.data.entity.attributes.get("otherfield").setRequiredLevel("required");
}
}
}
If the form is marked as complete, and a certain field is required but contains null, a message appears preventing a save. Default message in Dynamics - "You must provide a value for HF1"
I did a test and I can replicate the issue, if I set a two options to null and after I select No, getValue function returns null instead of false.
(I used only Google Chrome, but because is a supported customization it must works for all browsers)
If inside your requirements is possible (shows No as default value), I suggest to enforce the default value by code as this example:
var fieldA1 = Xrm.Page.getAttribute("new_FieldA1");
fieldA1.setRequiredLevel("required");
if (fieldA1.getValue()==null) { fieldA1.setValue(false); }
A required field must have a value, but a bit field always has a value, so I would actually expect this to be seen as containing a value even when it appears not to.
Can you post the onChange code for x_formcompleted too, since that is what is triggering the error?
You have two fields here, and I can't quite see the logic of how they interact.
Surely you need only one, which if ticked asks them to confirm and if they change their mind it gets reset.
Also consider using an option set with values yes / no / null (there is a built-in global option set for this). Make Null ("unassigned") the default, and make the field required (not by script, just always in the field properties).
Ok. If you didnt spell a full name right, and only entered the lastname, and the there exist more users with that lastname, in the recipient field, the ajax call will return an error with
Who did you mean: Mami Fox Megan Fox Blabla Fox
Now, I would like to make so you can click on them, choose who you meant to send to.
To do this I cannot use confirm, as confirm only have OK/CANCEL.
So i got told to use jQuery BlockUI Plugin, or just making a div and show().
But how can I prepend the error in a div(i know this), show it(i know this), and then make so you are able to click on them, and receive a alert on click ('you have chosen Mami Fox').
As i cannot make an prepared div with the names in(as the name are suggested from the page ajax requested, sendPM.php), and so, I would like to know how to do this.
--
Firstly i guess i would need to make json variable for each name. e.g
name1 : 'Mami Fox', name2 : 'Megan Fox', name3: 'Blabla Fox'
So in the div you can then prepend the names in there(instead of one variable with all names including "Who did you mean"), and make them so when you click on them, it will say "You have chosen"+data.name1 (example, where data is callback function name from the ajax success)..
--Just a thought.
You're going to have to create a workflow that supports the process that you want. This means using a flowchart or something. You can't just code the solution, you have to design it. http://en.wikipedia.org/wiki/Workflow
So the user selects a last name, but more than one last name exists.
BRANCH WORKFLOW FROM "STANDARD"
Build a list of all possible choices.
Present the user with a dialog to choose the appropriate name from the given list.
User selects a name.
RESUME WORKFLOW TO "STANDARD"
I'm new here so please go easy on me. This is somewhat of a confusing situation. :)
I'm working on a search input in which a user enters a name of another user (or part of a name) in a search text box and then a list of users matching that search string is returned. The problem is that it is a bit slow when there are tens of thousands of users involved. Due to this slowness, when the user quickly enters a name into the search input, the screen will begin to flash search results for each key stroke (well after the user has already entered the search string in). It's like a severely delayed reaction.
For instance, if I enter in the name 'Wendy', the search results for the search string 'W' (the first character I entered) will not even be displayed yet. The search results for the letter 'W' will then be displayed, followed by 'We' and so on and so forth even though i've already typed the full name and just want to see the results for 'Wendy'.
What I want to do is only perform the search when the user has not entered anything for a certain period of time (i'm thinking two seconds). Otherwise, the word 'Searching' will be displayed. The code of the Javascript method is below. Just as a note, that code currently works for searching through the users, I just need to implement the delayed execution.
function updateSearchResults() {
if($F('searchString').length > 0){
Element.update($('searchResultsScrollBox'), '<h3>Searching...</h3>');
$('searching').style.display = 'block';
var url = '<c:url value='ajaxFrontGetUsers.html'/>';
var ajax = new Ajax.Updater({success: 'searchResults'}, url,
{method: 'post', parameters: $('searchForm').serialize(true)});
$('searching').style.display = 'none';
}
}
I hope this all makes sense. Thanks in advance for anyone that can help.
Try the following steps:
Every few milliseconds, check to see if the textbox has new data in it.
If the textbox has new text, execute your Ajax, and copy the text to a variable (for comparison in step 1).
If you want to improve performance from there, activate the timer whenever the user types something, and deactivate it when the Ajax call is made.
Hey, thanks for your answer.
I ended up setting 500 millisecond intervals in which a javascript function would continuously check to see if new characters were entered in the search string within that 500 millisecond time period. If they were, the search function would be called to search on the string the user had entered. Otherwise, it would wait another 500 milliseconds until the user had stopped typing. In the end, it's very similar to what you proposed.
Thanks again!
Or you could put an "onkeypress"event handler on the item that clears some global variable or cancels a timer to keep the AJAX event from firing. I know Prototype implements this for you via it's in-place editor and the "frequency" option. (I believe it sets a timeout timer that it cancels after every key press.)
I know this is an old question, but for others taking a look, I think your going about this the wrong way. I think you should date/time stamp each ajax call, and keep track of the data time stamps in your javascript. Then, when an ajax call is returned you can check the date/time stamp and make sure it is the result set for the most resent ajax call. This way you do make the ajax call for each keystroke immediately, but only display results if the ajax results catches up to the typing.
Also, are you sending over ALL matching results? Like thousands for just the letter W? To speed up the javascript side maybe you should rank the results on the database and return only the top 10-20. The doesn't want to see more than 10-20 results anyways.
Additionally, is your SQL query optimal? Seems like the query is taking too long. If your doing a one sided like search (ie. like input+'%') not a two sided like search (ie. like '%' + input + '%') then there are some really good indexes you can put on the table to help you out.