سؤال

I want to use the publish/subscribe framework which is used internally by Strust2 jQuery plugin.

The user can select an account number from a list or type it in a textbox.

I want to publish an event when text box or select option changes. So the user can only type textbox OR select something from select box:

<s:textfield name="account"  onblur="$.publish('accountChanged',this,event)"/>
<s:select name="accountList" list="destinationAccounts"
    onblur="$.publish('accountChanged',this,event)"/>

Below is the js:

$.subscribe('accountChanged', function(event, data) {
    alert("New data is: " + data.value);
    if ( event.target.id=='account') {
        //Do something
    }
}

Here are issues:

  1. The data.value only works for textbox, for select box the data.value is undefined.
  2. I want to know which target received the event. event.target.id is not working! I think the event object is not a jQuery event object?

I reviewed the sample showcase application, but could not find any.

Am I calling $.publish method correctly? Are there better ways?

هل كانت مفيدة؟

المحلول

If you subscribe to topics keep the topic name unique for each tag that allows to separate handlers for the tag. The new event is created each time you publish the topic in the onblur event. The textfield handler for topic works as you described. The select tag doesn't work because wrong parameter passed as the data. The example of the working code

<s:textfield name="account"  onblur="$(this).publish('accountChanged', this, event)"/>
<s:select name="accountList" list="{'list1', 'list2','list3'}" onblur="$(this).publish('accountListChanged', this, event)"/>
<script type="text/javascript">
  $.subscribe('accountChanged', function(event, data) {
    alert("accountChanged: " + data.value);
  });
  $.subscribe('accountListChanged', function(event, data) {
    alert("accountListChanged: " + data.parentElement.value);
  });
</script> 

As you can see the data.value is undefined because data.parentElement.value should be used. event.target.id is not working because event.originalEvent.target.id should be used. The event object is a jQuery event, but originalEvent is DHTML object which is blur.

I don't know about your requirements, if you need to subscribe/publish events or use the original event handlers, I can't say what is better in this situation.

نصائح أخرى

The below code solved my issue:

As I could not find any example of publish/subscribe framework, I hope below example will help others!

The jsp will be

You must call ${this).publish not $.publish

<s:textfield name="account"  onblur="$(this).publish('destinationChanged', this, event)"/>
<s:select name="accountList" list="{'list1', 'list2','list3'}" onblur="$(this).publish('destinationChanged', this, event)" emptyOption="true"/>
<s:textfield name="destinationAccount" type="hidden" />

And the JS will be

$.subscribe('destinationChanged', function(event, data) {
            //If user types in the textbox 
            //then get the value and make the select box shows an empty option 
        if( !!data.value){
            destinationAccount= data.value;
        $('#destinationKnownAccount').val($("#destinationKnownAccount option:first").val());
        } else{
             //The user selected an account from select box. 
             // So get the value from select box and clean textbox          
            destinationAccount= data.parentElement.value;
            $('#destinationUnknownAccount').val('');
        }
            //Set the hidden box        
        $('#destinationAccount').val( destinationAccount);


    });

As mentioned one can use event.originalEvent.target.id to find which target was selected.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top