2013-04-07 51 views
4

我想在用户开始在表单中输入时将用户添加到发布的author列表中。当用户开始在表单中输入时标记

例如,当用户在表单中键入任何字母(或按下'enter'按钮)时,我会呼叫@post.authors.create(user_id: current_user.id)将用户添加到该特定帖子的作者列表中。我认为这是不可能实现的,但使用javascript提交ajax请求可能足以实现此方法。是否有可能在Rails应用程序中实现这种方法?如果是这样,有人可以给我一些方向吗?

+1

您应该在表单上监听['keydown'](http://api.jquery.com/keydown/)事件。如果发生,使用['$ .post'](http://api.jquery.com/jQuery.post/)将当前用户发布到您的控制器。 – Mischa 2013-04-08 00:32:48

+2

用户在实际提交表单之前是否需要添加为作者(大概保存任何更改)?我会认为你想做这件事的方式会更困难,并且可能会给你带来更多的复杂性,特别是如果用户要删除他们所做的任何更改,或者从未真正保存它们。如果你确实需要这样做,但它应该是可能的。 – 2013-04-08 00:34:33

+0

不是一个公约。如果我只是在这里输入并且没有点击“添加评论”,您将永远无法看到我的评论。 – 2013-04-08 00:38:33

回答

3

对于下面的答案,我假设你正在使用jQuery运行Ruby on Rails的,如JavaScript框架,并有(=作者)记录在当前用户(即会话中的当前用户ID)。我正在解释@ Mischa的想法:使用按键事件。

因此,正如你所解释的,你有一个表单来编辑帖子。我想你里面有一个textarea文本。例如<textarea id="posting">This is a post</textarea>

你的下一个要求是告诉服务器,“当用户在表单中键入任何字母(或按'enter'按钮)时”。因此,我们为“按键”事件定义一个事件处理程序。在按下第一个键之后,应该删除该事件处理程序。感谢@ user2257149以下代码(我调整了一点点):

function typeCatch(){ 
     $(this).off("keypress",typeCatch) // remove handler 
     console.log("User start type"); 
    } 

    $("#post").on("keypress",typeCatch); // add handler 

这段JavaScript代码片段必须<textarea>的定义如下。

现在我们有一个事件处理程序,它只被触发一次。在这个处理程序中,我们触发一个ajax调用来让服务器知道,当前用户正在编辑当前的帖子。正如我们在更新后的对象的特定属性,我们应该触发类似下面的网址:

PUT http://www.example.com/posts/123/add_current_author 

这意味着,我们应该使用HTTP PUT 方法来更新ID后和触发方法add_current_author in PostsController

所以我们调整功能typeCatch()到:

function typeCatch(){ 
    $(this).off("keypress",typeCatch)//remove handler 
    $.ajax({ 
    type: "POST", 
    url: '/posts/123/add_current_author', 
    data: JSON.stringify({_method: 'put'}) 
    }); 
} 

(由于大部分的浏览器不支持PUT方法,Ruby on Rails的技巧,通过发送POST参数“_method”,我得到这个从@迈克尔·科佩尔在他answer to Ruby on rails - PUT method on update ajax

您可能必须添加on Rails的(不知道下面,我轨红宝石这个特殊的路线是有点生疏):

resources :posts do 
    collection do 
    put "add_current_author" 
    end 
end 

现在,在您的PostsController中,您必须定义方法add_current_author。我假设你将@post实例化为before_filter中的实际文章(由给定的:id标识),并将当前用户保存在current_user中。因此,实际上它应该是一样简单:

def add_current_author 
    @post.authors.create(user_id: current_user.id) 
end 

尽管我必须承认,这看起来有点怪异(这是你的建议)。我想,我有一个1:N“上岗”和“用户”之间的连接被称为“作家”,并执行以下操作:

@post.authors << current_user 

还是那句话:感谢@Micha,@ user2257149和@迈克尔科佩尔。我提高了你的答案。

UPDATE: 作为赏金评论指出,OP希望“时所显示的标记由用户阅读”到“仅标记为已读,当用户按下评论形式的钥匙”从改变目前的功能。

所以目前EssayController具有show动作等

def show 
    ... 
    @essay.reader_links.create(reader_id: current_user.id) 
    ... 
end 

给定的线应被删除,因为当所示@essay当前用户不应该添加。而且,我在上面定义的<textarea>是一个在注释形式,因此HTML可能看起来像

<html> 
    ... 
    <form action="essay/123/comment" method="post"> 
    ... 
    <textarea name="comment_text" id="comment"></textarea> 
    ... 
    </form> 
    <script type="text/javascript"> 
    function typeCatch() { 
     ... 
    } 
    $("#post").on("keypress", typeCatch); 
    </script> 
</html> 

最后,行动add_current_author不应该,因为我认为,在PostController但在EssayController和路线分别改变。

更新2: 作为@Yarek牛逼陈述,而不是$("#post").on("keypress", typeCatch);,jQuery的功能one可用于:

function typeCatch(){ 
    $.ajax({ 
    type: "POST", 
    url: '/posts/123/add_current_author', 
    data: JSON.stringify({_method: 'put'}) 
    }); 
} 
$("#post").one("keypress", typeCatch); 
11

您必须先为按键制作事件处理程序并在第一次按下后移除。

function typeCatch(){ 
    $(this).off("keypress",typeCatch)//remove handler 
    console.log("User start type"); 
} 

$("$field_id").on("keypress",typeCatch) 
0
var flag = 0; 
$(document).on('keypress', function(e) { 
    if(flag == 0) { 
     doSomething(); 
     flag = 1; 
    } 
}); 
1

人都有每个人忘记了jQuery的$.one()功能?它的功能与$.on()相同,然后在$.off()之内。

相关问题