Viewed   475 times

I posted a question earlier and didn't have much luck, I am hoping to clear the contents of a second dropdown and repopulate the dropdown, depending on the value that is in the first dropdown.

I have the following select boxes as seen below:

   <select name = "car" id="Cars" onchange="myFunction(this)">
            <option value="0">Toyota</option>
            <option value="1">Audi</option>
            <option value="2">Suzuki</option>
   </select>

Underneath this dropdown I also have another drop down for models:

    <select id="emptyDropdown">
            <option value="0">R8</option>
            <option value="1">Quattro</option>
            <option value="2">A6 hatchback</option>
    </select>

onchange I want to clear the second dropdown and populate it with models related to the car brand. EG.

Audi - A8, A6, A4 etc.
Suzuki - Swift, Panda etc.


<script>
  function myFunction(obj)
  {
    $('#emptyDropdown').empty()
    var dropDown = document.getElementById("carId");
    var carId = dropDown.options[dropDown.selectedIndex].value;
    $.ajax({
            type: "POST",
            url: "/project/main/getcars",
            data: { 'carId': carId  },
            success: function(msg){
                ?????????
            }
        });
  }
</script>

I then have the following PHP function as seen below(I am using codeigniter) - this function uses the Car ID and returns a list of all the models as seen below:

public function getCars(){
        $this->load->model('car_model');

        $this->form_validation->set_rules('carId', 'carId', 'trim|xss_clean');

        if($this->form_validation->run()){
            $carId = $this->input->post('carId');
            $carModels = $this->user_management_model->getCarModels($carId);
        } else {
            echo "error";
        }   
}

I then do not know how to return each element in the array produced in PHP, to repopulate the dropdown list with ID = "emptyDropdown".The array generated in PHP has the following structure:

Array ( [0] => Array ( [ModelName] => R8 V6 Twin Turbo [ModelID] => 19 ) [1] => Array ( [ModelName] => A6 Hatchback  [ModelID] => 107 ) )

To clarify the question - how would I take each element in the array and put this as a new option in the dropdown list? is there a way to return the array to javscript and then repopulate in the success method of the ajax call?

Any help would be much appreciated, many thanks in advance

 Answers

3

This answer provides the necessary modifications to your code.

DISCLAIMER: Without seeing the exact install, be aware there may be a variety of factors that cause this to not work "as-is" in your installation. I do not know how your routes are set up, or if you are using Firebug or some other console to watch the ajax calls, but this should give you the building blocks:

First, change your php to output the array as a json-encoded string:

public function getCars(){
        $this->load->model('car_model');

        $this->form_validation->set_rules('carId', 'carId', 'trim|xss_clean');

        if($this->form_validation->run()){
            $carId = $this->input->post('carId');
            $carModels = $this->user_management_model->getCarModels($carId);
            // Add below to output the json for your javascript to pick up.
            echo json_encode($carModels);
            // a die here helps ensure a clean ajax call
            die();
        } else {
            echo "error";
        }   
}

Then, modify your script ajax call to have a success callback that gets the data and adds it to your dropdown:

function myFunction(obj)
  {
    $('#emptyDropdown').empty()
    var dropDown = document.getElementById("carId");
    var carId = dropDown.options[dropDown.selectedIndex].value;
    $.ajax({
            type: "POST",
            url: "/project/main/getcars",
            data: { 'carId': carId  },
            success: function(data){
                // Parse the returned json data
                var opts = $.parseJSON(data);
                // Use jQuery's each to iterate over the opts value
                $.each(opts, function(i, d) {
                    // You will need to alter the below to get the right values from your json object.  Guessing that d.id / d.modelName are columns in your carModels data
                    $('#emptyDropdown').append('<option value="' + d.ModelID + '">' + d.ModelName + '</option>');
                });
            }
        });
  }

Again - these are the building blocks. Use your browser console or a tool such as Firebug to watch the AJAX request, and the returned data, so you can modify as appropriate. Good luck!

Sunday, November 27, 2022
1

Yes, it's possible. Here's something to get you started.

Note: This uses the PHP class class.upload.php for uploading images. (http://www.verot.net/php_class_upload.htm)

All of this code has been tested and works. I just whipped it up, so it's pretty basic but should point you in the right direction. You'll need to sanitize inputs, do the correct messaging, etc.

Just create a file (index.html) and copy/paste the HTML and JavaScript into it. Then create a file post.php and put the PHP in it. Download the class.upload.php script and then create a directory named uploads. Give it the appropriate permissions (0755 or 0777). Keep everything in the same folder for this example. You should be good to go.

It's even possible to put the success and error messages right in the modal. I'm just using alert() here for brevity. If you want to put the messages in the modal, just create a <div> in the modal, give it an ID and then target that ID in the jQuery where I'm using alert(). It's pretty easy.

Edit: Added messaging to the example. :)

Here's the HTML and jQuery (index.html)

