How to get a reference to the list of a Flex List in Mouse Down event - list

I have a list in mxml. I need to show a menu when the user longpresses an item in the list. The menu will show some action on the item that has been pressed on.
I also have to make the pressed item the selected item in the list. So I need a reference to the list. I cannot find a normal way to get to the list so I did this:
var list:Object = event.currentTarget.parent.parent.parent.parent.parent
Which of course is hideous. I am looking for a better way to get a reference to the list.
Here is my code for the list:
<s:List id="catList" x="0" y="0" width="100%" height="100%" click="selectItemHandler(event)">
<s:itemRenderer>
<fx:Component>
<s:IconItemRenderer
styleName="labelFontStyle"
messageStyleName="descriptionFontStyle"
labelField="labelField"
messageField="descriptionField"
dataChange="onDataChange(event)"
mouseDown="onMouseDown(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function onMouseDown(event:MouseEvent):void
{
try
{
var tg:Object = event.target;
var selectedItem:Object = event.currentTarget.data;
if (selectedItem != null)
{
// Here I need to set the selectedItem property of
// the owning list.
// I don't know how to get to the list so I did this.
var list:Object = event.currentTarget.parent.parent.parent.parent.parent;
list.selectedItem = selectedItem;
}
} catch (e:Error) {}
}
]]>
</fx:Script>
</s:IconItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:List>

I'm not sure but won't just set the selected property in the itemrenderer's onMouseDown do the trick ?
selected = true;
If not, check if this will get you your list:
var myList:List = owner as List;
Another approach would be to create a custom event that contains your item and fire it from the itemrenderer. Then listen for that event on the list and set the selectedItem property to the item you got in the event

Related

How to draw the content of a NavigationView page?

I'm trying to make an UWP app.
I decided to add a NavigationView object, and I created some sections. I read the documentation, but I didn't find out how to draw the content of the page.
There is a Content property, but it sets the content of the page's label in the menu, not the content of the page of a single label as I'm trying to do.
How can I do it?
Thanks to everyone that will answer.
Update:
For the setting page, if you are using the default item of the NavigationView by enabling the IsSettingsVisible property, you could check the IsSettingsInvoked value of the NavigationViewItemInvokedEventArgs.
Here is the code that you could refer to
void App3::MainPage::nvSample_ItemInvoked(Windows::UI::Xaml::Controls::NavigationView^ sender, Windows::UI::Xaml::Controls::NavigationViewItemInvokedEventArgs^ args)
{
if (args->IsSettingsInvoked == true)
{
contentFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(SettingPage::typeid));
}
else
{
auto navItemTag = args->InvokedItemContainer->Tag->ToString();
if (navItemTag != nullptr)
{
// navigation logic here. You could use switch or other condition. This if is just a example.
if (navItemTag->Equals("SamplePage1"))
{
contentFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(SamplePage1::typeid));
}
}
}
}
If I understand you correctly, you want to show a Page in the NavigationView, right?
Generally, we will add a Frame object in the NavigationView content. The Frame Object could show the Page as you want.
Here is a very simple example about the NavigationView:
<NavigationView x:Name="nvSample" ItemInvoked="nvSample_ItemInvoked" Loaded="nvSample_Loaded">
<NavigationView.MenuItems>
<NavigationViewItem Icon="Play" Content="Menu Item1" Tag="SamplePage1" />
<NavigationViewItem Icon="Save" Content="Menu Item2" Tag="SamplePage2" />
<NavigationViewItem Icon="Refresh" Content="Menu Item3" Tag="SamplePage3" />
<NavigationViewItem Icon="Download" Content="Menu Item4" Tag="SamplePage4" />
</NavigationView.MenuItems>
<Frame x:Name="contentFrame"/>
</NavigationView>
In the code-behind, you will need to handle the NavigationView.ItemInvoked Event to control the navigation. Like the following code:
void App3::MainPage::nvSample_ItemInvoked(Windows::UI::Xaml::Controls::NavigationView^ sender, Windows::UI::Xaml::Controls::NavigationViewItemInvokedEventArgs^ args)
{
auto navItemTag = args->InvokedItemContainer->Tag->ToString();
if (navItemTag != nullptr)
{
// navigation logic here. You could use switch or other condition. This if is just a example.
if (navItemTag->Equals("SamplePage1"))
{
contentFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(SamplePage1::typeid));
}
}
}
void App3::MainPage::nvSample_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
//This is the HomePage
contentFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(HomePage::typeid));
}
This is a very simple c++/cx demo. You could get more information about the NavigationView Document:NavigationView. Or check it in the XAML Controls Gallery app.
You could also check the NavigationView Source code here: Get the source code (GitHub).

