سؤال

مرحبا مرة أخرى جسف المعلمون.

أنا أبحث عن مساعدة على العارضين مخصصة ومعالجات أجاكس.لا يمكن لمشروعنا استخدام زر الاختيار العادي وعارضين خانة الاختيار أثناء تقديمهم في الجداول وهذا يتعارض مع معايير شركتنا.لا يمكننا استخدام مكتبات مكونات الطرف الثالث.

لدينا العارض المخصصة التي استخدمناها في عدد قليل من المشاريع الآن أن يعمل بشكل جيد.ومع ذلك ، في هذا المشروع بالذات ، ولست بحاجة لتقديم معالج اياكس انقر لبعض أزرار الاختيار.اتباع النصيحة في الإجابة على هذا السؤال لقد أضفت الدعوة إلى RenderKitUtils.renderSelectOnclick(); وبينما يبدو أن تقديم نفس جافا سكريبت كما العارض القياسية ، وبالفعل ، لوحة شبكة فيريبوج يظهر الطلب الصادر ، لا يتم إطلاق مستمع تغيير قيمة بلدي وأنا أبحث عن مساعدة لماذا (فإنه يطلق بشكل جيد تماما مع العارض القياسية)

بعض التعليمات البرمجية:أولا ، إنشاء معالج أجاكس (يتم إنشاء زر الاختيار برمجيا)

          AjaxBehavior valueChangeAction = (AjaxBehavior) FacesUtils.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);

        valueChangeAction.addAjaxBehaviorListener(new ProbeQuestionListener(currentQuestion, "probeDiv" + questionNumber,
            probeDiv));

        selectUI.addClientBehavior("valueChange", valueChangeAction);
        valueChangeAction.setRender(Collections.singletonList("probeDiv" + questionNumber));

مع العارض القياسي ، ينتج هذا:

<table id="answer_1" class="marginLeft1a">
  <tbody>
    <tr>
      <td>
        <input id="answer_1:0" type="radio" onclick="mojarra.ab(this,event,'valueChange',0,'probeDiv2')" value="0" name="answer_1">
        <label for="answer_1:0"> Yes</label>
      </td><td>
         <input id="answer_1:1" type="radio" onclick="mojarra.ab(this,event,'valueChange',0,'probeDiv2')" value="1" name="answer_1">
         <label for="answer_1:1"> No</label>
     </td>
  </tr>

وكل شيء على ما يرام.يتم نشر طلب أجاكس ويتم إطلاق مستمع جانب الخادم الخاص بي.

الأجزاء ذات الصلة من العارض المخصص الخاص بي:

 public void encodeEnd(final FacesContext p_context, final UIComponent p_component) throws IOException {

    /* set up convenience fields */
    context = p_context;
    component = p_component;
    componentId = component.getClientId(context);

    // rendering divs etc omitted.

    while (iterator.hasNext()) {
        final UIComponent childComponent = iterator.next();
        // irrelevant code omited
        if ("javax.faces.SelectItem".equals(childComponent.getFamily())) {
            renderSelectItem(idIndex, childComponent);
            idIndex++;
        }
     }
 }

private void renderSelectItem(final int p_idIndex, final UIComponent p_childComponent) throws IOException {
        // unrelated code omitted
        writer.startElement("input", component);
        writer.writeAttribute("type", getInputType(), null);
        writer.writeAttribute("id", p_childComponentId, "id");
        writer.writeAttribute("name", componentId, "clientId");
        RenderKitUtils.renderSelectOnclick(context, component, false);
        writer.endElement("input");
        // unrelated code omitted
}

تحديث:طريقة فك التشفير في الفئة الأساسية للعارض الخاص بي هي:

    @Override
public void decode(final FacesContext p_context, final UIComponent p_component) {

    final Map<String, String> valuesMap = p_context.getExternalContext().getRequestParameterMap();

    final UIInput input = (UIInput) p_component; // NOSONAR

    final Object value = valuesMap.get(input.getClientId(p_context));
    // System.out.println("radio button decode: found " + value);
    input.setSubmittedValue(value);
}

هذا يجعل كما :

<span class="marginLeft1a" id="answer_1">
    <label for="answer_1:0">
    <input type="radio" value="0" onclick="mojarra.ab(this,event,'valueChange',0,'probeDiv2')" name="answer_1" id="answer_1:0"> 
     Yes
     </label>
     <label for="answer_1:1">
       <input type="radio" value="1" onclick="mojarra.ab(this,event,'valueChange',0,'probeDiv2')" name="answer_1" id="answer_1:1"> 
       No
     </label>
</span>

كما ترى ، فإن معالج النقر على جافا سكريبت متطابق ، وكذلك قيم سمة الاسم والمعرف لعلامات الإدخال.على الرغم من أن هذا يؤدي إلى طلب أجاكس ، لا يتم تشغيل المستمع جانب الخادم كما هو الحال مع الإصدار الأول.

أي أفكار ?

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

المحلول

ال decode() طريقة Renderer (أو UIComponent إذا لم يكن هناك العارض) من المفترض أن فك طلب أجاكس على أساس javax.faces.behavior.event طلب المعلمة والزناد ClientBehavior#decode() على سلوكيات العميل المطابقة.

في الأساس ، المنطق هو كما يلي:

Map<String, List<ClientBehavior>> behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();

if (!behaviors.isEmpty()) {
    Map<String, String> params = context.getExternalContext().getRequestParameterMap();
    String behaviorEvent = params.get("javax.faces.behavior.event");

    if (behaviorEvent != null) {
        List<ClientBehavior> behaviorsForEvent = behaviors.get(behaviorEvent);

        if (behaviorsForEvent != null && !behaviorsForEvent.isEmpty()) {
           String behaviorSource = params.get("javax.faces.source");

           if (isBehaviorSource(context, behaviorSource, component.getClientId())) {
               for (ClientBehavior behavior: behaviorsForEvent) {
                   behavior.decode(context, component);
               }
           }
        }
    }
}

نظرا لحقيقة أنك تستخدم RenderKitUtils و الناتج هتمل ولدت يحتوي على mojarra.ab(), ، سأفترض أنك تستخدم موجارا.في هذه الحالة ، ربما يكون من الحكمة تمديد العارض المخصص الخاص بك من RadioRenderer بدلا من ذلك ، تم تنفيذ كل هذا المنطق بالفعل في HtmlBasicRenderer و SelectManyCheckboxListRenderer حتى لا تحتاج إلى إعادة اختراع العجلة.

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