2011-12-28 11 views
7

Mam okno dialogowe jquery ui z opcją knockoutjs. Okno dialogowe można zamknąć, naciskając przycisk anulowania, naciskając przycisk zamykania na pasku tytułu okna dialogowego, naciskając klawisz Escape lub naciskając przycisk zapisu. Moim zamiarem jest, aby zdarzenia zamykające, zamykające i zamykające pasek tytułu odrzuciły okno dialogowe bez wykonywania z niego żadnych działań, natomiast naciśnięcie klawisza Enter lub kliknięcie "Zapisz" powinno wykonać akcję dialogową. Wszystko działa zgodnie z przeznaczeniem, z wyjątkiem klawisza Enter, który powoduje anulowanie, a nie wydarzenie przesyłania.knockoutjs przekazuje wiązanie nie obsługujące poprawnie wprowadź klucz

Stworzyłem jsfiddle, aby to zilustrować i dołączyć poniższy kod w celu znalezienia.

Moje przeprosiny dla kodu gadatliwym ...

genowe

<!-- ko with: dialog --> 
<div id="taskdlg" class="resizeableDialog" 
    data-bind="dialog: {autoOpen: false, title: 'Edit task', height: 200, width: 500, modal: true, close: updateCloseState}, openWhen: open"> 
    <form data-bind="submit: update"> 
     <table> 
      <tr> 
       <td style="width: 100px;"><label for="tasktitle">Title</label></td> 
       <td width="*"> 
        <input id="tasktitle" type="text" placeholder="Task name" data-bind="value: titletext, valueUpdate: 'afterkeydown'" /> 
       </td> 
      </tr> 
      <tr> 
       <td><button style="float: left;" data-bind="click: cancel">Cancel</button></td> 
       <td><button style="float: right;" type="submit">Save</button></td> 
      </tr> 
     </table> 
    </form> 
</div> 
<!-- /ko --> 

<button data-bind="click: editTask">Edit</button> 
<span data-bind="text: task"></span> 

JavaScript jest następująca:

ko.bindingHandlers.dialog = { 
    init: function(element, valueAccessor, allBindingsAccessor) { 
     var options = ko.utils.unwrapObservable(valueAccessor()); 
     setTimeout(function() { $(element).dialog(options || {}); }, 0); 

     //handle disposal (not strictly necessary in this scenario) 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).dialog("destroy"); 
     }); 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor) { 
     var shouldBeOpen = ko.utils.unwrapObservable(allBindingsAccessor().openWhen); 
     $(element) 
      .dialog(shouldBeOpen ? "open" : "close"); 
    } 
}; 

function Task(name) { 
    var self = this; 
    this.title = ko.observable(name); 

    this.toString = function() { return "Task: " + self.title(); }; 
} 

function TaskDialog(viewModel) { 
    var self = this; 

    this.viewModel = viewModel; 
    this.task = ko.observable(); 
    this.open = ko.observable(false); 
    this.titletext = ko.observable(); 

    this.editTask = function(task) { 
     self.task(task); 
     self.titletext(task.title()); 
     self.open(true); 
    } 

    this.update = function() { 
     var task = self.task(); 
     task.title(self.titletext()); 
     self.open(false); 
    } 

    this.updateCloseState = function() { 
     if (self.open()) 
      self.open(false); 
    } 

    this.cancel = function() { 
     self.open(false); 
    } 
} 


function viewModel() { 
    var self = this; 
    this.dialog = ko.observable(new TaskDialog(self)); 
    this.task = ko.observable(new Task('sample task')); 

    this.editTask = function() { 
     self.dialog().editTask(self.task()); 
    } 
}; 

ko.applyBindings(new viewModel()); 

Odpowiedz

15

Jeżeli przycisk nie posiada typ, a następnie przeglądarka przyjmuje założenie, że można go uznać za przycisk submit. Tak więc, kiedy uderzysz w enter, wykonywana jest metoda przycisku anulowania i zapobieganie faktycznemu przesyłaniu domyślnemu. Tak więc, gdybyś przesunął przycisk Zapisz przed przyciskiem Anuluj, działałby poprawnie.

Jednak prawdziwym sposobem na to naprawić tylko dodać type="button" do Anuluj:

<button type="button" style="float: left;" data-bind="click: cancel">Cancel</button> 

http://jsfiddle.net/rniemeyer/HwbD2/11/

+2

Dzięki! To niesamowite, ile czasu marnują głupie małe rzeczy ... –

+2

Tak, spędziłem dużo czasu, patrząc na ten jeden. Wydawało mi się, że było coś małego, czego nam brakowało i że nie wymagało to całego mnóstwa kodu do przechwytywania keyCode 13, etc ... –

Powiązane problemy