Question

I'm trying to save below project Model

public partial class Project: BaseModel
{
    public Project()
    {
        ProjectUsers = new List<ProjUser>();
    }

    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    [Display(Name="Project ID")]
    public int ProjectID { get; set; }

    [Required]
    public string Title { get; set; }
    [Display(Name = "Users")]
    public virtual List<ProjUser> ProjectUsers { get; set; }
}

ProjUser Model

public partial class ProjUser: BaseModel
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ProjUserID { get; set; }

    public int UserID { get; set; }

    public int ProjectID { get; set; }
    [ForeignKey("ProjectID")]
    public virtual Project Project { get; set; }

    public bool? Signatories { get; set; }

}

The Users are populated via a separate database and the link between the project and user are maintains via the ProjUser model, UserID value.

public partial class User : BaseModel
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserID { get; set; }
    [Required]
    [Display(Name = "dispUserName" , ResourceType = typeof(Resource))]
    public string UserName { get; set; }
}

In the view i'm populating the list of users as a selectable (JqueryUI) and selecting the users who are available in the project.

@model Impetro.Models.Project
@{
    ViewBag.Title = "ProjectSettings";
}

<h2>@ViewBag.Title</h2>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Project Settings</legend>
        @Html.HiddenFor(model => model.ProjectID)
        <div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Title)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Title)
            </div>
        </div>
    </fieldset>
<p>
    <input type="submit" value="Save" />
</p>
}
<h3>@Html.DisplayNameFor(model => model.ProjectUsers)</h3>
@{
    var pojectUserIDs = from pu in Model.ProjectUsers
                        select new { pu.UserID };

    String userIDstr = "";
    foreach (var user in pojectUserIDs)
    {
        userIDstr = userIDstr + "#" + user.UserID.ToString() + ";";
    }
}
@Html.Hidden("userValues", userIDstr, "id='userValues'")
<table data-impetro-uitype="selectable" data-impetro-selectorvalues="#userValues" id="projUserGrd">
    @foreach (var user in ViewBag.Users as IEnumerable<Impetro.Models.Global.User>)
    {
        <tr id="@user.UserID" class="ui-widget-content"><td>@user.UserName</td> <td>@Html.CheckBox("chk" + @user.UserID) @Html.Label("chk" + @user.UserID, "PO Signatory")</td></tr>
    }
</table>

The JS to convert the above table to a selectable and to select the already added users.

$(function () {
    $("[data-impetro-uitype='selectable']").bind("mousedown", function (e) {
        e.metaKey = true;
    })
    .selectable({
        filter: "tr",
        create: function (event, ui) {
            var selectable = $(this);
            var valueEle = selectable.attr("data-impetro-selectorvalues");
            var valArr = $(valueEle).val().split(";");
            for (var i = 0; i < valArr.length; i++) {
                if (valArr[i] == "") {
                    continue;
                }
                var id = valArr[i];
                selectable.find(id).addClass("ui-selected");
            }
        }
    });
});

How can the changes to the projusers list be captured in the model? Btw: Is there an easier method to select the values on initial load itself, which supports tracking the projUser list changes

Thanks in Advance

As Requested by lnanikian here is the GET Action for the controller. I still did not write the POST Action for this, becos im still in doubt about how to proceed with saving the details into the list.

public ActionResult ProjectSettings(int id)
    {
        ViewBag.Users = userRepository.All;
        return View(projectRepository.All
               .Where(p => p.ProjectID == id).SingleOrDefault());
    }
Was it helpful?

Solution

If I understand well. Let say when you click on the checkBox of the User he must be updated to the project? Whatn you can also do is create an Action who will save your User for the project.

[HttpPost]
public ActionResult AddUserToProj(int userId){
 //retreive the User by the Id with a Linq query or
 //just add to ProjUsers the Id of the UserId with other importants informations you can
 //pass via th eparameters 
}

And then in your view, in your JS function an Ajax Method who will be called let's say if your your user is checked then you call the Action

$(function () {
   $("[data-impetro-uitype='selectable']").bind("mousedown", function (e) {
    e.metaKey = true;
    })
    .selectable({
    filter: "tr",
    create: function (event, ui) {
        var selectable = $(this);
        var valueEle = selectable.attr("data-impetro-selectorvalues");
        var valArr = $(valueEle).val().split(";");
        for (var i = 0; i < valArr.length; i++) {
            if (valArr[i] == "") {
                continue;
            }
            var id = valArr[i];
            selectable.find(id).addClass("ui-selected");
        }
    }
});

$('#check').bind('change', function () {

   if($(this).is(':checked'))
    {//You can ask a question here by a popup
     var userID= $("userId") //You retreive userId in the line by wise selection

     $.ajax({
        url: "@Url.Action("AddUserToProj","ControllerName")",
        type: 'POST',
        dataType: 'json',
        data: {id = $userID },
        async: false,
        success: function (result) {
            //  process the results from the server
            alert('done')

            });

        },
        error: function (errorThrown) {
            alert('error');
        }
    });
  }
 else
  {
    // unchecked, You can call a Deletion Method if you create another Action to do that
  }
  });
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top