Tuesday 17 June 2014

Publish Your First App with AppExchange Checkout

Getting Started


Before you begin, get to know the Force.com platform, the ecosystem, and popular use cases. There are a lot of ways to do this.DeveloperForce is a developer’s best friend. The Idea Exchange will tell you what customers are asking for. AppExchange will show you which apps are popular. The important thing is to find your niche and start building that app.
Important: AppExchange Checkout works with Managed Packages managed via a License Management Application. If you are selling a Force.com Embedded app or an API only app, contact your ISV AE for non-Checkout options.

Initial Development


Develop your great app and start showing it to people. You can get a free developer org by joining DeveloperForce. It is entirely your call how mature the app should be before showing it to prospects. In general, the earlier, the better. Early viewers and testers will validate your ideas and, more importantly, share theirs. Continue iterating on your app until it is ready for broader testing.

During this early stage of development, you will need to learn about packaging your app, so now is a good time to take a look at theISVForce Guide. Chapter 4, Packaging and Testing Your App, is a great resource. As an ISV, you will only release managed apps, so focus on that section. Keep in mind that once customers start testing your app, and once you start releasing even early versions, it can be difficult to make sweeping changes to your architecture like removing objects and fields. Also, it’s possible for you to package your app in a way that limits its distribution potential. For example, while you can package features such as workflow and record types, these are not standard features in Professional Edition and your app will not install into PE orgs. It is important for you to keep these issues in mind as you develop your app, especially if it is complex, so you can plan and manage your development, and upgrade lifecycles appropriately.


Partner With Salesforce


Signup as a Salesforce partner. This is easy and only takes a few moments. You’ll be asked a few questions and before you know it, you’ll have access to the Partner Portal. Note that your partner portal credentials will end with “@partnerforce.com.” The Partner Portal has great information in it. If you are interested in exploring the ISV program in detail, you should visit the APP Academy.




Become an AppExchange Publisher



Once you are signed up as a partner, create an AppExchange Publishing Org (APO). In the Partner Portal, you’ll see a big button at the top of the screen labeled, “Create A Test Org.” For org type, select “Partner Developer Org.” You will receive new credentials by email. Be sure to login and set your password before proceeding. Note that the system will pick a username for you. If you don’t like it, feel free to change it. The purpose of this org is to help you publish listings on AppExchange.

You are now ready to start publishing on AppExchange. Point your browser to AppExchange, scroll to the bottom of the screen, and click the “List on the AppExchange” link. Login using the APO credentials you just received. You’ll need to answer a few questions. No, you have not published on AppExchange before. Yes, you agree to the terms and conditions. You are now ready to complete your profile. Don’t worry, you can edit this at any time. Notice there’s a link at the bottom labeled “Change Partnership.” You’ll need to save your profile, then click this link. You’ll be prompted for your partnership username and a password. This should be your “@partnerforce.com” username. Be sure to click save again once your partner username and password have been accepted.
Important. AppExchange Publishing Organizations operate on a hub and spoke model. The APO is the hub. It contains all of the information about your company, but doesn't contain any information about your apps. Apps should always be developed in an org other than your APO. When you are ready to publish an app, simply click on the "Your Organizations" link, and add the developer edition where you package your app to your APO. Once you connect the orgs, you will be able see information from your spoke orgs in your hub APO org.
Congratulations, you are now ready to create a new listing. You should now be on the Publisher home screen and see a big red button with the label, “Create New Listing.” Click this. Enter your unique app name, select the “app” option, and submit. You are now on the main listing screen. Note that every field has help text to the right of it. When you run into trouble, look for the help icon in the upper right of your screen. Keep in mind that you’ll be able to edit and enhance this listing as you go.



Signup For AppExchange Checkout



Note: If your app is free, you can skip this step.
Next sign up for AppExchange Checkout, the feature that lets customers pay for your applications directly on the AppExchange. Checkout is a service from salesforce.com and Stripe that bills your customers’ credit cards automatically and deposits money into your account. Stripe provides no-touch recurring billing and subscription management, including trials, coupons, upgrades/downgrades, and automatic renewals. It also automatically updates licenses in the License Management Application (LMA).
Signing up for Checkout is very easy – no merchant bank accounts or payment gateways are required. Start on the publisher home screen. If you’re lost in AppExchange, just stop, scroll to the bottom and click the “List on the AppExchange" link.
To sign up for Checkout, click Learn About Checkout at the top of your publisher home screen. After you agree to the terms and conditions, you can create your Stripe account. Connect your checking account, authorize the AppExchange to use your new Stripe account, and you are ready to use Checkout!
To get your app ready for Checkout, first create your subscription plans in Stripe. Per month, per year, and one-time payment plans are currently supported. Go back to your publisher home screen to edit your listings and choose which plans to offer on the Pricing tab. After you select your plans and associate them with your listing, your app is ready for Checkout. Customers who buy your app on the AppExchange will be asked to provide their credit card information. If they install your app, they will be charged according to the payment details you’ve specified.



Start Your Security Review



Note: you must have a contract in place, either AppExchange Checkout, above, or ISVForce signed up with a rep, in order to start your Security Review.
Next, kick off the Security Review process. Note that all apps on AppExchange must complete the security review process successfully. Click the “Offering” tab. Select the options, “Your application is a package” and “Install it directly from the AppExchange.” Next, associate your package with your listing by clicking “Change Packages.” If you have just uploaded your package, note that it can take a few minutes before that package is visible in AppExchange. Once it is visible, it can be a few more minutes before you can associate it with a listing. Save your page before continuing. Next, click “Start Review.” You will be directed to the Security Review wizard. Here you will supply all of the necessary information to initiate your security review. Take the time to fill this out carefully – incomplete information and failed reviews mean more time until your app can go to market. After completing the form, you will be prompted for your security review payment. Enter your credit card information and your review will be submitted to our security team.


Security Review Complete



Once your security review is complete and your app has passed, you’ll want to request the ISV Business Org by logging a ticket in the Partner Portal. This is a free two-license CRM org that you can use to manage your ISV business (leads, opportunities, licenses, sales and orders) . It comes pre-installed with the License Management App (LMA). The LMA helps you control which customers are allowed to use your app, how many users they are allowed, etc. Note that AppExchange Checkout controls LMA records for any apps a customer purchases through your AppExchange listing.

If you are an API-based app, you might want to request an API token. An API token lets GE and PE customers use your API-based app (SOAP and REST only). If you are not an API-based app, you do not need to do this.
Down to the last few steps. First, revisit the listing you created above. Does it have enough screen shots? Is it easy to understand? Have you added a YouTube demo? Make your listing easy to understand and display your contact information prominently. Also, remember those beta customers? Invite them to review your app so it has some reviews before going live.



Go Live


Now the fun part. Locate your listing in the Private Listings tab. Take a deep breath. Click “Make Public.” That’s it: your listing and your app are now live.
Now the fun part begins: marketing. If you haven’t already, now is the time to get noisy. Tell the world. Post to Facebook. Post to Twitter and mention @appexchange. Post to Pinterest. And then you’ll need to repeat this process with new angles. Post when you get a good review, post when you update your package, post anything you think is newsworthy. It’s important to keep up a regular cadence of marketing activity so you can continue to help prospects get to know you.


Notes


1. This model works for ISVForce apps. However, AppExchange Checkout does not yet support OEM apps, Directory apps, or external apps. If your model is not supported, talk to your ISV AE.
2. When you sign up as a Salesforce partner, our partner team will reach out to you. You should talk to them about your app and describe your use case in detail. In some cases, you might decide you want to pursue a partnership model that does not work with this step by step guide.




Monday 16 June 2014

Unable to fetch organization details for Eclipes


Recent past I came across Force.com IDE tool exception. It's actually network issue and nothing to do with Salesforce.

After installing eclipse and configuring Force.com IDE, I was trying to create a new Force.com project and got error "Unable to fetch organization details for <UserName>".

There can be different reasons for this and one of them is firewall settings. To pass through proxy server, one has to configure proxy settings. Once proxy setting are configured, eclipse bypasses the proxy and gets connected to internet.

Following are steps to configure proxy settings. Steps are almost same for all eclipse versions.

1) In Eclipse IDE, select “Window –> Preferences”
2) Preferences box prompt out, choose “Network Connections”.
3) Select “Manual” from Action Provider drop down list
4) Select Http in the List and click “Edit” button

5) Fill in the proxy server host and port number, (fill in the username and password if any)

Friday 13 June 2014

Salesforce.com Interview Questions



What is Force.com and Salesfore.com? Mention the differences.


Force.com is a cloud computing platform where the developers build multitenant applications.
Salesforce.com is also a cloud computing platform, it contains only standard objects.
Salesforce.com is hoisted on Force.com.

What are the Force.com editions and salesfoce.com editions?


Force.com includes 5 editions.
Free edition
Enterprise with one app
Enterprise with multiple app
Unlimited with one app
Unlimited with multiple apps

 SalesForce.com includes 5 editions
Contact Manager
Group
Professional edition
Enterprise edition
Unlimited edition

How many custom objects available in Professional and Enterprise edition and Unlimited?


Professional    50
Enterprises    200
Unlimited    2000

In Which edition the Apex Data Loader will support? What are those editions?  



Earlier Enterprise and Unlimited editions use to support Apex data loader. Now, Professional, Enterprise and Unlimited edition supports data loader.

Through Sales force Import wizard how many records we can import into S.F Objects and the wizard will support for which Objects?
Using Import wizard, we can upload up to 50000 records. And only Accounts, Contacts and custom object’s data can be imported.  If we want to import other objects like Opportunities and other object’s data, then we need to go for Apex Data Loader.


In which edition work flows are available in S.F?



