Solved

Array

Posted on 2014-04-10
12
183 Views
Last Modified: 2014-04-11
Hi,

I never used array in coldfusion. so, I am trying to store the data in an array then upload it to the input box.

My code is wrong.

<cfset fileArray=ArrayNew(3)>

 <CFIF isDefined("QGetFile") and #QGetFile.RecordCount# gt 0 >
 <cfoutput query="QGetFile">
<cfset fileArray[1]=#QGetFile.FileID#,#QGetFile.FileName#,#QGetFile.Path#> 
 </cfoutput>
</CFIF>

             <table width="610">
              
                  <cfloop from="1" to="3" index="ii"> 
                  <tr>        
                  <td style="width:120px;">File Description</td>
                    <td colspan="2" align="left" valign="top" style="padding-right:5px;">
                    
                     <CFIF isDefined("fileArray")>
                     <INPUT TYPE="text" value="#fileArray[1]#" NAME="FileID#ii#" id="FileID#ii#" style="width:400px;">
                     <cfelse>
                    <INPUT TYPE="text" NAME="FileID#ii#" id="FileID#ii#" style="width:400px;">
                    </CFIF>
                    
                     <CFIF isDefined("fileArray")>
                     <INPUT TYPE="text" value="#fileArray[2]#" NAME="FileDescription#ii#" id="FileDescription#ii#" style="width:400px;">
                     <cfelse>
                    <INPUT TYPE="text" NAME="FileDescription#ii#" id="FileDescription#ii#" style="width:400px;">
                    </CFIF>
                    
                     <CFIF isDefined("fileArray")>
                     <input type="hidden" value="#fileArray[2]#" Name="FileName#ii#" id="FileName#ii#"  />
                     <cfelse>
      				<input type="hidden" Name="FileName#ii#" id="FileName#ii#"  />
                    </CFIF>

                    
                     <CFIF isDefined("fileArray")>
                       <input type="hidden" value="#fileArray[3]#" Name="Path#ii#" id="Path#ii#"  />
                      <cfelse>
                       <input type="hidden" Name="Path#ii#" id="Path#ii#"  />
                      </CFIF>
                 </tr>
                  <tr>
                    <td style="width:120px;">&nbsp;</td>
                    <td align="left" valign="top" style="padding-right:5px;">
                    <INPUT TYPE="FILE" NAME="AttachFile#ii#" id="AttachFile#ii#" onchange="return validateFileExtension(this,'FileName#ii#','Path#ii#');" class="file" style="width:400px;">
     
                    </td>
                    <td align="left" valign="top" style="padding-right:5px;"> <input type="button" value="Delete" name="DeleteFile#ii#" id="DeleteFile#ii#" style="height:20px;float:right;" onclick="clearFile('AttachFile' + #ii#,'FileDescription' + #ii#,'FileName' + #ii#, 'Path' + #ii#, 'FileID' + #ii#  );" /></td>                    
                  </tr>
                 </cfloop>

                 
                  <tr>
                  <td style="width:100px;">&nbsp;</td>
                  <td colspan="2"><br />
                  <input type="submit" name="SubLogEntry" id="SubLogEntry" value="Submit Log" onclick="return ValidateForm();" >
                 
                  <input type="button" name="GoBack" id="GoBack" value="Go Back" onclick="history.go(-1);" ></td>
                  </tr>
                  </table>

Open in new window

0
Comment
Question by:lulu50
  • 6
  • 5
12 Comments
 
LVL 39

Expert Comment

by:gdemaria
ID: 39992496
Hi Lulu,
Need some explanation to what you're trying to store in the array.  Is it a simple list of items?

Currently, you are defining a 3-dimensional array; which I would try to avoid, they are pretty complex.  

<cfset fileArray=ArrayNew(3)>

This would create

FileArray[A][ B][C}

where A is a storage location 1 through whatever..  and for each location, you can have another set of locations B which can store 1 through whatever, then for each location of B you can have storage location C which can also store 1 through whatever.

So you can have

 FileArray [ 1 ] [ 100 ] [ 12 ]

Seems like too much!

