Search code examples
javascriptasp.net-coreasp.net-core-mvc

Send multiple lists from js view to c# mvc action


how can i input items (selectedPublishersList, selectedTranslatorsList, selectedAuthorsList) in this action I tried to get the data in the view and send it to the action, but every time the received value is null in the controller

c#

 [HttpPost]
 public async Task<ActionResult> Create(CreateBookViewModel model)
 {
     var bookCategory = await _bookCategoryService.GetById(model.CategoryId);
     var selectedAuthors = Request.Form["selectedAuthors"].ToString();
     var selectedPublishers = Request.Form["SelectedPublishers"].ToString();
     var selectedTranslators = Request.Form["SelectedTranslators"].ToString();

     //model.CategoryId = CategoryId;
     model.Category = bookCategory.Name;
     model.Authors = selectedAuthors.Split(',').ToList();
     model.Publishers = selectedPublishers.Split(',').ToList();
     model.Translators = selectedTranslators.Split(',').ToList();

     if (ModelState.IsValid)
     {
         var result = await _bookService.Create(model);
         if (result.IsSucceeded)
         {
             return RedirectToAction("Index", result);
         }
         else
         {
             ModelState.AddModelError(string.Empty, "خطا در ایجاد کتاب.");
         }
     }
     //return View(model);
     return RedirectToAction("Create");
 }

I tried using hidden input but I couldn't get the data in the action, I don't have much knowledge about js

html

            <div class="form-group">
                <label type="text" class="control-label">Authors:</label>
                <select class="form-control" id="authorInput" asp-items='new SelectList(Model.Authors,"Name")'>
                    <option value="">Select Author</option>
                </select>
                <button type="button" id="addAuthorButton" class="btn btn-primary">Add</button>
                <ul id="selectedAuthorsList" class="list-group" name="SelectedAuthors">
                    <!-- selected list... -->
                </ul>
                <span id="duplicateAuthorError" class="text-danger"></span>
            </div>

            <div class="form-group">
                <label type="text" class="control-label">Publishers:</label>
                <select class="form-control" id="publisherInput" asp-items='new SelectList(Model.Publishers,"Name")'>
                    <option value="">Select Publisher</option>
                </select>
                <button type="button" id="addPublisherButton" class="btn btn-primary">Add</button>
                <ul id="selectedPublishersList" class="list-group">
                    <!-- selected list... -->
                </ul>
                <span id="duplicatePublisherError" class="text-danger"></span>
            </div>

            <div class="form-group">
                <label type="text" class="control-label">Translators:</label>
                <select class="form-control" id="translatorInput" asp-items='new SelectList(Model.Translators,"Name")'>
                    <option value="">Select Translator</option>
                </select>
                <button type="button" id="addTranslatorButton" class="btn btn-primary">Add</button>
                <ul id="selectedTranslatorsList" class="list-group">
                    <!-- selected list... -->
                </ul>
                <span id="duplicateTranslatorError" class="text-danger"></span>
            </div>

            @* <input type="hidden" name="CategoryId" value="@Model.CategoryId" /> *@

            <input type="hidden" name="SelectedAuthors" id="SelectedAuthors" />
            <input type="hidden" name="SelectedPublishers" id="SelectedPublishers" />
            <input type="hidden" name="SelectedTranslators" id="SelectedTranslators" />


            <button type="submit" class="btn btn-primary">Save</button>
            <a class="btn btn-secondary" asp-action="Index">Back To Book List</a>

In this code, I tried to add values for each of the lists, if it is duplicated, I will encounter an error message and the items that were deleted before can be added again, and finally, the recorded data will be added to the action in Send C#

js

var selectedAuthors = [];
var selectedTranslators = [];
var selectedPublishers = [];

function initializeSelectionLists() {
    selectedAuthors = [];
    selectedTranslators = [];
    selectedPublishers = [];
}

// Is Repeated ??
function isDuplicate(itemName, selectedItemList) {
    return selectedItemList.includes(itemName);
}

function addToSelectedList(inputId, listId, errorId, selectedItemList) {
    var input = document.getElementById(inputId);
    var inputValue = input.value.trim();

    if (inputValue !== "") {
        if (!isDuplicate(inputValue, selectedItemList)) {
            var selectedList = document.getElementById(listId);
            var listItem = document.createElement("li");
            listItem.className = "list-group-item";
            listItem.textContent = inputValue;

            // Add deleted button to items
            var removeButton = document.createElement("button");
            removeButton.className = "btn btn-danger btn-sm float-left";
            removeButton.textContent = "Delete";
            removeButton.onclick = function () {
                selectedItemList = selectedItemList.filter(function (item) {
                    return item !== inputValue;
                });
                selectedList.removeChild(listItem);
                updateHiddenFields(); 
            };
            listItem.appendChild(removeButton);

         
            selectedItemList.push(inputValue);
            selectedList.appendChild(listItem);
            input.value = ""; 
            document.getElementById(errorId).textContent = ""; 
            updateHiddenFields(); 
        } else {
            document.getElementById(errorId).textContent = "duplicate";
        }
    }
}


function updateHiddenFields() {
    var selectedAuthors = selectedAuthors.join(",");
    var selectedPublishers = selectedPublishers.join(",");
    var selectedTranslators = selectedTranslators.join(",");

    console.log("SelectedAuthors: " + selectedAuthors);
    console.log("SelectedPublishers: " + selectedPublishers);
    console.log("SelectedTranslators: " + selectedTranslators);

    document.getElementById("SelectedAuthors").value = selectedAuthors;
    document.getElementById("SelectedPublishers").value = selectedPublishers;
    document.getElementById("SelectedTranslators").value = selectedTranslators;
}


// add selected author
document.getElementById("addAuthorButton").addEventListener("click", function () {
    addToSelectedList("authorInput", "selectedAuthorsList", "duplicateAuthorError", selectedAuthors);
});
// add selected Translator
document.getElementById("addTranslatorButton").addEventListener("click", function () {
    addToSelectedList("translatorInput", "selectedTranslatorsList", "duplicateTranslatorError", selectedTranslators);
});

// add selected Publisher
document.getElementById("addPublisherButton").addEventListener("click", function () {
    addToSelectedList("publisherInput", "selectedPublishersList", "duplicatePublisherError", selectedPublishers);
});

Solution

  • Have a little change to your function updateHiddenFields(), try to modify var selectedAuthors into var SelectedAuthors, like:

    function updateHiddenFields() {
        var SelectedAuthors = selectedAuthors.join(",");
        var SelectedPublishers = selectedPublishers.join(",");
        var SelectedTranslators = selectedTranslators.join(",");
    
        console.log("SelectedAuthors: " + SelectedAuthors);
        console.log("SelectedPublishers: " + SelectedPublishers);
        console.log("SelectedTranslators: " + SelectedTranslators);
    
        document.getElementById("SelectedAuthors").value = SelectedAuthors;
        document.getElementById("SelectedPublishers").value = SelectedPublishers;
        document.getElementById("SelectedTranslators").value = SelectedTranslators;
    }
    

    result: enter image description here

    Besides, try to reset the ModelState and invoke TryValidateModel in your case like:

    ...
    model.Translators = selectedTranslators.Split(',').ToList();
    ModelState.Clear();
    TryValidateModel(model);
    if (ModelState.IsValid)
    ...
    

    result:

    enter image description here