Address Validator using Google Maps - c#

I am creating a address validator web application using google maps.my UI:
]
Now which I want is after pressing ok button address should be shown into your address look like field like this 701 1st, Sunnywale, CA 94089
now my ok button click event is
FullAddress.Text = AddressLine1.Text + ',' + ' ' + City.Text + ',' + ' ' + State.Text+ ' ' +Zip.Text;
but when i add javascript to call google maps with my program its not working its throgh a error like as sample pic. Please help me guys.
ok button :
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="OK"
Width="62px" style="margin-left: 0px" />
Validate & Locate Me Button code:
<asp:Button ID="Submit" runat="server" style="margin-left: 97px" Text="Validate & Locate Me" Width="137px" />
Now jQuery and geocode part:
<script type="text/javascript">
// The following code show execute only after the page is fully loaded
$(document).ready(function () {
if ($('#MyForm').exists()) {
// Enable jQuery Validation for the form
$("#MyForm").validate({ onkeyup: false });
// Add validation rules to the FullAddress field
$("#FullAddress").rules("add", {
fulladdress: true,
required: true,
messages: {
fulladdress: "Google cannot locate this address."
}
});
// This function will be executed when the form is submitted
function FormSubmit() {
$.submitForm = true;
if (!$('#MyForm').valid()) {
return false;
} else {
if ($("#FullAddress").data("IsChecking") == true) {
$("#FullAddress").data("SubmitForm", true);
return false;
}
alert('Form Valid! Submit!');
// return true; // Uncomment to submit the form.
return false; // Supress the form submission for test purpose.
}
}
// Attach the FormSubmit function to the Submit button
if ($('#Submit').exists()) {
$("#Submit").click(FormSubmit);
}
// Execute the ForumSubmit function when the form is submitted
$('#MyForm').submit(FormSubmit);
}
});
// Create a jQuery exists method
jQuery.fn.exists = function () { return jQuery(this).length > 0; }
// Position the Google Map
function Map(elementId, geolocation) {
var myOptions = {
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById(elementId), myOptions);
map.setCenter(geolocation);
}
// FullAddress jQuery Validator
function FullAddressValidator(value, element, paras) {
// Convert the value variable into something a bit more descriptive
var CurrentAddress = value;
// If the address is blank, then this is for the required validator to deal with.
if (value.length == 0) {
return true;
}
// If we've already validated this address, then just return the previous result
if ($(element).data("LastAddressValidated") == CurrentAddress) {
return $(element).data("IsValid");
}
// We have a new address to validate, set the IsChecking flag to true and set the LastAddressValidated to the CurrentAddress
$(element).data("IsChecking", true);
$(element).data("LastAddressValidated", CurrentAddress);
// Google Maps doesn't like line-breaks, remove them
CurrentAddress = CurrentAddress.replace(/\n/g, "");
// Create a new Google geocoder
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': CurrentAddress }, function (results, status) {
// The code below only gets run after a successful Google service call has completed.
// Because this is an asynchronous call, the validator has already returned a 'true' result
// to supress an error message and then cancelled the form submission. The code below
// needs to fetch the true validation from the Google service and then re-execute the
// jQuery form validator to display the error message. Futhermore, if the form was
// being submitted, the code below needs to resume that submit.
// Google reported a valid geocoded address
if (status == google.maps.GeocoderStatus.OK) {
// Get the formatted Google result
var address = results[0].formatted_address;
// Count the commas in the fomatted address.
// This doesn't look great, but it helps us understand how specific the geocoded address
// is. For example, "CA" will geocde to "California, USA".
numCommas = address.match(/,/g).length;
// A full street address will have at least 3 commas. Alternate techniques involve
// fetching the address_components returned by Google Maps. That code looks even more ugly.
if (numCommas >= 3) {
// Replace the first comma found with a line-break
address = address.replace(/, /, "\n");
// Remove USA from the address (remove this, if this is important to you)
address = address.replace(/, USA$/, "");
// Check for the map_canvas, if it exists then position the Google Map
if ($("#map_canvas").exists()) {
$("#map_canvas").show();
Map("map_canvas", results[0].geometry.location);
}
// Set the textarea value to the geocoded address
$(element).val(address);
// Cache this latest result
$(element).data("LastAddressValidated", address);
// We have a valid geocoded address
$(element).data("IsValid", true);
} else {
// Google Maps was able to geocode the address, but it wasn't specific
// enough (not enough commas) to be a valid street address.
$(element).data("IsValid", false);
}
// Otherwise the address is invalid
} else {
$(element).data("IsValid", false);
}
// We're no longer in the midst of validating
$(element).data("IsChecking", false);
// Get the parent form element for this address field
var form = $(element).parents('form:first');
// This code is being run after the validation for this field,
// if the form was being submitted before this validtor was
// called then we need to re-submit the form.
if ($(element).data("SubmitForm") == true) {
form.submit();
} else {
// Re-validate this property so we can return the result.
form.validate().element(element);
}
});
// The FullAddress validator always returns 'true' when initially called.
// The true result will be return later by the geocode function (above)
return true;
}
// Define a new jQuery Validator method
$.validator.addMethod("fulladdress", FullAddressValidator);
</script>
</body>
</html>
Please help after pressing ok button full address isnt shown into Your address look like field.Instead of that its through a message: This Field is required. If further more details needed please mention it

