الانتقال إلى المحتوى
View in the app

A better way to browse. Learn more.

مجموعة مستخدمي أوراكل العربية

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

تعديل خاصية Selectionlistener في الجدول يسبب لي مشاكل أخرى

Featured Replies

بتاريخ:

السلام عليكم

أنا استخدم jdev 11.1.1.4.0

أنا لدي شاشة تتضمن جدولين وفق علاقة رئيسي/فرعي
أريد تحقيق حالة الاستخدام التالية:
1- يقوم المستخدم بإجراء تعديلات على بعض السجلات الموجودة ضمن الجدول الفرعي المرتبطة بسجل معين من الجدول الرئيسي.
2- يقوم المستخدم بالنقر على سجل آخر من سجلات الجدول الرئيسي من دون القيام بحفظ التعديلات المنفذة.
3- ظهور رسالة تنبيه تخبر المستخدم بضرورة حفظ التعديلات المنفذة أولا.
4- يعود المؤشر الضوئي للسجل الخاص بالجدول الرئيسي إلى السجل السابق (أي يتم رفض الانتقال إلى سجل جديد)
5- يقوم المستخدم بحفظ التعديلات التي قام بها.

لتحقيق ذلك استخدمت manged bean in SelectionListener attribute المتعلقة بالجدول الرئيسي وسميتها onTableSelect وكتبت الكود التالي:

onTableSelect(SelectionEvent selectionEvent) {
if (ADFUtils.getApplicationModuleForDataControl("CodesModuleDataControl").getTransaction().isDirty()) {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, getValueFromResourceBundle("hr.view.vcBundle","global.msgUnsavedChanges"), null));
// HERE i need to move highlight to the previous record //
}
else {
RichTable table = (RichTable)selectionEvent.getSource();
CollectionModel tableModel = (CollectionModel)table.getValue();
JUCtrlHierBinding adfTableBinding = (JUCtrlHierBinding) tableModel.getWrappedData();
DCIteratorBinding tableIteratorBinding = adfTableBinding.getDCIteratorBinding();
Object selectedRowData = table.getSelectedRowData();
JUCtrlHierNodeBinding nodeBinding = (JUCtrlHierNodeBinding) selectedRowData;
Key rwKey = nodeBinding.getRowKey();
tableIteratorBinding.setCurrentRowWithKey(rwKey.toStringFormat(true));
}



الكود يعمل بشكل صحيح ولكن المشكلة أن:
the master table highlight record Becomes Different from the itterator table,
My question is how can i move highlight record in the master table according to it itterator.

مع الشكر مقدما

بتاريخ:

شوف انا هنا لا أعلق بغرض الاجابة وان كان ممكن حل الموضوع ده عن طريق الحصول على ال Key الخاص بال Row ومن ثم جعله الSelected Row ولكن ما تفعله هو مثال ضخم لل Bad Practice ومحاربة ال Framework لان الناس كلها بتتجه نحو ال ajax وال PPR لتجنب ارسال الصفحة للسيرفر عند كل request وانت هنا بتعمل check على ال Transaction كله وكمان بتعمل submit للصفحة كل ما المستخدم يضغط على اى Row
ولاحظ كمان ان لو ال Transaction لم يكتمل لاى سبب من الاسباب او لانه Dirty لان المستخدم لم يقم بالحفظ فى اى مكان حيظهر له برضه الرسالة دى حتى لو لم يقم بالتعديل فى سجلات الجدول الفرعى لانك هنا بتعمل check على ال Transaction كله وليس على سجلات هذا الجدول فقط

بتاريخ:
  • كاتب الموضوع

ممكن حل الموضوع ده عن طريق الحصول على ال Key الخاص بال Row ومن ثم جعله الSelected Row


