Solved

Calling JS Calendar from image rather than text box in form

Posted on 2008-06-11
27
781 Views
Last Modified: 2010-04-21
Hi there,

I've got a form on page. It has two inputs:

1) hidden input that is set through an area variable
2) text box that when clicked calls a javascript calendar. When a date is selected it also submits the form.

What I want is to not use a text box but use an image that when clicked makes the JS calendar appear. Is this possible?

I've included two parts of my script. The form and the JS for the calendar.

Thanks in advance,

Daniel
<form action="clubnights.php" method="post" id="myForm">
 

Change date to: <input onclick="ds_sh(this);" name="clubnightdate" readonly="readonly" style="cursor: text" size="20">
 

<input type="hidden" name="areaid" value="<?php echo $aid; ?>"  />

<input type="hidden" name="submitted" value="TRUE" />
 
 

</form>
 

JS calendar
 

<script type="text/javascript">

// <!-- <![CDATA[
 

// Project: Dynamic Date Selector (DtTvB) - 2006-03-16

// Script featured on JavaScript Kit- http://www.javascriptkit.com

// Code begin...

// Set the initial date.

var ds_i_date = new Date();

ds_c_month = ds_i_date.getMonth() + 1;

ds_c_year = ds_i_date.getFullYear();
 

// Get Element By Id

function ds_getel(id) {

	return document.getElementById(id);

}
 

// Get the left and the top of the element.

function ds_getleft(el) {

	var tmp = el.offsetLeft;

	el = el.offsetParent

	while(el) {

		tmp += el.offsetLeft;

		el = el.offsetParent;

	}

	return tmp;

}

function ds_gettop(el) {

	var tmp = el.offsetTop;

	el = el.offsetParent

	while(el) {

		tmp += el.offsetTop;

		el = el.offsetParent;

	}

	return tmp;

}
 

// Output Element

var ds_oe = ds_getel('ds_calclass');

// Container

var ds_ce = ds_getel('ds_conclass');
 

// Output Buffering

var ds_ob = ''; 

function ds_ob_clean() {

	ds_ob = '';

}

function ds_ob_flush() {

	ds_oe.innerHTML = ds_ob;

	ds_ob_clean();

}

function ds_echo(t) {

	ds_ob += t;

}
 

var ds_element; // Text Element...
 

var ds_monthnames = [

'January', 'February', 'March', 'April', 'May', 'June',

'July', 'August', 'September', 'October', 'November', 'December'

]; // You can translate it for your language.
 

var ds_daynames = [

'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'

]; // You can translate it for your language.
 

// Calendar template

function ds_template_main_above(t) {

	return '<table cellpadding="3" cellspacing="1" class="ds_tbl">'

	     + '<tr>'

		 + '<td class="ds_head" style="cursor: pointer" onclick="ds_py();">&lt;&lt;</td>'

		 + '<td class="ds_head" style="cursor: pointer" onclick="ds_pm();">&lt;</td>'

		 + '<td class="ds_head" style="cursor: pointer" onclick="ds_hi();" colspan="3">[Close]</td>'

		 + '<td class="ds_head" style="cursor: pointer" onclick="ds_nm();">&gt;</td>'

		 + '<td class="ds_head" style="cursor: pointer" onclick="ds_ny();">&gt;&gt;</td>'

		 + '</tr>'

	     + '<tr>'

		 + '<td colspan="7" class="ds_head">' + t + '</td>'

		 + '</tr>'

		 + '<tr>';

}
 

function ds_template_day_row(t) {

	return '<td class="ds_subhead">' + t + '</td>';

	// Define width in CSS, XHTML 1.0 Strict doesn't have width property for it.

}
 

function ds_template_new_week() {

	return '</tr><tr>';

}
 

function ds_template_blank_cell(colspan) {

	return '<td colspan="' + colspan + '"></td>'

}
 

function ds_template_day(d, m, y) {

	return '<td class="ds_cell" onclick="ds_onclick(' + d + ',' + m + ',' + y + ')">' + d + '</td>';

	// Define width the day row.

}
 

function ds_template_main_below() {

	return '</tr>'

	     + '</table>';

}
 

// This one draws calendar...