<!DOCTYPE html>
    <html>
    <head>
        <title>Upload a Photo</title>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
        <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
        <!--[if lt IE 9]>
            <script src="//oss.maxcdn.com/libs/html5shiv/r29/html5.min.js"></script>
            <script src="//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->
    </head>
    <body>

        <div class="container">
            <button class="btn btn-primary" data-toggle="modal" data-target="#myModal">Open Modal</button>

            <div class="modal fade" id="myModal">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <form id="form" enctype="multipart/form-data" role="form">
                            <div class="modal-header">
                                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                                <h4 class="modal-title">Upload Photo</h4>
                            </div>
                            <div class="modal-body">
                                <div id="messages"></div>
                                <input type="file" name="file" id="file">
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                                <button type="submit" class="btn btn-primary">Save</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>

        </div>

        <script src="http://code.jquery.com/jquery.js"></script>
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
        <script>
            $('#form').submit(function(e) {

                var form = $(this);
                var formdata = false;
                if(window.FormData){
                    formdata = new FormData(form[0]);
                }

                var formAction = form.attr('action');

                $.ajax({
                    type        : 'POST',
                    url         : 'post.php',
                    cache       : false,
                    data        : formdata ? formdata : form.serialize(),
                    contentType : false,
                    processData : false,

                    success: function(response) {
                        if(response != 'error') {
                            //$('#messages').addClass('alert alert-success').text(response);
                            // OP requested to close the modal
                            $('#myModal').modal('hide');
                        } else {
                            $('#messages').addClass('alert alert-danger').text(response);
                        }
                    }
                });
                e.preventDefault();
            });
        </script>
    </body>
</html>

And your PHP script (post.php)

<?php

    require_once 'class.upload.php';

    $handle = new Upload($_FILES['file']);
    $handle->allowed = 'image/*';

    if($handle->uploaded) {
        $handle->Process('uploads');
        if($handle->processed) {
            echo 'Image uploaded';
        } else {
            echo 'error';
        }
    }
Thursday, October 13, 2022
 
phd
 
phd
2

In your controller method, change this:

if (!$user && $user == null) {

To this:

if (!$user || $user == null) {
Monday, December 12, 2022
 
3

Are you using Access-Control-Allow-Headers?

Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.

Try adding the following header to your preflight code.

header("Access-Control-Allow-Headers: content-type, origin, accept, X-API-KEY");

I recall having similar issues, seem to recall some of it being browser specific too...

If it helps here is a snippet from some code I know works:

// CORS and other headers.  Make sure file is not cached (as it happens for example on iOS devices)
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: ' . CORS_AUTH_MAX_AGE);

//CORS preflight
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'OPTIONS') {

    header("Access-Control-Allow-Headers: content-type, origin, accept, x-app-sig");

    $acrh = explode(',', strtolower($headers['Access-Control-Request-Headers']));
    foreach ($acrh as $k => $v) {
        $acrh[$k] = trim($v);
    }

    if (! isset($headers['Access-Control-Request-Headers']) || ! in_array('x-app-sig', $acrh)) {
        _log($h, '*** Bad preflight!' . PHP_EOL . print_r($headers, true) . PHP_EOL . print_r($_REQUEST, true));
        header("HTTP/1.1 401 Unauthorized");
        exit; //->
    }

    _log($h, '+++ Successful preflight.' . PHP_EOL . print_r($headers, true) . PHP_EOL . print_r($_REQUEST, true));
    exit; //->
}

//Now we are past preflight.  Actual Auth happens here, I check a signature that I post with payload.

Update: OK, think I better understand your question now. Posted a bit more code. First off, yes, we are doing essentially the same thing there. I just check that the preflight tried to white-list what it should have in terms of headers.

I think the part you are missing is that the preflight should/will not have the custom header you are trying to send. See the answer here: How do you send a custom header in a cross-domain (CORS) XMLHttpRequest?). So like I do you could check that the Access-Control-Request-Headers: are sent with the preflight, but you should not check for the actual header being present on that call.

Sounds like you just need to move a little of the code around server side - make the preflight pretty vanilla and dumb, then do your actual auth or checking of custom headers after successful preflight.

I use a HMAC signature sent with the payload myself to authenticate things after the preflight. I also check that the custom x-app-sig is supplied and what i expect though that is probably redundant.

Tuesday, September 6, 2022
 
ldrg
 
3

I'm using knockout and Webapi to power cascading dropdowns in an app I'm developing at the moment.

View I've got a basic dropdown list like below.

<select data-bind="options: CurrentList, 
                   optionsText: 'name',                                                        
                   value: CurrentListSelectedItem,
                   optionsCaption: 'Please Select...'"></select>

View Model

self.CurrentList = ko.observableArray(CurrentListData);
self.CurrentListSelectedItem = ko.observable();
self.CurrentListSelectedItem.subscribe(function () {
    //ajaxcall to populate list 2
});

Server side I've got a simple rest service that take an Id of a point in the tree and returns all its children, this way you can just chain as many of these dropdowns together as you wish (as long as your hierarchy has the levels to match.

See fiddle of working example with mocked data http://jsfiddle.net/tgriley1/vEBGS/

Tuesday, September 6, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :