Can validate and converter be combined in jsViews data-link? - jsviews

I can ensure data exists in an input element by including validate and required in jsViews' data-link attribute like this:
<input type="text" data-link="{validate activityCode required=true}">
And by following Boris Moore's example I can ensure the data returned to the model is cast as an integer instead of input's default type of string:
$.views.converters({
toInt: function(value) {
return parseInt(value); // simple example, without error checking
}
});
<input type="text" data-link="{:activityCode:toInt}">
Where I'm having a problem is combining both validation and converter. Nothing binds to the input element using this:
<input type="text" data-link="{validate activityCode:toInt required=true}">
Does anyone know of syntax that allows both validation and convertBack functionality to exist in the same data-link attribute?

You can use the syntax convert=... convertBack=... on any tag.
See two-way binding - convert and convertBack and using converters with other tags. (The second docs reference is for JsRender, so concerns convert only. But if using JsViews data-linking, then convertBack=... works in just the same way.)
Search for "convertBack=" and you'll find some examples, including this with radiogroup and this one with validate.

Related

How to pass handlebar item to function?

So, let's say that this is part of my code:
<li data-product-id="{{this.id}}"></li>
and after a few lines, I have this
<button id="Button" onclick="addToCart(${{this.id}})">Press</button>
However, ${{this.id}} doesn't seem to be right.
What should I write instead?
I am not sure what the dollar sign $ in the argument to your onclick handler is intended for. However, the onclick handler is JavaScript and therefore must contain valid JavaScript code.
If the dollar sign is to prepended to the product ID in the addToCart argument, then you will need to use quotations in order to make this argument a valid JavaScript string:
<button id="Button" onclick="addToCart('${{this.id}}')">Press</button>
Perhaps the dollar sign is not intended to be a part of the argument and it is being used mistakenly in a similar way to a JavaScript template string. If this is the case, the quotes will be required in the addToCart call only if the argument is intended to be a string. If the argument is to be a string, then the template should be:
<button id="Button" onclick="addToCart('{{this.id}}')">Press</button>
But if the argument is to be a number, then the quotes should not be included:
<button id="Button" onclick="addToCart({{this.id}})">Press</button>
I have provided a fiddle for reference.
Update
To "get" the item is a little more complicated. This is because, one the template is rendered, there is no existing reference to the data that was passed to the template function.
There are different approaches to solving this problem and the solution may be dependant upon your requirements. However, one simple way to render the entire product item object as the argument to addToCart would be to JSON.stringify the item where it is rendered. This would require writing a Handlebars helper, like:
Handlebars.registerHelper('serialize', obj => JSON.stringify(obj));
You would then utilize this helper in your template with:
<button id="Button" onclick="addToCart({{serialize this}})">Press</button>
I have created an example fiddle.

Get length of a string with data-link

I would like to display the length of the text in my textarea. But since I don't want to build an event handler for it, I would like to try to solve this with the data-link. Unfortunately I don't find a way to do this.
<textarea id="commentText" data-link="commentText()"></textarea>
<span><span id="commentTextLength">{^{>commentText().length}}</span>/300</span>
You can simply change the expression from commentText().length to commentText()^length.
See "deep linking".
In that way you make the expression update whenever there is an observable change in commentText() itself.
So you can write:
{^{>commentText()^length}}
or
<span data-link="commentText()^length"></span>
This works equally whether you are using a plain string value commentText^length or a computed observable commentText()^length as in your example.

Binding an inputText value to a viewScope with a computed name

I have an inputText component on a custom control and I am trying to bind the value to a viewScope, but the viewScope name is computed using a compositeData value and string.
If I hardcode the value binding it works, for example:
value="${viewScope['BillingDate_From']}"
The viewScope name is computed using the following javascript code:
compositeData.dateRangeFilter[0].from_fieldname + '_From'
I have tried many ways of achieving this but with no success, sometimes it errors, usually unexpected character errors but most of the time the inputText box is empty.
The code I have most recently tried:
value="${viewScope[#{javascript:compositeData.dateRangeFilter[0].from_fieldname + '_From'}]}"
I have found, and I don't know the reason for this, that trying to bind dynamically doesn't work if there's any string concatenation in the evaluation. The way I got around this was by creating a custom control that accepts a bindingValue and dataSource as parameters, then passing in the document and field name I want to use. For whatever reason, if the code uses composite data, it still allows for editing when the page loads.
Hi try this to build what you need:
The Control:
<xp:inputText id="inputText1">
<xp:this.value><![CDATA[${javascript:"#{"+compositeData.scopeName+"}";}]]></xp:this.value>
</xp:inputText>
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[${javascript:"#{"+compositeData.scopeName+"}";}]]></xp:this.value>
</xp:text>
The XPage using the Control:
<xc:cc id="xx">
<xc:this.scopeName><![CDATA[#{javascript:return "viewScope." + " calculatedScopeVarName";}]]></xc:this.scopeName>
</xc:cc>
<xp:button value="Beschriftung" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="xx">
<xp:this.action><![CDATA[#{javascript://}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
Instead of "viewScope" you cant add session or another scope and instead of calculatedScopeVar you can enter the name of your var. But this has a limit, it only works if the calculatedScopeVar is accesable through the component onLoad. For example it will not work if you use this control in a Repeat control and try to use the repeated array as calculatedScopeVar.

jqGrid: dataurl not working

I'm new to both jQuery and jQGrid. I tried to populate a dropdown combobox in the grid with data coming from server, I'm in java servlet environment.
I used dataUrl method and many others but still no luck with populating combo.
my js looks like:
...
{name:'idTipologia',index:'idTipologia', width:80,editable: true,edittype:"select",editoptions:{dataUrl: "/sohara/comboTipologiaAction.do"}...
...
my server side code basically is:
take a list from server, format data (whether json or not), open a PrintWriter, write info in it.
I tried both JSON conversion and plain text from Firebug I can see the response correctly formatted ("1:VALUE1;2:VALUE2")but the dropdown remains empty.
My question is:
Is there a peculiar way to organize the data in order to make this combo population?
Any help appreciated.
According to the jqGrid documentation, your problem is that the dataUrl needs to return HTML containing the SELECT element, not JSON:
The editoptions dataUrl parameter is valid only for element of edittype:select. The dataUrl parameter represent the url from where the html select element should be get.
When this option is set, the element will be filled with values from the AJAX request. The data should be a valid HTML select element with the desired options - something like:
<select>
<option value='1'>One</option>
<option value='2'>Two</option>
...
</select>
So the easiest solution is for you to just return HTML.
That said, I do not like the idea of returning UI elements directly. Another option is to use the buildSelect function to construct the SELECT element for you:
This option is relevant only if the dataUrl parameter is set. When the server response can not build the select element, you can use your own function to build the select. The function should return a string containing the select and options value(s) as described in dataUrl option. Parameter passed to this function is the server response
This answer provides an example of how to use buildSelect.

Handling Arrays of HTML Input Elements with Request.Form Like PHP

How can I properly receive these Array of Inputs on asp.net?
<input type=hidden name='field[name][]' value='alex' />
<input type=hidden name='field[name][]' value='mark' />
<input type=hidden name='field[name][]' value='helen' />
<input type=hidden name='field[age][]' value='22' />
<input type=hidden name='field[age][]' value='30' />
<input type=hidden name='field[age][]' value='29' />
In php you can access field by $field = $_POST["field"]
$field["name"] and $field["age"] are simply arrays containing names and ages.
actually, it does exist with asp.net. - you can use
string[] MyTest = Request.Form.GetValues("MyTest");
or
string[] MyTest = Request.QueryString.GetValues("MyTest");
You can use a standard string split - this is all php does for you behind the scenes. PHP is not a strongly typed language however which means that it is a LOT easier for them to provide the "appearance" of this functionality.
The reality is that php is just allowing you to provide comma delimited input and it automatically splits it for you.
So... if you want to do this in asp.net, you can use the same input name a number of times and it will be returned with the request object as a comma delimited list. I would not recommend using this approach for user entered input, but it will work fine if you are contrrolling the input like combining a list into a hidden input from a jquery script.
To get your head around what is happening (with php too.. all web dev techs are using the same http rules), just try posting a form with an input (don't set runat server) that is there twice.
<input type="text" name="MyTest" value="MyVal1" />
<input type="text" name="MyTest" value="MyVal2" />
On pageload add this
if(IsPostBack)
{
Response.Write(Request["MyTest"]);
}
You should see
MyVal1,MyVal2
On the screen.
Now, if you want this into an array, you can:
string[] myvals = Request["MyTest"].Split(',');
if you want Integers or other datatypes (php doesn't know/care what a datatype is really), you will have to loop through it and parse it into another array/generic list.
I don't know what your wanting as an end result, but understanding what the browser posts back is the first step and the short answer is...
Yes, ASP.NET can do this to (just a little more manually).
These are not arrays of inputs. HTML doesn't have a concept of arrays.
These are simply groups of inputs with the same name.
What are you trying to achieve? Why are you not using server side controls?
Update:
You can access the Request.Forms collection - it will hold the posted form elements.
Alternatively, use server side controls - you will be able to access these by ID.

Resources