使用糖cr中的ajax防止重复值

时间:2014-04-28 12:03:50

标签: ajax sugarcrm

我使用模块构建器创建模块,现在我有一个名为book name的字段 现在,如果我给同一本书名称2时间t正在接受。

我不想使用和插入来检查重复值,因为我想通过代码学习自定义。

所以我可以调用ajax并检查数据库天气,db中是否存在相同的书名,但我不知道控制器在sugar crm中是如何工作的。以及如何在糖crm中调用ajax。

任何人都可以指导我,非常感谢你的帮助。

1 个答案:

答案 0 :(得分:18)

如果您真的想使用ajax完成此操作,那么我建议您使用entryPoint。这种定制需要一些简单的事情。首先,您将编写一些javascript来执行实际的ajax调用。该ajax调用将发布到您编写的entryPoint。 entryPoint将为您运行查询并在编辑视图中向您返回响应。所以让我们先开始编写entryPoint。

首先,打开文件custom / include / MVC / Controller / entry_point_registry.php。如果文件夹结构和文件尚不存在,请继续创建它们。

将以下代码添加到entry_point_registry.php文件中:

$entry_point_registry['test'] = array('file' => 'custom/test.php', 'auth' => true);

关于该行的一些快速解释:

  • 测试的索引值可以更改为您喜欢的任何值。也许' unique_book_value'在你的情况下更有意义。您将在一分钟内看到如何使用此值。
  • 数组中的文件值指向您要放置实际代码的位置。你还应该给它一个更有意义的名字。它不需要匹配上面提到的数组键。
  • ' auth' => true部分确定浏览器是否需要与SugarCRM进行活动登录会话。在这种情况下(几乎所有),我建议保持这一点。

现在让我们看一下将在custom / test.php(或者你的情况下是unique_book_name.php)中的代码:

/* disclaimer: we are not gonna get all crazy with using PDO and parameterized queries at this point,
               but be aware that there is potential for sql injection here. The auth => true will help
               mitigate that somewhat, but you're never supposed to trust any input, blah blah blah. */

global $db; // load the global sugarcrm database object for your query

$book_name = urldecode($_REQUEST['book_name']); // we are gonna start with $_REQUEST to make this easier to test, but consider changing to $_POST when confirmed working as expected
$book_id   = urldecode($_REQUEST['book_id']);   // need to make sure this still works as expected when editing an existing record

// the $db->quote is an alias for mysql_real_escape_string() It still does not protect you completely from sql injection, but is better than not using it...
$sql = "SELECT id FROM book_module_table_name WHERE deleted = 0 AND name = '".$db->quote($book_name)."' AND id <> '".$db->quote($book_id)."'";

$res = $db->query($sql);

if ($db->getRowCount($res) > 0) {
    echo 'exists';
}
else {
    echo 'unique';
}

