Extending Screens for Multi-Select in the LightSwitch HTML Client (Mike Droney)

Extending Screens for Multi-Select in the LightSwitch HTML Client (Mike Droney)

Rate This
  • Comments 14

If you (like me) have always wanted to have a rich multi-select experience in LightSwitch HTML Client Lists, this article may be of interest to you. This sample will show a nice pattern for adding unbound screen content items to be manipulated by the user in a List Control for a multi-select operation.

Let’s take a simple HTML client application for managing contacts of mine. It contains a screen to Browse Contacts which looks like this:

clip_image002

In the runtime, it appears as:

clip_image004

Now I would like to add the ability to this screen to individually select and delete multiple contacts in one operation (as opposed to a delete button on each individual entity). First, add a custom control to the list item:

clip_image005

Make sure the Data Context is left as the default ‘Screen’ value, and in the Properties Window, set the Width and Height property values to ‘Fixed Size’ and Pixels to ‘60’ for each. Click the ‘Render Code’ link in the Properties Window to add the logic to render the control. Add the following lines of code to the render method:

 var checkbox = getCheckBox(contentItem);
 $(checkbox).appendTo($(element));

We are creating a variable ‘checkbox’ which calls a function which will return us a checkbox control and then are appending it to the element (which in this case is a list control item). Next we need the getCheckBox function, add the following function to the screen user code file:

 function getCheckBox(contentItem) {
   var checkbox = $("<input type='checkbox'/>");
   checkbox.css(
"height", "20");
   checkbox.css(
"width", "20");
   checkbox.css(
"margin", "10px");

  
checkbox.change(function () {
     
var checked = checkbox[0].checked;
     
if (!!contentItem.value.details["__isSelected"] !== checked) {
       contentItem.value.details[
"__isSelected"] = checked;
     }
   });
  
return checkbox;
 };

Note that you can always define a style in the user-customization.css file (located in the Content folder of the HTMLClient project) instead of hard-coding the css for the element as I have done above.

This function creates a JQuery Mobile checkbox control and sets an event handler function to set/unset a property on the contentItem directly, the ‘__isSelected’ property. This will allow us to manipulate list items which are selected.

The last thing we need is a button to invoke an operation to delete the selected items. First, add a button to the Command Bar of the Screen which invokes a new method named ‘DeleteSelected’. Right Click on the item in the content tree and select ‘Edit Execute Code’. In the user code file, add the following code to the function:

   msls.showMessageBox("Are you sure you want to Delete?",
       { title:
"Warning!", buttons: msls.MessageBoxButtons.yesNo }).then(function (response) {
       
switch (response) {
          
case msls.MessageBoxResult.yes:
               screen.getContacts().then(
function (contacts) {
                   contacts.data.forEach(
function (contact) {
                      
if (contact.details["__isSelected"]) {
                           contact.deleteEntity();
                       }
                   });
                   myapp.commitChanges();
               });
               
break;
           
case msls.MessageBoxResult.no:
           default:
              
break;
        }
    });

Looking at the code above, you can see I have added a MessageBox prompt for the user with a Yes/No response (this is good practice if you are going to perform multiple deletes!). Inside the case for Yes, we load all the Contacts in the screen, and loop through each one looking for any which have the property “__isSelected” and delete it.

You could also expand the scope of the checkbox changed event to keep track of a count of selected items on the Screen (for example, you may not wish to enable the ‘Delete Selected’ button if there are no items selected).

This is how the Screen looks now in the HTML Client:

clip_image007

Clicking the ‘Delete Selected’ button will now delete only those list items selected on our screen, speeding up our ability to perform selective operations! Thanks to the flexibility of JavaScript, extending screen content allows us to perform complex Screen tasks in LightSwitch.

For more common JavaScript snippets you can use in your LightSwitch apps, see:

How to: Modify an HTML Screen by Using Code

-Mike Droney, Senior Tester, LightSwitch Team


