tutorial texto habilitar fnaf despues deshabilitar cajas boton forms radio-button form-submit marionette

forms - texto - marionette fnaf



Manejar el botón de opción en Marionette js (1)

Intento crear una vista en mi aplicación que muestre preguntas de sondeo en una región de diálogo modal. Tal vez algo como esto, por ejemplo:

What is your favorite color? >Red >Blue >Green >Yellow >Other Submit Vote

He leído que Marionette js no admite formularios listos para usar y que se le recomienda que maneje por su cuenta.

Esa estructura de arriba, rama y hojas (pregunta y lista de opciones), me sugiere CompositeView. ¿Es eso correcto?

¿Cómo disparo un model.save () para grabar la selección? Una forma html quiere una acción. No estoy seguro de cómo conectar la acción de formulario a model.save ().

Mi borrador preliminar del código de ItemView y CompositeView está debajo. ¿Estoy en el estadio? ¿Cómo se debe ajustar?

var PollOptionItemView = Marionette.ItemView.extend({ template: Handlebars.compile( ''<input type="radio" name="group{{pollNum}}" value="{{option}}">{{option}}<br>'' ) }); var PollOptionsListView = Marionette.CompositeView.extend({ template: Handlebars.compile( //The question part ''<div id="poll">'' + ''<div>{{question}}</div>'' + ''</div>'' + //The list of options part ''<form name="pollQuestion" action="? what goes here ?">'' + ''<div id="poll-options">'' + ''</div>'' + ''<input type="submit" value="Submit your vote">'' + ''</form>'' ), itemView: PollOptionItemView, appendHtml: function (compositeView, itemView, index) { var childrenContainer = $(compositeView.$("#poll-options") || compositeView.el); var children = childrenContainer.children(); if (children.size() === index) { childrenContainer.append(itemView.el); } else { childrenContainer.children().eq(index).before(itemView.el); } } });

MÁS DETALLES:

Mi objetivo realmente es crear preguntas de encuesta de forma dinámica, lo que significa que las preguntas y las opciones no se conocen en tiempo de ejecución, sino que se consultan desde una base de datos SQL a partir de entonces. Si estuvieras mirando mi aplicación, lanzaría una encuesta en tu pantalla a través de SignalR. En esencia, le estoy diciendo a tu navegador "hey, ve a obtener el contenido de la pregunta número 1 de la base de datos y muéstralos". Mi idea era que las CompositeViews son las más adecuadas para esto porque están basadas en datos. Las preguntas y las opciones correspondientes podrían ser modelos almacenados y colecciones que la plantilla CompositeView podría representar dinámicamente a pedido. Tengo la mayor parte de esto conectado y se ve bien. Mi único problema parece ser la noción de qué tipo de plantilla mostrar. ¿Una forma? ¿O debería mi plantilla simplemente colocar algunos botones de radio en la pantalla con un botón de enviar debajo y escribir algunos javascript para intentar determinar qué selección hizo el usuario? Me gustaría no utilizar un formulario en absoluto y solo usar el framework de backbone para manejar el envío. Eso me parece limpio, pero quizás no sea posible o sabio. No estoy seguro todavía.


Utilizaría el siguiente enfoque:

  • Crea una colección de preguntas de tu encuesta
  • Crea vistas de artículos especiales para cada tipo de pregunta
  • En su CompositeView, elija el modelo itemView según su tipo
  • Use una validación simple para ver si todas las preguntas han sido respondidas
  • Muestra una matriz de todas las preguntas y sus resultados.

Para una implementación de ejemplo, vea este violín: http://jsfiddle.net/Cardiff/QRdhT/
Pantalla completa: http://jsfiddle.net/Cardiff/QRdhT/embedded/result/

Nota:

  • Pruébalo sin responder todas las preguntas para ver la validación en el trabajo
  • Verifique su consola en caso de éxito para ver los resultados

El código

// Define data var surveyData = [{ id: 1, type: ''multiplechoice'', question: ''What color do you like?'', options: ["Red", "Green", "Insanely blue", "Yellow?"], result: null, validationmsg: "Please choose a color." }, { id: 2, type: ''openquestion'', question: ''What food do you like?'', options: null, result: null, validationmsg: "Please explain what food you like." }, { id: 3, type: ''checkbox'', question: ''What movie genres do you prefer?'', options: ["Comedy", "Action", "Awesome", "Adventure", "1D"], result: null, validationmsg: "Please choose at least one movie genre." }]; // Setup models var questionModel = Backbone.Model.extend({ defaults: { type: null, question: "", options: null, result: null, validationmsg: "Please fill in this question." }, validate: function () { // Check if a result has been set, if not, invalidate if (!this.get(''result'')) { return false; } return true; } }); // Setup collection var surveyCollection = Backbone.Collection.extend({ model: questionModel }); var surveyCollectionInstance = new surveyCollection(surveyData); console.log(surveyCollectionInstance); // Define the ItemViews /// Base itemView var baseSurveyItemView = Marionette.ItemView.extend({ ui: { warningmsg: ''.warningmsg'', panel: ''.panel'' }, events: { ''change'': ''storeResult'' }, modelEvents: { ''showInvalidMessage'': ''showInvalidMessage'', ''hideInvalidMessage'': ''hideInvalidMessage'' }, showInvalidMessage: function() { // Show message this.ui.warningmsg.show(); // Add warning class this.ui.panel.addClass(''panel-warningborder''); }, hideInvalidMessage: function() { // Hide message this.ui.warningmsg.hide(); // Remove warning class this.ui.panel.removeClass(''panel-warningborder''); } }); /// Specific views var multipleChoiceItemView = baseSurveyItemView.extend({ template: "#view-multiplechoice", storeResult: function() { var value = this.$el.find("input[type=''radio'']:checked").val(); this.model.set(''result'', value); } }); var openQuestionItemView = baseSurveyItemView.extend({ template: "#view-openquestion", storeResult: function() { var value = this.$el.find("textarea").val(); this.model.set(''result'', value); } }); var checkBoxItemView = baseSurveyItemView.extend({ template: "#view-checkbox", storeResult: function() { var value = $("input[type=''checkbox'']:checked").map(function(){ return $(this).val(); }).get(); this.model.set(''result'', (_.isEmpty(value)) ? null : value); } }); // Define a CompositeView var surveyCompositeView = Marionette.CompositeView.extend({ template: "#survey", ui: { submitbutton: ''.btn-primary'' }, events: { ''click @ui.submitbutton'': ''submitSurvey'' }, itemViewContainer: ".questions", itemViews: { multiplechoice: multipleChoiceItemView, openquestion: openQuestionItemView, checkbox: checkBoxItemView }, getItemView: function (item) { // Get the view key for this item var viewId = item.get(''type''); // Get all defined views for this CompositeView var itemViewObject = Marionette.getOption(this, "itemViews"); // Get correct view using given key var itemView = itemViewObject[viewId]; if (!itemView) { throwError("An `itemView` must be specified", "NoItemViewError"); } return itemView; }, submitSurvey: function() { // Check if there are errors var hasErrors = false; _.each(this.collection.models, function(m) { // Validate model var modelValid = m.validate(); // If it''s invalid, trigger event on model if (!modelValid) { m.trigger(''showInvalidMessage''); hasErrors = true; } else { m.trigger(''hideInvalidMessage''); } }); // Check to see if it has errors, if so, raise message, otherwise output. if (hasErrors) { alert(''You haven/'t answered all questions yet, please check.''); } else { // No errors, parse results and log to console var surveyResult = _.map(this.collection.models, function(m) { return { id: m.get(''id''), result: m.get(''result'') } }); // Log to console alert(''Success! Check your console for the results''); console.log(surveyResult); // Close the survey view rm.get(''container'').close(); } } }); // Create a region var rm = new Marionette.RegionManager(); rm.addRegion("container", "#container"); // Create instance of composite view var movieCompViewInstance = new surveyCompositeView({ collection: surveyCollectionInstance }); // Show the survey rm.get(''container'').show(movieCompViewInstance);

Plantillas

<script type="text/html" id="survey"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title" > A cool survey regarding your life </h3> </div> <div class="panel-body"> <div class="questions"></div> <div class="submitbutton"> <button type="button" class="btn btn-primary">Submit survey!</button> </div> </div> </div > </script> <script type="text/template" id="view-multiplechoice"> <div class="panel panel-success"> <div class="panel-heading"> <h4 class="panel-title" > <%= question %> </h4> </div> <div class="panel-body"> <div class="warningmsg"><%= validationmsg %></div> <% _.each( options, function( option, index ){ %> <div class="radio"> <label> <input type="radio" name="optionsRadios" id="<%= index %>" value="<%= option %>"> <%= option %> </label> </div> <% }); %> </div> </div> </script> <script type="text/template" id="view-openquestion"> <div class="panel panel-success"> <div class="panel-heading"> <h4 class="panel-title" > <%= question %> </h4> </div> <div class="panel-body"> <div class="warningmsg"><%= validationmsg %></div> <textarea class="form-control" rows="3"></textarea> </div> </div > </script> <script type="text/template" id="view-checkbox"> <div class="panel panel-success"> <div class="panel-heading"> <h4 class="panel-title" > <%= question %> </h4> </div> <div class="panel-body"> <div class="warningmsg"><%= validationmsg %></div> <% _.each( options, function( option, index ){ %> <div class="checkbox"> <label> <input type="checkbox" value="<%= option %>"> <%= option %> </label> </div> <% }); %> </div> </div> </script> <div id="container"></div>

Actualización: ejemplo agregado de barras de control
Jsfiddle usando manubrios: http://jsfiddle.net/Cardiff/YrEP8/