Display a textbox based on checkbox selected when checkbox list is dynamic using JSF - jsf-1.2

I have a requirement in my project which specifies to display 2 textboxes based on a checkbox is checked. For every check box selected the 2 textboxes are the same. The twist is the check box list is dynamic to accomodate additions in the future. The check box list comes from DB.
How can this be done in JSF?

You can use valueChangeListener property of tag.
<h:selectManyCheckbox id="" value="#{bean.selectedItems}" valueChangeListener="#{bean.renderTextBox}">
<f:selectItems value="#{bean.checkBoxList}"/>
</h:selectManyCheckbox>
<h:inputText value="" rendered="#{bean.render}"/>
Have property called render in your bean.
In valuechange method i.e renderTextBox write following code
public void renderTextBox(event)
{
if(isInvokeApplicationPhase(event))
{
//change the value of render property to true or false depending on checkbox is checked or not
}
}
public boolean isInvokeApplicationPhase(FacesEvent event){
if(event.getPhaseId() != PhaseId.INVOKE_APPLICATION){
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
event.queue();
return false;
}
return true;
}
And to get checkbox list from database write following method
public List getcheckBoxList()
{
public List checkBoxList = null
// retrieve list of checkbox from your db(write query here and assign returned list to checkBoxList variable and return that varaible)
}
getcheckBoxList() is a getter method. I've bound checkBoxList variable to <f:selectItems> tag

You can use javascript to hide and display the input box
var checkbox=document.getElementById("ID");
if(checkbox.value== 'null')
checkbox.style.display = "none";
else
checkbox.style.display = "inline";

Related

Xamarin.Forms.EntryCell: How to trigger the event while input any key

