2011-12-28 16 views
7

Tengo un diálogo de jquery ui con un enlace de envío de knockoutjs en un formulario. El cuadro de diálogo se puede cerrar pulsando el botón cancelar, presionando el botón de cerrar en la barra de título del cuadro de diálogo, pulsando escape, o presionando el botón guardar. Mi intención es que los eventos de cierre de la cancelación, escape y barra de título dejen de lado el diálogo sin aplicar ninguna acción desde él, mientras que presionar enter o hacer clic en 'guardar' debería realizar la acción de diálogo. Todo funciona según lo previsto, excepto la tecla Intro, que da como resultado un evento de cancelación, en lugar de un evento de envío.knockoutjs enviar enlace no manipular la tecla enter correctamente

He creado un jsfiddle para ilustrar esto, e incluyo el código a continuación para referernce.

Mis disculpas por el código detallado ...

Gene

<!-- 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> 

El javascript es el siguiente:

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()); 

Respuesta

15

Si un botón no tiene un tipo, entonces el navegador hace una suposición de que se puede considerar un botón submit. Por lo tanto, cuando presionas enter, se está ejecutando el método del botón Cancelar e impidiendo que realmente se realice el envío predeterminado. Entonces, si moviera el botón Guardar antes del botón Cancelar, funcionaría correctamente.

Sin embargo, la verdadera manera de solucionarlo es sólo para añadir a su type="button" Cancelar:

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

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

+2

Gracias! Es increíble cuánto tiempo desperdician las estúpidas pequeñas cosas ... –

+2

Sí, pasé mucho tiempo mirando esto. Simplemente parecía que había algo pequeño que nos faltaba y que no requería un montón de código para capturar el código clave 13, etc. –

Cuestiones relacionadas