مشكورة أخت هالة
أنا لا أنكر أن هذه الطريقة -من حيث المبدأ- سوف ترهق السيرفر ولكني أريد ضبط عمليات الإدخال التي يقوم بها المستخدم وذلك من خلال إجباره على القيام بحفظ التغيرات التي قام بها على الجدول الفرعي قبل أن يقوم بالنقر على سجل جديد ضمن الجدول الرئيسي، (وذلك لان الحالة الافتراضية هي أنه يستطيع القيام بإدخال وتعديل ما يشاء ضمن الجدول الرئيسي والفرعي ومن ثم في حال قام بالضغط على مفتاح rollback فإنه سيلغي جميع التعديلات الحالية والسابقة التي نفذها وبالتالي سيأتي ويقول لي ما هذا النظام (الشوربة) لماذا لم تنبهني إلا أنني لم أقم بحفظ التغييرات .....!!)
ولهذا السبب فقد عدلت على الخاصية SelectionListener ضمن الجدول الرئيسي بحيث يتم فحص Transaction.

على كل حال أنا قرأت ADF Code Corner 96. How to invoke a table selection listener from Java
ووجدت الكود الذي أحصل من خلاله على Key الخاص بالـ Row وهو:
Key jboKey = new Key(new Object[] { currentRow.getAttribute("EmployeeId") });


ولكني لم أستطع جعله كــ Selected Row ضمن الجدول (أي تحريك Highlight السطر ليصبح عند الـ Key المحدد)

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

والله ولي التوفيق

بتاريخ:

يا اخ mhwad

انت هنا بتتكلم على حاجتين مختلفين تماما رسالة حفظ التغييرات بتظهر للمستخدم اثناء التصفح او الانتقال من Tab الى اخرى او اغلاق المتصفح او حتى بين تنقلات ال Train (وان كنت لم اجربها بعد فى ال train) وليس عند كل حركة يقوم بها المستخدم ولا تحدثنى عن الفورم لان الفورم لا يوجد به مفهوم ال MVC من الاساس

ومن ثم في حال قام بالضغط على مفتاح rollback فإنه سيلغي جميع التعديلات الحالية والسابقة التي نفذها


لماذا تستخدم rollback لعمل التراجع فما دامت تعديلات المستخدم ما زالت فى الفيو ولم يحدث لها submit الى ال model فهناك طرق عديده لعملية الالغاء غير ال rollback

عموما عيوب طريقتك هذه بخلاف ال performance انك لازم تكون متاكد ان ال transaction dirty بسبب تعديلات الجدول الفرعى وليس لاى سبب اخر وحتى لا نخرج عن الموضوع الاساسى لو عاوز تغير ال highlight للجدول الى السجل الذى قام المستخدم باجراء التعديلات على سجلاته الفرعية فاستخدم هذه الميثود

	if (hasPendingChanges()) {
		FacesContext context = FacesContext.getCurrentInstance();
		context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, null, "Pending changes Exist"));
		oracle.binding.BindingContainer bindings = getBindings();
		DCIteratorBinding iter = (DCIteratorBinding)bindings.get("DepartmentsView1Iterator");
		Key rowKey = iter.getCurrentRow().getKey();
		ArrayList tableRowKey = new ArrayList();
		tableRowKey.add(rowKey);
		RowKeySetImpl rks = new RowKeySetImpl();
		rks.add(tableRowKey);
		tt1.setSelectedRowKeys(rks);
		AdfFacesContext.getCurrentInstance().addPartialTarget(tt1);
	}



tt1 هو ال rich Table بتاعك
DepartmentsView1Iterator اسم الاتيرتور للجدول الرئيسى

بتاريخ:

توجد لي أكثر من ملاحظة على هذه المشاركة:
1. الخاصية selectionListener تقوم باستدعاء دالة معينة لجعل الصف هو الحالي وبالتالي يجب عليك استدعاء نفس الدالة بعد الانتهاء من كتابة الكود المخصص وإلا سيحدث الخلل الذي ذكرته
2. مسألة أن هذه العملية bad practice وتحارب الـ framework وترهق السيرفر مسألة غير دقيقة لأنه يجب علينا أن نعرف أنه مع كل ضغطة على أي سجل فإنه يحدث استدعاء للسيرفر في كل الأحوال ولذلك استدعائي لدالة معينة لن يكون الشئ المؤثر. لو لم يكن الضغط على السجل يذهب للسيرفر كان من الممكن أن أتفق معكم ولكن كون الـ request يذهب للسيرفر يجعلني أختلف معكم
3. هذا المتطلب هو دائماً ما يواجه كل من يحول من الفورم لأن المستخدم تعود على طريقة معينة ولذلك يتوقع وجود نفس الوظائف بالضبط في ADF حيث لا يفهم المستخدم مسألة اختلاف البيئة بين الاثنين ، فمثلاً واجهنا من قبل موقفاً مشابهاً حين طلب مننا مستخدم أنه عندما يقوم بالضغط على الزر Enter فإنه يتم نقل المؤشر إلى الحقل التالي ورفض المستخدم استخدام Tab وأصر على هذه النقطة فقمنا بتنفيذها له لأنه في النهاية هو المستفيد من النظام ولذلك نحن ننصح في هذه المواقف بالتحدث مع المستخدم ومحاولة إقناعه باستخدام طريقة الوب ، فإذا رفض وباتت الأمور صعبة ففي هذه الحالة يجب التنفيذ

