jQGrid + jQueryUI Autocomplete + combobox автоматично се отваря на фокус

Сигурен съм, че пропускам нещо много просто в това. След като си блъсках главата в бюрото (буквално) от няколко дни, се предавам на милостта на стека:

Използвам jQuery UI Autocomplete като падащ списък в моя jQGrid (знам! Вече потърсих решението другаде без резултат!). Бих искал падащото меню да се отваря, когато имам достъп до клетката за редактиране чрез събитието onSelectRow в jqGrid. По принцип искам да направя точно това, което се обсъжда тук:

Отворете jQuery UI ComboBox на фокус

и демо тук:

http://jsfiddle.net/gEuTV/

Единствената разлика е, че имам нужда от него в jqGrid. Опитах кода по-долу, през който (по погрешка) бих задействал падащия списък, за да се появи, когато редът е фокусиран, но падащият списък не се показва на фокуса на реда в събитието onSelect. Имам някакво подозрение, че просто поставям следния код на грешното място, но го пробвах навсякъде, където се сетя:

$("#"+id+"_usr_validation","#list2").bind("focus", function () {
this.value = '';
$(this).autocomplete("search", ''); 

Ето пълния ми код, включително мрежата:

$(function(){
    var lastsel;
     $("#list2").jqGrid({
            url: 'php_includes/uploadgrid.php',
            datatype: "json",
            mtype: 'GET',
            colNames:[
                    'User Value',
                    'Translated Value',
                    'User Validation,
                    ],
            colModel:[
                    {name:'usr_value',index:'usr_value', sortable:'true', width:60, align:"center", editable:false},
                    {name:'translated_value',index:'translated_value', sortable:'true', width:60, align:"center", editable:false},
                    {name:'usr_validation',index:'usr_validation', sortable:'true', width:60, align:"center", editable:true}
                    ],
            pager: '#pager2',
            rowNum: 1000,
            scroll: true,
            gridview: true,
            viewrecords: false,
            height: 'auto',
            hidegrid: false,
            autowidth: true,
            pgbuttons: false,
            pginput: false,
            forceFit: true,
            emptyrecords: "No record was loaded",
            onSelectRow: function(id){
                            if(id && id==lastsel){
                                    $("#list2").jqGrid('editRow',id,true,autocomp,'','','',selectNone);
                                    } else {
                            if(id && id!==lastsel){
                                    $("#list2").jqGrid('saveRow',lastsel);
                                    $("#list2").jqGrid('editRow',id,true,autocomp,'','','',selectNone);
                                    lastsel=id;
                                    }
                                }
                            },
            editurl: '/php_includes/jqGridCrud.php',
            });
            jQuery("#list2").jqGrid('navGrid',"#pager2",{edit:false, search:false, del:false, add:false})

         function selectNone(){
                     $("#list2").jqGrid('resetSelection');
                    }
                    //this function de-selects all previously accessed rows

            function autocomp(id) {
                    var term2 = $("#list2").jqGrid('getCell',id,'usr_value');
                    $("#"+id+"_usr_validation","#list2")
                            .autocomplete({
                                    source: function(request, response) {
                                              $.ajax({
                                                    url: "/php_includes/Autocomplete.php",
                                                    dataType: "json",
                                                    data: {
                                                            term : request.term,
                                                            term2 : term2,
                                                            },
                                                    success: function(data) {
                                                            response(data);
                                                            }
                                                    });
                                            },
                                    minLength: 0,
                                    select: function(event, ui) {
                                            $("#list2").val(ui.item.id);
                                            },

                            });
             $("#"+id+"_usr_validation","#list2").bind("focus", function () {
                    this.value = '';
                    $(this).autocomplete("search", '');
              });

            }
    });

person Josh    schedule 13.11.2011    source източник


Отговори (1)


Трябва да промените 'User Validation, на 'User Validation' и да премахнете завършващите запетаи на различни места от вашия код (като от editurl: '/php_includes/jqGridCrud.php',} и затворете, които са синтактични грешки в JavaScript, но се игнорират в много, но не във всички уеб браузъри).

АКТУАЛИЗИРАНО: Още един проблем е, че фокусът върху полето за редактиране ще бъде зададен преди oneditfunc ще бъде извикан, така че събитието "focus" не може да бъде задействано. Като заобиколно решение можете да задействате събитие „фокус“ ​​директно след .bind("focus", ....

Вижте модифицираната си демонстрация тук.

person Oleg    schedule 13.11.2011
comment
Олег- Първо, много благодаря за бързия отговор. Второ, за мен е голяма чест да получа отговор на въпроса си от вас, след като прочетох толкова много от вашите отговори в миналото. Благодаря за съветите относно форматирането - те са голяма помощ. Що се отнася до вашия отговор, единственият проблем, който виждам с него, е, че след като избера елемент от падащия списък, списъкът просто се отваря отново - което не ми позволява да избирам нищо. Опитах го на моя сървър за разработка (който има функционалността saveRow, която коментирахте) - със същия резултат. Някакви предположения? - person Josh; 14.11.2011
comment
Една редакция на горния коментар: кодът на Олег работи перфектно, ако потребителят използва клавиатурата, за да избере падащия елемент (напр. със стрелките надолу) и натисне enter. Просто не работи, ако потребителят използва мишката, за да избере елемента. - person Josh; 14.11.2011
comment
@Josh: Отговорих само на директния ви въпрос относно проблема с „фокуса“ и не проверих кода ви за автоматично довършване. Вие сте имали други проблеми. Демото трябва да работи правилно с Autocomplete и моите тестови данни. - person Oleg; 14.11.2011
comment
Благодаря Олег. Отговорихте перфектно на въпроса ми. По някаква причина, когато избера елемент от падащото меню (във вашата демонстрация), той просто отваря отново падащия списък. Предполагам, че просто нещо не е наред от моя страна. Благодаря отново. - person Josh; 14.11.2011
comment
@Josh: Добре дошъл си! В кой уеб браузър имате проблема? Използвахте ли първия от последната демонстрация? - person Oleg; 14.11.2011
comment
След по-нататъшен размисъл и преглед смятам, че поведението, към което се стремя, е по-добре свързано със събитие click(), отколкото събитие focus(), така че потребителят да може да щракне върху ред, падащото меню се появява автоматично, изберете елемент от списъка, след което падащото меню изчезва и избраният елемент остава в клетката. Съответно, с огромна помощ от вашия код, преработих вашия код, за да използвам просто събитие за щракване в следния раздел: - person Josh; 15.11.2011
comment
$(#+id+_usr_validation,#list2).click(function() { this.value = ''; $(this).autocomplete(search, ''); }) .click(); } - person Josh; 15.11.2011
comment

Проучвам GPS местоположението на Samsung Galaxy2 (Android 2.3.5). SG2 поддържа A-GPS, така че включих GPS, Wifi мрежа и подпомагане на сензора. Изглежда работи добре, но понякога GPS дава напълно различно местоположение на повече от 50 км от текущото ми място. Също така местоположението се променя често, въпреки че просто поставих телефона на едно място и никога не го докоснах.

Все още съм нов в Android, така че не съм сигурен какво причинява този проблем. По-долу е изходният код, обработващ GPS местоположението.:

public class LocationMonitor extends Service implements LocationListener,Runnable {
    .... other local variables here

    Object locationUpdateNotifier= null;
    public static GeoPoint ourLocation;


    public void synchronize()
    {
        if(ourLocation == null)
        {
            ourLocation = getLastKnownLocation();
            if(ourLocation == null) return;
        }

        //Load last time we synced
        long lastSyncTime = some_value;

        if(lastSyncTime < System.currentTimeMillis()  - UPDATE_FREQ)  //UPDATE_FREQ - default 30 minutes
        {
            handler.post(new Runnable() {
                public void run() {
                    GpsPingTask pingTask = new GpsPingTask(context,String.valueOf(ourLocation.getLatitudeE6()/1E6),String.valueOf(ourLocation.getLongitudeE6()/1E6));
                    pingTask.execute((Void)null); //Send location to server
                }
            });
            lastSyncTime =  System.currentTimeMillis();
            //Save new lastSync time 
        }
    }



    public void kill()
    {
        if(locationManager !=null)
            locationManager.removeUpdates(this);
    }

     public void onLocationChanged(Location location) {
        try
        {
            //Read latitude and longitude from location
            //Create Geo point so we can get a english street name address
            ourLocation = new GeoPoint((int)(location.getLatitude()*1E6),(int)(location.getLongitude()*1E6));

            if(locationUpdateNotifier != null)
            {
                synchronized (locationUpdateNotifier) {
                    locationUpdateNotifier.notify();
                }
            }

            if(!doneFirstUpdate)
            {
                doneFirstUpdate =true;
                Log.i("LocationMointor", "LocationMonitor.onLocationChanged() done first update at 0 frequency, resetting to normal speed");
                //Set it to update at the requested frequency
                resetLocationUpdatesFreq();
            }

            startSynchronizeThread();
        }
        catch (Throwable e) {
            Log.i("LocationMointor", "LocationMonitor.onLocationChanged(): " + e);
        }
    }


    public void onProviderDisabled(
            String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {}

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {}


    public void setTemporaryLocationUpdateFreq(int pingFreqSecs) {

        setTemporaryLocationUpdateFreq(pingFreqSecs, 10);
    }


    public void setTemporaryLocationUpdateFreq(int pingFreqSecs, int minimumDistanceMeters) {
        if(!doneFirstUpdate)
            doneFirstUpdate =true;

        tempLocationUpdateFreq = pingFreqSecs;
        tempLocationUpdateMeters = minimumDistanceMeters;
        handler.post(new Runnable()
        {
            public void run() {
                //Turn of location updates
                if(locationManager !=null)
                    locationManager.removeUpdates(locationMonitor);
                //Restart  location updates with new frequency
                locationManager.requestLocationUpdates(getGpsMode(), UPDATE_FREQ, tempLocationUpdateMeters,locationMonitor);
                //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, tempLocationUpdateFreq*1000, tempLocationUpdateMeters,locationMonitor);
            }
        });
    }

    private void startSynchronizeThread() {
        if(!running)
            new Thread(this).start();
    }


    public void resetLocationUpdatesFreq() {
        locationUpdateNotifier = null;
        handler.post(new Runnable()
        {
            public void run() {
                //Turn of location updates
                if(locationManager !=null) {
                    locationManager.removeUpdates(locationMonitor);
                    //Restart  location updates with default location update frequency
                    //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATE, MINIMUM_DISTANCECHANGE_FOR_UPDATE,locationMonitor);
                }
            }
        });
    }


    public void setLocationUpdateFreq(int pingFreqMins) {

        Log.i("LocationMointor", "LocationMonitor.setLocationUpdateFreq().mode: " + getGpsMode() + "pingFreq:" + pingFreqMins);

        //Save new frequency value
        SharedPreferences pref = context.getSharedPreferences(PREF_PING_FREQ, Context.MODE_PRIVATE);
        Editor prefEditor=  pref.edit();
        prefEditor.putInt(PREF_PING_FREQ, 10);
        prefEditor.commit();
        handler.post(new Runnable()
        {
            public void run() {
                //Turn of location updates
                if(locationManager !=null)
                    locationManager.removeUpdates(locationMonitor);
                //Restart  location updates with new piong frequency
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATE, MINIMUM_DISTANCECHANGE_FOR_UPDATE,locationMonitor);
            }
        });

    }


    public void addUpdateNotify(Object notifyable)
    {
        this.locationUpdateNotifier = notifyable;
    }


    public GeoPoint getLastKnownLocation()
    {
        Criteria crit = new Criteria();
        //Try get last known fine location
        crit.setAccuracy(Criteria.ACCURACY_FINE);
        String provider = locationManager.getBestProvider(crit, false);
        Location loc = locationManager.getLastKnownLocation(provider);
        //If we got no location, try coarse location
        if(loc == null)
        {

            crit.setAccuracy(Criteria.ACCURACY_COARSE);
            provider = locationManager.getBestProvider(crit, false);
            loc = locationManager.getLastKnownLocation(provider);
            //If nothing, return nothing
            if(loc == null)
            {
                Log.i("LocationMointor", "LocationMonitor.getLastKnownLocation() got no location");
                return null;
            }
        }

        //Create geopoint and return it.
        GeoPoint geoPoint = new GeoPoint((int)(loc.getLatitude()*1E6),(int)(loc.getLongitude()*1E6));
        Log.i("LocationMointor", "LocationMonitor.getLastKnownLocation() got "  +geoPoint);

        return geoPoint;
    }

    @Override
    public void run() {
        running = true;
        Object pauser = new Object();
        do{
            try
            {
                synchronize();
                synchronized(pauser)
                {
                    pauser.wait(UPDATE_FREQ);
                }

            }
            catch(Throwable ex)
            {
                Log.e("LocationMointor", "LocationMonitor.run() " +ex);
            }
        }
        while(running);
    }

    public void onCreate() {
        super.onCreate();

        this.context = this;
        this.locationMonitor= this;

        handler = new Handler(); 

        //Get the location manager service
        locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);

        //Start gps to get our location  
        this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, UPDATE_FREQ, this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        kill();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return mBinder;
    } 

    private final IBinder mBinder = new MyBinder();

    public class MyBinder extends Binder {
        public LocationMonitor getService() {
            return LocationMonitor.this;
        }
    }
}

Бихте ли ми помогнали да преодолея този проблем? Благодаря предварително.

- person Josh; 15.11.2011
comment
@Josh: Добре дошъл си! Не разбирам само необходимостта от изчистване на стойността (this.value = ''; или $(this).val('');), което правите. Ако редът бъде запазен (потребителят щраква върху Enter), старата стойност в мрежата ще бъде отхвърлена и нулирана с празен низ. Наистина ли е това, от което се нуждаете? Мисля, че просто използването на $(this).autocomplete("search", ''); е достатъчно. Оригиналната стойност все още е в полето за въвеждане, но ще се покаже пълното контекстно меню (независимо от стойността от полето за въвеждане). - person Oleg; 15.11.2011
comment
прав си. Нямах нужда от this.value = ''; нито имах нужда от $(this).val(''). Сега работи перфектно. Благодаря! - person Josh; 16.11.2011