function ds_draw_calendar(m, y) {

	// First clean the output buffer.

	ds_ob_clean();

	// Here we go, do the header

	ds_echo (ds_template_main_above(ds_monthnames[m - 1] + ' ' + y));

	for (i = 0; i < 7; i ++) {

		ds_echo (ds_template_day_row(ds_daynames[i]));

	}

	// Make a date object.

	var ds_dc_date = new Date();

	ds_dc_date.setMonth(m - 1);

	ds_dc_date.setFullYear(y);

	ds_dc_date.setDate(1);

	if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {

		days = 31;

	} else if (m == 4 || m == 6 || m == 9 || m == 11) {

		days = 30;

	} else {

		days = (y % 4 == 0) ? 29 : 28;

	}

	var first_day = ds_dc_date.getDay();

	var first_loop = 1;

	// Start the first week

	ds_echo (ds_template_new_week());

	// If sunday is not the first day of the month, make a blank cell...

	if (first_day != 0) {

		ds_echo (ds_template_blank_cell(first_day));

	}

	var j = first_day;

	for (i = 0; i < days; i ++) {

		// Today is sunday, make a new week.

		// If this sunday is the first day of the month,

		// we've made a new row for you already.

		if (j == 0 && !first_loop) {

			// New week!!

			ds_echo (ds_template_new_week());

		}

		// Make a row of that day!

		ds_echo (ds_template_day(i + 1, m, y));

		// This is not first loop anymore...

		first_loop = 0;

		// What is the next day?

		j ++;

		j %= 7;

	}

	// Do the footer

	ds_echo (ds_template_main_below());

	// And let's display..

	ds_ob_flush();

	// Scroll it into view.

	ds_ce.scrollIntoView();

}
 

// A function to show the calendar.

// When user click on the date, it will set the content of t.

function ds_sh(t) {

	// Set the element to set...

	ds_element = t;

	// Make a new date, and set the current month and year.

	var ds_sh_date = new Date();

	ds_c_month = ds_sh_date.getMonth() + 1;

	ds_c_year = ds_sh_date.getFullYear();

	// Draw the calendar

	ds_draw_calendar(ds_c_month, ds_c_year);

	// To change the position properly, we must show it first.

	ds_ce.style.display = '';

		// Move the calendar container!

	the_left = ds_getleft(t);

	the_top = ds_gettop(t) + t.offsetHeight;

	ds_ce.style.left = the_left + 'px';

	ds_ce.style.top = the_top + 'px';
 

}
 

// Hide the calendar.

function ds_hi() {

	ds_ce.style.display = 'none';

}
 

// Moves to the next month...

function ds_nm() {

	// Increase the current month.

	ds_c_month ++;

	// We have passed December, let's go to the next year.

	// Increase the current year, and set the current month to January.

	if (ds_c_month > 12) {

		ds_c_month = 1; 

		ds_c_year++;

	}

	// Redraw the calendar.

	ds_draw_calendar(ds_c_month, ds_c_year);

}
 

// Moves to the previous month...

function ds_pm() {

	ds_c_month = ds_c_month - 1; // Can't use dash-dash here, it will make the page invalid.

	// We have passed January, let's go back to the previous year.

	// Decrease the current year, and set the current month to December.

	if (ds_c_month < 1) {

		ds_c_month = 12; 

		ds_c_year = ds_c_year - 1; // Can't use dash-dash here, it will make the page invalid.

	}

	// Redraw the calendar.

	ds_draw_calendar(ds_c_month, ds_c_year);

}
 

// Moves to the next year...

function ds_ny() {

	// Increase the current year.

	ds_c_year++;

	// Redraw the calendar.

	ds_draw_calendar(ds_c_month, ds_c_year);

}
 

// Moves to the previous year...

function ds_py() {

	// Decrease the current year.

	ds_c_year = ds_c_year - 1; // Can't use dash-dash here, it will make the page invalid.

	// Redraw the calendar.

	ds_draw_calendar(ds_c_month, ds_c_year);

}
 

// Format the date to output.

function ds_format_date(d, m, y) {

	// 2 digits month.

	m2 = '00' + m;

	m2 = m2.substr(m2.length - 2);

	// 2 digits day.

	d2 = '00' + d;

	d2 = d2.substr(d2.length - 2);

	// YYYY-MM-DD

	return y + '-' + m2 + '-' + d2;

}
 

// When the user clicks the day.

function ds_onclick(d, m, y) {

	// Hide the calendar.

	ds_hi();

	

	// ***** add the line below

	

	// Set the value of it, if we can.

      if (typeof(ds_element.value) != 'undefined') {

            ds_element.value = ds_format_date(d, m, y);

      // Maybe we want to set the HTML in it.

      } else if (typeof(ds_element.innerHTML) != 'undefined') {

            ds_element.innerHTML = ds_format_date(d, m, y);

      // I don't know how should we display it, just alert it to user.

      } else {

            alert (ds_format_date(d, m, y));

      }
 
 

   // we ADD THe FOLLOWING:

   document.getElementById("myForm").submit();

   }

Open in new window

0
Comment
Question by:dm404
  • 11
  • 9
  • 2
