Search code examples
javascriptphpjquerycodeignitergrocery-crud

How to get back data of a new element created in a new window into a dropdown list


I am using codeigniter and grocerycrud.

I have a view, in this view I have some dropdowns, those dropdowns are being feed from the controller:

public function programar_ruta()
{
    if($this->model_privilegios->validar_usuario()==true)           
    {
        $data['destinos'] = $this->model_querys_usuario->get_destinos();
        $this->load->view('usuario/dynamic_form2',$data); 
    }
}

My model function code:

  public function get_destinos ()
  {
    $this-> db ->select('*');
    $this-> db ->from('destinos');
    $this -> db -> where('empresa', $_SESSION['empresa']);
    $query = $this->db->get();
    return $query->result();
  }

Inside of my form I have the dropdowns and a button heading to a controller function that allows to add a new "Destino":

<td width="18%" align="left">
<select name="destinos[]" id="origen0"> 
<?php foreach($destinos as $row) 
   { echo '<option value="'.$row->nombre.'">'.$row->nombre.'</option>'; } ?> 
</select>
<input type="button" value="..." onClick="window.open
 ('<?php echo base_url()?>index.php/usuario/destinos/add','Nuevo Destino','width=800,height=600')" title="Agregar nuevo destino"/></td>

The code "index.php/usuario/destinos/add'" is heading to a standar grocerycrud function.

My question is: there is a way to add the new element into the dropdown options without refreshing the window?


Solution

  • Yes, via AJAX -!

    Here is what I'm going to walk you through:

    1). the window that opens displays a form, which adds a destination to your database.

    2). A timer-script will wait for the window to close, and fetch the new destino and add it to your menu.

    3). You'll need to add in the server-side script that handles the JS's request...

    So-! first, you'll want to take that 'onClick' out, and handle your JS in a separate place - Let's start by changing:

    <input type="button" value="..." onClick="window.open([...]

    to:

    <input type="button" id="newDestino" />

    Now, in your JS, you need to give it a click handler:

    $("#newDestino").click(function(){
    
        var desinoMas = window.open('/index.php/usuario/destinos/add','Nuevo Destino','width=800,height=600');
    
        var windowCloseChecker = setInterval(function() {
                if (win.closed) {
                    clearInterval(timer);
                    addDestino(); 
                }
            }, 1000);
    
    
    }); 
    

    The part where you do <?php echo base_url() ?> is not necessary - just use the absolutepath: '/index.php' --- If i am missing something, and it is really necessary - just throw the script toward the bottom of the page in a <script> tag, and use your <?php echo like normal

    So now, let us define our addDestino function:

    function addDestino(){
    
    $.ajax({
        url : "index.php/usuario/destinos/updateClientMenu",
        method: "POST" // this is really irrelevant,
        success: function(response){
             $("#origen0").html(response); 
        }
    
    
    });
    
    
    
    }
    

    You'll see that I named the script index.php/usuario/destinos/updateClientMenu -- you can name it whatever you want, but that script needs to generate some simple html to add to your DOM.

    You can get away with the following code, which should be quite familiar to you-!

    <?php
    
    //[...] You'll obviously need to re-query for the destinos, here.
    
     foreach($destinos as $row) 
       { $response .= '<option value="'.$row->nombre.'">'.$row->nombre.'</option>'; }
    
    echo $response;
    
     ?> 
    

    You noticed that I stored all the $destinos into a variable before echoing it.

    Now, the echo $response feeds back into the success function in our addDestinos function-!! - which simply takes that response and replaces the html of the menu, with the fresh HTML.

    So, to clarify and wrap it up, it all goes something like this:

    The button gets clicked, a new window opens with a form - when the form is filled out, it submits to create a new destino. When the window closes, a script notices the window is closes and asks the server for a new desinos menu. The server responds with a refreshed list of destinos.

    NOW -! This script can be improved -!

    So, I suggest you try it for yourself, as an exercise:

    Instead of getting the whole list, just get the most recently added destino. (You'll need to use $.append() instead of $.html() in this case )

    Good luck -!