Is there a feature in Xamarin Forms which will point to (scroll up) to a label which became visible after validation? What I am trying to do is: if required field is blank I display label under it - saying that it needs to be filled out, I have a scrollable page and when label becomes visible I want to make it show that label by scrolling the page to desired location, so user will know what is missing.
Thank you.
You have two distinct points to implement:
first, your entry validation: there are many ways to do it, but you can take a look at this fully documented sample from Xamarin: Entry validation sample
Then next, you have to scroll to the (first) invalid entry control. That means that all your entries must be embedded into a parent Scrollview control. Then you have to find the first invalid UI element to scroll to (make your own "business" method to find this control).
Then just call the Scrollview scroll method. An example sample code could be:
// in your xaml.cs
//
public Task FocusInvalidEntryAsync()
{
var firstInvalidEntry = FindInvalidEntries().FirstOrDefault();
if(firstInvalidEntry != null)
{
return parentScrollView.ScrollToAsync(firstInvalidEntry, ScrollToPosition.MakeVisible, true);
}
return Task.FromResult(true);
}
The FindInvalidEntries() method is your own method to determine wich UI entry is invalid (maybe it needs your ViewModel).
Then ScrolltoAsync() is a method that will scroll the parent scrollview to the desired control. The last parameter indicates if you want to display the scroll animation.
Tell me if it's clear !
Related
Question
I'm working with Adobe Scene7 BasicZoomViewer and I'm looking for a way to tell the ZoomViewer to reset the zoom so that the user is no longer zoomed in on an image but instead will show the default "zoom" level.
What I've found
The closest thing I found to what I need is this reset property ZoomView.reset which "Resets the viewport when the frame (image) changes. If set to 0 it preserves the current viewport with the best possible fit while preserving the aspect ratio of the newly set image".
This looks close to something I need but it states that it will reset or preserve the aspect ratio when a new image has been inserted but I am not inserting new images.
Demo from Adobe
There is a button on the image that the API inserts into the page that resets the zoom level. Adobe provides a demo page that shows what I'm working with. If you look at the bottom left, the right-most button is the reset button. When clicked, it has to make some kind of API call and I need to figure out which one it is.
Edit
I've been able to find a minified version of the BasicZoomViewer and I am currently attempting to make sense of the code.
There is an event listener placed on the "Zoom Reset Button" that just simply calls a reset() method on line 274 in the uglified version of the file. Currently, I am trying to make sense of the file and figure out how to access this method.
c.zoomResetButton.addEventListener("click", function () {
c.zoomView.zoomReset()
});
I will be answering my own question. If someone finds a better way please feel free to answer as well.
tldr;
Create a variable to hold the instance of your s7viewers.BasicZoomViewer() and inside of that you can access the event handlers and much more.
Example of calling the reset zoom handler
// instantiate the s7viewers class and save it in a variable
var s7BasicZoomViewer = new s7viewers.BasicZoomViewer({
containerId: 's7viewer',
params: {
asset: assetUrl,
serverurl: serverUrl
})
// example of how to call the "zoomReset()" method
s7BasicZoomViewer.zoomResetButton.component.events.click[0].handler()
Explanation
After digging through the minified code that was uglified I found an event listener on the s7zoomresetbutton DOM class name, or perhaps it's watching for the ID of that DOM element which is the same ID as the container div for your S7 BasicZoom Viewer plus some added text to make this ID unique. For example, if the container div is s7viewer then the reset zoom button will have an ID of s7viewer_zoomresetbutton.
Now, going through the code I found this event listener which let me know there must be some way to call the zoomReset() method.
c.zoomResetButton.addEventListener("click", function () {
c.zoomView.zoomReset()
});
In the code above, the value of c is this or in other words it's the instance of your S7 BasicViewerZoom and in my case I have multiple depending on how many images I need to zoom on.
When instantiating the s7viewers class you can then reference that instance later and access the event handlers on each button and other properties and methods.
From there it was just looking through the object returned from the instance and calling the handler for the reset button.
I have a list widget with five rows per page. When the user goes to the next page I reload the page (by doing an unload/load on the data source with the new page number) and that works fine. However, the list stays scrolled to the bottom. How can I scroll the list to the top so the user does not have to?
I tried the ways that work in standard HTML but they do not work in AppMaker, and I cannot find any documentation on how to do this.
Thanks for any tips or pointers.
I realize this is an old post, but for future visitors, here's what worked for me - you need to set the index of the list to zero. App Maker ensures that it scrolls the last selected item into view, and maintains this across navigations.
You can do this by passing in a callback function that runs after loading the list. For me, I reload the list from a dropdown widget that filters the list, so in the onValueChange event I've added:
// Load datasource
widget.datasource.load(function() {
// Set index to 1 to ensure we scroll to top of list
app.datasources.YOURDATASOURCE.selectIndex(0);
});
You can achieve the desired behavior by doing the following:
In the outline, locate the TablePanel widget and select the List:TableBody widget
2.In the property editor, scroll to the Events section and click on the onDataLoad event value. Then click on Custom Action.
Type in this code var elem = widget.getElement(); elem.scrollTop = 0; so that it looks like this
Make sure the change is saved and then preview your app and it should work. Let me know if you need something else or if it don't work.
For me Morfinismo's answer didn't work, but the following did:
In the style editor add CSS for the List element:
.app-pageName-nameOfTheListWidget {
overflow-y: auto;
}
And in the Property Editor under Layout set a Max height.
I have a gridpanel and want to show a errortooltip on mouse hover as we see for textfields and combobox. Is there any inbuilt component to show this error styled tooltip for grid panel.
i am doing this to find validate based on the number of records in the grid panel.Please Help
There's nothing built-in to accomplish this, but you can still do it. Lucky for you, I had to do something like this not too long ago.
You'll need to use a column renderer. You'll also need to store the error message on the record itself, or have a way to access error messages by record. Your renderer should look something like this:
renderer: function(value, metaData, record){
if(/* record has error */){
metaData.tdCls += " x-form-invalid-field"; // Squiggly red lines
metaData.tdAttr = "data-errorqtip='This is my error message!'";
}
return value;
}
You may need to play around with styling and whatnot, but that is the gist of it. Also, you'll have to refresh your grid if the validity of your records changes, to make sure your tooltips say updated.
I would like to add custom right clicks to a number of spark list controls.
I have tried the following as an item renderer. (as per the flex 4 cook book).
Full Render code here http://pastebin.com/Kx8tJ1cY
When I right click on the Spark List I simply get the Adobe Default Context menu.
This is the same default behaviour I had before I added any code to this.
Could anyone tell me how to add right clicks to List Items in Flex 4.
Please and Thank you.
I found the problem/solution. You cant use context menus if there are Vboxes or Tab Navigators. Which is insane because it means I cant do relative layout properly or decent variable width design.
Quoted from: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/ContextMenu.html
For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
Christopher Huyler posted something similar (source code available here). From the article:
Start out by grabbing the Javascript code from Google's code repository.
Step 1 – Setup custom context menu code
Create a new Flex project in Flex Builder. Copy rightclick.js and swfobject.js into the html-template folder of your project. From here, I had to make several changes…
I modified the RightClick.init() function to accept an object and container value as input. This allows me to pass in the name of the application as the object instead of having it be called the same thing every time.
I included rightclick.js and swfobject.js in the header of index.template.html.
I added a new div to the body called “flashcontent”.
I added an onload handler to the body tag to initialize RightClick
I replaced AC_FL_RunContent(…) with new SWFObject(…) making sure to maintain all template variables.
After making these changes, I verified that no right-click context menu appears in my application.
Step 2 – Listen for the rightClick event
Next I added a few lines to the main mxml file of my application to listen for the ExternalInterface event that will be dispatched when I right-click my appliction.
private function handleCreationComplete():void
{
ExternalInterface.addCallback("rightClick", handleRightClick);
}
private function handleRightClick():void
{
Alert.show("Right Click Success!");
}
Step 3 – Dispatch an event to the correct object
Getting the event to the main application is easy, but we actually want the appropriate child object to be notified when the right-click event occurs. Since I am not using any double-click events in my application I decided I would treat every right-click event like a double-click event. Users without a two button mouse (aka Mac users) can simply double-click to get the same menu while users with a two button mouse just have to right-click. Here is how I make sure the event is dispatched to the appropriate object.
private function handleRightClick():void
{
var objects:Array = systemManager.getObjectsUnderPoint(
new Point(mouseX,mouseY));
if (objects.length>0)
{
var object:Object = objects[objects.length-1];
var relatedObject:InteractiveObject;
if (object is InteractiveObject)
relatedObject = object as InteractiveObject;
else if (object.parent && object.parent is InteractiveObject)
relatedObject = object.parent;
var event:MouseEvent = new MouseEvent(
MouseEvent.DOUBLE_CLICK,true,false,mouseX,mouseY,
relatedObject);
object.dispatchEvent(event);
}
}
I hope this helps!
Is there any code or custom options available to achieve the following :
1> When an error occurs in a text box, the validation shows the error. Forces the user to remove the error and only then proceed to complete remaining text inputs. KEEPS the mouse focus on the Text Box.
I have used built in mx:Validator tags, but it does not coerce the user to remove the error. Instead, user can easily go ahead without rectifying the error.
2> Can the error message which generally appears as a tooltip when mouse focus moves over the text input with the error, REMAIN until the user removes error and not just be displayed on mouse hover action?
You can customize your ToolTips to show your Error. Check this link to customize your tooltip, to show your error in ToolTips
For #2, check out http://aralbalkan.com/1125.
Unfortunately, it is a lot of hassle if you have multiple/large forms. It is unfortunate flex doesn't provide more styling options for the error tooltip.
#1 seems to be a bad UI design. While you may not allow them to submit a form unless they enter valid information, they should be able to navigate around the form freely and fill in the information as they choose. Just my opinion.
A solution to question 1) is as follows;
Use the Validator.validateAll static method to check that all form items are valid before allowing the form to be submitted. The following snippet is taken from a good flex example which shows this
private function resetForm() :void
{
btnLogin.enabled = false;
}
private function validateUs() :void
{
btnLogin.enabled = (Validator.validateAll([val1,val2]).length == 0);
}
The complete example is here
http://idletogether.com/easy-form-validation-and-submit-button-enable-disable-in-flex-3/