Simply use 2 FORMS to keep your controls. First one will have the address fields and the OK button.
Second will have the rest. Change your code accordingly. It should work. Otherwise you need to assign classes and group the controls into 2 sets.
What I mean by 2 sets is that "OK" button should validate the fields above it. And "Validate and Locate Me" button should validate only "Your address look like" text box. With jquery you can think of many ways how to group controls and validate them.
If this is not solving please provide the HTML as well or use http://jsfiddle.net/
-- edit --
The problem you have is when you press OK, it validates a field beneath it. Now what I feel is you have used a Required Field Validator without any grouping. Please specify a ValidationGroup property to separate the validation criteria of "OK" button and "Validate and Locate Me" button.
If you don't know how to use ValidationGroup let me know.
~ CJ

Related

Selenium.WebElement.Text is returning blank using C#

I am currently trying to obtain some printed text from an automated test website after I have completed a form. The returned values are displayed to the user on the screen after submitting the form, but for some reason I cannot obtain 2 of the 4 text values with Selenium's WebElement, I have tried using .Text and GetAttribute("value"), and they both return blank. Yet the first 2 pieces of text returned, I am able to retrieve. Please see screenshot below along with the code.
//Then I verify the form submitted
Constants.confirmationName = driver.FindElement(By.CssSelector("#name"));
if (Constants.confirmationName.Text == "Name:QA Automation")
{
Console.WriteLine(Constants.confirmationName.Text);
}
else
{
Console.WriteLine("We have a different name stored for you.");
}
Constants.confirmationEmail = driver.FindElement(By.CssSelector("#email"));
if (Constants.confirmationEmail.Text == "Email:automation#hotmail.com")
{
Console.WriteLine(Constants.confirmationEmail.Text);
}
else
{
Console.WriteLine("We have a different email stored for you.");
}
Thread.Sleep(2000);
//NOT WORKING
Constants.confirmationCurrentAddress = driver.FindElement(By.CssSelector("#currentAddress"));
Thread.Sleep(2000);
if (Constants.confirmationCurrentAddress.Text == "Current Address :Cedars 2 ")
{
Console.WriteLine(Constants.confirmationCurrentAddress.Text);
}
else
{
Console.WriteLine("We have a different current address stored for you.");
}
//NOT WORKING
Constants.confirmationPermanentAddress = driver.FindElement(By.CssSelector("#permanentAddress"));
if (Constants.confirmationPermanentAddress.Text == "Permananet Address :63 Wheat Drive")
{
Console.WriteLine(Constants.confirmationPermanentAddress.Text);
}
else
{
Console.WriteLine("We have a different permanent address stored for you.");
}
The code confirms the name that is printed, and I can see it returned, same goes for the email address, but the current address and permanent address both return blank, I've tried to add in wait times too, but to no avail.
The website in question is https://demoqa.com/text-box, if you fill in the fields, then click Submit, you will see the printed information underneath.
Any help would be greatly appreciated as it's driving me insane!
Check the HTML for any other Elements that share the same Id of currentAddress and permanentAddress, I reckon this is the problem as it's likely finding that first element matching that Id and that element has no text (hence the empty string and no exception).
Your code looks fine to me, and the fact that email and name work correctly suggests your code is also fine.
try changing this
Constants.confirmationCurrentAddress = driver.FindElement(By.CssSelector("#currentAddress"));
to
Constants.confirmationCurrentAddress = driver.FindElement(By.CssSelector("p#currentAddress"));
that should help narrow down and find the element you're looking for.
With in the ToolsQA Text Box webpage once you click on the Submit button as the values of Full Name and Email are immediately rendered within <p> tags:
You can use the .Text property to extract the innerText as follows:
Constants.confirmationName = driver.FindElement(By.CssSelector("#name"));
if (Constants.confirmationName.Text == "Name:QA Automation")
{
Console.WriteLine(Constants.confirmationName.Text);
}
But the values of Current Address and Permanent Address are not rendered immediately within <textarea> tags
Hence, to extract the value of Current Address and Permananet Address instead of using the Text property you need to use GetAttribute("value") method as follows:
To extract Current Address:
Constants.confirmationCurrentAddress = driver.FindElement(By.CssSelector("#currentAddress"));
if (Constants.confirmationCurrentAddress.GetAttribute("value") == "Current Address :Cedars 2 ")
{
Console.WriteLine(Constants.confirmationCurrentAddress.Text);
}
To extract Permananet Address:
Constants.confirmationPermanentAddress = driver.FindElement(By.CssSelector("#permanentAddress"));
if (Constants.confirmationPermanentAddress.GetAttribute("value") == "Permananet Address :63 Wheat Drive")
{
Console.WriteLine(Constants.confirmationPermanentAddress.Text);
}

