Dynamicaly ملء مربع تحرير وسرد مع القيم من الخريطة بناء على ما هو المختار في آخر تحرير وسرد

StackOverflow https://stackoverflow.com/questions/156852

سؤال

حسنا, هنا واحدة جافا/جافا سكريبت معلمو:

في التطبيق واحد من وحدات التحكم يمر TreeMap إلى أنه JSP.هذه خريطة صناعة السيارات الأسماء مفاتيح قوائم سيارة القيم.هذه السيارة هي كائنات بسيطة الفاصوليا تحتوي على اسم السيارة, id, سنة الإنتاج إلخ.لذا الخريطة يبدو شيئا من هذا القبيل (هذا مجرد مثال لتوضيح الأمور قليلا):

المفتاح:بورش
القيمة:قائمة تحتوي على ثلاث سيارات الكائنات(على سبيل المثال في 911 كاريرا ، Boxter مع محترمة سنوات من الإنتاج ids)
المفتاح:فيات
القيمة:قائمة تحتوي على اثنين من السيارات الكائنات(على سبيل المثال ، بونتو و أونو)
الخ...

الآن في JSP لدي اثنين من comboboxes.ينبغي للمرء الحصول على قائمة من الشركات المصنعة للسيارات(مفاتيح من خريطة هذا الجزء أعرف كيف أفعل) ، والآخر أن dynamicaly تغيير لعرض أسماء السيارات عندما يقوم المستخدم بتحديد بعض المصنعة من أول مربع تحرير وسرد.لذا, فعلى سبيل المثال, المستخدم بتحديد "بورش" في أول مربع تحرير وسرد ، والثاني يعرض فورا "في 911 كاريرا ، Boxter"...

بعد أن أمضى بضعة أيام في محاولة لمعرفة كيفية القيام بذلك ، أنا على استعداد لقبول الهزيمة.حاولت الكثير من الأشياء المختلفة ولكن في كل مرة كنت أصاب الجدار somewehere على طول الطريق.أي شخص يمكن أن تشير إلى كيف أن هذا النهج ؟ نعم أنا جافا سكريبت مبتدئ, إذا كان أي شخص أتساءل...

تحرير:لقد retagged هذا رمز التحدي.مجد شخص يحل هذا دون استخدام أي سكريبت إطار (مثل مسج).

هل كانت مفيدة؟

المحلول 2

وعلى أي حال جيدة، كما قلت، أنا أخيرا تمكنت من القيام بذلك بنفسي، حتى هنا جوابي ...

وأتلقى الخريطة من وحدة تحكم بلدي مثل هذا (أنا باستخدام الربيع، لا أعرف كيف يعمل هذا مع أطر أخرى):

<c:set var="manufacturersAndModels" scope="page" value="${MANUFACTURERS_AND_MODELS_MAP}"/>

وهذه هي بلدي المجموعات:

<select id="manufacturersList" name="manufacturersList" onchange="populateModelsCombo(this.options[this.selectedIndex].index);" >
                  <c:forEach var="manufacturersItem" items="<%= manufacturers%>">
                    <option value='<c:out value="${manufacturersItem}" />'><c:out value="${manufacturersItem}" /></option>
                  </c:forEach>
                </select>

و

select id="modelsList" name="modelsList"
                  <c:forEach var="model" items="<%= models %>" >
                    <option value='<c:out value="${model}" />'><c:out value="${model}" /></option>
                  </c:forEach>
                </select>

وأنا المستوردة الطبقات التالية (قد، بالطبع، تم تغيير بعض الأسماء):

<%@ page import="org.mycompany.Car,java.util.Map,java.util.TreeMap,java.util.List,java.util.ArrayList,java.util.Set,java.util.Iterator;" %>

وهنا الرمز الذي يفعل كل هذا العمل الشاق:

<script type="text/javascript">
<%  
     Map mansAndModels = new TreeMap();
     mansAndModels = (TreeMap) pageContext.getAttribute("manufacturersAndModels");
     Set manufacturers = mansAndModels.keySet(); //We'll use this one to populate the first combo
     Object[] manufacturersArray = manufacturers.toArray();

     List cars;
     List models = new ArrayList(); //We'll populate the second combo the first time the page is displayed with this list


 //initial second combo population
     cars = (List) mansAndModels.get(manufacturersArray[0]);

     for(Iterator iter = cars.iterator(); iter.hasNext();) {

       Car car = (Car) iter.next();
       models.add(car.getModel());
     }
%>