27 Comments
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
You can try something like this:

<!--- include field --->
Change date to: <input onclick="ds_sh(this);" id="clubnightdate" name="clubnightdate" readonly="readonly" style="cursor: text" size="20">
<!--- include image --->
<a href="Javascript:ds_sh('clubnightdate');"><img src="images/ico_calendar_bl.gif" width="12" height="12" border="0"></a>

0
 

Author Comment

by:dm404
Comment Utility
Hi msfletch,

The script produces the same textbox, which acts the same as it did before.

Also there is a small square next to it, which calls the calendar but also has a pop up after day has been selected.

Any more ideas?

Thanks in advance,

Daniel
0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
Daniel,

The square is caused by the fact that you most likely do not have the image "images/ico_calendar_bl.gif" on your server. Replace the image ref with whatever image you are wanting to use.

So you do not want the textbox to show, and you want the calendar to submit on checkout?

Try this:

<!--- include hidden date field --->
<input type=hidden id="clubnightdate" name="clubnightdate" onChange="document.myForm.submit();">

** The above will require you to add the name element to the form tag at the top of the page and call it myForm like:

<form action="clubnights.php" method="post" id="myForm" name="myForm">

<!--- include image --->
Change date to: <a href="Javascript:ds_sh('clubnightdate');"><img src="calendar_icon_here" width="12" height="12" border="0"></a>

** Above requires you to replace the "calendar_icon_here" with the image reference for whatever you want people to click on to open the calendar.

Hope this helps.
0
 

Author Comment

by:dm404
Comment Utility
Hi msflecth.

The good news is that I can now see the image and it calls the calendar when clicked.

The bad news..

The page functionality has stopped working i.e. its not returning any records.

The way I have it set up at the moment is that when a day is selected on the calendar the form is submitted. This was working fine, this is included in the JS of the calendar (see below).

I'm not sure how to get around this problem?

// When the user clicks the day.

function ds_onclick(d, m, y) {

	// Hide the calendar.

	ds_hi();

	

	// Set the value of it, if we can.

      if (typeof(ds_element.value) != 'undefined') {

            ds_element.value = ds_format_date(d, m, y);

      // Maybe we want to set the HTML in it.

      } else if (typeof(ds_element.innerHTML) != 'undefined') {

            ds_element.innerHTML = ds_format_date(d, m, y);

      // I don't know how should we display it, just alert it to user.

      } else {

            alert (ds_format_date(d, m, y));

      }
 
 

   // we ADD THe FOLLOWING:

   document.getElementById("myForm").submit();

   }

Open in new window

0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
OK,

So you already have the calendar submitting from the existing JS. Try removing the onChange="document.myForm.submit();" from the "clubnightdate" form field. This is likely keeping things from processing correctly.
0
 

Author Comment

by:dm404
Comment Utility
HI MSflecth,

Thanks for your time again.

OK so I removed the onChange="document.myForm.submit();" .

From what I can see the form is being submitted however its still not working properly. This is what happens..

I click a date, a pop up appears with the date I selected, the form submits, page reloads without date value present?

Any idea why this is happening?

Thanks again,

Daniel
0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
Daniel,

Are there any javascript errors that appear, like "value expected" or anything like that? I will have to look at the code more closely to see what the JS is actually doing, but until then, a thought I had was that the problem may be due to the JS submitting the form before the value is added.

You can try adding the onChange="document.myForm.submit();" back to the hidden text field and removing the document.getElementById("myForm").submit(); from the JS to see what happens.

Let me know how that goes.
0
 

Author Comment

by:dm404
Comment Utility
Hmm when I do the above it says error on page on the bottom left of the browser... : (.

Thanks for your efforts so far.

The way I have the form at the top definitely works.
0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
Just to verify, did you add the name="myForm" to the form code like so:

<form action="clubnights.php" method="post" id="myForm" name="myForm">

Referencing a form with the onChange="document.myForm.submit();" would not read the ID value of the form element, only the name element.

You could also change the inline peice from:

<input type=hidden id="clubnightdate" name="clubnightdate" onChange="document.myForm.submit();">

... to what you had in the JS:

<input type=hidden id="clubnightdate" name="clubnightdate" onChange="document.getElementById("myForm").submit(); ">

0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
Also,

Double-clicking the "error on page" message should bring up an alert box mith more information and a line number reference. Having the actual error and the code from that line number (along eith the 10 lines before and after) would be helpful in troubleshooting the issue.
0
 

Author Comment

by:dm404
Comment Utility
Just to verify, did you add the name="myForm" to the form code like so:

<form action="clubnights.php" method="post" id="myForm" name="myForm">
-- Yes i have done this.

The error that comes on the bottom left declares line 397 which is the } else { line....

      // Set the value of it, if we can.
      if (typeof(ds_element.value) != 'undefined') {
            ds_element.value = ds_format_date(d, m, y);
      // Maybe we want to set the HTML in it.
      } else if (typeof(ds_element.innerHTML) != 'undefined') {
            ds_element.innerHTML = ds_format_date(d, m, y);
      // I don't know how should we display it, just alert it to user.
      } else {
            alert (ds_format_date(d, m, y));
      }


   // we ADD THe FOLLOWING:
   document.getElementById("myForm").submit();
   }

