5

I know this would be crazy to have feature!!! Is there a way where when the user enters the zip code do an automatch and fill the state and city ?

I was looking at http://daspecster.github.com/ziptastic/demo.html

This is exactly what I want but in a VF page!!!

Can somebody guide me how to use the javscript inside the VF page/provide any other alternatives to this approach ?

Thanks a lot!! EDIT :

I was trying to use this : http://css-tricks.com/using-ziptastic/ forum and do the following :

for some reason the alert is not showing up!!!I tried to debug using chrome and found no errors too. I tried to use mouseover on #zip as well as keydown, both do not work. Why would the mouseover/keydown event not work

Am i missing something?

       <apex:page standardStylesheets="false" showheader="false" sidebar="false" docType="html-5.0" cache="true">
        <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js"/>
        <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js"/>
    <script>
    var j$ = jQuery.noConflict();
    j$(document).ready(function(){ 
    j$(".fancy-form div > div").hide();
    });
    $("#zip").mouseover(function() {
    alert('Entered mouse over block');
    });

    </script>
<form action="#" method="post" class="fancy-form">


      <fieldset>
        <legend>Address</legend>

        <div>
          <div>
            <input type="text" name="address-line-1" id="address-line-1"/>
            <label for="address-line-1">Street #1</label>
          </div>
        </div>
        <div>
          <div>
            <input type="text" name="address-line-2" id="address-line-2"/>
            <label for="address-line-2">Street #2</label>
          </div>
        </div>
        <div>
          <div class="city-wrap">
            <input type="text" name="city" id="city"/>
            <label for="city">City</label>
          </div>
           <div class="state-wrap">
            <input type="text" name="state" id="state"/>
            <label for="state">State</label>
          </div>
           <div class="zip-wrap">
            <input type="text" pattern="[0-9]*" name="zip" id="zip"/>
            <label for="zip">Zip</label>
            <p class="zip-error">Not a real zip code.</p>
          </div>
        </div>

        <div>
          <input type="submit" value="Submit"/>
        </div>

      </fieldset>
1
  • You could also look at something like PostCodeAnywhere, an appexchange app which facilitates address completion. It supplies a database of addresses, which is the most important ingredient. Commented Dec 13, 2012 at 6:53

2 Answers 2

6

Just in case if someones interested on how I made this work :/ Here we go the magical Ziptastic at work :)

This is from the Ziptastic API using Ajax with in Visualforce:

<apex:page standardStylesheets="false" docType="html-5.0" cache="true">
<apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js"/>
<apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js"/>
<style>
form .zip-wrap {
  display: block !important;
}
</style>
<script>
var j$ = jQuery.noConflict();
j$(document).ready(function(){ 
j$(".fancy-form div > div").hide();
j$(".zip-error").hide();
});
function mouseover(elm){
if ((elm.length == 5) && (is_int(elm))) {
  j$.ajax({
      url: "http://zip.elevenbasetwo.com",
      cache: false,
      dataType: "json",
      type: "GET",
      data: "zip=" + elm,
      success: function(result, success) {
        j$(".fancy-form div > div").slideDown(); /* Show the fields */

        j$("#city").val(result.city); /* Fill the data */
        j$("#state").val(result.state);

        j$(".zip-error").hide(); /* In case they failed once before */

        j$("#address-line-1").focus(); /* Put cursor where they need it */
        j$(".zip-invalid").hide();
      },
      error: function(result, success) {
        j$(".zip-error").show(); /* Ruh row */
      }

  });

  }
  else{
  j$(".zip-invalid").show();
  }
}
function is_int(value){ 
  if ((parseFloat(value) == parseInt(value)) && !isNaN(value)) {
      return true;
  } else { 
      return false;
  } 
} 
function window_refresh(){
j$(".zip-invalid").hide();
} 
</script>
<form action="#" method="post" class="fancy-form">
  <fieldset>
    <legend>Address</legend>
    <div>
      <div>
        <input type="text" name="address-line-1" id="address-line-1"/>
        <label for="address-line-1">Street #1</label>
      </div>
    </div>
    <div>
      <div>
        <input type="text" name="address-line-2" id="address-line-2"/>
        <label for="address-line-2">Street #2</label>
      </div>
    </div>
    <div>
      <div class="city-wrap">
        <input type="text" name="city" id="city"/>
        <label for="city">City</label>
      </div>
       <div class="state-wrap">
        <input type="text" name="state" id="state"/>
        <label for="state">State</label>
      </div>
       <div class="zip-wrap">
        <input type="text" pattern="[0-9]*" name="zip" id="zip" onchange="mouseover(this.value)"/>
        <label for="zip">Zip</label>
        <p class="zip-error">Not a real zip code.</p>
      </div>
    </div>
    <div>
    <div class="zip-invalid">
    <p> Zip value cannot be more than 5 characters</p>
    <input type="button" value="close" onclick="window_refresh()"/>
    </div>
      <input type="submit" value="Submit"/>
    </div>
  </fieldset>
</form>
</apex:page>   

If Someone is looking for code to look values from the orgs database than looking at the API look at the code below :

This is by using Sforce.connection.query and using the datasource as account