How to update Scroll values while using Bunit automation scripts

We have a requirement to update the scrollLeft value of the a element in blazor platform. We have tried to update the scroll Left property through databinding using the below code snippet. But its not working. So it is a mandatory to use the JS code to update the scrollLeft property of the parent element.
#page "/Scroll"
#using Microsoft.JSInterop;
#inject IJSRuntime JSRuntime;
<input type="button" #onclick="#OnScroll" value="scroll" />
<input type="button" #onclick="#OnScrollJs" value="scroll-Js" />
<div id="parentDiv" style="width:500px;height:300px;overflow:auto" scrollLeft="#ScrollLeft" scrollRight="#ScrollRight">
<div id="childDiv" style="width:1500px;height:1500px"></div>
</div>
#code {
double ScrollLeft = 0;
double ScrollRight = 0;
private void OnScroll()
{
ScrollLeft = 200;
ScrollRight = 200;
}
private async void OnScrollJs()
{
await JSRuntime.InvokeVoidAsync("onChangeScrollValues", "parentDiv", 200, 200);
}
}
JS code was shown in below
window.onChangeScrollValues = function (id, left, top) {
var element = document.getElementById(id);
element.scrollLeft = left; element.scrollTop = top;
}
From the above code when we use the JS code snippet to update the DOM elements means, it does not suitable for Bunit testing. So in this scenario how I able to set the Scroll values in Bunit scripts ?
bUnit doesn't run JavaScript, instead you can write a test that verifies that the onChangeScrollValues is correctly called when scroll-Js button is clicked.
Something like this should suffice:
// arrange
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var cut = ctx.RenderComponent<MyComponent>(); // replace MyComponent with the name of the component.
// act
cut.Find("input[value=scroll-Js]").Click();
// assert
cut.JSInterop.VerifyInvoke("onChangeScrollValues");

Combox first row not selectable