关于使用直接数据库查询的说明:您可以使用api方法来完成此操作。 (提示:$ bean-&gt; retrieve_by_string_fields() - 如果你想走这条路线,请查看这篇文章:http://developer.sugarcrm.com/2012/03/23/howto-using-the-bean-instead-of-sql-all-the-time/)但是,我发现api相当慢,ajax应该尽可能快。如果客户要求我提供此功能,那么我有99%的机会使用直接数据库查询。如果我当天感觉很喜欢,可能会使用PDO和参数化查询,但这是您的通话。

使用上面的代码,您应该能够导航到https://crm.yourdomain.com/index.php?entryPoint=test并运行我们刚写的代码。

然而,此时你所得到的只是白屏。如果您修改网址以包含entryPoint部分并且它加载您的主页或不转到白屏,则有3个可能的原因:

  1. 你为$ entry_point_registry [&#39; test&#39;]添加了不同的东西。如果是这样更改url以读取index.php?entryPoint = whatever_you_put_as_the_array_key
  2. 你的域名中的文件夹或某些内容中有糖,所以不是crm.yourdomain.com,它位于某个地方丑陋和愚蠢,如youdomain.com/sugarcrm/,如果是这种情况,请确保您正在修改网址这样就可以保留实际的域部分。好的,我会为你拼出来...... https://yourdomain.com/sugarcrm/index.php?entryPoint=test
  3. 这种情况比较少见,但由于某些原因我无法弄清楚有时需要在添加新的入口点时重新加载apache。如果你有shell访问权限,快速/etc/init.d/apache2重新加载应该可以解决问题。如果你没有shell访问权限,你可能需要与你的托管服务提供商一起打开一张票(或者在你有控制权的情况下获得一个fricking vps !!!,c&#39; mon man!)
  4. 仍然无法使用?你注意到&#34; s&#34;在https?试试http而不是购买9美元的ssl证书,geez man!

    好的继续前进。让我们稍微测试一下entryPoint。将记录添加到图书模块。让我们来加上这本书&#34;艺术之战&#34; (不,不是战争艺术,虽然你也应该给它一个阅读)。

    现在在网址中添加:index.php?entryPoint = test&amp; book_name = Art%20of%20War

    哦,gawd,url编码是可怕的!别担心。

    你应该希望得到一个丑陋的白色屏幕,文字&#34;存在&#34;。如果你这样做,请确保它也能以其他方式工作。在网址中为图书名称添加2,希望它现在会说&#34; unique&#34;。

    快速注意:如果您正在使用Sugar,那么您可能也会使用在搜索字符串时不区分大小写的mysql。如果您确实需要区分大小写,请查看此SO文章: How can I make SQL case sensitive string comparison on MySQL?

    好的,现在我们的entryPoint正在运行,我们可以继续进行有趣的部分,让所有东西都变得无趣。有几种方法可以解决这个问题,但不是走最基本的路线,而是要告诉你我发现的最可靠的路线。

    您可能需要创建以下文件:custom / modules / CUSTOM_BOOK_MODULE / views / view.edit.php(我希望现在我不需要指出更改该路径以使用您的模块名称。 ..

    假设这个文件不存在,我们从头开始这里需要看起来像:

    if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
    
    class CUSTOM_BOOK_MODULEViewEdit extends ViewEdit
    {
        public function display()
        {
            // make sure it works in the subpanel too
            $this->useForSubpanel = true;
    
            // make the name value available in the tpl file
            $this->ss->assign('name_value', $this->bean->name);
    
            // load the parsed contents of the tpl into this var
            $name_input_code = $this->ss->fetch('custom/modules/CUSTOM_BOOK_MODULE/tpls/unique_book_checker.tpl.js');
    
            // pass the parsed contents down into the editviewdefs
            $this->ss->assign('custom_name_code', $name_input_code);
    
            // definitely need to call the parent method
            parent::display();
        }
    }
    

    事情看起来很好。现在我们要在这个文件中编写代码:custom / modules / CUSTOM_BOOK_MODULE / tpls / unique_book_checker.tpl.js

    首先是几个假设:

    1. 我们预计这是Sugar 6.5+并且jquery已经可用。如果您使用的是早期版本,则需要手动添加jquery。

    2. 我们将把事件监听器放在name字段上。如果您要检查的图书名称值实际上是一个不同的字段名称,那么只需在下面的javascript中调整它。

    3. 以下是custom / modules / CUSTOM_BOOK_MODULE / unique_book_checker.tpl.js的代码:

      <input type="text" name="name" id="name" maxlength="255" value="{$name_value}" />
      <span id="book_unique_result"></span>
      
      {literal}
      <script type="text/javascript">
      
      $(document).ready(function() {
      
          $('#name').blur(function(){
      
              $('#book_unique_result').html('<strong> checking name...</strong>');
      
              $.post('index.php?entryPoint=test', {book_name: $('#name').val(), book_id: $('[name="record"]').val()}, function(data){
      
                  if (data == 'exists') {
                      removeFromValidate('EditView', 'name');
                      addToValidate('EditView', 'name', 'float', true, 'Book Name Must be Unique.');
      
                      $('#book_unique_result').html('<strong style="color:red;"> &#x2717;</strong>');
                  }
                  else if (data == 'unique') {
                      removeFromValidate('EditView', 'name');
                      addToValidate('EditView', 'name', '', true, 'Name Required');
      
                      $('#book_unique_result').html('<strong style="color:green;"> &#x2713;</strong>');
                  }
                  else {
                      // uh oh! maybe you have php display errors on?
                  }
      
              });
          });
      });
      </script>
      {/literal}
      

      另一个注意事项:当代码检测到该名称已存在时,我们会有点hacky并使用Sugar内置的验证内容来阻止记录保存。基本上,我们说如果名称已经存在,那么名称值必须是浮点数。我认为这是不太可能的,并将做到这一点。但是,如果您有一本名为3.14的书或类似的书,并且您尝试创建副本,则此代码不会阻止保存。它会告诉您找到了重复项,但它不会阻止保存。

      唷!好的,最后两步,他们很容易。 首先,打开文件:custom / modules / CUSTOM_BOOK_MODULE / metadata / editviewdefs.php。 接下来,找到提供name字段元数据的部分,并添加此customCode属性,使其如下所示:

      array (
      'name' => 'name',
      'customCode' => '{$custom_name_code}',
      ),
      

      最后,您需要进行快速修复和重建,以使元数据更改生效。转到管理员&gt;修复&gt;快速修复&amp;重建。

      轰!你应该好好去!

      checking for unique book name uh oh thats a duplicate okay safe to save