1.7 to 4 Multiselect Conversion

  1. #1

    1.7 to 4 Multiselect Conversion

    Hello again,

    Running into a couple of issues updating from 1.7 to 4.
    Previously had multiselects which are now broken, just looking for the version 4 equivalent.
    The items no longer working are:
    • AfterDrop (Direct Event)
    • DblClick (Direct Event)
    • Click (Listener)
    • AfterDrop(Listener)


     <ext:MultiSelect ID="MSReadyToPrint" runat="server" AutoWidth="True" DragGroup="grp1"
                        DropGroup="grp1" MultiSelect="false" AutoHeight="True" MinHeight="500px">
                        <DirectEvents>
                            <AfterDrop OnEvent="MSReadyToPrint_BeforeDrop">
                                <ExtraParams>
                                    <ext:Parameter Name="values" Value="getDroppedValues(this, data)" Mode="Raw" Encode="true" />
                                </ExtraParams>
                            </AfterDrop>
                            <DblClick OnEvent="DoubleClick_Show">
                                <ExtraParams>
                                    <ext:Parameter Name="value" Value="this.store.getAt(index).get(this.valueField)"
                                        Mode="Raw" />
                                </ExtraParams>
                            </DblClick>
                        </DirectEvents>
                        <Listeners>
                            <Click Handler="#{MSReadyToPrint}.clear();" />
                            <AfterDrop Handler="#{MSReadyToPrint}.clear();" />
                        </Listeners>
                    </ext:MultiSelect>


    Thanks
  2. #2
    Hi. I found the following notes in the breaking changes document that should help solve the issue:

    https://examples2.ext.net/#/Getting_...EAKING_CHANGES

    185. The MultiSelect's Click and DblClick events have been removed.
         Please use the ItemClick and ItemDblClick events of its ListConfig.
        
         Example
    
         // Old
         <ext:MultiSelect runat="server">
             <Listeners>
                 <Click Handler="alert('Click');" />
                 <DblClick Handler="alert('DblClick');" />
             </Listeners>
         </ext:MultiSelect>
    
    
         // New
         <ext:MultiSelect runat="server">
             <ListConfig>
                 <Listeners>
                     <ItemClick Handler="alert('ItemClick');" />
                     <ItemDblClick Handler="alert('ItemDblClick');" />
                 </Listeners>
             </ListConfig>
         </ext:MultiSelect>
  3. #3
    Hi Geoff,
    Thanks for the reply.

    I seem to be having issues with the direct events not firing.

     <ext:MultiSelect ID="MSReadyToPrint" runat="server" AutoWidth="True" DragGroup="grp1"
                        DropGroup="grp1" MultiSelect="false" AutoHeight="True" MinHeight="100" Margin="0">
                        
                        <DirectEvents>
                            
                            <Drop OnEvent="MSReadyToPrint_BeforeDrop">
                                <ExtraParams>
                                    <ext:Parameter Name="values" Value="getDroppedValues(this, data)" Mode="Raw" Encode="true" />
                                </ExtraParams>
                            </Drop>
                            
                            <DoubleTap OnEvent="DoubleClick_Show">
                                <ExtraParams>
                                    <ext:Parameter Name="value" Value="this.store.getAt(index).get(this.valueField)"
                                        Mode="Raw" />
                                </ExtraParams>
                            </DoubleTap>
                        </DirectEvents>
                        <ListConfig>
                        <Listeners>
                            
                            <ItemClick Handler="#{MSReadyToPrint}.clear();" />
                            
                            <Drop Handler="#{MSReadyToPrint}.clear();" />
                        </Listeners>
    
                        </ListConfig>
                    </ext:MultiSelect>
    Protected Sub MSReadyToPrint_BeforeDrop(sender As Object, e As DirectEventArgs)
    
            Dim value As List(Of String) = JSON.Deserialize(Of List(Of String))(e.ExtraParams("values"))
            For Each i In value
                UpdateTicketStatus(11, Integer.Parse(i))
            Next
        End Sub

    As I was using AfterDrop & DblClick which no longer seems to be available.
    I have changed to Drop and DoubleTap but to no avail.
  4. #4
    Hello, InHousePrint!

    I see three issues (or possible issues) in your code sample:

    1. your direct events are set outside ListConfig block. Remember direct events are (in simple terms) server-side listeners, so they have some level of correspondence, context and event names, for two.
    2. you didn't provide a full example but, in the DoubleTap handler, where it gathers the extra params, this.valueField might be null/undefined, thus the direct method won't be called at all, or will always pass an empty value, as it won't match a field in the store.
    3. The DoubleTap event actually works, the way you set it up, but I believe it is not what you want. Suppose you add a Title="MySelectBox" to the MultiSelect. If you double-click the title bar, the event will trigger. You want it to trigger when you click an entry, right? Besides, it won't have the component context as it looks like you expect by the this.store reference in the code. Well, I think you want here is the ItemDblCLick event from within the ListConfig block.

    Could you take these in consideration? If they don't help at all, let us know. Remember to keep the browser console open, as it may log issues with client-side code that could potentially prevent the event from calling. If the extra params code fails, it may prevent the direct event from triggering at all.

    Hope this help!
    Fabrício Murta
    Developer & Support Expert
  5. #5
    Hi fabricio.murta,

    Thank you for your reply, yes most of your suggestions have worked, changing the double tap to the ItemDblClick and placing the Directevents inside the Listconfig now have the server side firing correctly.
    You are also correct in that the 'this.valueField' is yielding null results. This was working prior to the version 4 upgrade.
    I do have a previous post as reference from many years ago I posted to get this working in version 1 which Danill helped me with.

    https://forums.ext.net/showthread.ph...et-value/page2

    It may give you some more context as what I'm trying to achieve.

    In essence what I'm try to do is pass the value id to server side of the item i have double clicked or dragged.



    <ext:MultiSelect ID="MSReadyToPrint" runat="server" AutoWidth="True" DragGroup="grp1"
                        DropGroup="grp1" MultiSelect="false" AutoHeight="True" MinHeight="100" Margin="0">
                        <ListConfig>
                            <DirectEvents>
                                
                            <Drop OnEvent="MSReadyToPrint_BeforeDrop">
                                <ExtraParams>
                                    <ext:Parameter Name="values" Value="getDroppedValues(this, data)" Mode="Raw" Encode="true" />
                                </ExtraParams>
                            </Drop>
                            <ItemDblClick OnEvent="DoubleClick_Show">
                                <ExtraParams>
                                    <ext:Parameter Name="value" Value="this.store.getAt(index).get(this.valueField)" Mode="Raw" />
                                </ExtraParams>
                            </ItemDblClick>
                            </DirectEvents>
                        <Listeners>
                            <ItemClick Handler="#{MSReadyToPrint}.clear();" />
                            <Drop Handler="#{MSReadyToPrint}.clear();" />
                        </Listeners>
                        </ListConfig>
                    </ext:MultiSelect>

     <script type="text/javascript">
            var getDroppedValues = function (field, data) {
                var values = [];
                Ext.each(data.records, function (record) {
                    values.push(record.get(field.values));
                }, field);
                return values;
            };
    
            
    
        </script>

    Protected Sub DoubleClick_Show(sender As Object, e As DirectEventArgs)
            HFInforBoxShowing.Value = True
            Dim TID As Integer = Integer.Parse(e.ExtraParams("value").ToString)
    
            ViewJobTicketDetails.ShowTicketDetails(TID, True)
    
    
        End Sub
    Protected Sub MSReadyToPrint_BeforeDrop(sender As Object, e As DirectEventArgs)
    
            Dim value As List(Of String) = JSON.Deserialize(Of List(Of String))(e.ExtraParams("values"))
            For Each i In value
                UpdateTicketStatus(11, Integer.Parse(i))
            Next
        End Sub
  6. #6
    Hello again, @InHousePrint!

    Okay, so now we got the event handling issue working, right? And you still miss passing the ID of the double-clicked entry, or drag-dropped entries, to the server code.

    As for the double clicking one, I found the valueField is still there if you get down to the multiselect's pickerField property. I just fiddled with the code using the browser's developer tools to find what I assumed we needed.

    That said, at least one way to handle getting the ID during the ItemDblClick event, is replacing your code to this:

    record.get(item.pickerField.valueField)
    (this is just the javascript part within the ExtraParams block)

    As for the drag-dropping event, the change is similar. The only bit that seems to need to change in your implementation of getDroppedValues() is field.values to field.pickerField.valueField.

    Just looking at the code, I wouldn't expect field.values to work even in the older version, as you were relying on field.valueField as the field within the record... But well, what counts is what works now, right? This should get your code fully functional now.

    Hope the information is provided in a way clear to understand. If that's confuse, let us know.
    Fabrício Murta
    Developer & Support Expert
  7. #7
    Hi fabricio.murta,

    Thank you for your reply, your suggestions have worked and I can now access the value in the code behind.
    For future, is there any documentation I can read to learn more about the value/fields available for such situations and code structure?

    Thanks again

    Guy
  8. #8
    Hello again, Guy!

    As for the specific issue, I just navigated the definitions from javascript debugger, but of course this needs some in-depth knowledge and clues (like knowing dropdown components usually have a "picker", and so on). The advantage of this method is, we find what works and just works. Downside, you may just hit a private member/method that's bound to stop working the next release, and that won't be in the breaking changes list, as private entities may change without previous notice (they are private for a reason).

    As for the documentation, if you follow it, you're at least ensuring you'd get some sort of notice (through changelogs) if something there is changed the next version.

    The main client-side (Ext JS, from Sencha) documentation is at: https://docs.sencha.com/extjs/6.6.0/classic/Ext.html

    Notice Ext.NET uses the "classic toolkit" as you'll see references about in Sencha website.

    As for the C# API docs, you are safer to rely on IntelliSense in Visual Studio, but we also keep a documentation page available at https://docs.ext.net/.

    The MultiSelect component is at: https://docs.sencha.com/extjs/6.6.0/...ltiSelect.html

    The MultiSelect's ListConfig events are handled by an Ext.view.BoundList.

    Keep reading below if you want to learn some quirks on the documentation-driven solution for this thread. It turns out we pointed you to a solution that could be replaced by something safer between version updates. Hopefully this could help you -- and others -- to solve also other issues before needing to seek help. Which is probably what you want when you asked about documentation.

    If you check the itemdblclick event document entry, you'll see it has the parameter names as this, record, item, index, e, eOpts. But watch out as, probably to avoid breaking changes Sencha introduced in the past (by renaming the parameters of the events), in Ext.NET we map the parameters into item, record, node, index! Unfortunately in the past Ext JS introduced many unnecessary breaking changes, and we tried our best not to forward them between minor versions to our users; and they ended up surviving even through major versions.

    You can check the argument names either by the live page with developer tools or via a tool we have in Examples Explorers that, given the component and event name, it gives the argument names: https://examples4.ext.net/#/Events/Listeners/Arguments/ (select BoundList, then ItemDblClick for the item in question).

    So, here when we use item, in Ext.NET, we're referring to this in the documentation. And then item is but the own BoundList.

    Further following the BoundList documentation, there's no pickerField within, not even as 'private', in the documentation! We relied on it to get the valueField in the solution we suggested. So that's something that could break without any notice, at any point between releases.

    Knowing that pickerField returns just the very MultiSelect component, we can then just find a reliable alternative into getting the component, that's on the documentation. So here's two alternatives:

    1. Reference the component via App.MSReadyToPrint.valueField (very safe, but is something that will break if you change the component's ID, or if you reuse code throughout your application).
    record.get(App.MSReadyToPrint.valueField)

    2. Call the documented up() method to get the enclosing component. If you do heavy code reuse throughout the application this might be the best choice, and you'd also want to handle exceptions, like the enclosing component not being something that has a valueField at all.

    With the second approach, the suggested codes should be changed to, respectively:

    record.get(item.up().valueField)
    and

    field.up().valueField
    In a last approach, in the case you are craving for performance (which I believe it would not be the case for the little benefit it gives), you can just rely on using the constant "field1" instead of item.up().valueField or field.up().valueField.

    Hope this helps to guide you on following the documentation to understand this and for figuring out other issues!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. [CLOSED] Conversion
    By majunior in forum 2.x Premium Help
    Replies: 8
    Last Post: May 29, 2013, 4:50 PM
  2. Replies: 4
    Last Post: May 09, 2012, 10:24 PM
  3. DateTime conversion error
    By HexElffilter in forum 1.x Help
    Replies: 6
    Last Post: Feb 21, 2012, 12:29 PM
  4. [CLOSED] TimeField Conversion
    By capecod in forum 1.x Premium Help
    Replies: 3
    Last Post: Oct 25, 2010, 10:19 AM
  5. [CLOSED] JSON conversion
    By Lex in forum 1.x Premium Help
    Replies: 3
    Last Post: Sep 22, 2008, 5:06 AM

Posting Permissions