2

I have a requirement to restrict input on a textbox. On page load, the text boxes in a repeater are auto-filled with the carton quantity of the item in the repeater. I'm doing this in the OnItemCreated method with this code:

txt.Text = DataBinder.Eval(e.Item.DataItem, "CtnQty").ToString();

What I need to do is restirct the input (preferrably using Javascript) so that if more than the default value is selected, the value is automatically set to the next multiple. If less, whatever value is entered is accepted. So for example, if the default is 12 and 13 is entered, it needs to auto-correct this to 24. If 11 is entered, the value stays at 11.

I have been playing with the Math.round function, like so:

<input type="text" onblur="this.value=Math.round(parseInt(this.value)/12)*12" />

But I can't get it to accept a dynamic value. Doing this causes a 'server tag is not well formed' parse error:

<input type="text" onblur="this.value=Math.round(parseInt(this.value)/<%# DataBinder.Eval(Container.DataItem, "CTNQTY") %>)*<%# DataBinder.Eval(Container.DataItem, "CTNQTY") %>" />

And then I'll have the problem of the accept if less than default, multiplt if more. I think I need a more detailed Javascript function for this, but after much Googling can't find what I'm after. Any ideas will be most welcome.

Thanks

odinel
  • 566
  • 1
  • 5
  • 28
  • @deathApril: I have the original value stored in the CTNQTY dataitem. I tried submitting it using ' instead of " (on jbl's suggestion). The syntax didn't error, but it didn't work either. Are you suggesting I need to store it on the page, in a hidden field or something...? – odinel Oct 25 '12 at 16:04
  • on second reading, your solution for this is good enought, e.g. `var defaultValue = <%# DataBinder.Eval(Container.DataItem, "CTNQTY") %>`, i used html5 `data-*` approach for better readability of the output code, e.g. if you have more input fields – Aprillion Oct 25 '12 at 16:31

2 Answers2

0

First, I would say that code using DataItem should be located in ItemDataBound, unless you bind your data on each postback, which is not always good practice.

About the not well formed tag, you can try something like this, using single quotes for your onblur :

<input type="text" onblur='this.value=Math.round(parseInt(this.value)/<%# DataBinder.Eval(Container.DataItem, "CTNQTY") %>)*<%# DataBinder.Eval(Container.DataItem, "CTNQTY") %>' />

About a js function, maybe this example can be of some help (BTW : using libraries such as jQuery for event handling should be a way better option) :

http://jsfiddle.net/nqCGp/

<html>
    <body>

      <script>
            function verify(qty){
               return function(event){event.target.value=Math.round(parseInt(event.target.value)/qty)*qty;};
            }
              </script>
      <form>
              <input type='text' onblur="(verify(12))(event)"/>
              <input type='text' onblur="(verify(14))(event)"/>        
      </form>
    </body>
</html>
jbl
  • 15,179
  • 3
  • 34
  • 101
  • almost +1, but why are you using `onblur` as html argument instead of an event handler inside script??? – Aprillion Oct 25 '12 at 15:51
  • @deathApril : in fact I'm not really familiar with html event handling syntax, mostly using jQuery these days. But I wanted to stay close to the question. I will edit to mention that there are way better options ;-) – jbl Oct 25 '12 at 15:57
  • see my answer for simplyfied solution using pure javascript – Aprillion Oct 25 '12 at 16:26
  • @odinel btw in your repeater my example would translate to : – jbl Oct 26 '12 at 07:39
0

this is a html5 + pure javascript solution for your problem - use jQuery or feature detection for cross-browser and future compatibility of handling the change event (similar to blur, but only if something was changed, should work if user presses enter before the form is submitted, but i didn't test it)

<input type="number" id="ctnQty" value="14" data-default-value="14">
<script>
    var changeHandler = function(e) {
        var defaultValue = e.target.dataset.defaultValue;
        var v = e.target.value;
        if (v > defaultValue) {
            v = (Math.floor(v / defaultValue) + 1) * defaultValue;
            e.target.value = v;
        };
    };
    document.getElementById("ctnQty").onchange = changeHandler;
</script>

UPDATE: more general solution with reusable function and local variables

http://jsfiddle.net/Aprillion/CcQ6t/3/

Community
  • 1
  • 1
Aprillion
  • 21,510
  • 5
  • 55
  • 89
  • looks like change event [doesn't propagate](http://stackoverflow.com/q/265074/1176601), so `e.target` can be replaced by `this` – Aprillion Oct 25 '12 at 16:56
  • it's possible to get the original `value` property and store it as `defaultValue` without `data-*` attributes - let me know if it's needed and i update the answer – Aprillion Oct 25 '12 at 17:01
  • Thanks for the tips guys. I've been dragged off this job today unfortunately, but will be able to look again with fresh eyes on Monday and hopefully sort it out. – odinel Oct 26 '12 at 14:24