function populateModelsCombo(key) {
  var modelsArray = new Array();

  //Here goes the tricky part, we populate a two-dimensional javascript array with values from the map
<%                          
     for(int i = 0; i < manufacturersArray.length; i++) {

       cars = (List) mansAndModels.get(manufacturersArray[i]);
       Iterator carsIterator = cars.iterator();           
%>
    singleManufacturerModelsArray = new Array();
<%
    for(int j = 0; carsIterator.hasNext(); j++) {

      Car car = (Car) carsIterator.next();

 %>         
    singleManufacturerModelsArray[<%= j%>] = "<%= car.getModel()%>";
 <%
       }
 %>
  modelsArray[<%= i%>] = singleManufacturerModelsArray;
 <%
     }         
 %>   

  var modelsList = document.getElementById("modelsList");

  //Empty the second combo
  while(modelsList.hasChildNodes()) {
    modelsList.removeChild(modelsList.childNodes[0]);
  }

 //Populate the second combo with new values
  for (i = 0; i < modelsArray[key].length; i++) {

    modelsList.options[i] = new Option(modelsArray[key][i], modelsArray[key][i]);
  }      
}

نصائح أخرى

أنا فقط أحب التحدي.

لا مسج, عادي فقط جافا سكريبت, اختبارها على سفاري.

أود أن أضيف الملاحظات التالية مسبقا:

  • إنه الفيلي طويلة بسبب خطأ التحقق.
  • اثنين من أجزاء ولدت ، أول عقدة النصي مع الخريطة ومحتويات manufacterer حدد
  • يعمل على الجهاز الخاص بي (TM) (سفاري/OS X)
  • لا يوجد (css) التصميم تطبيقها.لدي ذوق سيء جدا لا فائدة على أي حال.

.

<body>
  <script>
  // DYNAMIC
  // Generate in JSP
  // You can put the script tag in the body
  var modelsPerManufacturer = {
    'porsche' : [ 'boxter', '911', 'carrera' ],
    'fiat': [ 'punto', 'uno' ]  
  };
  </script>

  <script>
  // STATIC
  function setSelectOptionsForModels(modelArray) {
    var selectBox = document.myForm.models;

    for (i = selectBox.length - 1; i>= 0; i--) {
    // Bottom-up for less flicker
    selectBox.remove(i);  
    }

    for (i = 0; i< modelArray.length; i++) {
     var text = modelArray[i];
      var opt = new Option(text,text, false, false);
      selectBox.add(opt);
    }  
  }

  function setModels() {
    var index = document.myForm.manufacturer.selectedIndex;
    if (index == -1) {
    return;
    }

    var manufacturerOption = document.myForm.manufacturer.options[index];
    if (!manufacturerOption) {
      // Strange, the form does not have an option with given index.
      return;
    }
    manufacturer = manufacturerOption.value;

    var modelsForManufacturer = modelsPerManufacturer[manufacturer];
    if (!modelsForManufacturer) {
      // This modelsForManufacturer is not in the modelsPerManufacturer map
      return; // or alert
    }   
    setSelectOptionsForModels(modelsForManufacturer);
  }

  function modelSelected() {
    var index = document.myForm.models.selectedIndex;
    if (index == -1) {
      return;
    }
    alert("You selected " + document.myForm.models.options[index].value);
  }
  </script>
  <form name="myForm">
    <select onchange="setModels()" id="manufacturer" size="5">
      <!-- Options generated by the JSP -->
      <!-- value is index of the modelsPerManufacturer map -->
      <option value="porsche">Porsche</option>
      <option value="fiat">Fiat</option>
    </select>

    <select onChange="modelSelected()" id="models" size="5">
      <!-- Filled dynamically by setModels -->
    </select>
  </form>

</body>

هل تستخدم الدعامات؟

وسوف تحتاج بعض جافا سكريبت الخداع (أو AJAX) لتحقيق ذلك.

وماذا كنت بحاجة إلى فعله هو، في مكان ما في شفرة جافا سكريبت (ترك جانبا كيف تولد لمدة دقيقة):

var map = {
   'porsche': [ 'boxter', '911', 'carrera' ],
   'fiat': ['punto', 'uno']
};

وهذا هو في الأساس نسخة من بنية البيانات من جانب الخادم الخاص بك، أي خريطة مرتبطا من قبل الشركة المصنعة، كل قيمة وجود مجموعة واسعة من أنواع السيارات.

وبعد ذلك، في الحدث عند_التغيير الخاص للمصنعين، وكنت بحاجة للحصول على مجموعة من الخريطة المحددة أعلاه، ومن ثم إنشاء قائمة من الخيارات من ذلك. (راجع devguru.com - أنه يحتوي على الكثير من المعلومات المفيدة حول كائنات جافا سكريبت قياسي).

واعتمادا على كيفية كبيرة قائمتك السيارات و، على الرغم من أنه قد يكون من الأفضل أن يذهب AJAX الطريق.

وكنت بحاجة إلى إنشاء وحدة تحكم جديدة التي نظرت إلى أعلى قائمة أنواع السيارات نظرا منتج، ومن ثم إلى الأمام الدخول إلى JSP الذي عاد <لأ href = "http://www.json.org/" يختلط = "نوفولو noreferrer"> JSON (وأنه ليس من الضروري أن يكون JSON، لكنه يعمل بشكل جيد بالنسبة لي).

وبعد ذلك، استخدام مكتبة مثل مسج لاسترداد قائمة السيارات في الحدث عند_التغيير للحصول على قائمة المصنعين. (مسج هو إطار جافا سكريبت ممتاز لتعرف - فإنه جعل التنمية مع جافا سكريبت أسهل بكثير وثائق جيدة جدا).

وآمل أن بعض من تلك المنطقي؟

وهنا هو العمل، وقطع ولصق الإجابة في التخطيط الاستراتيجي المشترك دون أي مكتبات العلامة أو الاعتماد على الخارج على الإطلاق. الخريطة مع النماذج هي ضمنية ولكن يجب أن لا تشكل أي مشاكل.

وأنا فصل هذه الإجابة من إجابتي السابقة كما JSP أضاف لا يحسن القراءة. وفي "الحياة الحقيقية" أنا لن حملي JSP مع كل منطق جزءا لا يتجزأ ولكن وضعه في فئة في مكان ما. أو استخدام العلامات.

وكل ذلك "الأول" الاشياء هو منع superfluos "،" في الشفرة التي تم إنشاؤها. باستخدام foreach dosn't تعطيك أي معرفة مقدار العناصر، لذلك قمت بفحص الماضي. يمكنك أيضا تخطي التعامل مع العنصر الأول والشريط الأخير "،" بعد ذلك عن طريق تقليل طول البناء بنسبة 1.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%@page import="java.util.Map"%>
<%@page import="java.util.TreeMap"%>
<%@page import="java.util.Arrays"%>
<%@page import="java.util.Collection"%>
<%@page import="java.util.List"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Challenge</title>
</head>
<body onload="setModels()">
<% // You would get your map some other way.
    Map<String,List<String>> map = new TreeMap<String,List<String>>();
    map.put("porsche", Arrays.asList(new String[]{"911", "Carrera"}));
    map.put("mercedes", Arrays.asList(new String[]{"foo", "bar"}));
%>

<%! // You may wish to put this in a class
  public String modelsToJavascriptList(Collection<String> items) {
    StringBuilder builder = new StringBuilder();
    builder.append('[');
    boolean first = true;
    for (String item : items) {
        if (!first) {
          builder.append(',');
        } else {
          first = false;
        }
        builder.append('\'').append(item).append('\'');
    }
    builder.append(']');
    return builder.toString();
  }

  public String mfMapToString(Map<String,List<String>> mfmap) {
    StringBuilder builder = new StringBuilder();
    builder.append('{');
    boolean first = true;
    for (String mf : mfmap.keySet()) {
      if (!first) {
          builder.append(',');
      } else {
          first = false;
      }
      builder.append('\'').append(mf).append('\'');
      builder.append(" : ");
      builder.append( modelsToJavascriptList(mfmap.get(mf)) );
    }
    builder.append("};");
    return builder.toString();
  }
%>

<script>
var modelsPerManufacturer =<%= mfMapToString(map) %>
  function setSelectOptionsForModels(modelArray) {
    var selectBox = document.myForm.models;

    for (i = selectBox.length - 1; i>= 0; i--) {
    // Bottom-up for less flicker
    selectBox.remove(i);
    }

    for (i = 0; i< modelArray.length; i++) {
     var text = modelArray[i];
      var opt = new Option(text,text, false, false);
      selectBox.add(opt);
    }
  }

  function setModels() {
    var index = document.myForm.manufacturer.selectedIndex;
    if (index == -1) {
    return;
    }

    var manufacturerOption = document.myForm.manufacturer.options[index];
    if (!manufacturerOption) {
      // Strange, the form does not have an option with given index.
      return;
    }
    manufacturer = manufacturerOption.value;

    var modelsForManufacturer = modelsPerManufacturer[manufacturer];
    if (!modelsForManufacturer) {
      // This modelsForManufacturer is not in the modelsPerManufacturer map
      return; // or alert
    }
    setSelectOptionsForModels(modelsForManufacturer);
  }

  function modelSelected() {
    var index = document.myForm.models.selectedIndex;
    if (index == -1) {
      return;
    }
    alert("You selected " + document.myForm.models.options[index].value);
  }
  </script>
  <form name="myForm">
    <select onchange="setModels()" id="manufacturer" size="5">
      <% boolean first = true;
         for (String mf : map.keySet()) { %>
          <option value="<%= mf %>" <%= first ? "SELECTED" : "" %>><%= mf %></option>
      <%   first = false;
         } %>
    </select>

    <select onChange="modelSelected()" id="models" size="5">
      <!-- Filled dynamically by setModels -->
    </select>
  </form>