In Enterprise edition and in unlimited edition, we have these work flows. We do not have these work flows in group and professional editions. We can get these workflows in professional edition also as an add-on.



What is the data and file storage capacity in Professional and Enterprise and Unlimited editions Org wide? What is the storage capacity for each user in above editions?



                            Data storage (Org)        File storage (Org)         Dstorage/Fstorage(User)

Professional         1GB                            1GB                       20MB/100MB
Enterprises     1GB                            1GB                       20MB/100MB
Unlimited                  1GB                            1GB                      120MB/100MB
                       

In Which Edition Outlook and Excel and Mobile Lite are available in S.F? 



Mobile Lite users can view, create, edit, and delete accounts, assets, contacts, leads, opportunities, events, tasks, cases, and solutions from mobile.
 Mobile lite is available in all editions i.e.; Group edition, Professional edition, Enterprise edition, Unlimited edition.
Outlook  connect to sales force is used to sync contacts, Events and mails to sales force. Like mobile lite feature this is also available in all above mentioned editions.

What is app exchange?



The developed custom applications can be uploaded into the app exchange so that the other person can share the applicaition.

What is a VLOOKUP in S.F?



VLOOKUP is actually a function in sales force which is used to bring relevant value to that record from another record automatically.

What are the types of bindings available in Visual force?



Using get; set in apex, we can bind variables in visual force.

ex:     public String textdemo{get;set;} // in apex
        <apex:input text value=”{!textdemo}”>  

Using methods in controller

Ex: <apex:selectlist value=”textdemo”>
            <apex:selectoptions value=”listt”/>
    </apex:selectoptions>
//In apex

Public List<Account> getlistt(){
      Return [select Id,Name from Account]; \\ returns list
}

What are the types of relationships present in S.F?


4 types
Master-Detail
Lookup
Junction Object
Hierarchy

What is junction Object and what does it mean?



Junction object is a custom object which is used to create many to many relationship between two objects.
It always contains two Master-Detail relationships.

Differences between Master-Detail and Lookup
Both are used to create one to many relationship between two objects.
In case of MD, if Parent is deleted, child is also deleted.
In case of Lookup, if Parent is deleted, child is not deleted.

In MD, Child is mandatory, but in Lookup, child is not mandatory.

When I want to export data into SF from Apex Data Loader, which Option should be enable in Profile?


Enable API


Types of Reports in S.F?


3 types of reports in S.F
 Tabular reports:  Tabular report is used to represent the data simply in tabular format.  Summarizing on a particular field cannot be done.

Summary reports: In summary report, we can summate or group the data based on a column.

 Matrix report: In matrix report we can summarize the data both in rows and columns.

What is an Assignments rule?



It is a Rule to specify how leads are assigned to users or queues as they are created manually, captured from the web, or imported via the lead import wizards.

What is a web- lead?



Capturing a lead from a website and routing it into lead object in Sales Force is called wed-lead (web to lead).

What is lookup and Master Details and what is difference between them. 



Both Lookup and Master detail fields are used to link a record in one object to another record in another object.
In lookup, if we delete master records, child records will not be deleted.
In master-detail, if we delete master records, child records will also be deleted.

Child record is mandatory for Master-Detail.

What is an External Id?



External Id is an id that can be given to any field in an object. An external id will be generated on the field that we mention. This field will be used to detect duplicate values when we try to import data into sales force using an external system like apex data loader, informatica data loader etc.

What are the Types of Account and difference between them?



We have two types of accounts.
Personal accounts
Business accounts.
In personal accounts, person’s name will be taken as primary considerations where as in business accounts, there will be no person name, but company name will be taken into consideration.


How many ways to do a field is mandatory?



There are two ways to declare a field to be mandatory.
At the time of creating the field, mentioning the field should contain a value to save a record.
In page layout, we can mention the field to be mandatory.


What is a Field level Security?



Giving permissions to users based on Profiles.
Mentioning the availibity of a field to the users for viewing and editing purpose based on profile is called field level security.
While creating a field,we can mention the security level of that field fr every profile by deciding its level of accessibility to each profile.

Difference between Formula and Roll-up summary



Formula: is a read only field that derives a value from a formula expression that we define.
Roll-up summary: A read-only field that displays the sum, minimum, or maximum value of a field in a related list or the record count of all records listed in a related list.

Difference btw isNull and isBlank



IsNull – it supports for Number field.
IsBlank- it supports for Text field.

What is a workflow? Types of workflow and actions in workflow.



Workflow is a force platform business logic engine that allows us to automatically send email alerts, assign tasks, field updates based on rules that we define.

2 types:
Immediate actions:  That executes when a record matches the criteria.
Time-dependent:  When a record matches the criteria, and executes according to time triggers.

Actions:
Task : Asign a new task to user.
Email-alerts : Send email to one or more recipients that are specified.
Field Updates : Update value of a field.
Outbound Messages: Send a configurable API message to designed listener.

Types of email templates

Text
Html with letter head
Custom Template
Visual Force.