بتاريخ:
  • كاتب الموضوع

مشكورة أخت هالة
أنا في الحقيقة أعرف أن هذا الطلب لا يتناغم مع تصميم صفحات الويب ولكن كما قال الأخ مصطفى أحيانا نبقى تحت رحمة المستخدم الذي تعود على استخدام تطبيقات الفورم
وأيضا من وجهة نظر أخرى فهو التحدي لإمكانية السيطرة على كل تحركات المستخدم
وبالنسبة لشكل الصفحة فهو حتما عبارة عن جدولين فقط وهما الجدول الرئيسي والجدول الفرعي فقط
وبالنسبة للكود الذي كتبتيه فقد وصلت إلى طريقة أسهل وفيما يلي النص الكامل للمثيود الذي يقود بتعديل خاصية SelectionListener والذي سميته onTableSelect:

 public void onTableSelect(SelectionEvent selectionEvent) {   
   RichTable table = (RichTable)selectionEvent.getSource();
   if (this.pendingChangesExist(getAmDataControlName())) {
  table.setSelectedRowKeys(selectionEvent.getRemovedSet());
  AdfFacesContext.getCurrentInstance().addPartialTarget(table);
  FacesContext context = FacesContext.getCurrentInstance();
  context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, getValueFromResourceBundle("hr.view.vcBundle","global.msgUnsavedChanges"), null));
   }
   else {   
  CollectionModel tableModel = (CollectionModel)table.getValue();
  JUCtrlHierBinding adfTableBinding = (JUCtrlHierBinding) tableModel.getWrappedData();
  DCIteratorBinding tableIteratorBinding = adfTableBinding.getDCIteratorBinding();		   
  Object selectedRowData = table.getSelectedRowData();	 
  JUCtrlHierNodeBinding nodeBinding = (JUCtrlHierNodeBinding) selectedRowData;	 
  Key rwKey = nodeBinding.getRowKey();
  tableIteratorBinding.setCurrentRowWithKey(rwKey.toStringFormat(true));	 
   }
 }



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

بتاريخ:

الاخ / mhwad

من ناحية الكود فاكيد طبعا الكود اللى كاتبه Frank Nimphius هو الافضل ده ال product Manager الخاص باوراكل :) مش اى حد
اما من ناحية موضوع تاثيره على ال performance وتجريب ال performance بوجه عام فعمره محيبان دلوقتى لانك فى بيئة التطوير ومفيش مستخدم غيرك وعندك one instance من الابليكيشن موديول فالامور كلها مظبوطه

التاثير على ال performance يتم اختباره فى ال production عند وجود عدد من المستخدمين المتزامنين مع بعض والعديد من ال requests وال Application module instances وحدوث امور عديده عند زيادة الrequests كال Activation وال passivation مثلا

بتاريخ:

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

انضم إلى المناقشة

يمكنك المشاركة الآن والتسجيل لاحقاً. إذا كان لديك حساب, سجل دخولك الآن لتقوم بالمشاركة من خلال حسابك.

زائر
أضف رد على هذا الموضوع...

برجاء الإنتباه

بإستخدامك للموقع فأنت تتعهد بالموافقة على هذه البنود: سياسة الخصوصية

Account

Navigation

البحث

إعداد إشعارات المتصفح الفورية

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.