Hope this helps,
#

Thanks again!
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

 
LVL 4

Expert Comment

by:msfletch
Comment Utility
OK dm404,

Sometimes these things come down to relationships and context which are hard to identify without the code to test. Can you post your entire code set (as it now sits) so I can view it all in context.

Thanks.

0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
Sorry I couldn't help more. Good luck.
0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
dm404,

I just wanted to post my final thoughts here in case anyone happened upon before the question was deleted. If you have not already solved the issue, this may help:

Since the text field was working correctly before being hidden and before the the image reference was added, it would seemt o indicate that one of two things would cause the problem:

1) The javascript is having an issue with the "hidden" type of the text field. You could try replacing it with [style="display:none"] to achieve the same visible effect without actually defining it as hidden. This might workbetter with the JS Calendar Javascript.

2) The JS Calendar code is having a problem with the pointing if the reference. You could try using a fully qualified reference like:

<a href="Javascript:ds_sh('document.myForm.clubnightdate');"><img src="calendar_icon_here" width="12" height="12" border="0"></a>

... instead of:

<a href="Javascript:ds_sh('clubnightdate');"><img src="calendar_icon_here" width="12" height="12" border="0"></a>

Anyway .. happy coding!
0
 

Author Comment

by:dm404
Comment Utility
Hi MSfletch,

Thanks for your persistance!! I'll have a go tonight.

PS I didn't realise the question would be deleted!

Don't care about the refund..I just want to call this JS from an image :)
0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
No worries. I don't like to see questions go unanswered, especially with so much good back and forth. Good luck! =)
0
 

Author Comment

by:dm404
Comment Utility
Hi PenguinMod,

I'd very much like to leave the question open. If you could call additional experts that would be awesome, it is a tricky question so the more the merrier!

Thanks again,

Dan
0
 
LVL 75

Accepted Solution

by:
Michel Plungjan earned 500 total points
Comment Utility
1. use
<a href="#"
onClick="ds_sh(document.myForm.clubnightdate); // NOTE THE LACK OF QUOTES! We are passing the object itself
return false"><img src="calendar_icon_here" width="12" height="12" border="0"></a>

which is the canonical way of calling a script without leaving the page and to pass it the field

2. to call submit from a field in the form, you can do this.form.submit() HOWEVER

3. onChange is NOT triggered when a field is updated by script and even if it were, I am sure that a HIDDEN field would not trigger onChange anyway.

so the best way seems to use ds_element.form.submit() in the calendar script just after the field is filled (or use the document.getElementById('myForm').submit() like you have now, but then the form must have an ID too)

Michel
<form NAME="myForm" id="myForm">

<input name="clubnightdate" type="hidden">

 

<input type="hidden" name="areaid" value="x"  />

<input type="hidden" name="submitted" value="TRUE" />

 

 

</form>

<div id="ds_conclass"></div>

<div id="ds_calclass"></div>

<a href="#"

onClick="ds_sh(document.myForm.clubnightdate); 

return false"><img src="calendar_icon_here" width="12" height="12" border="0"></a>

Open in new window

0
 
LVL 75

Expert Comment

by:Michel Plungjan
Comment Utility
And the "B" grade was because?
0
 
LVL 4

Expert Comment

by:msfletch
Comment Utility
Grades should be given based on answers from an individual, not the group as a whole. They affect the point total given to the one whose answer is accepted.
0
 

Author Comment

by:dm404
Comment Utility
My bad.
0
 

Author Closing Comment

by:dm404
Comment Utility
Good Job, sorry about the previous grading.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
In this tutorial viewers will learn how to style transparent/translucent elements using alpha transparency in CSS Start with a normal styled element, such as a div.: Define its "background-color" property as "rgba (255, 255, 255, .5): The numbers in…
In this tutorial viewers will learn how to embed custom externally-hosted Google Fonts using the Google Font API in CSS Go to the Google Fonts website at google.com/fonts: Browse or search based on font properties or name to find a suitable font for…

762 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

12 Experts available now in Live!

Get 1:1 Help Now