Hopefully, a one dimensional array will do it for you...
<cfset fileArray=ArrayNew(1)>



Also, you don't need all these tests to see if fileArray Exists because it always exists.
                     <CFIF isDefined("fileArray")>
                     <INPUT TYPE="text" value="#fileArray[1]#" NAME="FileID#ii#" id="FileID#ii#" style="width:400px;">
                     <cfelse>
                    <INPUT TYPE="text" NAME="FileID#ii#" id="FileID#ii#" style="width:400px;">
                    </CFIF>

It always exists because you define it here,
<cfset fileArray=ArrayNew(3)>

So the <cfelse> of the above will never be used
0
 
LVL 39

Expert Comment

by:gdemaria
ID: 39992572
After more reading, I see that you are working to have a form list, where you can have any number of form fields repeated 1 to X.

This is a bit of code that I have with a little explanation, I wonder if it will be helpful.  The idea is to create for FORM variable with a number appended.   Start by looking down at the CFQUERY and see how I create form variables appended with numbers.   Then you can see in the form at the bottom how the values are displayed.  Last, look at the top and see how I loop through the form values submitted to save the data to the database.


You need to create a series of form field names by appending a counter to the end of each field (such as qty1, qty2, qty3, etc).  
 Here is a code snippet of another project (involving naming and describing photos).

Hide the primary key (in my example below it is "photoID") in a hidden field for each record.   
This way you can easily handle updating or inserting records on the same screen.   

The variable at the top allows you to customize the number of "additional rows" at the bottom you would like to display for New records.   
This also handles deleting, just remove the values of the name and description and the record will be deleted. 
 Alternatively, a "delete me" checkbox could be added.<cfset application.datasource = "YOUR DATASOURCE HERE">
 
<cfparam name="url.listingID" default="1">
<cfparam name="form.listingID" default="#url.listingID#">
 
<cfset variables.extraBlankRows = 3> <!---- number of extra blank records to add at the end for inserting ----->
<cfset variables.error = ""> <!---- will contain any error messages for display below later ----->
 
