Enhancing your LightSwitch List, Tiles and Table controls – Updated!
We have refactored from the earlier build… so please review the new steps!
As of May 2014, Out of the Box LightSwitch list, tiles and table controls only allow for selection of a single item.
Until now!
The demo/test drive has been updated showing the new upcoming functionality check it out: MultiSelect Preview
So… we’re like squirrels here, constantly distracted. And so with that said, we’ve nailed down our long term name for the library. Going forward we’ll be branding as LightSwitch Wires, or lsWires for short. Since in reality that’s kind of what we all do. We add the wiring to LightSwitch to make things work or work better. And this naming convention works for our other disciplines like Kendo UI and Syncfusion. We’ll keep the “Wires” branding and just swap out the prefix for the type of wires we’re providing. Thanks for your patience, this is the LAST breaking change.
Now on with it… Within the lsWires library we've provided the functionality to enhance the list and table controls
- Selection of multiple items
- Ability to limit the number of selections
- Select/Unselect all items
- Get the selected item count
- Retrieve the data of the selected items
- Persist selections for the session
- We no longer take over the ItemTap
- Multiple lists can be on the same screen
- Same code base works across all 3 control types
Sounds awesome eh? So lets get started on how to implement this new functionality…
- Create a new LightSwitch 2013 HTML Application
- Lets name it: itgLsMultiSelect
- When at the Start with data screen, click on Attach to external…
- Data Source Type: OData Service
- OData service endpoint:
http://services.odata.org/northwind/northwind.svc/ - Authentication type: None
- Choose the following entities:
Customer
Employee
Product - Name the data source: Northwind
- Click the finish button
- Close any open editor windows
- Save your solution
- Over in your your Solution Explorer pain
- Add the following NuGet package to the HTML Client project
lo-dash.js - From our GitHub repository
Add lsWires.js to your Scripts folder
Add lsWires.css to your Content folder - Now open up your default.htm file in the client project
- Add lo-dash.js followed by lsWires.js to the scripts section
- Add the lsWires.css as the last stylesheet
- Right click on the Screens folder, select Add Screen…
- Select Browse Data Screen
- Screen Data: Northwind.Customers
- Click ok
- Save your solution, run the application
- Go ahead and click on items, notice single selection
- Stop your application
- Click on the Tile List, Customers
- Click on Edit PostRender Code in the properties window
- To get intellisense, drag from solution explorer the file lsWires.js onto your page
- Now we only need ONE line of code to enable multi-select
// Enable multi-item selection on this tile control lsWire.list.enableMultiSelect(contentItem);
- Before you can run, remove the default ItemTap that LightSwitch automatically adds for the list. We did not create the view screen that the ItemTap is expecting so you’ll get an error when selecting if you don’t.
- Save your solution, run your app
- BOOM! Multi-Select enabled!
- You can also unselect by clicking a selected item
- Hmmmm… how do I get the data of the selected items?
- Stop your application
- Under the Customer List Tab, add a new Group
- Move it right under the Command Bar
- Change the type to be a Columns Layout
- Then add 3 more Rows Layout under the columns layout
- For all 3 change the width setting to Fit to Content
- Add a new Button into the first rows layout
- Select Write my own method, name it: GetSelected
- Double click the button to edit the code
- We're going to add a few lines
Get the list contentItem
Call our method to get the data, which returns an array of entities
Then we'll display the datavar list = screen.findContentItem("Customers"); var count = lsWire.list.selectedCount(list); var selected = lsWire.list.selected(list); var text = "Customers Selected\n\n"; _.forEach(selected, function(item) { text += item.CustomerID + " - " + item.CompanyName + "\n"; }); text += "\n\nCount = " + count; window.alert(text);
- Save and run your application
- Select a few items, click on Get Selected
- Unselect a few, Get Selected, only selected get returned
- Ok lets continue going thru adding functionality
- Add two local properties, boolean
- Name them SelectAll and SetLimits
- Drag the SelectAll under the second Rows Layout
- Change the control type to be of a Custom Control
- Over in the properties window, set the label position to None
- Then click on Edit Render Code and add the following
// Render a checkbox lsWire.checkbox.render(element, contentItem); // When the checkbox changes state, either select all or not contentItem.dataBind("screen.SelectAll", function (newValue) { if (newValue != undefined) { var list = contentItem.screen.findContentItem("Customers"); lsWire.list.selectAll(list, newValue); } });
- Now drag the SetLimits property under your 3rd Rows Layout
- Change the control type to be of a Custom Control
- Change its Display Name to: Limit of 4
- Change the label position to None
- Then click on Edit Render Code and add the following for this one, its a bit more lengthy as we’re adding in some cool features
// Render our checkbox lsWire.checkbox.render(element, contentItem); // When the checkbox changes state, set or remove our limits contentItem.dataBind("screen.SetLimits", function (newValue) { if (newValue !== undefined) { // Our dependent item var selectAll = contentItem.screen.findContentItem("SelectAll"); // Get our list var list = contentItem.screen.findContentItem("Customers"); // Current count of selected items var count = lsWire.list.selectedCount(list); // If the checkbox is selected, limit to 4 items if (newValue != undefined && newValue === true) { // Set our limit, returns the limit count var ttl = lsWire.list.totalSelectionsAllowed(list, 4); // if select all was set, checked if (selectAll.value === true) // set the property to false, dataBinding will do the rest contentItem.screen.SelectAll = false; // Else is the current count greater than our limit? else if (count > ttl) { // Count is greater, so unselect all items lsWire.list.selectAll(list, false); } // Since we are limiting, disable the select all checkbox selectAll.isEnabled = false; } else { // Limit was unselected, renable select all and remove limits selectAll.isEnabled = true; lsWire.list.totalSelectionsAllowed(list, null); } } });
- Its that easy!
- Save and run your application
- Toggle your limits
- Select your 4 items, try and select a 5th
- No can do! Now unselect a selected and select another
- Notice the Select All is no longer a valid option
- Uncheck the Limit of 4
- Test again, notice the limitations were removed
- So what happens if this was a list vs a Tile List?
- Stop your application
- In the screen designer, change the control type to List
- Run your app, test the functionality
- As you see, same code, different control type, same results!
- Now you ask… table too?
- Yep! Go ahead and change it to a table control
- Run and test the app
- Same code, works as expected on all 3 controls!
So there you go… an easy, reproduceable method of enabling multi-select on your LightSwitch list controls. You can even have multiple lists on the same screen, each will behave independently. We'll leave that up to you to go play around and test. Our sample project already has a multi-list screen if you want to go check it out.
We’ve added functionality to persist selections for a session. Its also a key part for a table control if you are going to allow your clients to change the sort order by clicking on the columns. You’ll set the control to persistSelections and it won’t be a problem. Check out the sample project for the code, its quite simple. Also check out the live preview on how it works.
Obviously if you are using an ItemTap to get to an edit/view screen, you would not implement this, but you could, since we no longer take that over and we do allow for persistent selections. But for most, selection and batch processing, this is the ticket.
One final note regarding the Select All functionality. We are selecting and working with rendered items. So with virtual scrolling, not all items from a query have been returned and rendered. Which means if you do a Select All, scroll and more data comes down, the new data is not selected. Of course one could go and press the Select All button again, or you could do a dataBind and fire off another Select All. But I don't see many instances of where that is appropriate. But you could.
Enjoy! More to come…