title: Django - Reverse Engineering the Admin site's "Add Foreign Key" button
body: <p><strong>TL;DR (Short synopsis):</strong> </p>
  
  <p>I have recreated the admin "Add" button in my own project. However, when I hit "save" on the parent form, it is not recognizing the new select element.</p>
  
  <p><strong>Whole Story:</strong></p>
  
  <p>I have that functionality working in my own project... almost. I need help figuring out the last step. As it is now, I have a "+" button, I click it, a popup shows up, I add a new object, hit save, popup closes and that new item is now in my select box and selected - just like the admin page. However, when I hit save on this parent form, I get the error that I've selected an item not in the list. Of course, since the page has reloaded, my new item <em>is</em> part of the list and I just hit save again and it works. Of course, I need it to save on the first time! </p>
  
  <p>The basic setup is my Parent model is called <code>System</code> and the foreign key model is called <code>Zone</code>. The <code>Zone</code> model lists how many zones a system has (1 zone,2 zones,10 zones, etc...)</p>
  
  <p>OK, some code:</p>
  
  <p>The "Add" link in the template of the parent form:</p>
  
  <p><code>&lt;a href="/systems/zones/new/?popup=1" id="add_id_numZones" onclick="return showAddPopup(this);"&gt;Add&lt;/a&gt;</code></p>
  
  <p>In my <code>New_Zone</code> view, after saving the new zone, I check if the <code>popup</code> <code>GET</code> variable is 1, if so, return a javascript function. Here's the view:</p>
  
  <pre><code>        ...
          if form.is_valid():
              f = form.save(commit=False)
              pk_value = f.numOfZones
              form.save()
              obj = Zone_Info.objects.get(numOfZones=pk_value)
              if isPopup == "1":
                  return HttpResponse('&lt;script&gt;opener.closeAddPopup(window, "%s", "%s");&lt;/script&gt;' % (escape(pk_value), escape(obj)))
          ...
  </code></pre>
  
  <p>And here is my Javascript (largely copied from the admin javascript:</p>
  
  <pre><code>function html_unescape(text) {
  // Unescape a string that was escaped using django.utils.html.escape.
      text = text.replace(/&amp;lt;/g, '&lt;');
      text = text.replace(/&amp;gt;/g, '&gt;');
      text = text.replace(/&amp;quot;/g, '"');
      text = text.replace(/&amp;#39;/g, "'");
      text = text.replace(/&amp;amp;/g, '&amp;');
      return text;
  }
  
  function windowname_to_id(text) {
      text = text.replace(/__dot__/g, '.');
      text = text.replace(/__dash__/g, '-');
      return text;
  }
  
  
  function showAddPopup(triggeringLink, pWin) {
      var name = triggeringLink.id.replace(/^add_/, '');
      href = triggeringLink.href;
      var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
      win.focus();
      return false;
  }
  
  function closeAddPopup(win, newID, newRepr) {
      newID = html_unescape(newID);
      newRepr = html_unescape(newRepr);
      var name = windowname_to_id(win.name);
      var elem = document.getElementById(name);
      if (elem) {
          if (elem.nodeName == 'SELECT') {
              var o = new Option(newRepr, newID);
              elem.options[elem.options.length] = o;
              o.selected = true;
          } else if (elem.nodeName == 'INPUT') {
              if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 &amp;&amp; elem.value) {
                  elem.value += ',' + newID;
              } else {
                  elem.value = newID;
              }
          }
      } else {
          var toId = name + "_to";
          elem = document.getElementById(toId);
          var o = new Option(newRepr, newID);
          SelectBox.add_to_cache(toId, o);
          SelectBox.redisplay(toId);
      }
  
      win.close();
  }
  </code></pre>
  
  <p>I took a look at <a href="https://stackoverflow.com/questions/5744480/django-admin-relatedobjectlookups-how-does-it-refresh-and-set-the-select-on">this</a> question and it seems that I am doing precisely the same thing. </p>
  
  <p>Any ideas on how to get that last step of getting the form to recognize the new select element?</p>
  
  <p>Thanks!</p>