<!----- the action, will insert or update the record ----->
<cfif isDefined("form.btnHouseFeatures")>
  <cftry>
    <!---- loop through every record, add or update depending on whether they already had an ID ----->
    <cfloop index="kk" from="1" to="#val(form.totalRecords)#">
        <cfset variables.somethingEntered = true> <!---- assume some data was entered for each record ---->
    	<cfset form.photoname = form['photoname' & kk]>
    	<cfset form.description = form['description' & kk]>
    	<cfset form.photoID = form['photoID' & kk]>
        <cfif len(form.photoname) + len(form.description) eq 0>
          <cfset variables.somethingEntered= false> <!---- this record is blank ---->
        </cfif>
        <cfif val(form.photoID) eq 0> <!---- no primary key, so insert ---->
           <cfif variables.somethingEntered> <!--- don't save a blank record ---->
            <cfquery name="insertPhotos" datasource="#application.datasource#">
              insert into photos (photoname, description, listingID)
              values ('#form.photoname#','#form.description#',#form.ListingID#)
            </cfquery>
           </cfif>
        <cfelse> <!----- already exists, so update it ----->
           <cfif variables.somethingEntered> 
             <cfquery name="updatePhotos" datasource="#application.datasource#">
              update photos
                set photoname = '#form.photoname#'
                  , description = '#form.description#'
              where photoID = #val(form.photoID)#
            </cfquery>
           <cfelse> <!---- nothing entered, so delete the record ---->
             <cfquery name="deletePhotos" datasource="#application.datasource#">
              delete photos where photoID = #val(form.photoID)#
             </cfquery>
           </cfif>
        </cfif>
    </cfloop>
 
  <cfcatch type="Any">
     <cfset variables.error = cfcatch.message>
  </cfcatch>
  </cftry>
</cfif>
 
 
<!---- FETCH DATA
       Only fetch data from the database is there were no errors 
       If there were errors, show the error and the same data as entered, but not saved yet ------>
<cfif len(variables.error) eq 0>
    <!---- fetch the data from the database and convert into an array ----->
    <cfquery name="getData" datasource="#application.datasource#">
      SELECT ListingID, photoID, photoname, description
      FROM photos
      where ListingID = #val(form.ListingID)#
      order by photoName
    </cfquery>
    <cfloop query="getData">  <!---- create a form variable for every record, every column in the format:  form.columName1 ------>
      <cfloop index="aCol" list="#getData.columnList#">
        <cfset form[aCol & getData.currentRow] = getData[aCol][getData.currentRow]>
      </cfloop>
    </cfloop>
    <cfset form.totalRecords = getData.recordCount>
    <!----- create extra form variables that are blank, same format form.columnName2 ---->
    <cfloop index="kk" from="1" to="#variables.extraBlankRows#"> 
      <cfset form.totalRecords = form.totalRecords + 1>
      <cfloop index="aCol" list="#getData.columnList#">
        <cfset form[aCol & form.totalRecords] = "">
      </cfloop>
    </cfloop>
</cfif>
 
<cfif len(variables.error)> <!----- show the error ----->
 <div style="background-color:pink;color:maroon;padding:10px;font-weight:bold;">
  <cfoutput>Error: #variables.error#</cfoutput>
 </div>
</cfif>
 
<cfform name="myform" id="myform">
    <h1>ENTER .JPG NAMES &amp; DESCRIPTIVE TEXT HERE</h1>
    <cfoutput>
    <table width="525" border="0" cellpadding="2" cellspacing="2">
      <tr>
        <th width="144" scope="col">Photo Name</th>
        <th width="412" scope="col">Description</th>
      </tr>
      <!---- us a simple counter, not the ID to tack onto the variable names ----->
      <cfloop index="ii" from="1" to="#form.totalRecords#">
      <tr>
        <td valign="top"><input type="text" name="photoname#ii#" value="#form['photoname'&ii]#"/></td>
        <td><textarea name="description#ii#" cols="70" rows="3">#form['description' & ii]#</textarea>
            <input type="hidden" name="photoID#ii#" value="#form['photoID' & ii]#"> <!---- the primary key of the table ----->
        </td>
      </tr>
      </cfloop>
      <tr>
        <td>
        <cfoutput>
        <input type="hidden" name="listingID" value="#URL.ListingID#">
        <input type="Hidden" name="totalRecords" value="#form.totalRecords#">
        </cfoutput>
        </td>
        <td align="left"><cfinput type="submit" name="btnHouseFeatures" value="ADD PHOTOS"/></td>
      </tr>
    </table>
    </cfoutput>
</cfform>

Open in new window

0
 
LVL 15

Expert Comment

by:myselfrandhawa
ID: 39993356
Jumping in as i need to know what exactly is going on, Keep up expert
0
 

Author Comment

by:lulu50
ID: 39994048
gdemaria,

Thank you for the example.  

it is similar to what I want to do. you're right I don't need array or if isdefined lol lol

I don't know what I am thinking!!!!

so, I changed the code to be similar to your example but I get this error.  

error

    <cfquery name = "QGetFile"  datasource='#strDSN#' username='#strUID#' password='#strPWD#' result="file">
			select FileID, FileName from Files
			where IssueID = #url.ID#
		</cfquery>


<cfloop query="QGetFile">  
      <cfloop index="k" list="#QGetFile.columnList#">
        <cfset file[k & QGetFile.currentRow] = getData[k][QGetFile.currentRow]>
      </cfloop>
    </cfloop>

            <table width="610">
              <cfoutput>
                  <cfloop from="1" to="3" index="ii"> 
                  <tr>        
                  <td style="width:120px;">File Description</td>
                    <td colspan="2" align="left" valign="top" style="padding-right:5px;">             
                    <INPUT TYPE="hidden" NAME="FileID#ii#" id="FileID#ii#" value="#file['FileID'&ii]#">
                    <INPUT TYPE="text" NAME="FileDescription#ii#" value="#file['FileName'&ii]#" id="FileDescription#ii#" style="width:400px;">
                 </tr>
                  <tr>
                    <td style="width:120px;">&nbsp;</td>
                    <td align="left" valign="top" style="padding-right:5px;">
                   <INPUT TYPE="FILE" NAME="AttachFile#ii#" id="AttachFile#ii#" onchange="return validateFileExtension(this,'FileName#ii#','Path#ii#');" class="file" style="width:400px;"> 
                    </td>
                    <td align="left" valign="top" style="padding-right:5px;"> 
                <input type="button" value="Delete" name="DeleteFile#ii#" id="DeleteFile#ii#" style="height:20px;float:right;" onclick="clearFile('AttachFile#ii#','FileDescription#ii#','FileName#ii#', 'Path#ii#', 'FileID#ii#' );" />  
                    </td>                    
                  </tr>
                 </cfloop>
				</cfoutput>
                  <tr>
                  <td style="width:100px;">&nbsp;</td>
                  <td colspan="2"><br />
                  <input type="submit" name="SubLogEntry" id="SubLogEntry" value="Submit Log" onclick="return ValidateForm();" >
                  <input type="button" name="GoBack" id="GoBack" value="Go Back" onclick="history.go(-1);" ></td>
                  </tr>
                  </table>

Open in new window

0
 
LVL 39

Accepted Solution

by:
gdemaria earned 500 total points
ID: 39994220
Here are the changes that I've made:
  I changed the scope to "Form" instead of "File."   This will become very handy when you submit the form.  
  I added a "recordCount" variable.   You had hard-coded 3.  Perhaps you are sure it will always be 3, but if only 2 record are in the database, the could would throw an error.  This way it will not.
  I commented out the two onClick actions only for the moment,  They seem to refer to field that do not exist (fileDescription and path).  I thought they could be put back after the page was working.


	<cfquery name = "QGetFile"  datasource='#strDSN#' username='#strUID#' password='#strPWD#' result="file">
	  select FileID, FileName 
	    from Files
	  where IssueID = #url.ID#
	</cfquery>
    <cfloop query="QGetFile">  
      <cfloop index="k" list="#QGetFile.columnList#">
        <cfset form[k & QGetFile.currentRow] = getData[k][QGetFile.currentRow]>
      </cfloop>
    </cfloop>
    <cfset form.recordCount = QGetFile.recordCount>
	
	<table width="610">
	  <cfoutput>
	      <cfloop from="1" to="#val(form.recordCount)#" index="ii"> 
	      <tr>        
	      <td style="width:120px;">File Description</td>
	        <td colspan="2" align="left" valign="top" style="padding-right:5px;">             
	        <INPUT TYPE="hidden" NAME="FileID#ii#" id="FileID#ii#" value="#form['FileID'&ii]#">
	        <INPUT TYPE="text"   NAME="FileName#ii#" value="#form['FileName'&ii]#" id="FileName#ii#" style="width:400px;">
	     </tr>
	      <tr>
	        <td style="width:120px;">&nbsp;</td>
	        <td align="left" valign="top" style="padding-right:5px;">
	         <INPUT TYPE="FILE" NAME="AttachFile#ii#" id="AttachFile#ii#"  class="file" style="width:400px;">  <!---- add back later: onchange="return validateFileExtension(this,'FileName#ii#','Path#ii#');" ----->
	        </td>
	        <td align="left" valign="top" style="padding-right:5px;"> 
	        <input type="button" value="Delete" name="DeleteFile#ii#" id="DeleteFile#ii#" style="height:20px;float:right;"  />  <!--- add back later   onclick="clearFile('AttachFile#ii#','FileDescription#ii#','FileName#ii#', 'Path#ii#', 'FileID#ii#' );" ----> 
	        </td>                    
	      </tr>
	     </cfloop>
	</cfoutput>
	      <tr>
	      <td style="width:100px;">&nbsp;</td>
	      <td colspan="2"><br />
		  <input type="Hidden" name="recordCount" id="recordCount" value="#val(form.recordCount)#"> <!--- the number of records/form rows displayed ---->
	      <input type="submit" name="SubLogEntry" id="SubLogEntry" value="Submit Log" onclick="return ValidateForm();" >
	      <input type="button" name="GoBack" id="GoBack" value="Go Back" onclick="history.go(-1);" ></td>
	      </tr>
 </table>

Open in new window

0
 

Author Comment

by:lulu50
ID: 39994401
gdemaria,

I made the changes, but I get this error.

hmmm, it says Getdata is undefined.


error
<cfoutput>SQL: #file.SQL#</cfoutput> 

 <cfloop query="QGetFile">  
      <cfloop index="k" list="#QGetFile.columnList#">
        <cfset form[k & QGetFile.currentRow] = getData[k][QGetFile.currentRow]>
      </cfloop>
    </cfloop>
    
    
    <cfset form.recordCount = QGetFile.recordCount>

            <table width="610">
              <cfoutput>
                 <cfloop from="1" to="#val(form.recordCount)#" index="ii"> 
                  <tr>        
                  <td style="width:120px;">File Description</td>
                    <td colspan="2" align="left" valign="top" style="padding-right:5px;">             
                    <INPUT TYPE="hidden" NAME="FileID#ii#" id="FileID#ii#" value="#form['FileID'&ii]#">
                    <INPUT TYPE="text" NAME="FileDescription#ii#" value="#form['FileName'&ii]#" id="FileDescription#ii#" style="width:400px;">
                 </tr>
                  <tr>
                    <td style="width:120px;">&nbsp;</td>
                    <td align="left" valign="top" style="padding-right:5px;">
                   <INPUT TYPE="FILE" NAME="AttachFile#ii#" id="AttachFile#ii#" onchange="return validateFileExtension(this,'FileName#ii#','Path#ii#');" class="file" style="width:400px;"> 
                    </td>
                    <td align="left" valign="top" style="padding-right:5px;"> 
                <input type="button" value="Delete" name="DeleteFile#ii#" id="DeleteFile#ii#" style="height:20px;float:right;" onclick="clearFile('AttachFile#ii#','FileDescription#ii#','FileName#ii#', 'Path#ii#', 'FileID#ii#' );" />  
                    </td>                    
                  </tr>
                 </cfloop>
				</cfoutput>
                  <tr>
                  <td style="width:100px;">&nbsp;</td>
                  <td colspan="2"><br />
                    <input type="Hidden" name="recordCount" id="recordCount" value="#val(form.recordCount)#">
                  <input type="submit" name="SubLogEntry" id="SubLogEntry" value="Submit Log" onclick="return ValidateForm();" >
                  <input type="button" name="GoBack" id="GoBack" value="Go Back" onclick="history.go(-1);" ></td>
                  </tr>
                  </table> 

Open in new window

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:lulu50
ID: 39994417
oh I got it

It's my query lol lol
0
 

Author Comment

by:lulu50
ID: 39994451
gdemaria,

I want to say if #val(form.recordCount)# not equal to 3 then just display the input file up to 3.

so, if I only have one file in the database I want to display this file and two more that are blank.


something like this:

<cfoutput>SQL: #file.SQL#</cfoutput> 

 <cfloop query="QGetFile">  
      <cfloop index="k" list="#QGetFile.columnList#">
        <cfset form[k & QGetFile.currentRow] = QGetFile[k][QGetFile.currentRow]>
      </cfloop>
    </cfloop>
    
    
    <cfset form.recordCount = QGetFile.recordCount>
	<cfset formMinusRecordCount = (3 - #val(form.recordCount)#)>
	<cfset totalcount = (#val(form.recordCount)# + #formMinusRecordCount#)>
    
    
            <table width="610">
              <cfoutput>
                 <cfloop from="1" to="#val(form.recordCount)#" index="ii"> 
                  <tr>        
                  <td style="width:120px;">File Description</td>
                    <td colspan="2" align="left" valign="top" style="padding-right:5px;">             
                    <INPUT TYPE="hidden" NAME="FileID#ii#" id="FileID#ii#" value="#form['FileID'&ii]#">
                    <INPUT TYPE="text" NAME="FileDescription#ii#" value="#form['FileName'&ii]#" id="FileDescription#ii#" style="width:400px;">
                 </tr>
                  <tr>
                    <td style="width:120px;">&nbsp;</td>
                    <td align="left" valign="top" style="padding-right:5px;">
                   <INPUT TYPE="FILE" NAME="AttachFile#ii#" id="AttachFile#ii#" onchange="return validateFileExtension(this,'FileName#ii#','Path#ii#');" class="file" style="width:400px;"> 
                    </td>
                    <td align="left" valign="top" style="padding-right:5px;"> 
                <input type="button" value="Delete" name="DeleteFile#ii#" id="DeleteFile#ii#" style="height:20px;float:right;" onclick="clearFile('AttachFile#ii#','FileDescription#ii#','FileName#ii#', 'Path#ii#', 'FileID#ii#' );" />  
                    </td>                    
                  </tr>
                 </cfloop>
                 
                 <cfif #formMinusRecordCount# gt 0>
                   <cfloop from="#val(form.recordCount)# + 1" to="#totalcount#" index="ii"> 
                   <tr>        
                  <td style="width:120px;">File Description</td>
                    <td colspan="2" align="left" valign="top" style="padding-right:5px;">             
                    <INPUT TYPE="hidden" NAME="FileID#ii#" id="FileID#ii#" value="#form['FileID'&ii]#">
                    <INPUT TYPE="text" NAME="FileDescription#ii#" value="#form['FileName'&ii]#" id="FileDescription#ii#" style="width:400px;">
                 </tr>
                  <tr>
                    <td style="width:120px;">&nbsp;</td>
                    <td align="left" valign="top" style="padding-right:5px;">
                   <INPUT TYPE="FILE" NAME="AttachFile#ii#" id="AttachFile#ii#" onchange="return validateFileExtension(this,'FileName#ii#','Path#ii#');" class="file" style="width:400px;"> 
                    </td>
                    <td align="left" valign="top" style="padding-right:5px;"> 
                <input type="button" value="Delete" name="DeleteFile#ii#" id="DeleteFile#ii#" style="height:20px;float:right;" onclick="clearFile('AttachFile#ii#','FileDescription#ii#','FileName#ii#', 'Path#ii#', 'FileID#ii#' );" />  
                    </td>                    
                  </tr>
                 
                 </cfloop>
                 </cfif>
                 
				</cfoutput>
                  <tr>
                  <td style="width:100px;">&nbsp;</td>
                  <td colspan="2"><br />
                    <input type="Hidden" name="recordCount" id="recordCount" value="#val(form.recordCount)#">
                  <input type="submit" name="SubLogEntry" id="SubLogEntry" value="Submit Log" onclick="return ValidateForm();" >
                  <input type="button" name="GoBack" id="GoBack" value="Go Back" onclick="history.go(-1);" ></td>
                  </tr>
                  </table> 

Open in new window

0
 
LVL 39

Expert Comment

by:gdemaria
ID: 39994483
Try using min()

You could limit theloop..

<cfloop  from="1"   to="#min(val(form.recordCount),3)#"   index="ii">


or  this may be better to limit the value of recordCount so you it is holding the right number....

<cfset form.recordCount = min(form.recordCount, 3)>


Or come to think of it.   Just limit the records fetch from your query...


<cfquery name = "QGetFile"  datasource='#strDSN#' username='#strUID#' password='#strPWD#' result="file" maxrows="3">
0
 

Author Comment

by:lulu50
ID: 39994573
gdemaria,

Thank you for all your help.

It work great!!!!!

Thank you again and maybe again lol lol
0
 

Author Closing Comment

by:lulu50
ID: 39994575
Thanks,
0
 
LVL 39

Expert Comment

by:gdemaria
ID: 39994964
when you've got the same part done (put it at the top of the same file) , I can help you with a pass-through on error.

That is, when you have an error, the page will show the error message and the form will display all the same values, but not be saved.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Today, I was working on some optimization and spam-stopping techniques when I encountered Ben Nadel's post to reduce spam feature using Math (http://www.bennadel.com/blog/197-How-I-Stop-Spammers-On-My-ColdFusion-Blog.htm). While this method is not o…
Sometimes databases have MILLIONS of records and we need a way to quickly query that table to return the results me need. Sure you could use CFQUERY but it takes too long when there are millions of records. That is why SOLR was invented. Please …
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now