Question

J'ai donc cette application dans ASP MVC 3. Ma base de données a deux tables: Comenzi et Détaliomenzi Avec une relation un-à-plusieurs (et un lien-sql) - dans mon application, je veux que mes utilisateurs achètent des produits en fabriquant un oder (stocké dans le tableau Comenzi) et pour cela, une liste de produits qu'il souhaite acheter ( sera stocké dans detaliicomenzi avec ordre.id comme clé étrangère). Fondamentalement, après avoir créé une nouvelle entrée pour Comenzi, je veux pouvoir faire une liste de produits pour cette commande (quelque chose comme un graphique de magasin mais l'utilisateur choisira ses produits en vue, ajoutant combien de produits comme il le veut) .

j'ai utilisé Steve Sanderson Méthode d'édition (et de création) d'une liste de longueurs variables.

- Voici le modèle pour lequel je crée la liste.

Lorsque je choisis un seul produit pour oder, je dois d'abord sélectionner le groupe (Grupa) auquel il appartient à une liste déroulante (en utilisant Listagrupe) puis à partir d'une deuxième liste déroulante (Listaproduse) un produit de ce groupe particulier de produits que j'ai sélectionnés dans la première liste déroulante.

public class Comd
{
    public string Grupa { get; set; }

    public string Produs { get; set; }

    public string Cantitate { get; set; }

    public string Pret { get; set;}

    public string TVA { get; set; }

    public string Total { get; set; }

    public List<SelectListItem> ListaGrupe
    {
        get;
        set;
    }

    public List<SelectListItem> ListaProduse
    {
        get;
        set;
    }
}    

--Le controlle:

    public ActionResult ComandaDetaliu(string id)
    {

        Comd model = new Comd();
        IProduseRepository _prod = new ProduseRepository();

        model.ListaGrupe = _listecomanda.GetGrupe();

        string first = model.ListaGrupe[0].Value;

        model.ListaProduse = _listecomanda.GetProduse(first);

        string pret = _prod.GetByDenumire(model.ListaProduse[0].Text).pret.ToString();
        model.Pret = pret;

        double fr = 0.24;
        model.TVA = fr.ToString();

        var data = new[] { model };

        return View(data);
    }

-- La vue

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"       Inherits="System.Web.Mvc.ViewPage<IEnumerable<InMVC3.Models.Comd>>" %>
<%@ Import Namespace="InMVC3.Helpers"%>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

 <h2>Comanda numarul: <%: RouteData.Values["id"].ToString()%></h2>

<% using(Html.BeginForm()) { %>
    <div id="editorRows">
        <% foreach (var item in Model)
            Html.RenderPartial("ProduseEditor", item);
        %>
    </div>
    <%= Html.ActionLink("Adauga alt produs", "Add", null, new { id = "addItem" }) %>

    <input type="submit" value="Finished" />
<% } %>    

- la vue partielle "éditeur de Produse"

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<InMVC3.Models.Comd>" %>
<%@ Import Namespace="InMVC3.Helpers" %>

<div class="editorRow">

                   <script type="text/javascript">
                       $(document).ready(function () {
                           $("#Grupa").change(function () {

                               var url = '<%= Url.Content("~/") %>' + "Comenzi/ForProduse";
                               var ddlsource = "#Grupa";
                               var ddltarget = "#Produs";
                               $.getJSON(url, { id: $(ddlsource).val() }, function (data) {
                                   $(ddltarget).empty();
                                   $.each(data, function (index, optionData) {
                                       $(ddltarget).append("<option value='" + optionData.Value + "'>" + optionData.Text + "</option>");
                                   });

                               });
                           });
                       });

            </script>    


<% using(Html.BeginCollectionItem("comds")) { %>

    Grupa: <%= Html.DropDownListFor(x => x.Grupa, Model.ListaGrupe) %> 
    Produsul: <%= Html.DropDownListFor(x => x.Produs, Model.ListaProduse) %> 
    Cantitate: <%=Html.TextBoxFor(x=>x.Cantitate) %>
    Pret: <%=Html.DisplayFor(x => x.Pret, new { size = 4})%>
    TVA: <%= Html.DisplayFor(x=>x.TVA) %>
    Total: <%=Html.DisplayFor(x=>x.Total) %>

    <a href="#" class="deleteRow">Sterge</a>
<% } %>

- et la méthode jsonresult

    public JsonResult ForProduse(string id)
    {
        throw new NotSupportedException();
        JsonResult result = new JsonResult();
        var produsele = _listecomanda.GetProduse(id);
        result.Data = produsele;
        result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        return result;
    }

Tout ce que je dois savoir, c'est comment passer l'appel à l'action JSONRESULT, car c'est ce qui ne fonctionne pas, de sorte que lorsque je change la valeur sélectionnée dans la première liste déroulante pour modifier dynamiquement la seconde également. Bien sûr, j'ai également besoin de changer les autres propriétés, mais qu'après avoir obtenu comment faire getjson travailler.

Si vous avez besoin de plus de détails, dites-moi.

Mise à jour 1:

- L'assistant

public static class HtmlPrefixScopeExtensions
{
    private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";

    public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
    {
        var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
        string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();

        // autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
        html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex)));

        return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
    }

    public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
    {
        return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
    }

    private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
    {
        // We need to use the same sequence of IDs following a server-side validation failure,  
        // otherwise the framework won't render the validation error messages next to each item.
        string key = idsToReuseKey + collectionName;
        var queue = (Queue<string>)httpContext.Items[key];
        if (queue == null) {
            httpContext.Items[key] = queue = new Queue<string>();
            var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
            if (!string.IsNullOrEmpty(previouslyUsedIds))
                foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
                    queue.Enqueue(previouslyUsedId);
        }
        return queue;
    }

    private class HtmlFieldPrefixScope : IDisposable
    {
        private readonly TemplateInfo templateInfo;
        private readonly string previousHtmlFieldPrefix;

        public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
        {
            this.templateInfo = templateInfo;

            previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
            templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
        }

        public void Dispose()
        {
            templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
        }
    }
}

