1

Imagine a table (actually constructed of divs) with rows and in the final cell in each row, I have an input text and a link that look like this:

<input type="text" name="message" id="message_@Model.IncidentId" value="">
<a href="/RegisterAjax/@Model.IncidentId" id="send_@Model.IncidentId">Send a Comment</a>

After each row (the parent div), I have a chunk of code like the following to ajaxify the link and text input:

$('#send_@Model.IncidentId').click(function () {
            var msg = $('#message_@Model.IncidentId').val();
            if (msg != '') { $(this).attr('href', this.href + '?msg=' + msg) }
            $.post(this.href, function (json) {
                if (json.jsonResult === null) {
                    $("#msg_@Model.IncidentId").html("Sent...");
                } else {
                    window.location.href = json.jsonResult;
                }
            });
            return false;
        });

It works. However, there are at least 10 of these on each page. What I'm trying to do is consolidate the jquery into one function to handle all the links. Can I use jquery "this" or pass the IncidentId to the jquery function or something? It seems like "this" would not work because the input text is outside of the link? How can I do this to have one function for the entire page?

Keep in mind it's not imperative that I splash everything with the IncidentId. So, if I need to make one or more of the ids or names generic, that would be ok. It just needs to not get confused about what pair it's handling. I've seen some comments that a form might help, but 10+ forms on a page is ok? Plus, as it stands, there will never be any other input fields than what is shown above.

I appreciate your help. Thanks.

Update: So, I basically used Søren's recommended html5 data-* (data-id) attribute in my link, gave it a class name, and then moved my url down to the function as well...and then simply replaced all my @Model.IncidentIds. The one catch is that I had to use the following to register my click event:

$(document).on('click', ".ajax-link", function () {

I guess because I'm using handlebars to dynamically generate the page? I hadn't tested the original function since I moved it to my infinite scroll layout mentioned in the comments. Thanks all for replying.

Sum None
  • 2,164
  • 3
  • 27
  • 32
  • Show a full row structure, or atleast a full cell...no need to use ID's for this sort of thing...use classes and traversals – charlietfl Jul 27 '15 at 15:24
  • Doh, sorry, thanks for the reply, if you look at the answer and solution [here](http://stackoverflow.com/questions/31639030/razor-model-helpers-in-jquery-handlebars-infinite-scroll), you can see the structure...and the text field and link above are wrapped in one more div with the name msg_@Model.IncidentId. But, I think I see what I can do now and maybe need to do some restructuring of divs. Thanks again. – Sum None Jul 28 '15 at 06:03
  • still best to provide a little more structure...rmemeber these questions are here for a long time for others as well – charlietfl Jul 28 '15 at 10:21
  • I agree, I try to be as descriptive and wordy as possible (and many times still get no replies). All the info is here. The "here" in my comment above is a hyperlink to my actual entire page on another question that I had (with no replies that I solved myself and followed up with). The link and text input above (in this question) are simply inserted where you see "Partial Goes Here" in that page encapsulated by one more div.... In the future, I will heed your advice and be more redundant though as I didn't even think about js being able to traverse with things like .find and .closest.. Thanks. – Sum None Jul 28 '15 at 10:47

3 Answers3

1

First, make sure you have some useful class name's in place. E.g.,

<input type="text" class="incident-message" name="message" id="message_@Model.IncidentId" value="">
<a href="/RegisterAjax/@Model.IncidentId" class="incident-link" id="send_@Model.IncidentId">Send a Comment</a>

That should allow you to create a nice, row-generic script like this:

$('.incident-link').click(function(e) {
    e.preventDefault();

    var $this = $(this),
        $row = $this.closest('div'),
        $msg = $row.find('.incident-message');

    var msg = $msg.val();

    if (msg != '') {
        $this.attr('href', $this.attr('href') + '?msg=' + msg);
    }

    $.post($this.attr('href'), function (json) {
        if (json.jsonResult === null) {
            // I didn't see any markup for your #msg element, but assuming
            // that you give it a useful classname, you can do something
            // similar to this:
            $row.find('.some-msg-className').html('Sent...');
        } else {
            window.location.href = json.jsonResult;
        }
    });
});
jmar777
  • 38,796
  • 11
  • 66
  • 64
  • Thank you for the answer, it was definitely helpful, +1 for the speedy brilliance and showing me I still have a lot to learn.... – Sum None Jul 28 '15 at 08:22
1

Try this:

<input type="text" name="message" data-input-id="1" value="">
<a class="ajax-link" href="#" data-link-id="1">Send a Comment</a>    

$('.ajax-link').click(function () {
        var id = $(this).attr('data-link-id');
        var msg = $('[data-link-id='+id+']').val();
        if (msg != '') { $(this).attr('href', this.href + '?msg=' + msg) }
        $.post(this.href, function (json) {
            if (json.jsonResult === null) {
                $("[data-link-id='+id+']").html("Sent...");
            } else {
                console.debug(json.jsonResult);
            }
        });
        return false;
    });

Make sure the link and field have the same id

Søren Beck Jensen
  • 1,676
  • 1
  • 12
  • 22
  • Thank you!! I had forgotten about html5 data-* attributes... This is ultimately what I used, although I had to make some adjustments. I'll update my answer... – Sum None Jul 28 '15 at 08:23
0

As far as grouping the events to a single handler, just use a class instead of id's.

$('.thisKind').click(function () {

or if the content is dynamic, use a single event for the parent with a selector in the on() method

$('#parentId').on("click", ".thisKind", function() {

As far as the this usage, you should familiarize yourself with jquery's DOM traversal using closest() to go up the tree and find() to go down

robisrob
  • 940
  • 12
  • 23