Leave a Comment
  • Please add 2 and 5 and type the answer here:
  • Post
  • Beautiful, clean code. Could you post a similar logic that would work in Silverlight client?

  • Hi Marcelo,

    There are a couple of articles dealing with this problem from the SilverLight side.  

    First, Yann has a detailed article on multi-select in the SilverLight datagrid: code.msdn.microsoft.com/.../How-To-Enable-Multiple-Row-0ca9662c

    Second, here is a thread which deals with adding checkboxes to a SilverLight datagrid: social.msdn.microsoft.com/.../vb-activating-multi-selection-with-checkboxes-in-a-lightswitch-grid-with-a-oneliner

    Hope this helps,

    Mike

  • This is awesome. Multi select is one of those essentials that has always been missing from the standard lightswitch features.

  • Hi

    I cloned your choice-list control and on clicking the Ok button (see the link to the image below), the code shown below always returns 'true'.

    Please let me know where I am going wrong.

    Thanks, Mark.

    dl.dropboxusercontent.com/.../Pic8.png

  • Hi Mark,

    Huy followed up with a couple of suggestions on the forum thread: social.msdn.microsoft.com/.../multiselect-issue-html5-client

    Thanks,

    Mike

  • awesome!  Why cant we have this in choice box for  standard Lightswitch as well? it is so overdue.

  • Sorry, in your code:

    msls.showMessageBox("Are you sure you want to Delete?",

          { title: "Warning!", buttons: msls.MessageBoxButtons.yesNo }).then(function (response) {

          switch (response) {

              case msls.MessageBoxResult.yes:

                  screen.getContacts().then(function (contacts) {

                      contacts.data.forEach(function (contact) {

                          if (contact.details["__isSelected"]) {

                              contact.deleteEntity();

                          }

                      });

                      myapp.commitChanges();

                  });

                  break;

              case msls.MessageBoxResult.no:

              default:

                  break;

           }

       });

    I don't understand where is the method getContacts()?? What does it do?

  • Hoàng,

    The line 'screen.getContacts()' gets the data for the contacts list.  Specifically it creates a JavaScript promise.  For every screen member (which can be seen on the left section of the screen designer in the first screen shot), LightSwitch will generate a 'screen.get[ScreenMember]' method.  The blog article code uses the first parameter of the '.then()' method to access the data on successful retrieval of the data.  In the code example from the article, contacts.data is an object array with all the data from the contact list on the screen.

    Hope that helps,

    Elizabeth Maher

    LightSwitch Team

  • Hi Mike,

    Thanks for the mention for the old SilverLight grid sample. :-)

    I'm wanting to do exactly the same thing that you've demonstrated, with the new table control in VS 2013. So far I haven't got it to work.

    Should the same code do the job? Is there perhaps multiple-select functionality built into the control that hasn't been directly exposed?

    What would you recommend, to add multiple selection to the table control?

    Thanks,

    Yann

  • @Yann,

    I was able to use the same code in a table control and it worked fine. The only change I made was to flip the List to a Table. What error are you seeing?

    The table control is based on the JQM table control. As far as I know they don't have a checkbox feature built into it.

    -Thanks

    Patrick

  • OK, thanks for that Patrick. I must be doing something wrong then. I'll try again.

    I'll have a search for any info on the jQuery Mobile table control then, but if anyone knows anything on doing multiple selection with the table control (or for that matter formatting columns & rows as well), I'd love to hear from you.

  • Excellent.  Thank you.

  • Hi Mike,

    Thanks for this code that works fine on LS2013 Update 2.

    I changed the deleteEntity by modifying values on selected lines and the "commitChange" by an "applyChange" to stay on the same screen. It works fine but I would like to deselect the checkbox after changes. How to deselect all checkboxes by code ?

    Thanks. Laurent

  • @Laurent

    $("input[type=checkbox]").prop("checked", false);

Page 1 of 1 (14 items)