MVC 5 Losing validator

I have noticed a strange behavior in MVC 5 (C#) with the form validator.
This is my code to check on keyup for errors:
var $validatr = $('form').data('validator');
var settngs = $validatr.settings;
settngs.onkeyup = function (element, eventType) {
if (!$validatr.element(element)) {
$(this.currentForm).triggerHandler("invalid-form", [this]);
}
};
settngs.onfocusout = false;
I have noticed that this code works on some forms, on other not. I tried to get the validator also like this:
var $validatr = $('form').validate();
But it is still not working. Important: then I noticed that the the code is working for the registration form only if the user is not logged already. (I can access the registration form also when the user is logged). When the user is logged I get this error:
TypeError: $validatr is undefined
In this case the error for the input form pops-up only when there is an out_of_focus of the element.
UPDATE:
If I delete this cookie: AspNet.ApplicationCookie and refresh the page the user is logged out and the onKeyUp validation is working. What is going on?
If you have more than one form on a page or you have a popup that contains a form on the page the Jquery selector can have multiple forms targeted the way you are using your selector. I would suggest you target a form by Id instead
var $validatr = $('#myForm1').data('validator');
Or alternatively using a loop to target all form elements
$('form').each(function( index, form ) {
var settngs = form.settings;
settngs.onkeyup = function (element, eventType) {
if (!form.element(element)) {
form.triggerHandler("invalid-form", [this]);
}
};
settngs.onfocusout = false;
});

In EWL, how do I show custom validation content at an arbitrary place in the page?

I have a page that collects an email address, and upon submission of the form I see if that email exists. If it does, the user can't create the entity. Instead of showing a normal validation error status message, I would like to show a nice paragraph explaining the situation with a couple links.
I've tried creating the paragraph and hiding it with either .visible = false or display:none, and then making it visible inside the method passed to AddTopValidationMethod. This does not work.
I know I can have HTML status messages but 1) I don't think this would be as good and 2) I wouldn't be able to build my links using EwfLink - I'd have to hand-write an anchor tag.
What's the best solution here?
Try this:
// Add the form item to the page.
var validationFailed = false;
myPanel.AddControlsReturnThis( myMod.GetEmailAddressTextFormItem( false, validationErrorNotifier: () => validationFailed = true, validationList: myPostBack ).ToControl() );
// Add the email-address-exists error placeholder to the page.
myPanel.AddControlsReturnThis(
new ModificationErrorPlaceholder(
new Validation(
( pbv, validator ) => {
if( validationFailed )
return;
if( emailAddressExists( myMod.EmailAddress ) )
validator.NoteErrorAndAddMessage( "The user will never see this." );
},
myPostBack ),
errors => {
if( !errors.Any() )
return Enumerable.Empty<Control>();
// Use any controls you want here!
var link = EwfLink.Create( MyDestinationPage.GetInfo(), new TextActionControlStyle( "has a link" ) );
return new Paragraph( new Control[] { "This sentence ".GetLiteralControl(), link, " in it.".GetLiteralControl() } ).ToSingleElementArray();
} ) );
And if you want your explanatory paragraph to be above the email address form item, add its validation to a BasicValidationList, which you can add to your post-back object after you've created the form item.