I have a problem with Xamarin.Forms.EntryCell. I want to know how to trigger an event if the text of the EntryCell has changed. Not the event 'Completed', it is just triggered when I press Enter after inputting anything.
<EntryCell
Label="User Id"
x:Name="UserIdEntryCell"
HorizontalTextAlignment="End"
Completed="UserIdCompleted"/>
Obviously there is no event that is fired when the text is changed (see the docs). Anyway, this does not mean that you can't achieve what you want, by means of Text property. Since you are using the event I do not assume that you use MVVM (you should really give it a try, though), hence we'll have to create a property we will bind the EntryCell.Text to in your view (I'm assuming a view, but for a page it would be quite similar)
In your code behind add a property Text that calls HandleTextChanged from its setter:
class MyView : ContentView
{
string _text;
public string Text
{
get => _text;
set
{
_text = value;
HandleTextChanged();
}
}
private void HandleTextChange()
{
// do whatever you need to do
}
}
You can bind this property to EntryCell.Text from your XAML
Now MyView.Text will be set every time the text in your EntryCell changes.

Insert id into list if checkbox is checked

Net MVC and I have a table with products I want to buy.
I want to use a Checkbox to confirm the purchase.
But how can I insert the ID in a List<int>?
I have a class Approved with an attribute List<int> approve
I tried:
#Html.CheckBoxFor(m.approve.Add(id))
#Html.CheckBoxFor(m=>m.approve.Add(id))
#Html.CheckBoxFor(ViewBag.l.approve.Add(id)
How can that task be done ?
You can easyly bind a list to a model:
Model Binding To A List
So, you simply need to make a list of a class created for this, which includes the integer id, and a boolean to hold the checkbox state, somethign like this:
public class IdState
{
public int Id {get;set;}
public bool Checked {get;set;}
}
The list must be of this class, i.e. List<IdState>
The key is using a syntax like this:
Html.CheckBoxFor(m => m[i].Product)
Which will produce and input whose name is something like this:
name="[0].Product"
Then, the model binder will bind your list automatically. Of course, your post action must recevied a List<IdState> to function properly.
u can use html to insert id to your checkbox
#model yourModel
//for generate checkbox
<input type="checkbox" #(yourmodel ? " checked=checked " : null) name="YourCheckBoxName" value="#model.ID" >
use formCollection for get value in your controller from your view
I solved this problem that way:
This Javascript function walks through all checkboxes and saves the Id of the checked once to an hidden input.
<script>
function submit() {
var x = new Array();
for (i = 0; i < ids.length; i++){
if ($("#" + ids[i].toString() + ".cb").is(':checked')) {
x.push(ids[i]);
}
}
console.log(x.toString());
$("#str").val(x.toString());
}
</script>
After toggling a checkbox the value of the hidden input is refreshed
<script>
$(document).ready(function () {
$("input.cb").change(function () {
submit();
});
});
</script>
Here I create an array with all possible ids to improve simplicity and performance.
Otherwise I had to walk through all possible ids and check them.
<script>ids.push(#id);</script>
This is my checkbox:
<input type="checkbox" value="#id" id="#id" class="cb" />

How to select an item of mx:ComboBox on the basis of substring entered through keyboard

I am using <mx:ComboBox /> and I want to select a matching item on the basis of string entered through keyboard. Currently, <mx:ComboBox /> selects the first matching item based on the first character only. I want this functionality to be customized. I am unable to find that KeyboardEvent listener which does the matching so that I can override it.
To do this yourself, you should look at the following bits and pieces of code below from the ComboBox and ListBase classes. ListBase is what the ComboBox component uses for it's drop down list.
The ComboBox appears to be deferring the keyboard input to the drop down list. It then listens for events from the drop down list to know when the selection has changed (as a result of keyboard or mouse input).
Flex components usually override a method called keyDownHandler() to process the keyboard input when they have focus. Starting there, we come across ComboBox line 2231:
// Redispatch the event to the dropdown
// and let its keyDownHandler() handle it.
dropdown.dispatchEvent(event.clone());
event.stopPropagation();
So now the keyDownHandler() in the drop down list will get executed. That method has a giant switch statement, where the default case statement on line 9197 of ListBase looks like this:
default:
{
if (findKey(event.charCode))
event.stopPropagation();
}
This is where the drop down list decides what to select based on keyboard input (when the input is not an arrow key or page up, etc.). The protected findKey() method simply calls the public findString() method to do this work.
So to override this behavior yourself:
extend the ListBase class and override the findKey() or findString() methods with your custom logic
extend ComboBox class and override the createChildren() method so you can instantiate your custom ListBase class instead of the default one.
Here is the class which I've used in order to make it work. searchStr is user inputted string which needs to be matched. If no dataprovider item gets matched to the searchStr, the overridden listener falls back to the default behaviour. I am using Timer to flush the inputted searchStr after 2 seconds. The possible drawback is that it is assuming the dataprovider to be a collection of String values. But you can modify it accordingly as the need may be.
public class CustomComboBox extends ComboBox
{
private var searchStr:String="";
private var ticker:Timer;
public function CustomComboBox()
{
super();
ticker = new Timer(2000);
ticker.addEventListener(TimerEvent.TIMER, resetSearchString);
}
override protected function keyDownHandler(event:KeyboardEvent):void
{
super.keyDownHandler(event);
// code to search items in the list based on user input.
// Earlier, the default behavior shows the matched items in the dropdown, based on first character only.
// user input is invisible to user.
if((event.charCode>=0x20 && event.charCode<=0x7E) || event.charCode==8) //Range of printable characters is 0x20[space] to 0x7E[~] in ASCII. 8 is ASCII code of [backspace].
{
ticker.reset();
ticker.start();
if(event.charCode==8)
{
if(searchStr=="")
return;
searchStr = searchStr.substr(0, searchStr.length-1);
}
else
{
searchStr += String.fromCharCode(event.charCode);
searchStr = searchStr.toLowerCase();
}
for each(var str:String in dataProvider)
{
if(str.toLowerCase().indexOf(searchStr, 0)>-1)
{
this.selectedItem = dropdown.selectedItem = str;
dropdown.scrollToIndex(dropdown.selectedIndex);
break;
}
}
}
}
/**
* reset the search string and reset the timer.
**/
private function resetSearchString(evt:TimerEvent):void
{
searchStr = "";
ticker.reset();
}
}

DevExpress XtraGrid FocusedRowChanged event problem when changing datasource

This problem has bugged me for several years and maybe someone here knows a simple solution, since I just ran into it again.
QUESTION: Is there any way to get the XtraGrid to "forget" the current focused row index before a new (different) datasource is assigned to the grid?
BACKGROUND
We use the XtraGrid as a kind of controller for what is displayed in another panel of a multipane Winform.
Now imagine a hypothetical scenario where the datasource of the XtraGrid keeps changing according to menu selections. Menu item 1 populates the grid with a list of today's entrees in the cafeteria: Id, Name. Menu item 2 populates the grid with a list of Customers the user must phone that day: ID, Name. Important thing is that these are separate distinct datasources, and the grid's datasource is being assigned and reassigned.
CRITICAL FACT FOR THIS QUESTION:
We want the grid's FocusedRowChanged event to be the single place where we trap the user's selection in the controller grid. We are a "no spaghetti code" shop. FocusedRowChanged is better than a click event because it handles keyboard navigation too. The row with the focus contains the ID of the detail record we need to fetch from the database for display in Panel #2. This works--most of the time.
Here's how it doesn't work: let's say that on a given day, the list of customers the user must contact contains only one row. So the first (and only) row in the grid is the focused row. Now let's say that the user goes up to the menu and selects the menu item to display the day's cafeteria entrees. When the user clicks on the first item in the Entrees list, the FocusedRowChanged event does NOT fire because the grid has retained a memory of the focused row index from the previous datasource. The focused row index has not changed. And thus the user's selection doesn't trigger anything.
I tried to get DevExpress to offer a second more row-object-oriented mode (as distinct from row-index-oriented approach) whereby each row in the grid would have a GUID, and the FocusedRowChanged event would fire whenever the GUID of the currently focused row differed from the GUID of the previously focused row, regardless of whether the focused row index happened to be the same. This would allow dynamic changes of datasource and enable the desired behavior. But they demurred.
So I'll ask my question again, Is there any way to get the XtraGrid to "forget" the current focused row index before a new datasource is assigned to the grid?
Tim, I had the exact same problem when the grid only had one row of data in it and then changed data sources. I solved it by setting the gridview.FocusedRowHandle = -1 after setting the new datasource.
In a similar situation, I am subscribing to the
FocusedRowObjectChanged
event (using DevExpress 16.1).
I think that the best solution to this problem is to create a new GridView object and override its DoChangeFocusedRowInternal method. Below you will find the default implementation of this method. All you need to do is to change the marked row just as your needs dictate. Also, take a look at the How to create a GridView descendant class and register it for design-time use article, it contains some useful information.
public class MyGridView : GridView {
protected override void DoChangeFocusedRowInternal(int newRowHandle, bool updateCurrentRow) {
if(this.lockFocusedRowChange != 0) return;
if(!IsValidRowHandle(newRowHandle))
newRowHandle = DevExpress.Data.DataController.InvalidRow;
if(FocusedRowHandle == newRowHandle) return; // <<<<<<
int currentRowHandle = FocusedRowHandle;
BeginLockFocusedRowChange();
try {
DoChangeFocusedRow(FocusedRowHandle, newRowHandle, updateCurrentRow);
}
finally {
EndLockFocusedRowChange();
}
RaiseFocusedRowChanged(currentRowHandle, newRowHandle);
}
}
UPDATE
My code:
namespace MyXtraGrid {
public class MyGridControl : GridControl {
protected override BaseView CreateDefaultView() {
return CreateView("MyGridView");
}
protected override void RegisterAvailableViewsCore(InfoCollection collection) {
base.RegisterAvailableViewsCore(collection);
collection.Add(new MyGridViewInfoRegistrator());
}
}
public class MyGridViewInfoRegistrator : GridInfoRegistrator {
public override string ViewName { get { return "MyGridView"; } }
public override BaseView CreateView(GridControl grid) {
return new MyGridView(grid as GridControl);
}
}
public class MyGridView : GridView {
public MyGridView(GridControl ownerGrid) : base(ownerGrid) { }
public MyGridView() { }
protected virtual bool RowEqual(int focusedRowHandle, int newRowHandle) {
if(IsDesignMode)
return focusedRowHandle == newRowHandle;
DataRow row1 = GetDataRow(focusedRowHandle);
DataRow row2 = GetDataRow(newRowHandle);
return row1 == row2;
}
protected override void DoChangeFocusedRowInternal(int newRowHandle, bool updateCurrentRow) {
if(this.lockFocusedRowChange != 0) return;
if(!IsValidRowHandle(newRowHandle))
newRowHandle = DevExpress.Data.DataController.InvalidRow;
if(RowEqual(FocusedRowHandle, newRowHandle))
return;
int currentRowHandle = FocusedRowHandle;
BeginLockFocusedRowChange();
try {
DoChangeFocusedRow(FocusedRowHandle, newRowHandle, updateCurrentRow);
}
finally {
EndLockFocusedRowChange();
}
RaiseFocusedRowChanged(currentRowHandle, newRowHandle);
}
}
}
You can subscribe on the DataSourceChanged event which will fire when Data source changes (you guessed it!) so then you can get using GetFocusedObject() the object and display the relevant items for the other grid...

Extending DropDownList to include an extra option

I want to extend DropDownList control to include an option for creating or editing the options. For example; for a list of projects in the dropdown list, there will be another option that says "Create new project..." or "Edit projects..." and this will be the last option in the list. When user selects this option, the selectedIndex or selectedItem will not change and corresponding action will be taken (for example a popup window shows up). This will be a convenient way for the end user.
Now I want this to work independent of the context and the class must be reusable. User will only specify the optionText and optionFunction to work this out. The basic structure of the class looks like this:
public class OptiveDropDownList extends DropDownList
{
private var _enableOption:Boolean;
private var _optionText:String;
private var _originalDataProvider:IList;
[Bindable] public var optionFunction:Function;
public function OptiveDropDownList()
{
super();
}
public function set optionText(value:String):void
{
_optionText = value;
dataProvider = _originalDataProvider;
}
public function set enableOption(value:Boolean):void
{
_enableOption = value;
dataProvider = _originalDataProvider;
}
public override function set dataProvider(value:IList):void
{
_originalDataProvider = value;
var dp:IList = null;
if(!value){
dp=new ArrayCollection(value.toArray());
if(_enableOption){
var opt:Object=new Object();
opt[labelField]=_optionText;
dp.addItem(opt);
}
}
super.dataProvider = dp;
}
[Bindable]
public override function get dataProvider():IList
{
return _originalDataProvider;
}
}
I hope my code is clear to understand, I am adding an extra object to the dataprovider for the option. Field names are self-explanatory.
Now my question is how to know whether the dataprovider's items have changed? Which functions should I override and how to do it. I have tried using a ChangeWatcher to watch the length property of the dataprovider, but it doesnt work if only an object in the dataprovider has changed. I need to capture these changes and update the view.
I also need to capture the selection and call optionFunction, preventing the default action not to give index out of bounds error.
Thanks in advance.
Just add an event listener to the original dataProvider. All implementations of IList should dispatch CollectionEvent.COLLECTION_CHANGE when the the list changes (e.g. add, remove or when an existing object in the list has been changed). In your event handler you can update the DropDownList's dataProvider accordingly.
By overriding the mx_internal method setSelectedIndex() you can adjust the selection according to your wishes. Take a look at the blog post "Disable selection on some items in a spark List" for some inspiration.

Resources