summaryrefslogtreecommitdiff
path: root/httemplate/elements
diff options
context:
space:
mode:
authorIvan Kohler <ivan-debian@420.am>2012-03-15 13:56:48 -0700
committerIvan Kohler <ivan-debian@420.am>2012-03-15 13:56:48 -0700
commit7d68066ea33f9f85fe14ce663372642d7ec2ad20 (patch)
treef659173a23d541da3032f8a8156f888810d7efda /httemplate/elements
parentd622dc369cc0856fb791658b35f889470a7da605 (diff)
parenta69299c596de60f4b26db7431165f7f3ffe928e2 (diff)
Merge branch 'master' of git.freeside.biz:/home/git/freeside
Diffstat (limited to 'httemplate/elements')
-rw-r--r--httemplate/elements/masked_input_1.1.js195
-rw-r--r--httemplate/elements/tr-input-mac_addr.html11
-rw-r--r--httemplate/elements/tr-input-mask.html41
-rw-r--r--httemplate/elements/tr-select-router_block_ip.html47
4 files changed, 281 insertions, 13 deletions
diff --git a/httemplate/elements/masked_input_1.1.js b/httemplate/elements/masked_input_1.1.js
new file mode 100644
index 000000000..05efa779b
--- /dev/null
+++ b/httemplate/elements/masked_input_1.1.js
@@ -0,0 +1,195 @@
+/***********************************************************************
+ Masked Input version 1.1
+************************************************************************
+Author: Kendall Conrad
+Home page: http://www.angelwatt.com/coding/masked_input.php
+Created: 2008-12-16
+Modified: 2010-04-14
+Description:
+License: This work is licensed under a Creative Commons Attribution-Share Alike
+ 3.0 United States License http://creativecommons.org/licenses/by-sa/3.0/us/
+
+Argument pieces:
+- elm: [req] text input node to apply the mask on
+- format: [req] string format for the mask
+- allowed: [opt, '0123456789'] string with chars allowed to be typed
+- sep: [opt, '\/:-'] string of char(s) used as separators in mask
+- typeon: [opt, '_YMDhms'] string of chars in mask that can be typed on
+- onbadkey: [opt, null] function to run when user types a unallowed key
+- badkeywait: [opt, 0] used with onbadkey. Indicates how long (in ms) to lock
+ text input for onbadkey function to run
+***********************************************************************/
+function MaskedInput(args)
+{
+ if (args['elm'] === null || args['format'] === null) { return false; }
+ var el = args['elm'],
+ format = args['format'],
+ allowed = args['allowed'] || '0123456789',
+ sep = args['separator'] || '\/:-',
+ open = args['typeon'] || '_YMDhms',
+ onbadkey = args['onbadkey'] || function(){},
+ badwait = args['badkeywait'] || 0;
+
+ var locked = false, hold = 0;
+ el.value = format;
+ // Assign events
+ el.onkeydown = KeyHandlerDown; //
+ el.onkeypress = KeyHandlerPress; // add event handlers to element
+ el.onkeyup = KeyHandlerUp; //
+
+ function GetKey(code)
+ {
+ code = code || window.event, ch = '';
+ var keyCode = code.which, evt = code.type;
+ if (keyCode == null) { keyCode = code.keyCode; }
+ if (keyCode === null) { return ''; } // no key, no play
+ // deal with special keys
+ switch (keyCode) {
+ case 8: ch = 'bksp'; break;
+ case 46: // handle del and . both being 46
+ ch = (evt == 'keydown') ? 'del' : '.'; break;
+ case 16: ch = 'shift'; break;//shift
+ case 0:/*CRAP*/ case 9:/*TAB*/ case 13:/*ENTER*/
+ ch = 'etc'; break;
+ case 37: case 38: case 39: case 40: // arrow keys
+ ch = (!code.shiftKey &&
+ (code.charCode != 39 && code.charCode !== undefined)) ?
+ 'etc' : String.fromCharCode(keyCode);
+ break;
+ // default to thinking it's a character or digit
+ default: ch = String.fromCharCode(keyCode);
+ }
+ return ch;
+ }
+ function KeyHandlerDown(e)
+ {
+ e = e || event;
+ if (locked) { return false; }
+ var key = GetKey(e);
+ if (el.value == '') { el.value = format; SetTextCursor(el,0); }
+ // Only do update for bksp del
+ if (key == 'bksp' || key == 'del') { Update(key); return false; }
+ else if (key == 'etc' || key == 'shift') { return true; }
+ else { return true; }
+ }
+ function KeyHandlerPress(e)
+ {
+ e = e || event;
+ if (locked) { return false; }
+ var key = GetKey(e);
+ // Check if modifier key is being pressed; command
+ if (key=='etc' || e.metaKey || e.ctrlKey || e.altKey) { return true; }
+ if (key != 'bksp' && key != 'del' && key != 'etc' && key != 'shift') {
+ if (!GoodOnes(key)) { return false; }
+ return Update(key);
+ }
+ else { return false; }
+ }
+ function KeyHandlerUp(e) { hold = 0; }
+ function Update(key)
+ {
+ var p = GetTextCursor(el), c = el.value, val = '';
+ // Handle keys now
+ switch (true) {
+ case (allowed.indexOf(key) != -1):
+ if (++p > format.length) { return false; } // if text csor at end
+ // Handle cases where user places csor before separator
+ while (sep.indexOf(c.charAt(p-1)) != -1 && p <= format.length) { p++; }
+ val = c.substr(0, p-1) + key + c.substr(p);
+ // Move csor up a spot if next char is a separator char
+ if (allowed.indexOf(c.charAt(p)) == -1
+ && open.indexOf(c.charAt(p)) == -1) { p++; }
+ break;
+ case (key=='bksp'): // backspace
+ if (--p < 0) return false; // at start of field
+ // If previous char is a separator, move a little more
+ while (allowed.indexOf(c.charAt(p)) == -1
+ && open.indexOf(c.charAt(p)) == -1
+ && p > 1) { p--; }
+ val = c.substr(0, p) + format.substr(p,1) + c.substr(p+1);
+ break;
+ case (key=='del'): // forward delete
+ if (p >= c.length) { return false; } // at end of field
+ // If next char is a separator and not the end of the text field
+ while (sep.indexOf(c.charAt(p)) != -1
+ && c.charAt(p) != '') { p++; }
+ val = c.substr(0, p) + format.substr(p,1) + c.substr(p+1);
+ p++; // Move position forward
+ break;
+ case (key=='etc'): return true; // Catch other allowed chars
+ default: return false; // Ignore the rest
+ }
+ el.value = ''; // blank it first (Firefox issue)
+ el.value = val; // put updated value back in
+ SetTextCursor(el, p); // Set the text cursor
+ return false;
+ }
+ function GetTextCursor(node)
+ {
+ try {
+ if (node.selectionStart >= 0) { return node.selectionStart; }
+ else if (document.selection) {// IE
+ var ntxt = node.value; // getting starting text
+ var rng = document.selection.createRange();
+ rng.text = '|%|';
+ var start = node.value.indexOf('|%|');
+ rng.moveStart('character', -3);
+ rng.text = '';
+ // put starting text back in,
+ // fixes issue if all text was highlighted
+ node.value = ntxt;
+ return start;
+ } return -1;
+ } catch(e) { return false; }
+ }
+ function SetTextCursor(node, pos)
+ {
+ try {
+ if (node.selectionStart) {
+ node.focus();
+ node.setSelectionRange(pos,pos);
+ }
+ else if (node.createTextRange) { // IE
+ var rng = node.createTextRange();
+ rng.move('character', pos);
+ rng.select();
+ }
+ } catch(e) { return false; }
+ }
+ function GoodOnes(k)
+ {
+ if (allowed.indexOf(k) == -1 && k!='bksp' && k!='del' && k!='etc') {
+ var p = GetTextCursor(el); // Need to ensure cursor position not lost
+ locked = true; onbadkey();
+ // Hold lock long enough for onbadkey function to run
+ setTimeout(function(){locked=false; SetTextCursor(el,p);}, badwait);
+ return false;
+ } return true;
+ }
+ function resetField() {
+ el.value = format;
+ }
+ function setAllowed(a) {
+ allowed = a;
+ resetField();
+ }
+ function setFormat(f) {
+ format = f;
+ resetField();
+ }
+ function setSeparator(s) {
+ sep = s;
+ resetField();
+ }
+ function setTypeon(t) {
+ open = t;
+ resetField();
+ }
+ return {
+ resetField:resetField,
+ setAllowed:setAllowed,
+ setFormat:setFormat,
+ setSeparator:setSeparator,
+ setTypeon:setTypeon
+ }
+}
diff --git a/httemplate/elements/tr-input-mac_addr.html b/httemplate/elements/tr-input-mac_addr.html
new file mode 100644
index 000000000..d768d4e71
--- /dev/null
+++ b/httemplate/elements/tr-input-mac_addr.html
@@ -0,0 +1,11 @@
+<& /elements/tr-input-mask.html,
+ format => '__:__:__:__:__:__',
+ allowed => '0123456789ABCDEFabcdef',
+ %opt,
+&>
+<%init>
+my %opt = @_;
+my $value = length($opt{curr_value}) ? $opt{curr_value} : $opt{value};
+$value =~ s/\W//g;
+$opt{curr_value} = join(':', $value =~ /../g);
+</%init>
diff --git a/httemplate/elements/tr-input-mask.html b/httemplate/elements/tr-input-mask.html
new file mode 100644
index 000000000..33725b9a5
--- /dev/null
+++ b/httemplate/elements/tr-input-mask.html
@@ -0,0 +1,41 @@
+% if ( !$init ) {
+<script type="text/javascript" src="<%$p%>elements/masked_input_1.1.js">
+</script>
+% $init++;
+% }
+<& /elements/tr-input-text.html, id => $id, @_ &>
+<script type="text/javascript">
+MaskedInput({
+ elm: document.getElementById('<%$id%>'),
+ format: '<% $opt{format} %>',
+ <% $opt{allowed} ? "allowed: '$opt{allowed}'," : '' %>
+ <% $opt{typeon} ? "typeon: '$opt{typeon}'," : '' %>
+});
+document.getElementById('<%$id%>').value = <% $value |js_string %>;
+</script>
+<%shared>
+my $init = 0;
+</%shared>
+<%init>
+my %opt = @_;
+# must have a DOM id
+my $id = $opt{id} || sprintf('input%04d',int(rand(10000)));
+my $value = length($opt{curr_value}) ? $opt{curr_value} : $opt{value} || '';
+</%init>
+<%doc>
+Set up a text input field with input masking.
+
+<& /elements/tr-input-mask.html,
+ format => '____-__-__',
+ #typeon => '_YMDhms', # which characters in the format represent blanks
+ #allowed => '0123456789', # characters allowed in the blanks
+ ... all other options as for tr-input-text.html
+&>
+
+Note that the value sent on form submission will contain the mask
+separators, and if value/curr_value is passed, it should also be
+formatted to fit the mask.
+
+Uses masked_input_1.1.js by Kendall Conrad, available under a Creative Commons
+Attribution-ShareAlike license.
+</%doc>
diff --git a/httemplate/elements/tr-select-router_block_ip.html b/httemplate/elements/tr-select-router_block_ip.html
index 45d1dacd8..ed8fe810f 100644
--- a/httemplate/elements/tr-select-router_block_ip.html
+++ b/httemplate/elements/tr-select-router_block_ip.html
@@ -1,14 +1,22 @@
<script type="text/javascript">
-var auto_addr_routernum = <% encode_json(\%auto_addr_routernum) %>;
-function hide_if_auto_addr(obj, i) {
+var manual_addr_routernum = <% encode_json(\%manual_addr_routernum) %>;
+var ip_addr_curr_value = <% $opt{'ip_addr'} |js_string %>;
+function lock_ip_addr(obj, i) {
var routernum = obj.value;
var select_blocknum = document.getElementsByName('blocknum')[0];
- var label_auto_addr = document.getElementById('label_auto_addr');
var input_ip_addr = document.getElementById('input_ip_addr');
- var auto = ( auto_addr_routernum[routernum] == 'Y' );
- select_blocknum.style.display = auto ? '' : 'none';
- label_auto_addr.style.display = auto ? '' : 'none';
- input_ip_addr.style.display = !auto ? '' : 'none';
+ if ( manual_addr_routernum[routernum] == 'Y' ) {
+%# enable ip_addr, default it to its previous value, and hide block selection
+ select_blocknum.style.display = 'none';
+ input_ip_addr.value = ip_addr_curr_value;
+ input_ip_addr.disabled = false;
+ }
+ else {
+%# the reverse
+ select_blocknum.style.display = '';
+ input_ip_addr.disabled = true;
+ input_ip_addr.value = '(automatic)';
+ }
}
</script>
<& /elements/tr-td-label.html, label => ($opt{'label'} || 'Router') &>
@@ -19,7 +27,7 @@ function hide_if_auto_addr(obj, i) {
records => \@routers,
name_col => 'routername',
value_col => 'routernum',
- onchange => 'hide_if_auto_addr',
+ onchange => 'lock_ip_addr',
curr_value=> $opt{'routernum'},
},
{
@@ -44,17 +52,18 @@ function hide_if_auto_addr(obj, i) {
% }
% else {
<input type="text" id="input_ip_addr" name="ip_addr"
- style="display:none" value="<% $opt{'ip_addr'} |h%>">
+ value="<% $opt{'ip_addr'} |h%>">
% }
- <span id="label_auto_addr"><% $opt{'ip_addr'} || '' %>
- <i>(automatic)</i></span>
</td> </tr>
+<input type="hidden" name="prev_ip_addr" value="<% $opt{'ip_addr'} |h%>">
<script type="text/javascript">
-hide_if_auto_addr(document.getElementsByName('routernum')[0],0);
+lock_ip_addr(document.getElementsByName('routernum')[0],0);
</script>
<%init>
+
my %opt = @_;
my @routers;
+my $conf = FS::Conf->new;
my $svc_x = $opt{'object'};
if ( $svc_x ) {
@@ -91,5 +100,17 @@ else {
@routers = qsearch('router', {});
}
-my %auto_addr_routernum = map { $_->routernum, $_->auto_addr } @routers;
+my %manual_addr_routernum = map { $_->routernum, $_->manual_addr } @routers;
+
+if ( $conf->exists('auto_router') ) {
+ # Then show an "(automatic)" router, with no blocks. manual_addr is on
+ # so that the ip_addr field will be unlocked.
+ unshift @routers, FS::router->new({
+ 'routernum' => '',
+ 'routername' => '(automatic)',
+ 'manual_addr' => 'Y',
+ });
+ $manual_addr_routernum{''} = 'Y';
+}
+
</%init>