I'm new to Blackberry Development and i have to implement a search functionality. It is supposed to be like when i input something in the search field and press the search button it should pass that string to a url as a parameter. Can anyone put me in right direction so as i can understand how to implement it.
If you want the searching to be done on a remote server, and just want the user to be able to enter a search term, then you'll first want a manger with two fields, such as a BasicEditField and a ButtonField. Then you'll want to hook up the button field to submit a request when it is clicked (I assume from your description that is http, but it could be anything). If your button field is stored in a buttonField variable, and your edit field is stored in your editField variable, and you have a method named sendRequest that takes a parameter and sends a request to the url, then you might have:
buttonField.setChangeListener(new FieldChangeListener() {
public void fieldChanged (Field field, int context) {
(new Thread() {
public void run() {
sendRequest(editField.getText());
}
}).start();
}
});
This might look a little complicated, but it breaks down pretty easily:
By calling setChangeListener, we ensure that the fieldChanged method will be called whenever the button is pressed
When fieldChanged is called, we will be in the UI thread. We don't want to lock the UI while we make the request, so you should send the request in a new thread.
getText gets the current text that the user has entered, and passes it to your sendRequest method
The sendRequest method should send the request to the url you mentioned. This will differ depending on how old devices you need to support - BlackBerry introduced a new networking API in 5.0 and expanded on it in 6.0, that simplifies network communications significantly.
I'm assuming you'll be parsing some sort of response that holds the search results. In this case, you'll also want a manager (such as a VerticalFieldManager) to store those results. Then you would add a field for every result that you wanted to show. You'll need to be careful to be holding the UI event lock when doing this, however, since it will probably be executing in a background thread. For example, you might have:
public void addResult(String result) {
synchronized(Application.getEventLock()) {
searchResults.add(new LabelField(result));
}
}
This would just show results in a label field, but you could obviously have more complex fields if you wanted more complicated behavior or more complicated UI.
Related
Using a asp mvc system, I would like to perform some kind of user notification that a record was added into the database.
Current paradigm... navPage -> modPage -> datagridPage -> newDatabasePage -> (record added action) This is where it stops, the user is not notified that record is added or failure, it simply reloads the view.
Currently - i am using some text in a viewbag variable after the record was added and based on this value, display a simple javascript message box. But I think there is a better way.
Was thinking that a modal popup implemented through jquery would accomplish this task, but i was educated this was not an optimal solution without using a messaging framework (signalR etc).
Another approach was to use an additional partial page - another partial page????
Any different options that i have missed here would be greatly appreciated.
You can add some beautiful notifications using sweetalert2, here is the documentation
Are you using Bootstrap (or similar)?
Can you not just pass some information into a hidden-as-default alert div?
Assuming you're using EF, when you save an object you can capture the new Id so you can just check for this.
Instead of reloading the view, redirect to the action that creates the initial view and change it so you can pass in the new Id:
int newId = _context.SaveChanges();
return RedirectToAction("GridView", new { Id = newId });
Then change the signature of the Action:
public async Task<ActionResult> GridView(int? Id)
You can then just check if the Id has a value and do something with that information. Then just add that to the ViewModel for the page and display the alert if required:
if (Id.HasValue)
{
viewModel.displayAlert = true;
}
If you don't want to reload the view in full then you can accomplish the same thing using Ajax calls.
I want to add a check to the click event of a button, when check failed, I want to cancel the super call, how to do it?
I have tried to use FormControlCancelableSuperEventArgs and FormControlCancelEventArgs in event handler of clicking event, but both of them return null.
Below is my test code.
[FormControlEventHandler(formControlStr(LedgerJournalTable, Approve), FormControlEventType::Clicking)]
public static void Approve_OnClicking(FormControl sender, FormControlEventArgs e)
{
FormControlCancelEventArgs ce1 = e as FormControlCancelEventArgs; // ce1 returns null
FormControlCancelableSuperEventArgs ce2 = e as FormControlCancelableSuperEventArgs; // ce2 returns null too
}
I know I can complete it by throw exception, but I think it is not a official way.
So how can I cancel the super call by a official way?
I don't think it's possible to achieve what you want to. The super() call in the Approve button on the LedgerJournalTable form is doing nothing outside of the frameworks form management such as screen refresh and other tasks that won't affect the logic (because it is a regular button and NOT a menu item button). The button is creating a new menu function in code and calling it explicitly, but is not actually calling the menu item in the super() call.
I would create another approve button in an extension, hide the out-of-the-box button, and in your extension button's OnClicked event copy the logic from the original button, and then modify it in any way that you need, such as skipping the menu function call based on certain logic/conditions that your requirements dictate.
In Vaadin 8.2, I have a Grid bound to a bean using a data provider (AbstractBackEndDataProvider). Data is fetched from a DB, filters are applied:
Grid grid = new Grid<>();
grid.setDataProvider(dataProvider.withConfigurableFilter()); // dataProvider derives from AbstractBackEndDataProvider<T,F>
The essential flow is the following: user inputs an item id in a form and submits, a submit event listener gets the user input, creates a new filter and updates the data provider:
filterSubmitButton.addClickListener(event -> {
try {
ItemListFilter filter = new ItemListFilter(
itemFilter.getValue(), // itemFilter = new TextField();
);
filterBinder.writeBean(filter);
dataProvider.setFilter(filter);
} catch (ValidationException e) {
//...
}
});
When the data provider gets the filter updated it calls a service to fetch new items from DB with the filter applied (to the DB query). Vaadin takes care of refreshing the Grid with new data afterwards.
What I want is to have a callback at this last moment. Say an use case would be to check if a filtered fetched result set contains only one item, to select this item in the Grid (which in its turn will trigger an event showing item details in another pane). Or to select the first grid row after initial list is loaded
But the problem is that there is neither grid.addRefreshListener() nor dataProvider.addRefreshmentListener(). Any other listeners do not seem to apply in this case.
Thanks for any help in advance.
The only solution I've found is a trade-off.
The item list presenter (which handles the view with the grid) passes its com.vaadin.event.EventRouter to dataProvider (I've modified the dataProvider to hold an EventRounter as a member). And now instead of streaming DB results directly from the dataProvider I fire an event that the data is fetched (using EventRouter). The presenter can subscribe to this event and then delegate it to the presenter of the details panel. There you can read the fetched results (the event contains them), check if there's only one entry and open it by id.
public class ListItemDataProvider extends AbstractBackEndDataProvider<Item, ItemFilter> {
//...
#Override
protected Stream<Item> fetchFromBackEnd(Query<Item, ItemFilter> query) {
// ...
List<Item> fetchedResults = service.fetch(query.getOffset(), query.getLimit(), orderBy, getFilter(query));
eventRouter.fireEvent(new FilteredDataFetchedEvent(this, fetchedResults));
return fetchedResults.stream();
}
}
#Controller
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ItemListPresenter {
// ...
public void addFilteredDataFetchedListener(ItemListView.FilteredDataFetchedListener listener) {
eventRouter.addListener(FilteredDataFetchedEvent.class, listener, FilteredDataFetchedListener.FILTERED_DATA_FETCHED);
}
}
Few notes:
This is not exactly what I needed. Yes, I can do the most of my use case, if the filter is applied the list is reloaded and the details view gets the event to reload too. But I can't re-use the "selectionChanged" event listeners for this and actually can't select a row in the grid at all (just because the event from dataProdiver is thrown before the grid is updated).
This is sort of a dirty trick, because now the dataProvider throws events and deals with eventRouters of views/presenters. On the other hand Vaadins data providers anyway do allow to subscribe on events. Using that out-of-box grid-dataProvider reactive binding we just don't have an event fired after data is fetched, so we do it in a custom way.
What could also work is use the given Vaadin's subscriber dataProvider.addDataProviderListener and delegate from there an event containing the filled filter and just act independently catching that event in the details panel. But then you would need to execute sql queries twice (which can be costly) or cache them etc. This brings no benefits in comparison to the given and is still a trade-off.
When you invoke dataprovider.refreshAll(), the associated grid is automatially refreshed. Therefore, after following lines in your code:
filterBinder.writeBean(filter);
dataProvider.setFilter(filter);
add logic to get size of returned records (eg. dataprovider.size()) and if that equals one (01), invoke some other logic to select the one record and display its details in other panel.
I am streaming a file to client for download. But it may happen that file size could be really big (upto few GBs) and thus I don't want to block the user to click other buttons on the webpage which goes to the same controller as Download. From reading on internet, I found that I can make it asynchronous using "Async" and "Completed" suffixes and this is my code:
public void DownloadAsync(string filename, string Id, string docId)
{
AsyncManager.OutstandingOperations.Increment();
// code to get the file from server and send it to client.
AsyncManager.OutstandingOperations.Decrement();
}
public ActionResult DownloadCompleted()
{
return RedirectToAction("Index");
}
public string OtherAction()
{
// code for this action.
}
When I click the Download on webpage and also clicks the "OtherAction" button. It still process the requests synchronously. The "OtherAction" just returns a string to user and is not time intensive and that's why I didn't make it asynchronous.
Do I need to include some code between the .Increment() and .Decrement() operations to wrap the code to download file inside "something" to start a new thread or something like that? I am not able to figure out what other piece I am missing here. I am inheriting the controller from AsyncController.
I think that you are missing some concepts here. You have two parts.
The server
Every request is asynchronous even without using any Async, so the user can send other requests to the server without being blocked.
The client
As long as the user starts the download and don't exit the browser or stop the download, the user can keep doing operations in the same tab or in another. The request that it's being completed by the download don't stop.
So, you don't need to make anything async in the server. I would just recommend my users to use some download manager if the download is several GB heavy
I am struts2 for developing my application.
Sample code of action class would be
class sampleAction extends Action {
private List<Employee> employee;
public validate(){
--logic for validation
}
public String prepopulate(){
--logic for populating value of employee list
}
--getters and setters
}
Now my problem is on page load i call prepopulate function and populate the value of employee list. After page submit validate method is called and during that if some error happens control redirects to jsp. but this time the value of employee list is empty. I am using this list for autocompleter tag in struts2.
I have never used Struts 2 built-in validation mechanism, as I prefer client-side validation to avoid an extra round trip. This is purely a personal choice and not a standard.
First I will suggest you not to use Action and use ActionSupport: ActionSupport provides a lot of functionality out of the box and you need not to do everything yourself.
I am assuming that you are using defaultStack and if this is the case than it provides out of the box Prepare Interceptor which takes care of preparing any values before the action itself is called.
In your case, validate is called before the execute method, so you never will get a chance to re-fill the values you need in your JSP.
All you need to make sure that you have prepare() method in your action class. Here are more details for this interceptor:
Prepare Interceptor
FAQ: How do we repopulate controls when validation fails