METTRE À JOURJ'ai maintenant un autre problème. Lorsque je publie cette liste sur l'actiont, j'obtiens l'erreur suivante au pour chaque Instruction à l'intérieur de l'action du contrôleur: La référence d'objet n'est pas définie à une instance d'un objet.

- l'action du contrôleur

    [HttpPost]
    public ActionResult ComandaDetaliu(IEnumerable<Comd> comenzi)
    {
        if (ModelState.IsValid)
        {
            foreach (var item in comenzi)
            {
                detalii_comenzi det = new detalii_comenzi();

                det.id_comanda = Convert.ToInt32(RouteData.Values["id"].ToString());
                det.id_produs = Convert.ToInt32(item.Produs);
                det.cantitate_comandata = Convert.ToDecimal(item.Cantitate);
                det.cantitate_livrata = 0;
                det.pret =Convert.ToDecimal(item.Pret);
                det.tvap = Convert.ToDecimal(item.TVA);
            }
            return RedirectToAction("Index");
        }
        return View(comenzi);
    }
Était-ce utile?

La solution

Votre problème est les ID en double - chaque ligne a une liste déroulante avec ID "Grupa", donc votre sélecteur jQuery correspondra aux déroutes dans chaque ligne.

Vous devez ajouter un préfixe aux contrôles - il existe plusieurs façons d'y parvenir - une recherche de "MVC3 Field Prefix" soulève plusieurs autres questions:

La plupart d'entre eux sont axés sur la cartographie lorsque le formulaire est publié, mais le même problème s'applique à votre JavaScript.

Vous pouvez simplement mettre à jour les identifiants de votre script en quelque chose comme "#@(ViewBag.Prefix)Grupa", mais une meilleure approche serait d'utiliser des classes au lieu d'identifiant dans votre sélecteur et de rendre le script réutilisable - quelque chose comme:

ddlSource = this;
ddlDest = this.Parent().find(".produs");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top