我使用模块构建器创建模块,现在我有一个名为book name的字段 现在,如果我给同一本书名称2时间t正在接受。
我不想使用和插入来检查重复值,因为我想通过代码学习自定义。
所以我可以调用ajax并检查数据库天气,db中是否存在相同的书名,但我不知道控制器在sugar crm中是如何工作的。以及如何在糖crm中调用ajax。
任何人都可以指导我,非常感谢你的帮助。
答案 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);
关于该行的一些快速解释:
现在让我们看一下将在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个可能的原因:
仍然无法使用?你注意到&#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
首先是几个假设:
我们预计这是Sugar 6.5+并且jquery已经可用。如果您使用的是早期版本,则需要手动添加jquery。
我们将把事件监听器放在name字段上。如果您要检查的图书名称值实际上是一个不同的字段名称,那么只需在下面的javascript中调整它。
以下是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;"> ✗</strong>');
}
else if (data == 'unique') {
removeFromValidate('EditView', 'name');
addToValidate('EditView', 'name', '', true, 'Name Required');
$('#book_unique_result').html('<strong style="color:green;"> ✓</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;重建。
轰!你应该好好去!