</body>
</html>

وماذا عن شيء من هذا القبيل، وذلك باستخدام النموذج؟ أولا، لديك حدد مربع فئات:

<SELECT onchange="changeCategory(this.options[this.selectedIndex].value); return false;">
   <OPTION value="#categoryID#">#category#</OPTION>
   ...

وبعد ذلك، يمكنك إخراج N مختلفة مختارة صناديق، واحد لكل فئة من الفئات الفرعية:

<SELECT name="myFormVar" class="categorySelect">
...                                        

وchangeCategory لديك جافا سكريبت تعطيل وظيفة كل يختار مع categorySelect الطبقة، ومن ثم تمكن فقط واحد لمعرف_الفئة الحالي.

// Hide all category select boxes except the new one
function changeCategory(categoryID) {

   $$("select.categorySelect").each(function (select) {
      select.hide();
      select.disable();
   });

   $(categoryID).show();
   $(categoryID).enable();
}

وعند إخفاء / تعطيل مثل هذا في النموذج، فإنه يخفي ليس فقط على الصفحة، لكنه سيبقي هذا المتغير شكل من النشر. ذلك على الرغم من أن يكون لديك N يختار مع نفس الاسم شكل متغير (myFormVar)، إلا أن نشطة واحدة المشاركات.

قبل

وليس ذلك لفترة طويلة فكرت شيئا من هذا القبيل.

وعن طريق مسج وTexoTela إضافة على أنه لم يكن من الصعب أن جميع.

أولا، لديك بنية بيانات مثل الخريطة المذكورة أعلاه:

var map = {
   'porsche': [ 'boxter', '911', 'carrera' ],
   'fiat': ['punto', 'uno']
}; 

وHTML يجب أن تبدو مماثلة ل:

<select size="4" id="manufacturers">
</select>
<select size="4" id="models">
</select>

وبعد ذلك، يمكنك ملء التحرير والسرد الأول مع رمز مسج مثل:

$(document).ready(
  function() {
    $("#bronsysteem").change( manufacturerSelected() );
  } );
);

وحيث manufacturerSelected هو رد مسجلة على الحدث onChange

function manufacturerSelected() {
  newSelection = $("#manufacturers").selectedValues();
  if (newSelection.length != 1) {
    alert("Expected a selection!");
    return; 
  }
  newSelection = newSelection[0];
  fillModels(newSelection);     
}

function fillModels(manufacterer) {
    var models = map[manufacturer];

    $("models").removeOption(/./); // Empty combo

    for(modelId in models) {
       model = models[modelId];
       $("models").addOption(model,model); // Value, Text
    }
}

وهذا ينبغي أن تفعل خدعة.

تجدر الإشارة إلى أنه قد تكون هناك أخطاء في بناء الجملة في هناك. لقد تحرير قانون بلدي لتعكس حالة استخدامك وكان لتجريد الكثير جدا بها.

إذا هذا يساعد سأكون ممتنا تعليق.

وأما وظيفة إضافية على على مشاركتي السابقة. يمكنك وضع علامة النصي في JSP الخاص بك حيث كنت أعاد على الخريطة. مثال عن بالتكرار عبر خرائط يمكن العثور عليها في <لأ href = "http://www.onjava.com/pub/a/onjava/2003/07/30/jakartastruts.html؟page=2" يختلط = "noreferrer نوفولو "> الخرائط في الدعامات .

وماذا كنت ترغب في تحقيق (إذا كنت لا تبالي تقديم النموذج) هو أنني أعتقد أن شيئا مثل:

<script>
  var map = {
  <logic:iterate id="entry" name="myForm" property="myMap">
     '<bean:write name=" user" property="key"/>' : [
     <logic:iterate id="model" name="entry" property="value">
       '<bean:write name=" model" property="name"/>' ,
     </logic:iterate>
     ] ,
 </logic:iterate>
  };
</script>

لا يزال لديك بعض superfuous "،" والتي قد ترغب في منع، ولكن أعتقد أن هذا ينبغي أن تفعل خدعة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top