我已经使用模块构建器创建模块,现在我有一个名为book name的字段现在如果我给同一个书名2时间t正在接受.
我不想使用和插入检查重复值,因为我想通过代码学习自定义.
所以我可以调用ajax并检查数据库天气,db中是否存在相同的书名,但我不知道控制器在sugar crm中是如何工作的.以及如何在糖crm中调用ajax.
任何人都可以指导我,非常感谢你的帮助.
dmu*_*lvi 20
如果你真的想用ajax来完成这个,那么我建议你选择一个入口点.这种定制需要一些简单的事情.首先,您将编写一些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);
Run Code Online (Sandbox Code Playgroud)
关于该行的一些快速解释:
现在让我们看一下将在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';
}
Run Code Online (Sandbox Code Playgroud)
关于使用直接数据库查询的注意事项:您可以使用api方法来实现此目的.(提示:$ bean-> 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并运行我们刚刚编写的代码.
但是在这一点上,你所能得到的只是一个白色的屏幕.如果您修改URL以包含entryPoint部分并且它加载您的主页或不转到白屏,则有3个可能的原因:
还是行不通?您是否注意到https中的"s"?试试http而不是购买9美元的ssl证书,geez man!
好的继续前进.让我们稍微测试一下entryPoint.将记录添加到图书模块.让我们加上"艺术之战"一书(不,不是战争艺术,虽然你也应该给它一个阅读).
现在在url中添加:index.php?entryPoint = test&book_name = Art%20of%20War
哦,gawd,url编码是可怕的!别担心.
你应该希望得到一个丑陋的白色屏幕,文字"存在".如果你确实让它确保它也以另一种方式工作.在网址中为书名添加2,希望它现在会说"唯一".
快速注意:如果你正在使用Sugar,你可能也使用mysql,它在搜索字符串时不区分大小写.如果您确实需要区分大小写,请查看此SO文章: 如何在MySQL上进行SQL区分大小写的字符串比较?
好的,现在我们的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();
}
}
Run Code Online (Sandbox Code Playgroud)
事情看起来很好.现在我们要在这个文件中编写代码: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}
Run Code Online (Sandbox Code Playgroud)
另一个注意事项:当代码检测到名称已经存在时,我们会得到一些hacky并使用Sugar的内置验证内容来防止记录保存.基本上,我们说如果名称已经存在,那么名称值必须是浮点数.我认为这是不太可能的,并将做到这一点.但是,如果您有一本名为3.14的书或类似的书,并且您尝试创建副本,则此代码不会阻止保存.它会告诉您找到了重复项,但它不会阻止保存.
唷!好的,最后两步,他们很容易.首先,打开文件:custom/modules/CUSTOM_BOOK_MODULE/metadata/editviewdefs.php.接下来,找到提供name字段元数据的部分,并添加此customCode属性,使其如下所示:
array (
'name' => 'name',
'customCode' => '{$custom_name_code}',
),
Run Code Online (Sandbox Code Playgroud)
最后,您需要进行快速修复和重建,以使元数据更改生效.转至管理>修复>快速修复和重建.
繁荣!你应该好好去!

| 归档时间: |
|
| 查看次数: |
4565 次 |
| 最近记录: |