Invoke JavaScript from C# code behind [duplicate]

This question already has answers here:
Calling JavaScript Function From CodeBehind
(21 answers)
Closed 9 years ago.
I am trying to learn asp.net. Assuming that I have this code:
if (command.ExecuteNonQuery() == 0)
{
// JavaScript like alert("true");
}
else
{
// JavaScript like alert("false");
}
How to I can invoke JavaScript from C# code behind? How to do that by putting that JavaScript in Scripts directory which is created by default in MS Visual Studio?
Here is method I will use from time to time to send a pop message from the code behind. I try to avoid having to do this - but sometimes I need to.
private void LoadClientScriptMessage(string message)
{
StringBuilder script = new StringBuilder();
script.Append(#"<script language='javascript'>");
script.Append(#"alert('" + message + "');");
script.Append(#"</script>");
Page.ClientScript.RegisterStartupScript(this.GetType(), "messageScript", script.ToString());
}
You can use RegisterStartupScript to load a javascript function from CodeBehind.
Please note that javascript will only run at client side when the page is render at client's browser.
Regular Page
Page.ClientScript.RegisterStartupScript(this.GetType(), "myfunc" + UniqueID,
"myJavascriptFunction();", true);
Ajax Page
You need to use ScriptManager if you use ajax.
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "myfunc" + UniqueID,
"myJavascriptFunction();", true);
Usually these "startupscripts" are handy for translations or passing settings to javascript.
Although the solution Mike provided is correct on the .Net side I doubt in a clean (read: no spaghetti code) production environment this is a good practice. It would be better to add .Net variables to a javascript object like so:
// GA example
public static string GetAnalyticsSettingsScript()
{
var settings = new StringBuilder();
var logged = ProjectContext.CurrentUser != null ? "Logged" : "Not Logged";
var account = Configuration.Configuration.GoogleAnalyticsAccount;
// check the required objects since it might not yet exist
settings.AppendLine("Project = window.Project || {};");
settings.AppendLine("Project.analytics = Project.analytics || {};");
settings.AppendLine("Project.analytics.settings = Project.analytics.settings || {};");
settings.AppendFormat("Project.analytics.settings.account = '{0}';", account);
settings.AppendLine();
settings.AppendFormat("Project.analytics.settings.logged = '{0}';", logged);
settings.AppendLine();
return settings.ToString();
}
And then use the common Page.ClientScript.RegisterStartupScript to add it to the HTML.
private void RegisterAnalyticsSettingsScript()
{
string script = GoogleAnalyticsConfiguration.GetAnalyticsSettingsScript();
if (!string.IsNullOrEmpty(script))
{
Page.ClientScript.RegisterStartupScript(GetType(), "AnalyticsSettings", script, true);
}
}
On the JavaScript side it might look like this:
// IIFE
(function($){
// 1. CONFIGURATION
var cfg = {
trackingSetup: {
account: "UA-xxx-1",
allowLinker: true,
domainName: "auto",
siteSpeedSampleRate: 100,
pluginUrl: "//www.google-analytics.com/plugins/ga/inpage_linkid.js"
},
customVariablesSetup: {
usertype: {
slot: 1,
property: "User_type",
value: "Not Logged",
scope: 1
}
}
};
// 2. DOM PROJECT OBJECT
window.Project = window.Project || {};
window.Project.analytics = {
init: function(){
// loading ga.js here with ajax
},
activate: function(){
var proj = this,
account = proj.settings.account || cfg.trackingSetup.account,
logged = proj.settings.logged || cfg.customVariablesSetup.usertype.value;
// override the cfg with settings from .net
cfg.trackingSetup.account = account;
cfg.customVariablesSetup.usertype.value = logged;
// binding events, and more ...
}
};
// 3. INITIALIZE ON LOAD
Project.analytics.init();
// 4. ACTIVATE ONCE THE DOM IS READY
$(function () {
Project.analytics.activate();
});
}(jQuery));
The advantage with this setup is you can load an asynchronous object and override the settings of this object by .Net. Using a configuration object you directly inject javascript into the object and override it when found.
This approach allows me to easily get translation strings, settings, and so on ...
It requires a little bit knowledge of both.
Please note the real power of tis approach lies in the "direct initialization" and "delayed activation". This is necessary as you might not know when (during loading of the page) these object are live. The delay helps overriding the proper objects.
This might be a long shot, but sometimes I need a c# property/value from the server side displaying or manipulated on the client side.
c# code behind page
public string Name {get; set;}
JavaScript on Aspx page
var name = '<%=Name%>';
Populating to client side is generally easier, depending on your issue. Just a thought!

Javascript works on IE but not on Firefox and gives me error as Error: cprofiledetailscollapse is not defined

I use C#.net.
I wrote JavaScript for hide and show expand and collapse div accordingly. It work well in IE but not on Firefox, not even call the JavaScript function and gives me error as Error: ctl00_cpContents_dlSearchList_ctl08_profiledetailscollapse is not defined.
My JavaScript is as follows
function displayDiv(divCompact, divExpand) {
//alert('1');
var str = "ctl00_cpContents_";
var divstyle = new String();
// alert("ibtnShowHide" + ibtnShowHide);
divstyle = divCompact.style.display;
if (divstyle.toLowerCase() == "block" || divstyle == "") {
divCompact.style.display = "none";
divExpand.style.display = "block";
// ibtnShowHide.ImageUrl = "images/expand_img.GIF";
}
else {
// ibtnShowHide.ImageUrl = "images/restore_img.GIF";
divCompact.style.display = "block";
divExpand.style.display = "none";
}
return false;
}
ctl00_cpContents_dlSearchList_ctl08_profiledetailscollapse is an element id generated by ASP.NET. It's a profiledetailscollapse control inside dlSearchList.
JavaScript variable "ctl00_cpContents_dlSearchList_ctl08_profiledetailscollapse" is not
defined. Firefox does not automatically create, for each element with an id, a
variable in the global scope named after that id and containing a reference
to the element.
You might want to consider using jQuery to make sure that your DOM manipulation is cross-browser compatible.

Categories