How to make first row of combobox not-selectable? (https://learn.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.ComboBox?view=winrt-19041)
Combox first row not selectable
You could detect DropDownOpened event and find the fist item with ContainerFromIndex then disable it like the following. Because Combobox dropdown is lazy load, so we need add the task delay in DropDownOpened event.
private async void MyCb_DropDownOpened(object sender, object e)
{
await Task.Delay(100);
var item = MyCb.ContainerFromIndex(0) as ComboBoxItem;
if (item != null)
{
item.IsEnabled = false;
}
}

unable to display list of items with Nativescript-Vue GridLayout

Nativescript-vue newbie here...
I am using nativescript-vue to display a list of items. When the .vue page loads, the grid should just be an empty table. When a button is clicked, the grid is populated with sub-elements of a list I retrieved from a service. I am running into two issues:
There is only one row, where there should be a row per item in the list.
The date will be a date element such as 06-01-2019 11:30:01 but I would prefer to display it as 06-01-2019
In my *.vue:
<RadListView for="item in itemList" layout="grid" #itemTap="onItemTap">
<v-template>
<GridLayout rows="20, 20" class="list-item list-item-grid">
<GridLayout row="1" rows="25, 35" columns="auto, auto, auto, auto">
<Label col="0" :text="item.date" class="list-item-left" textWrap="true"verticalAlignment="middle" horizontalAlignment="left"></Label>
....
</GridLayout>
</GridLayout>
</v-template>
</RadListView>
....
<script>
expot default {
data() {
return {
itemList: []
};
},
methods: {
getItems() {
// really simplified but it will return something like:
// [{"date" :"09-01-2019 11:32:01", "name":" first last"}]
service.getItemArray()
}
},
beforeMount: function() {
this.itemList= this.getItems();
}
</script>
I have put a shortened Playground version here:
You could try a v-if to render the RadListView after the button is clicked, or manual load on demand.

Persistent AdminLTE sidebar state

I've inherited some work on an AdminLTE sidebar on a Django website. The page in question uses an "extends" block to load AdminLTE's index.html page right off the bat. Links on our treeview sidebar cause the entire page to reload, including the sidebar, so the state of any expanded treeview menus is lost whenever someone clicks a link.
I'm guessing there's some well-known way of making the sidebar keep its treeview menus open, but I've yet to find it. There are some working examples on the AdminLTE site, but I can't figure out how they work.
Can someone point me to the right piece of documentation to help me make my sidebar persistent across page loads?
Treeview css class works in an unordered list so any child links only show up when the parent list is clicked. An example of this is if you have "home" and then "About" "About-Locations". When you click About it is a tree-view class and on the sidebar it will show locations underneath it. When you click on home the locations sidebar link will not be displayed as this is how the css is written for the list.
The code can be found in the "AdminLTE.css" file.
I'm not working on django, I work on a MVC Razor app.
For the same problem, I use this solution :
I store the link clicked on the menu (ajax send to the server and session storage, but you can use cookie or what you want).
The link clicked is inserted in the java script below :
$(" ul.treeview-menu > li > a").on("click", function ()
{
if (this.href == "#")
return;
$.ajax({
type: "POST",
url: '/Outils/SetActiveMenu',
data: { url: this.href },
dataType: "json"
});
})
$(document).ready(function () {
var v = "#Html.Raw(Session["ActiveMenu"] == null?"": Session["ActiveMenu"].ToString())";
if(v == "") return;
var a = $('a[href="' + v + '"]');
openParentMenu(a);
a.css("background-color", "#E3E6E5");
});
function openParentMenu(item)
{
var parent = item.parent().closest("li.treeview");
if (parent.length != 0) {
openParentMenu(parent);
parent[0].children.item("a").click();
}
}
Here is the code for reference.
/* Tree()
* ======
* Converts the sidebar into a multilevel
* tree view menu.
*
* #type Function
* #Usage: $.AdminLTE.tree('.sidebar')
*/
$.AdminLTE.tree = function (menu) {
var _this = this;
var animationSpeed = $.AdminLTE.options.animationSpeed;
$(menu).on('click', 'li a', function (e) {
//Get the clicked link and the next element
var $this = $(this);
var checkElement = $this.next();
//Check if the next element is a menu and is visible
if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible')) && (!$('body').hasClass('sidebar-collapse'))) {
//Close the menu
checkElement.slideUp(animationSpeed, function () {
checkElement.removeClass('menu-open');
//Fix the layout in case the sidebar stretches over the height of the window
//_this.layout.fix();
});
checkElement.parent("li").removeClass("active");
}
//If the menu is not visible
else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) {
//Get the parent menu
var parent = $this.parents('ul').first();
//Close all open menus within the parent
var ul = parent.find('ul:visible').slideUp(animationSpeed);
//Remove the menu-open class from the parent
ul.removeClass('menu-open');
//Get the parent li
var parent_li = $this.parent("li");
//Open the target menu and add the menu-open class
checkElement.slideDown(animationSpeed, function () {
//Add the class active to the parent li
checkElement.addClass('menu-open');
parent.find('li.active').removeClass('active');
parent_li.addClass('active');
//Fix the layout in case the sidebar stretches over the height of the window
_this.layout.fix();
});
}
//if this isn't a link, prevent the page from being redirected
if (checkElement.is('.treeview-menu')) {
e.preventDefault();
}
});
};
I have used the inbuilt functionality mentioned by #MDT and have created a function:
function toggleCollapsibleList(){
//Get the clicked link and the next element
var $this = $('#parent-list-item-id');
var checkElement = $('#an-id-for-collapsible-li-with-treeview-class');
//Check if the next element is a menu and is visible
if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible')) && (!$('body').hasClass('sidebar-collapse'))) {
//Close the menu
checkElement.slideUp(500, function () {
checkElement.removeClass('menu-open');
//Fix the layout in case the sidebar stretches over the height of the window
//_this.layout.fix();
});
checkElement.parent("li").removeClass("active");
}
//If the menu is not visible
else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) {
//Get the parent menu
var parent = $this.parents('ul').first();
//Close all open menus within the parent
var ul = parent.find('ul:visible').slideUp(500);
//Remove the menu-open class from the parent
ul.removeClass('menu-open');
//Get the parent li
var parent_li = $this.parent("li");
//Open the target menu and add the menu-open class
checkElement.slideDown(500, function () {
//Add the class active to the parent li
checkElement.addClass('menu-open');
parent.find('li.active').removeClass('active');
parent_li.addClass('active');
//Fix the layout in case the sidebar stretches over the height of the window
});
}}
This worked for me :)