Difference btw Profiles and Roles?



Profiles: Field level or Object level security can be given by profiles
Roles:  Record level security can be given by Roles.

Profile is mandatory.


Types in roles:

Manual Sharing
OWD (organization wide default):
Public read
Public read/write
Private
Sharing rules
Role Hierarchy


What is a wrapper class?


 A wrapper class is a class whose instances are collections of other objects.

What are collections and types of collections?



Collection is an object which groups multiple elements into a single unit.

List: Ordered collection of elements which allows duplicates.
Set: Unordered collection of elements which do not allow duplicates.
Map: Pair of two elements, in which the first element is always unique.


Types of Reports: 



Tabular: Display data in a tabular form. No summarizing is allowed.
Summary: Summarize data on one column based on single criteria.
Matrix: Summarize data on both row and columns.



Difference between VF and S-Control



               VF                      S-Control

It is a markup language like XML, HTML It is a procedural language like Java, Ajax
Automation of data is there- Binding No automation of data- Manual Binding
Style sheet(CSS) is included CSS is not included
Native
Accessibility of object

{! ($Objecttype.ObjectName.accessable)}----------- returns true if object is accessible.

What are Global keywords?
Used to access various values from components on a page or from user objects or from URL, for each object we have each key word.

URL Current Page
Profile Page Reference
User Object Type
Resource Component

What is a Page Reference?



Page reference is a class in apex, which is used to redirect to another page.
By creating an object to this class, we can use this object to forward to another page as shown in example below:

