1

In my ASP.NET MVC 4 Web application I have two Models:

  1. Block that has a property Block LinkedBlock.
  2. BlockCollection which contains multiple Block. Every Block instance in Block.LinkedBlock is guaranteed to be also in the BlockCollection.

Now, what I want to do is the following:
If a Block has a linked block it should get a onchange handler that sets the text of the linked block to the text of this block.

Now, in principle, this is pretty simple:

if (Model.LinkedBlock != null)
{
    var onChange = string.Format("setText({0}, this.text);", linkedBlockId);
    @Html.TextBoxFor(m => m.Text, new { onchange = onChange });
}
<script type="text/javascript" language="javascript">
    function setText(id, text) {
        $("#" + id).val(text);
    }

But the problem is, that I have no idea how to get the correct HTML ID of the linked block.

How do I get it?

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443

2 Answers2

1

Just add any ID you want to your HTML helper when you're rendering linked blocks, like:

@Html.TextBoxFor(m => m.Text, new { id = blockId });

Where blockId is your unique ID, say the ID record has in the database. Later, you can reference this ID when you're constructing onChange handler call. something like:

var onChange = string.Format("setText({0}, this.text);", Model.LinkedBlock.ID);

If you provide more context I'd be able to give you more sample code.

Floremin
  • 3,969
  • 15
  • 20
  • I wanted to avoid this, because it might be possible that I am displaying the same block multiple times. As I understand it, ASP.NET MVC would create unique HTML IDs for each of the generated controls, while this approach would use the same ID for multiple UI elements. – Daniel Hilgarth Apr 11 '13 at 19:49
  • ASP.NET WebForms would generate a unique ID, but only for ASP.NET controls. There are no actual MVC controls. – Floremin Apr 11 '13 at 19:52
  • I am talking about the standard HTML controls generated by `Html.EditorFor` and the IDs of them. – Daniel Hilgarth Apr 11 '13 at 19:56
  • You could come up with some other way of finding the linked block in your rendered html. Say, put your block and all linked blocks in a container div. Set `data-id="[linked block ID]"` for a linked block and then use jQuery to find the linked block within the same container as the block. – Floremin Apr 11 '13 at 19:58
  • I went with using the database ID. For now, a block is only displayed once. If that changes, I have to revisit this decision. – Daniel Hilgarth Apr 11 '13 at 20:38
1

In the Block Model you should have an Id property. Then on your view you can reference that Id. For example:

class Block
{
    public Block LinkedBlock { get; set; }
    public int Id { get; set; }
}

Your view has to be strongly typed:

@model Models.Block

or the following depending on what your are doing:

@model Models.BlockCollection

Then change your code to (just add the reference to the linked block):

if (Model.LinkedBlock != null)
{
    var onChange = string.Format("setText({0}, this.text);", Model.LinkedBlock.Id);
    @Html.TextBoxFor(m => m.Text, new { onchange = onChange });
}

You obviously have to make sure all the linkedBlocks are on the page with their respective ids.

Does that help?

Rafi
  • 2,433
  • 1
  • 25
  • 33
  • Unfortunately, that doesn't help, because the HTML ID generated by ASP.NET MVC for the UI element has nothing to do with the ID of the Model. – Daniel Hilgarth Apr 11 '13 at 19:47
  • true should have mentioned overriding the id attribute like Floremin above. – Rafi Apr 11 '13 at 20:53
  • In terms of the issue of the same id appearing twice (see above), why is that an issue? Wouldn't you want all of the same blocks to have the same text? If that is the case JQuery would change all of them. Not sure what your requirements are. – Rafi Apr 11 '13 at 20:55
  • It's simply not valid to have multiple elements with the same ID. See [here](http://stackoverflow.com/questions/5611963/can-multiple-different-html-elements-have-the-same-id-if-theyre-different-types) for example. – Daniel Hilgarth Apr 11 '13 at 21:11
  • Even if it isn't valid it does work. If you want it to be valid use a [data attribute](http://api.jquery.com/data/) and use JQuery to call it. There is no problem for multiple data attributes to have the same value. – Rafi Apr 11 '13 at 21:44
  • Thanks for the suggestion. I will have a look at it. – Daniel Hilgarth Apr 11 '13 at 22:19