it-swarm-vi.com

Làm cách nào để truy xuất các giá trị duy nhất trước dấu ngoặc đơn trong truy vấn Bộ lọc JFormFieldList?

Tôi có một bộ lọc tùy chỉnh JHtml được tạo bởi một lớp mở rộng JFormField. Nó được thêm vào trong khung nhìn với đoạn mã sau:

JHtmlSidebar::addFilter(
    '- Select Height -',
    'filter_height',
    JHtml::_('select.options', $heightOptions, "value", "text", $this->state->get('filter.height'), true)
);

Nó hoạt động như dự định nhưng vì một số lý do, bộ lọc sẽ không hiển thị văn bản mặc định (- Chọn Chiều cao -) mà thay vào đó hiển thị chuỗi "chọn một tùy chọn" (Tôi đã bao gồm một bộ lọc khác - được mã hóa theo cách tương tự - trong ảnh chụp màn hình để hiển thị những gì nó sẽ trông như thế nào).

enter image description here

Sau một vài lần loay hoay, tôi nhận ra rằng tôi có thể sửa nó bằng cách thay đổi truy vấn cơ sở dữ liệu của mình trong lớp JFormField. Lớp JFormField ban đầu của tôi như sau:

JFormHelper::loadFieldClass('list');

class JFormFieldHeight extends JFormFieldList
{
    protected $type = 'Height';

    public function getOptions()
    {
        $options = array();

        $db     = JFactory::getDbo();
        $query  = $db->getQuery(true);

        $query->select("DISTINCT LEFT(a.description2, LOCATE('(', a.description2) - 1) AS height");
        $query->from('#__cadcam_disc AS a');
        $query->order("LEFT(a.description2, LOCATE('(', a.description2) - 1)");

        $db->setQuery($query);
        $options = $db->loadObjectList();

        if ($db->getErrorNum()) {
            JError::raiseWarning(500, $db->getErrorMsg());
        }

        return $options;
    }
}

Mã này gây ra sự cố nhưng nếu tôi loại bỏ hàm LOCATE khỏi truy vấn thì nó hoạt động tốt. Rõ ràng tôi cần giữ truy vấn ban đầu để đây không phải là một lựa chọn.

Đối với thông tin, hộp chọn được tải với các giá trị trong cả hai trường hợp bao gồm giá trị mặc định nhưng ngay cả việc chọn giá trị mặc định sẽ trở lại chuỗi "chọn một tùy chọn":

enter image description here

Bất kỳ ý tưởng những gì đang xảy ra ở đây?

3
doovers

Tôi nghĩ rằng tôi đã tìm thấy vấn đề. Tôi đang làm việc trên một trong những tiện ích mở rộng của riêng mình khi vấn đề tương tự xuất hiện. Kiểm tra đầu ra HTML và xem có hai tùy chọn có giá trị 0 không.

Đây là chức năng gây ra vấn đề

public function getAdminList()
{
    $db = JFactory::getDbo();
    $query  = $db->getQuery(true);

    $query->select('DISTINCT notify.admin_to_notify AS id');
    $query->from('#__babelu_exams_notification_profiles AS notify');

    $query->select('admin.name');
    $query->join('LEFT', '#__users AS admin ON admin.id = notify.admin_to_notify');

    $query->order('admin.name');

    $db->setQuery($query);
    return $db->loadObjectList();
}

Như bạn có thể thấy, cả hai chúng tôi đều sử dụng bộ chọn DISTINCT có lẽ là gốc rễ của vấn đề. Kiểm tra đầu ra HTML, đây là giao diện được chọn

<select name="filter[admin]" id="filter_admin" class="span12 small chzn-done" onchange="this.form.submit()" style="display: none;">
   <option value="">
       Filter by Administrator
   </option>
   <option value="0" selected="selected">
       Not Assigned
   </option>
   <option value="0" selected="selected"></option>
</select>

Vì vậy, tôi đã thay đổi phần cuối của hàm getAdminList () để thêm một tiêu đề vào mặc định trước khi gửi nó đến chế độ xem của tôi.

result = $db->loadObjectList();
    if ($result[0]->id == 0)
    {
        $result[0]->name = JText::_('COM_BABELU_EXAMS_RESULTS_NONE_ASSIGNED');
    }
    else
    {
        $notAssigned = new stdClass();
        $notAssigned->name = JText::_('COM_BABELU_EXAMS_RESULTS_NONE_ASSIGNED');
        $notAssigned->id = 0;
        array_unshift($result, $notAssigned);
    }

    return $result;

Và vấn đề đã được giải quyết.

Tôi hi vọng cái này giúp được. Chúc mừng Joomla!

2
Mathew Lenning

Tôi đoán rằng nguyên nhân của vấn đề là do kết quả của truy vấn nên tôi đã chơi xung quanh với nó một chút và loại bỏ bất kỳ chuỗi không số nào được trả về như vậy:

$query->select("DISTINCT LEFT(a.description2, LOCATE('(', a.description2) - 1) AS height");
$query->from('#__cadcam_disc AS a');
$query->where("LEFT(a.description2, LOCATE('(', a.description2) - 1) > 0");
$query->order("LEFT(a.description2, LOCATE('(', a.description2) - 1) + 0");

Và điều đó đã khắc phục tình hình.

Tôi vẫn không hiểu nguyên nhân của vấn đề nhưng ít nhất nó đã được sửa.

1
doovers

Bạn không đề cập đến phiên bản Joomla mà bạn đang làm việc nhưng:

1) Nếu bạn muốn "- Chọn Chiều cao -" Tôi không chắc tại sao bạn lại gói nó trong JText::_() gọi trước. JText::_() được sử dụng dịch một khóa từ tệp ngôn ngữ, ví dụ: nếu bạn có tệp này trong tệp tiếng Anh trong /components/com_mycomponent/language/en-GB/en-GB.com_mycomponent.ini có dòng này trong đó (cùng với nhiều tệp khác)

 COM_MYCOMPONENT_PLACEHOLDER_SELECT_HEIGHT="- Select Height -"

Lưu ý rằng khóa bên trái của = Không có khoảng trắng trong đó và được khóa bởi thành phần. Theo mặc định, nếu không tìm thấy khóa, bạn nên lấy lại văn bản được truyền vào hàm, nhưng, bằng cách xóa cuộc gọi JText::_() bạn có thể loại bỏ vấn đề đó.

2) Bạn sẽ cần thêm mã cho JFormField đó là nơi mục đầu tiên thường được đặt, vì vậy chúng ta có thể thấy vấn đề là gì.

Một print_r($heightOptions) cũng có thể làm sáng tỏ những gì đang diễn ra.

Trước đây trong một JFormFieldList mở rộng, chúng tôi đã thêm mục đầu tiên vào $options Được tạo từ cơ sở dữ liệu, ví dụ:

$noneSelected = new stdClass;
$noneSelected->value = '';
$noneSelected->text = '- ' . JText::_('COM_MYCOMPONENT_PLACEHOLDER_SELECT_HEIGHT') . ' -';
array_splice($options, 0, 0, array($noneSelected));
0
Craig

Như một vấn đề về việc hiển thị một số tinh chỉnh/thực tiễn tốt nhất, tôi sẽ giải quyết giải pháp được đăng của @ doovers.

$query = $db->getQuery(true)
    ->select("DISTINCT SUBSTRING_INDEX(description2, '(', 1) AS height");
    ->from("#__cadcam_disc");
    ->where("LOCATE('(', description2) > 0")
    ->order("height");
  • SUBSTRING_INDEX() là lệnh gọi hàm đơn tương đương với LEFT(LOCATE())
  • Một bí danh bảng (a) là không cần thiết vì chỉ có một bảng được truy vấn (không có sự mơ hồ để giải quyết).
  • Khi lọc ra các giá trị không có ( Trong mệnh đề WHERE của bạn, bạn chỉ có thể kiểm tra giá trị LOCATE() (ký tự đầu tiên sẽ ở vị trí 0, nhưng logic của nhiệm vụ của bạn có nghĩa là chúng tôi không cần kiểm tra xem > -1, ergo > 0 sẽ làm gì.
  • Thao tác chuỗi trong mệnh đề SELECT được đặt bí danh cột là height có thể được tham chiếu trong mệnh đề ORDER BY. Điều này là dễ dàng hơn nhiều trên mắt.

Đây là một sân chơi cho bất cứ ai muốn tìm hiểu các chức năng này tốt hơn.

https://www.db-fiddle.com/f/ci6ZfAQAPkbMKtak4T5kbm/

0
mickmackusa