Public Pagereference go()
{
           Pagereference p = new pageReference(‘http://www.google.com’);
Return p;
}

What is MVC?



The main aim of the MVC architecture is to separate the business logic and application data from the presentation data to the user.

Model: The model object knows about all the data that need to be displayed.
View: The view represents the presentation of the application (User Interface).
Controller: Actual business logic of VF is present here.


What are the Controllers available in Force.com?



3 types of controllers are available
Standard Controller: Used for both custom and standard objects.
Custom Controller: is an apex class that implements all the logic for a page without leveraging the functionality of a standard controller.
Extension Controller: is an apex class which adds functionality to existing standard and custom controllers.

What is a difference between render, rerender and renderAs? 



Render: is an attribute used in VF to hide or show certain components in visual force page.
        Rerender: Used to refresh a part of a page in visual force page when an action occurs.
        Render as: Used to convert entire visual force into PDF
        Render as = “pdf”.


How can you access URL Parameters in to a visual force page?



 Using $CurrentPage, you can access the query string parameters for the page by specifying the parameters attribute, after which you can access each individual parameter.
$CurrentPage.parameters.parameter_name

Ex: $CurrentPage.parameters.location

What are annotations ant their types?



Annotations are used to bypass the methods in the way they execute.
@Future: Used to execute the methods asynchronously.
@IsTest: Used to test the methods.
@ReadOnly
@Deprecated
@Remote Action

What is a difference between <apex: dataTable />, <apex: pageBlockTable />?



Only standard style sheets used in page block table,
 If we want to add custom style sheets we have to data table.

What is a Sandbox? Types of sandbox.



Sandbox is the exact replica of the production.
3 Types:
Configuration
Developer
Full

What are triggers? Types of Triggers



Trigger is a piece of code that is executed before or after a particular field of certain type is inserted, updated or deleted.
Bulk Trigger:  All triggers are bulk triggers by default, and can process multiple records at a time. You should always plan on processing more than one record at a time.
   Bulk triggers can handle both single record updates and bulk operations like:
Data import
Mass actions, such as record owner changes and deletes
Recursive Apex methods and triggers that invoke bulk DML statements.
Recursive trigger:


ActionSupport: A component that adds AJAX support to another component, allowing the component to be refreshed asynchronously by the server when a particular event occurs, such as a button click or mouseover.

 ActionFunction: A component that provides support for invoking controller action methods directly from JavaScript code using an AJAX request.

ActionPoller:  A timer that sends an AJAX update request to the server according to a time interval that you specify.

What is Batch Apex? How can you implement Batch Apex?(Dynamic Apex)



Batch Apex gives you the ability to operate over large amounts of data by chunking the job into smaller parts, thereby keeping within the governor limits.
Using batch Apex, you can build complex, long-running processes on the Force.com platform. For example, you could build an archiving solution that runs on a nightly basis, looking for records past a certain date and adding them to an archive.

What is a Callout method? How does it invoke, how many methods available in Classes and Triggers?



It is used to invoke the External services HTTP or web services.
An Apex callout enables you to integrate your Apex with an external service by making a call to an external Web service or sending a HTTP request from an Apex script and then receiving the response. Apex provides integration with Web services that utilize SOAP and WSDL, or HTTP services (RESTful services).

What is a difference between System log and debug log?



System Log console is a separate window that displays debugging information, as well as its cumulative limits and source code. It can be considered a context-sensitive execution viewer showing the source of an operation, what triggered that operation, and what occurred afterward. Use the System Log console to view debug logs that include database events, Apex processing, workflow, and validation logic.

Debug log records database operations, system processes, and errors that occur when executing a transaction or while running unit tests. The system generates a debug log for a user every time that user executes a transaction that is included in the filter criteria.

SOQL: Salesforce.com Object Query Language

SOSL: Salesforce.com Object Search Language

What is a Force.com IDE?



Ans. Force.com IDE is a development environment which is available as a plug-in to be installed in Eclipse and used. This IDE can be used to work on and manipulate the salesforce structure like authoring Apex classes, Visual force pages, apex triggers etc.,

What is a Managed Package and Unmanaged package?



Unmanaged vs. Managed
Managed packages are AppExchange packages that can be upgraded in the installer's organization. They differ from unmanaged packages in that some components are locked, allowing the upgrade process. Unmanaged packages do not include locked components and can not be upgraded.

Before the Winter '07 release, all packages were unmanaged. Now, you can convert an unmanaged package to managed to ensure your installed users get upgrades.

Unmanaged Package Managed Package
What Completely Editable by Developer and Installer
Can NOT be upgraded Certain Components are locked
No Destructive Changes to app
Supports Seamless Upgrading
Supports LMA for Managing Installs
When to Use 1:1 Distribution
Extensive Modification Required 1:Many Distribution
Commerical Intent
Foresee Upgrades
Editions Supported All Editions can create Unmanaged Packages ONLY Developer Edition can create Managed Packages


Managed packages differ from unmanaged packages in many other ways. Before creating managed packages, here are a few things to consider:
You must use a Developer Edition organization to create and work with a managed package.
A Developer Edition organization can contain a single managed package and many unmanaged packages.
You must register a Namespace Prefix - A Namespace Prefix is a series of characters prefixed to your Custom Objects and Fields to prevent conflict when installed in another salesforce.com org.


When you release a managed package, meaning it is uploaded with the Managed - Released option selected, the properties of its components change to prevent developers and installers from making harmful changes. For a list of each package component type and their properties, see Properties of Managed Packages. If you do not want to offer upgrades to your package, consider keeping it unmanaged.

If you plan to release your app as a Managed Package, please read out guide on Planning the Release of Managed Packages

If you already have a Unmanaged Package and you'd like to convert it to Managed, please review the following: Converting Unmanaged Packages to Managed

Now that you understand the difference and benefits of each type of package, let's see how easy it is to make your Unmanaged package from above into a Managed Package.


Customer portal



With Salesforce CRM’s customer portal, your customers can log cases and get updates 24x7. All via the intuitive user experience for which Salesforce CRM is famous. The result—higher customer satisfaction at a lower cost.

Partner portal



Outsource your service management by allowing third-party service reps to manage customer cases via the partner portal. Service partners can do everything they need to resolve customer support issues: search the solution database, log cases, make case comments, and run reports.


53.What are the rules Criteria to create a work flow?  How many ways to fire a work flows and when should those available? What are the actions in work flow?



Ans. Criteria that cause salesforce.com to apply the workflow rule.
    Immediate actions that execute when a record matches the criteria.
     Time-dependent actions that salesforce.com queues when a record matches the criteria, and executes according to time triggers.
In 2 ways,
1. Immediate action: when criteria matches record then workflow will be fired immediately.
2. Timedependent action: Fires according to time triggers.
           Tasks - Assign a new task to a user, role, or record owner.
Email Alerts - Send an email to one or more recipients you specify.
Field Updates - Update the value of a field on a record.
Outbound Messages - Send a secure configurable API message (in XML format) to a                                                        designated listener.

54. Types of Sandboxes and what are those and In Which editions those are available?



Ans.   3 types of Sandboxes available, those are Developer, Full and Configuration. In all editions.

55. What is test coverage code % for the classes and triggers and what is the test method syntax?



Ans.  75%.

56.Types of Triggers and what is a Bulk Trigger?



Ans. All triggers are bulk triggers by default, and can process multiple records at a time. You should always plan on processing more than one record at a time.
        Bulk triggers can handle both single record updates and bulk operations like:
Data import
Bulk Force.com API calls
Mass actions, such as record owner changes and deletes
Recursive Apex methods and triggers that invoke bulk DML statements.



57.What are the types of bindings available in Visual force?



Ans . 1. Using GET-SET in apex, we can bind variables in visual force.
         2. Using methods in controller.


58. What is a Wrapper Class in S.F?



Ans. A wrapper class is a class whose instances are collections of other objects.


59. What are formula and Rollup Summary fields and Difference between them? When should Rollup- Summary field enable?



Formula: A read-only field that derives its value from a formula expression that we define. The formula field is updated when any of the source fields change.
Rollup Summary: A read-only field that displays the sum, minimum, or maximum value of a field in a related list or the record count of all records listed in a related list.

Difference is below:
                  Formula fields calculate values using fields within single record, roll-up summary fields calculate values from a set of related records.
When we give the master-detail relationship it get’s enable to the master object

TIC TAC TOE GAME IN SFDC



Visualforce Page : 


<apex:page standardStylesheets="false" showHeader="false">
  <SCRIPT>


if (document.all||document.getElementById){
document.write('<style>.tictac{')
document.write('width:50px;height:50px;')
document.write('}</style>')
}

var sqr1
var sqr2
var sqr3
var sqr4
var sqr5
var sqr6
var sqr7
var sqr8
var sqr9
var sqr1T = 0
var sqr2T = 0
var sqr3T = 0
var sqr4T = 0
var sqr5T = 0
var sqr6T = 0
var sqr7T = 0
var sqr8T = 0
var sqr9T = 0
var moveCount = 0
var turn = 0
var mode = 1

function vari()
{
sqr1 = document.tic.sqr1.value
sqr2 = document.tic.sqr2.value
sqr3 = document.tic.sqr3.value
sqr4 = document.tic.sqr4.value
sqr5 = document.tic.sqr5.value
sqr6 = document.tic.sqr6.value
sqr7 = document.tic.sqr7.value
sqr8 = document.tic.sqr8.value
sqr9 = document.tic.sqr9.value
}
function check()
{
  if(sqr1 == " X " && sqr2 == " X " && sqr3 == " X ")
  {
    alert("You Win!")
    reset()
  } 
  else if(sqr4 == " X " && sqr5 == " X " && sqr6 == " X ")
  {
    alert("You Win!")
    reset()
  } 
  else if(sqr7 == " X " && sqr8 == " X " && sqr9 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr1 == " X " && sqr4 == " X " && sqr7 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr2 == " X " && sqr5 == " X " && sqr8 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr3 == " X " && sqr6 == " X " && sqr9 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr3 == " X " && sqr5 == " X " && sqr7 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else
  {
    winCheck()
    check2()
    drawCheck()  
  } 
}

function check2()
{
  vari()
  drawCheck()
  if(sqr1 == " O " && sqr2 == " O " && sqr3 == " O ")
  {
    alert("You Lose!")
    reset()
  } 
  else if(sqr4 == " O " && sqr5 == " O " && sqr6 == " O ")
  {
    alert("You Lose!")
    reset()
  } 
  else if(sqr7 == " O " && sqr8 == " O " && sqr9 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr1 == " O " && sqr4 == " O " && sqr7 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr2 == " O " && sqr5 == " O " && sqr8 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr3 == " O " && sqr6 == " O " && sqr9 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr3 == " O " && sqr5 == " O " && sqr7 == " O ")
  {
    alert("You Lose!")
    reset()
  }
}

function player1Check()
{
  if(sqr1 == " X " && sqr2 == " X " && sqr3 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  } 
  else if(sqr4 == " X " && sqr5 == " X " && sqr6 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  } 
  else if(sqr7 == " X " && sqr8 == " X " && sqr9 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr1 == " X " && sqr4 == " X " && sqr7 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr2 == " X " && sqr5 == " X " && sqr8 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr3 == " X " && sqr6 == " X " && sqr9 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr3 == " X " && sqr5 == " X " && sqr7 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else
  {
    player2Check()
    drawCheck()  
  } 
}

function player2Check()
{
  vari()
  drawCheck()
  if(sqr1 == " O " && sqr2 == " O " && sqr3 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  } 
  else if(sqr4 == " O " && sqr5 == " O " && sqr6 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  } 
  else if(sqr7 == " O " && sqr8 == " O " && sqr9 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr1 == " O " && sqr4 == " O " && sqr7 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr2 == " O " && sqr5 == " O " && sqr8 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr3 == " O " && sqr6 == " O " && sqr9 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr3 == " O " && sqr5 == " O " && sqr7 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
}

function drawCheck()
{
  vari()
  moveCount = sqr1T + sqr2T + sqr3T + sqr4T + sqr5T + sqr6T + sqr7T + sqr8T + sqr9T 
  if(moveCount == 9)
  {
    reset()
    alert("Draw") 
  }
}

function winCheck()
{
  check2()
  if(sqr1 == " O " && sqr2 == " O " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr2 == " O " && sqr3 == " O " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr4 == " O " && sqr5 == " O " && sqr6T == 0 && turn == 1)
  {
    document.tic.sqr6.value = " O "
    sqr6T = 1;
    turn = 0;
  }
  else if(sqr5 == " O " && sqr6 == " O " && sqr4T == 0 && turn == 1)
  {
    document.tic.sqr4.value = " O "
    sqr4T = 1;
    turn = 0;
  }
  else if(sqr7 == " O " && sqr8 == " O " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr8 == " O " && sqr9 == " O " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr5 == " O " && sqr9 == " O " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr3 == " O " && sqr5 == " O " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr7 == " O " && sqr5 == " O " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr3 == " O " && sqr2T == 0 && turn == 1)
  {
    document.tic.sqr2.value = " O "
    sqr2T = 1;
    turn = 0;
  }
  else if(sqr4 == " O " && sqr6 == " O " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr7 == " O " && sqr9 == " O " && sqr8T == 0 && turn == 1)
  {
    document.tic.sqr8.value = " O "
    sqr8T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr7 == " O " && sqr4T == 0 && turn == 1)
  {
    document.tic.sqr4.value = " O "
    sqr4T = 1;
    turn = 0;
  }
  else if(sqr2 == " O " && sqr8 == " O " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr3 == " O " && sqr9 == " O " && sqr6T == 0 && turn == 1)
  {
    document.tic.sqr6.value = " O "
    sqr6T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr4 == " O " && sqr7 == " O " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr5 == " O " && sqr8 == " O " && sqr2T == 0 && turn == 1)
  {
    document.tic.sqr2.value = " O "
    sqr2T = 1;
    turn = 0;
  }
  else if(sqr6 == " O " && sqr9 == " O " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr4 == " O " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr2 == " O " && sqr5 == " O " && sqr8T == 0 && turn == 1)
  {
    document.tic.sqr8.value = " O "
    sqr8T = 1;
    turn = 0;
  }
  else if(sqr3 == " O " && sqr6 == " O " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr9 == " O " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr3 == " O " && sqr7 == " O " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else
  {
    computer()
  }
  check2()
}
function computer()
{
  check2()
  if(sqr1 == " X " && sqr2 == " X " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr2 == " X " && sqr3 == " X " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr4 == " X " && sqr5 == " X " && sqr6T == 0 && turn == 1)
  {
    document.tic.sqr6.value = " O "
    sqr6T = 1;
    turn = 0;
  }
  else if(sqr5 == " X " && sqr6 == " X " && sqr4T == 0 && turn == 1)
  {
    document.tic.sqr4.value = " O "
    sqr4T = 1;
    turn = 0;
  }
  else if(sqr7 == " X " && sqr8 == " X " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr8 == " X " && sqr9 == " X " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr5 == " X " && sqr9 == " X " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr3 == " X " && sqr5 == " X " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr7 == " X " && sqr5 == " X " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr3 == " X " && sqr2T == 0 && turn == 1)
  {
    document.tic.sqr2.value = " O "
    sqr2T = 1;
    turn = 0;
  }
  else if(sqr4 == " X " && sqr6 == " X " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr7 == " X " && sqr9 == " X " && sqr8T == 0 && turn == 1)
  {
    document.tic.sqr8.value = " O "
    sqr8T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr7 == " X " && sqr4T == 0 && turn == 1)
  {
    document.tic.sqr4.value = " O "
    sqr4T = 1;
    turn = 0;
  }
  else if(sqr2 == " X " && sqr8 == " X " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr3 == " X " && sqr9 == " X " && sqr6T == 0 && turn == 1)
  {
    document.tic.sqr6.value = " O "
    sqr6T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr4 == " X " && sqr7 == " X " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr5 == " X " && sqr8 == " X " && sqr2T == 0 && turn == 1)
  {
    document.tic.sqr2.value = " O "
    sqr2T = 1;
    turn = 0;
  }
  else if(sqr6 == " X " && sqr9 == " X " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr4 == " X " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr2 == " X " && sqr5 == " X " && sqr8T == 0 && turn == 1)
  {
    document.tic.sqr8.value = " O "
    sqr8T = 1;
    turn = 0;
  }
  else if(sqr3 == " X " && sqr6 == " X " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr9 == " X " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr3 == " X " && sqr7 == " X " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else
  {
    AI()
  }
  check2()
}

function AI()
{
  vari()
  if(document.tic.sqr5.value == "     " && turn == 1)
  {
    document.tic.sqr5.value = " O "
    turn = 0
    sqr5T = 1
  }
  else if(document.tic.sqr1.value == "     " && turn == 1)
  {
    document.tic.sqr1.value = " O "
    turn = 0
    sqr1T = 1
  }
  else if(document.tic.sqr9.value == "     " && turn == 1)
  {
    document.tic.sqr9.value = " O "
    turn = 0
    sqr9T = 1
  }
  else if(document.tic.sqr6.value == "     " && turn == 1)
  {
    document.tic.sqr6.value = " O "
    turn = 0
    sqr6T = 1
  }
  else if(document.tic.sqr2.value == "     " && turn == 1)
  {
    document.tic.sqr2.value = " O "
    turn = 0
    sqr2T = 1
  }
  else if(document.tic.sqr8.value == "     " && turn == 1)
  {
    document.tic.sqr8.value = " O "
    turn = 0
    sqr8T = 1
  }
  else if(document.tic.sqr3.value == "     " && turn == 1)
  {
    document.tic.sqr3.value = " O "
    turn = 0
    sqr3T = 1
  }
  else if(document.tic.sqr7.value == "     " && turn == 1)
  {
    document.tic.sqr7.value = " O "
    turn = 0
    sqr7T = 1
  }
  else if(document.tic.sqr4.value == "     " && turn == 1)
  {
    document.tic.sqr4.value = " O "
    turn = 0
    sqr4T = 1
  }
  check2()
}

function reset()
{
  document.tic.sqr1.value = "     "
  document.tic.sqr2.value = "     "
  document.tic.sqr3.value = "     "
  document.tic.sqr4.value = "     "
  document.tic.sqr5.value = "     "
  document.tic.sqr6.value = "     "
  document.tic.sqr7.value = "     "
  document.tic.sqr8.value = "     "
  document.tic.sqr9.value = "     "
  sqr1T = 0
  sqr2T = 0
  sqr3T = 0
  sqr4T = 0
  sqr5T = 0
  sqr6T = 0
  sqr7T = 0
  sqr8T = 0
  sqr9T = 0
  vari()
  turn = 0
  moveCount = 0
}

function resetter()
{
  reset()
}
</SCRIPT>

<FORM NAME="tic">
<INPUT TYPE="button" NAME="sqr1" class="tictac" value="     " onClick="if(document.tic.sqr1.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr1.value = ' X '; sqr1T = 1; turn = 1; vari(); check();} else if(document.tic.sqr1.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr1.value = ' X '; sqr1T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr1.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr1.value = ' O '; sqr1T = 1; turn = 1; vari(); player1Check()} drawCheck()"/>
<INPUT TYPE="button" NAME="sqr2" class="tictac" value="     " onClick="if(document.tic.sqr2.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr2.value = ' X '; sqr2T = 1; turn = 1; vari(); check();} else if(document.tic.sqr2.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr2.value = ' X '; sqr2T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr2.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr2.value = ' O '; sqr2T = 1; turn = 1; vari(); player1Check()} drawCheck()"/>
<INPUT TYPE="button" NAME="sqr3" class="tictac" value="     " onClick="if(document.tic.sqr3.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr3.value = ' X '; sqr3T = 1; turn = 1; vari(); check();} else if(document.tic.sqr3.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr3.value = ' X '; sqr3T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr3.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr3.value = ' O '; sqr3T = 1; turn = 1; vari(); player1Check()} drawCheck()"/><br />
<INPUT TYPE="button" NAME="sqr4" class="tictac" value="     " onClick="if(document.tic.sqr4.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr4.value = ' X '; sqr4T = 1; turn = 1; vari(); check();} else if(document.tic.sqr4.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr4.value = ' X '; sqr4T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr4.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr4.value = ' O '; sqr4T = 1; turn = 1; vari(); player1Check()} drawCheck()"/>
<INPUT TYPE="button" NAME="sqr5" class="tictac" value="     " onClick="if(document.tic.sqr5.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr5.value = ' X '; sqr5T = 1; turn = 1; vari(); check();} else if(document.tic.sqr5.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr5.value = ' X '; sqr5T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr5.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr5.value = ' O '; sqr5T = 1; turn = 1; vari(); player1Check()} drawCheck()"/>
<INPUT TYPE="button" NAME="sqr6" class="tictac" value="     " onClick="if(document.tic.sqr6.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr6.value = ' X '; sqr6T = 1; turn = 1; vari(); check();} else if(document.tic.sqr6.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr6.value = ' X '; sqr6T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr6.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr6.value = ' O '; sqr6T = 1; turn = 1; vari(); player1Check()} drawCheck()"/><br />
<INPUT TYPE="button" NAME="sqr7" class="tictac" value="     " onClick="if(document.tic.sqr7.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr7.value = ' X '; sqr7T = 1; turn = 1; vari(); check();} else if(document.tic.sqr7.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr7.value = ' X '; sqr7T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr7.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr7.value = ' O '; sqr7T = 1; turn = 1; vari(); player1Check()} drawCheck()"/>
<INPUT TYPE="button" NAME="sqr8" class="tictac" value="     " onClick="if(document.tic.sqr8.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr8.value = ' X '; sqr8T = 1; turn = 1; vari(); check();} else if(document.tic.sqr8.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr8.value = ' X '; sqr8T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr8.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr8.value = ' O '; sqr8T = 1; turn = 1; vari(); player1Check()} drawCheck()"/>
<INPUT TYPE="button" NAME="sqr9" class="tictac" value="     " onClick="if(document.tic.sqr9.value == '     ' && turn == 0 && mode == 1) {document.tic.sqr9.value = ' X '; sqr9T = 1; turn = 1; vari(); check();} else if(document.tic.sqr9.value == '     ' && turn == 1 && mode == 2) {document.tic.sqr9.value = ' X '; sqr9T = 1; turn = 0; vari(); player1Check()} else if(document.tic.sqr9.value == '     ' && turn == 0 && mode == 2) {document.tic.sqr9.value = ' O '; sqr9T = 1; turn = 1; vari(); player1Check()} drawCheck()"/>
</form>
</apex:page>