<apex:page standardStylesheets="false" docType="html-5.0" cache="true" >
<apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js"/>
<apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js"/>
<script src="/soap/ajax/15.0/connection.js" type="text/javascript"></script>
<script src="/soap/ajax/15.0/apex.js" type="text/javascript"></script>
<style>
form .zip-wrap {
  display: block !important;
}
</style>
<script>
var j$ = jQuery.noConflict();
j$(document).ready(function(){ 
j$(".fancy-form div > div").hide();
j$(".zip-error").hide();
});
function mouseover(elm){
    sforce.connection.sessionId = "{!$Api.Session_ID}";
    if ((elm.length == 5) && (is_int(elm))) {
        var result = sforce.connection.query("SELECT id, name,BillingPostalCode,BillingState,BillingCity from ACCOUNT where BillingPostalCode = \'"+elm+"\' limit 1");
        if(result.size != 0){
            var records = result.getArray("records");
                var record;
                for (var i=0; i< records.length; i++) {
                    record = records[i];
                    if(record.BillingPostalCode = elm ){
                            j$(".fancy-form div > div").slideDown(); /* Show the fields */

                            j$("#city").val(record.BillingCity); /* Fill the data */
                            j$("#state").val(record.BillingState);

                            j$(".zip-error").hide(); /* In case they failed once before */

                            j$("#address-line-1").focus(); /* Put cursor where they need it */
                            j$(".zip-lengthexceeded").hide();
                      }

            }
        }
        else{
        alert('Zip Code not found');
        }
    }
    else{
    alert('Zip Code length cannot exceed 5 characters');
    }
}
function is_int(value){ 
  if ((parseFloat(value) == parseInt(value)) && !isNaN(value)) {
      return true;
  } else { 
      return false;
  } 
} 
function window_refresh(){
j$(".zip-invalid").hide();
} 
</script>
<form action="#" method="post" class="fancy-form">
  <fieldset>
    <legend>Address</legend>
    <div>
      <div>
        <input type="text" name="address-line-1" id="address-line-1"/>
        <label for="address-line-1">Street #1</label>
      </div>
    </div>
    <div>
      <div>
        <input type="text" name="address-line-2" id="address-line-2"/>
        <label for="address-line-2">Street #2</label>
      </div>
    </div>
    <div>
      <div class="city-wrap">
        <input type="text" name="city" id="city"/>
        <label for="city">City</label>
      </div>
       <div class="state-wrap">
        <input type="text" name="state" id="state"/>
        <label for="state">State</label>
      </div>
       <div class="zip-wrap">
       <apex:form>
        <input type="text" id="zip" onchange="mouseover(this.value)"/> Zip
       </apex:form>

        <p class="zip-error">Not a real zip code.</p>
      </div>
    </div>

    <div>
      <input type="submit" value="Submit"/>
    </div>
  </fieldset>
</form>
</apex:page>
5
  • very cool. any reason you didn't keep the onchange unobtrusive?
    – Phil B
    Commented Dec 13, 2012 at 22:28
  • Nope!!! I was just poking around the existing html I took from the post and did some apexy twists!!!!I am too naive with Jscript and Jquery so any corrections to the code will be most welcome :)
    – Rao
    Commented Dec 13, 2012 at 22:48
  • nice find. you should take a look at these comments on your referenced css-tricks article for a small, but important, change.
    – zjeh
    Commented Dec 13, 2012 at 23:55
  • Can someone point on how to make this unobtrusive !!! I tried using the j$("#zip").mouseover(function() { alert('Entered mouse over block'); }); Still no luck the page seems to be non responsive for the mouseover
    – Rao
    Commented Dec 14, 2012 at 0:46
  • Try this: api.jquery.com/hover. I don't think there is a jquery method mouseover. I believe in addition to hover theres mouseeenter and mouseleave. Hover is a combination of both.
    – Phil B
    Commented Dec 14, 2012 at 14:27
2

It may not be exactly what you need, but I've had good success using jQuery plugins (autocomplete in particular) in conjunction with VF form fields. The only real "tricky" part is that since VF auto-generates element ID's, you usually have to use CSS selectors like the following:

$("[id$='myVFID']")

Which uses the "ID ends with" selector since your VF-generated ID will be something like

j_id0:j_id83:myVFID

You could either modify the autocomplete plugin for your purposes, or implement functionality just like the page you linked to using vanilla JS (with or without jQuery). The only difference in implementing in VF is going to be how your page is constructed, and how the backend data source is served up.

2
  • +1 although {!$Component} sounds the official way and when I quickly have to cheat the system I abuse the fact styleClass="myUniqueReference" does not get automagically prefixed like id field does ;)
    – eyescream
    Commented Dec 13, 2012 at 22:11
  • Yeah should have mentioned that too, although since I generally externalize all my JS for performance reasons, it doesn't have access to VF tags. You should be aware that under many browsers, using CSS class selectors is significantly slower than using ID selectors (even the "ends with" selector). It is unnoticeable under modern browsers with small element counts, but gets noticeable under larger pages even on a fast machine using Chrome.
    – jkraybill
    Commented Dec 13, 2012 at 23:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .