FilteredTextBox in Lift? - scala

I'm looking for a filteredTextBox in lift to block users from inserting wrong input types.
Something like this Ajax example: http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/FilteredTextBox/FilteredTextBox.aspx
Someone knows something similar in lift or knows if SHtml.ajaxText has some Attribute to do that?

If you are targeting HTML5 capable browsers, SHtml has outputs for specific types - like SHtml.number(...) and SHtml.range(...). You can accomplish the same thing using SHtml.ajaxText(label, func, "type" -> "number") (or "type" -> "range", etc...).
To target other browsers (or for more robust functionality), JQuery might be your best bet. You could write your own validation function to get called, or googling quickly found this library which looks like it would work (though there must be others too). Based on their documentation, to use it, it looks like you'd just need to do this:
Snippet:
//add a class for the type (in this case to validate lowercase)
".lc-input" #> SHtml.ajaxText(label, func, "class" -> "validate-this-lowercase")
Template:
//Add this into a processed template - head_merge should add to the head of the document
<head_merge>
<script type="text/javascript">
$(document).ready(function(){
$(".validate-this-lowercase").filter_input({regex:'[a-z]'});
});
</script>
</head_merge>
<span class="lc-input"></span>

Related

Set class or ID on <h:inputHidden> in JSF

I'm trying to set a class or id parameter on a <h:inputHidden> in JSF. The code looks like this:
<h:inputHidden value="#{getData.name}" class="targ" />
But in the browser, the class isn't set:
<input type="hidden" name="j_idt6" value="j_idt6">
I need to set a class to this parameter, because I have a JavaScript autocomplete function for a <h:inputText> that sets a value in the hidden input, which needs to be passed in the next page.
Any ideas? Thanks!
I know it's a little bit late, but it can help someone in the future.
As inputHidden shows nothing in the browser there's no sense to allow it to have a class.
You can use the Id but as the Id could change as you change the component parents using it would bring some headache.
I'd suggest as a workaround, you can give it a parent so you can manipulate it by javascript.
Exemple:
JSF
<h:panelGroup styleClass="someCssClass">
<h:inputHidden id="someId" value="someValue" />
</h:panelGroup>
Javascript (using jQuery, you could use pure javascript also)
$('.someCssClass input[type=hidden]').val('yourNewValue');
None of these answers here satisfied my needs (need the PrimeFaces component, need class not ID, wrapping is too much work), so here's what I came up with:
Use pass-through attributes: https://www.primefaces.org/jsf-2-2-pass-through-attributes
Use pass:hidden-class="blah" (in my case, it's xmlns:pass up top)
Use [attribute=value] selector:
https://www.w3schools.com/cssref/sel_attribute_value.asp
document.querySelector multiple data-attributes in one element
That basically boils down to using something like this (because h:inputHidden becomes a regular input): document.querySelector("input[hidden-class=" + blah + "]")
Please, see similar question - How can I know the id of a JSF component so I can use in Javascript
You can sed "id" property, but in final html code it can be not the same, but composite: for example, if your input with id="myhidden" is inside form with id="myform", final input will have id="myform:myhidden".
In the end, I used a standard HTML <input type="hidden"> tag, as I had no advantages for using the JSF one. If you're trying to set a value in a hidden input with JavaScript, I recommend using this workaround.

KnockoutJS and Property-Dependent Create/Edit-View (Master/Detail Scenario)

I am having trouble creating a property-dependent create/edit-view in KnockoutJS.
Here's the thing: everything I create are "People" of sorts - it could be a Healthcare Professional, Plumber, Mechanic or Engineer. Depending on what kind/type of person it is, I need to enter different data.
Here an example:
Healthcare Professional: Name, Telephone, Hospital, etc.
Plumber: Name, Telephone, Crafts, etc.
Engineer: Name, Telephone, Specialities, etc.
What I can do is create properties on my ViewModels such as "showCity", "showHospital" and so on to hide individual form-fields.
However, for the sake of separation, I would like to use entirely different forms: again, I could set the respective form to only show if the condition is met.
However, I would like KnockoutJS to only render the respective form that should be used (the Person's type is always determined when it is first created - it cannot be changed).
What I don't end-up doing is have one form that is shown and ten that are there (and data-bound) but hidden.
I tried using the "if" binding like so: <div data-bind="with: $root.selectedPerson"><form data-bind="if: $data.type='mathematician'"></form></div>, but to no avail.
Would anybody know what the best-practice is in this case?
Your if binding is setting the $data.type value, not comparing it. Try:
<div data-bind="with: $root.selectedPerson"><form data-bind="if: $data.type() === 'mathematician'"></form></div>
Although this is fine, I always try to avoid code in my data-binding markup. I would try and create a computed that would return the resulting true/false of the comparison, but in your situation, you would need one for each person type, and that would get tricky. For that, I would turn to templates. You could do:
<div data-bind="template: { name: $root.selectedPerson().type, data: $root.selectedPerson }"></div>
<script type="text/html" id="mathematician">...</script>
<script type="text/html" id="plumber">...</script>
*Note: As of KO version 2.3.0, the name property of the template binding can accept observables. If you're using a previous version, be sure to call the observable in the binding: name: $root.selectedPerson().type()

Parameter and view naming collisions in Play/Scala templates

I am new to Play Framework and still trying to wrap my head around some things with the new Scala template engine.
Let's say I have the following package structure:
app/
app/controllers/Items.scala
app/models/Item.scala
app/views/layouts/page.scala.html
app/views/item/show.scala.html
app/views/item/details.scala.html //partial
And this is my item/show template:
#(item: Item, form: Form[Item])(implicit flash: Flash)
#layout.page() {
#*want to include details partial, wont work due to item param*#
#item.details(item)
}
Since including another template (e.g. including item/details above) is the exact same syntax as accessing a template parameter (e.g. item above), obviously this existing naming convention won't work without something changing.
I know I can rename my "app.views.item" package to "app.views.items", and rely on singular/plural forms to differentiate the view from the param name, but this does not seem like a very straightforward solution. Also what if I really want the parameter name to be the same as the view package?
One idea I have is to prepend all my views with an extra top level package:
app/views/views/item/details.scala.html
So the include syntax would be #views.item.details(), but again this is obviously a hack.
What is a good way to avoid this issue? How can I better organize my code to avoid such naming collisions?
Most other template engines use operations like "include" or "render" to specify a partial include. I don't mean to offend anyone here, but is the Play Scala template engine syntax so terse that it actually dictates the organization of code?
3 solutions:
First
Typpicaly for partial templates you should use tags as described in the docs, where app/views/tags folder is a base:
file: app/views/tags/product.scala.html
in the templates (no initial import required in the parent view full syntax will allow you to avoid name-clash: #tags.packageName.tagName()):
<div id="container">
#tags.product(item)
</div>
Of course in your case you can also use packages in the base folder
file: app/views/tags/item/product.scala.html
<div id="container">
#tags.item.product(item)
</div>
I'm pretty sure that'll solve your problem.
Second
To avoid clash without changing package's name you can just rename the item in your view, also I recommend do not use a form name for the Form[T] as it can conflict with helpers:
#(existingItem: Item, existingItemForm: Form[Item])(implicit flash: Flash)
#layout.page() {
#item.details(existingItem)
}
Third
If you'll fill your Form[Item] before passing to the view with given Item object, you don't need to pass both, as most probably you can get data from the form:
#(itemForm: Form[Item])(implicit flash: Flash)
#layout.page() {
<div>Name of item is: #itemForm("name").value (this is a replacemnet for ##existingItem.name </div>
#item.details(itemForm)
}
Of course in you product.scala.html you'll need to change the #(item: Item) param to #(itemForm: Form[Item])

jQuery+JS computed selector

Sorry for the bad wording of the title, but here's my problem. Suppose I have a list where every item has a class:
<ol>
<li class="chapter">Chapter 1</li>
<li class="chapter">Chapter 2</li>
...
I want to select the item which is corresponding to make the user's current chapter, which is known by javascript, in bold. So if the user is on Chapter 2 I would do something like:
$(".chapter:eq(2)").css("font-weight", "bold");
But I can't do
$(".chapter:eq("+currentChapter+")").css("font-weight", "bold");
as it gives me Uncaught SyntaxError: Unexpected identifier
Any help would be appreciated.
Edit: I'm using a template to insert the variables but I have verified that currentChapter is in fact defined and the number I expect it to be.
function fetchContent(startSlide) {ldelim}
var chapterSize = {$chapterSize};
var currentChapter = {$chapter};
var chapterName = "{$chapterName}";
alert(typeof(currentChapter)); // number
alert(currentChapter); //e.g. 3 works
alert(currentChapter + "aaa"); //e.g. 3aaa
$(".chapter:eq("+currentChapter+")").css("font-weight", "bold"); // doesn't work
Try a different approach, fetch all elements and then select only the one you want (I know it's best to select your element right in the selector, but just to try it out).
$(".chapter").eq(currentChapter).css("font-weight", "bold");
Also, looking at your code, it seems like currentChapter is a local variable inside the fetchContent function. Are you sure you can access that variable when you are calling the jQuery function? Try to check the existence and value of the currentChapter variable right before calling the jQuery function which is causing you problems.
EDIT
From the jQuery documentation jQuery :eq() selector
Because :eq() is a jQuery extension and not part of the CSS
specification, queries using :eq() cannot take advantage of the
performance boost provided by the native DOM querySelectorAll()
method. For better performance in modern browsers, use
$("your-pure-css-selector").eq(index) instead.

Div as Ajax.ActionLink

Is it possible to create Ajax.ActionLink which has instead of text, the whole DIV?
I'd like to map div on Ajax.ActionLink
I don't think that this will work using the standard MVC Ajax scripts. I believe that the MVC javascript is created to use an <a> element by default. On a different note, embedding a div tag within an <a> is not valid XHTML. What are you trying to achieve?
Using Jquery is probably the easiet way you want to go. As an example:
<div onclick="SomeAjaxFunction()">some div content</div>
function SomeAjaxFunction()
{
$.get('<%= Url.Action("SomeAction", "InSomeController") %>', function(data) {
$('.result').html(data); // assuming a partial view
alert('Load was performed.');
});
}
However, if you are dead set on using MS Ajax, to work with divs, you need to possibly look at the Sys.Mvc.MvcHelpers._asyncRequest function and do some of your own re-wrapping to make it usable. I have not tried or tested this, so use at your own risk. (Stick with the Jquery, there is far better help and support available.)