Backbone doesn't forget previous model - javascript

I'm trying to create a page where I can see list of my items, and edit them when clicked (on a separate page).
But when I browse trough different items (models), and then try to edit one item, every other item that I have loaded edits too.
My view:
App.Views.Items.Types.Type = Backbone.View.extend({
template: '#template_itemtypeview',
el: '#content',
initialize: function() {
$('.manage_items_header').show();
this.render();
},
render: function() {
var self = this;
var itemtypes = new App.Collections.ItemTypes();
itemtypes.fetch({
success: function() {
var template = _.template($(self.template).html());
$(self.el).html(template({
model: self.model.toJSON(),
itemtypes: itemtypes.models
}));
}
});
return this;
},
events: {
"change": "change",
"click .save": "save",
"click .delete": "delete",
},
change: function(event) {
// Remove any existing alert message
App.Utils.hideAlert();
// Apply the change to the model
var target = event.target;
var change = {};
if (target.type == 'checkbox') {
change[target.name] = target.checked;
} else {
change[target.name] = target.value;
}
this.model.set(change);
},
save: function() {
var self = this;
this.model.save(null, {
success: function(model) {
self.render();
App.app.navigate('items/types/' + model.id, false);
App.Utils.showAlert('Success!', 'Item type saved successfully', 'alert-success');
},
error: function() {
App.Utils.showAlert('Error', 'An error occurred while trying to delete this item type', 'alert-error');
}
});
},
delete: function() {
var self = this;
this.model.destroy({
success: function() {
App.app.navigate('items/types/new', true);
alert('Item type deleted successfully');
//window.history.back();
}
});
return false;
} });
Relavent part of route:
itemTypeAdd: function(){
App.Views.HeaderView.selectMenuItem('manage_items');
new App.Views.Items.Types.Type({
model: new App.Models.ItemType()
});
},
itemTypeShow: function(id){
App.Views.HeaderView.selectMenuItem('manage_items');
var itemtype = new App.Models.ItemType({id: id});
itemtype.fetch({success: function(){
new App.Views.Items.Types.Type({
model: itemtype
});
}});
},
HTML:
<form class="form-horizontal span5">
<fieldset>
<legend>Item Type Details</legend>
<br/>
<div class="control-group">
<label for="collectionID" class="control-label">ID:</label>
<div class="controls">
<input id="collectionID" name="id" type="text" value="<%= model.id === null ? '' : model.id %>" class="span3"
disabled/>
</div>
</div>
<div class="control-group">
<label for="name" class="control-label">Name:</label>
<div class="controls">
<input type="text" id="name" name="name" value="<%= model.name %>"/>
<span class="help-inline"></span>
</div>
</div>
<div class="control-group">
<label for="name" class="control-label">Has places?:</label>
<div class="controls">
<input type="checkbox" name="has_place"<% if(model.has_place) { %> checked="checked"<% } %>>
<span class="help-inline"></span>
</div>
</div>
</fieldset>
<div class="form-actions">
Save
Delete
</div>
</form>
<div class="span2">
<legend>Item Types + New</legend>
<ul id="itemtypes_list">
<%
_.each(itemtypes,function(item,key,list){
%>
<li><%= item.attributes.name %></li>
<%
});
%>
</ul>
</div>

Related

Select gets double options after submit form modal

I got a problem with a bootstrap modal form and dynamic select options.
When I open the modal, there is an input and two select options.
One select is populating the second after a user check an option from
the first select.
On the first load, the select options are working ok.
When I submit the form (with Save button) and I reopen the modal, the first select gets the correct options but the second got double options.
When I reload the page everything gets back to normal until I submit the form again.
$(document).ready(function () {
var table = $('table.setting-groups');
var table_permissions = $('table.settings-groups-permissions');
var table_permissions_edit = $('table.settings-groups-permissions-edit');
var permissions = [];
var dataArray = [];
$('#addGroupModal').on('shown.bs.modal', function (e) {
$('select#permission_category').each(function () {
var $select = $(this);
$select.empty().append('<option></option>');
$.ajax({
url: $select.attr('data-source')
}).then(function (options) {
options.map(function (option) {
var $option = $('<option>');
$option
.val(option[$select.attr('data-valueKey')])
.text(option[$select.attr('data-displayKey')]);
$select.append($option);
});
});
});
$('select#permission_category').change(function () {
var category = $('select#permission_category').val();
if (category !== '') {
$('select#permission_category_description').each(function () {
var $select = $(this);
$select.empty().append('<option></option>');
$.ajax({
url: $select.attr('data-source'),
data: {category: category}
}).then(function (options) {
options.map(function (option) {
var $option = $('<option>');
$option
.val(option[$select.attr('data-valueKey')])
.text(option[$select.attr('data-displayKey')]);
$select.append($option);
});
});
});
} else {
$('select#permission_category_description')[0].empty();
}
});
$('select#permission_category_description').change(function () {
var category = $('select#permission_category').val();
var description = $('select#permission_category_description').val();
var check = $.inArray(description, permissions) > -1;
if (!check) {
permissions.push(description);
table_permissions.DataTable().row.add({
"category": category,
"description": description
}).draw();
}
});
// Save permissions
$('form#add-group').submit(function (e) {
$('#savebtn').button('loading');
e.preventDefault();
var form = $(this);
// Push table data (permissions) to form for submit
$('<input>').attr({
type: 'hidden',
id: 'permissions',
name: 'permissions',
value: permissions
}).appendTo(form);
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: new FormData(this),
dataType: 'json',
processData: false,
contentType: false,
success: function (data) {
$('#addGroupModal').modal('toggle');
swal(
'Επιβεβαίωση Καταχώριση',
'Η ομάδα δικαιωμάτων καταχωρήθηκε επιτυχώς',
'success'
).then(function () {
permissions = [];
dataArray = [];
form[0].reset();
$('select#permission_category_description').empty();
table_permissions.DataTable().destroy();
table.DataTable().ajax.reload();
});
},
error: function (data) {
swal(
'Αποτυχία Καταχώρισης',
data.responseText,
'error'
)
}
});
});
// Remove row when you click X
table_permissions.on('click', '.delete', function () {
table_permissions.DataTable().row('.selected').remove().draw(false);
});
});
$('#addGroupModal').on('hide.bs.modal', function (e) {
// Clean forms / select / datatables / arrays on modal close
$('select#permission_category_description').empty();
$('form')[0].reset();
table_permissions.DataTable().destroy();
permissions = [];
dataArray = [];
});
$('#editGroupModal').on('shown.bs.modal', function (e) {
var id = $(e.relatedTarget).data('id');
$.post('../../custom/json/groups.php?view', {id: id}, function (arr) {
$('input#group_name').val(arr.description);
// Get existing permissions from groups
dataArray = arr.data.map(function (value) {
return value.description;
});
});
$('select#permission_category_edit').each(function () {
var $select = $(this);
$select.empty().append('<option></option>');
$.ajax({
url: $select.attr('data-source')
}).then(function (options) {
options.map(function (option) {
var $option = $('<option>');
$option
.val(option[$select.attr('data-valueKey')])
.text(option[$select.attr('data-displayKey')]);
$select.append($option);
});
});
});
$('select#permission_category_edit').change(function () {
var category = $('select#permission_category_edit').val();
if (category !== '') {
$('select#permission_category_description_edit').each(function () {
var $select = $(this);
$select.empty().append('<option></option>');
$.ajax({
url: $select.attr('data-source'),
data: {category: category}
}).then(function (options) {
options.map(function (option) {
var $option = $('<option>');
$option
.val(option[$select.attr('data-valueKey')])
.text(option[$select.attr('data-displayKey')]);
$select.append($option);
});
});
});
} else {
$('select#permission_category_description_edit')[0].empty();
}
});
$('select#permission_category_description_edit').change(function () {
var category = $('select#permission_category_edit').val();
var description = $('select#permission_category_description_edit').val();
permissions = dataArray;
var check = $.inArray(description, permissions) > -1;
if (!check) {
permissions.push(description);
table_permissions_edit.DataTable().row.add({
"category": category,
"description": description
}).draw();
}
});
var settingGroupsPermissionsEdit = {
"destroy": true,
"processing": true,
"deferRender": true,
"responsive": true,
"select": true ,
"searching": false,
"paging": false,
"info": false,
"ordering": false,
"language": {
"url": "/custom/js/data-tables/Greek.json"
},
"ajax": "../../custom/json/groups.php?view&id=" + id,
"dataSrc": "data",
"columns": [
{data: "category", className: "text-center"},
{data: "description", className: "text-center"},
{
data: null, className: "text-center btn-actions", render: function (data, type, row) {
return '<a data-id="' + data.description + '" class="danger p-0 delete"><i class="ft-x font-medium-3 mr-2"></i></a>';
}
}
]
};
$('table.settings-groups-permissions-edit').DataTable($.extend(true, {}, settingGroupsPermissionsEdit, {}));
// Save permissions
$('form#edit-group').submit(function (e) {
$('#editbtn').button('loading');
e.preventDefault();
var form = $(this);
// Push table data (permissions) to form for submit
$('<input>').attr({
type: 'hidden',
id: 'permissions',
name: 'permissions',
value: permissions
}).appendTo(form);
$.ajax({
url: form.attr('action') + '&id=' + id,
type: form.attr('method'),
data: new FormData(this),
dataType: 'json',
processData: false,
contentType: false,
success: function (data) {
$('#editGroupModal').modal('toggle');
swal(
'Επιβεβαίωση Ενημέρωσης',
'Η ομάδα δικαιωμάτων ενημερώθηκε επιτυχώς',
'success'
).then(function () {
permissions = [];
dataArray = [];
form[0].reset();
$('select#permission_category_description_edit').empty();
table_permissions_edit.DataTable().destroy();
table.DataTable().ajax.reload();
});
},
error: function (data) {
swal(
'Αποτυχία Ενημέρωσης',
data.responseText,
'error'
)
}
});
});
// Remove row when you click X
table_permissions_edit.on('click', '.delete', function () {
var row_desc = table_permissions_edit.DataTable().rows('.selected').data().pluck('description')[0];
permissions = remove(permissions, row_desc); // remove element from posted permissions array
table_permissions_edit.DataTable().row('.selected').remove().draw();
});
});
$('#editGroupModal').on('hide.bs.modal', function (e) {
// Clean forms / select / datatables / arrays on modal close
$('select#permission_category_description_edit').empty();
$('form')[0].reset();
table_permissions_edit.DataTable().destroy();
permissions = [];
dataArray = [];
});
// Delete group
table.on('click', '.swal-delete', function () {
var id = $(this).data('id');
swal({
title: 'Διαγραφή',
text: 'Είστε σίγουρος/η οτι θέλετε να διαγράψετε την ομάδα δικαιωμάτων;',
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#0CC27E',
cancelButtonColor: '#FF586B',
confirmButtonText: 'Ναι',
cancelButtonText: 'Όχι'
}).then(function (isConfirm) {
if (isConfirm) {
$.post("../../custom/json/groups.php?delete", {id: id}, function (data) {
swal(
'Επιβεβαίωση Διαγραφής',
'Η ομάδα δικαιωμάτων διαγράφηκε επιτυχώς',
'success'
).then(function () {
table.DataTable().ajax.reload();
});
});
}
}).catch(swal.noop);
});
// Remove element from an array
function remove(array, value) {
return array.filter(function (element) {
return element !== value;
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- BEGIN ADD GROUP MODAL-->
<div class="modal fade text-left" id="addGroupModal" role="dialog" aria-labelledby="addGroupModal" style="display: none;" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<form id="add-group" action="/custom/json/groups.php?add" method="post" class="form form-horizontal" autocomplete="off" enctype="multipart/form-data">
<div class="modal-header bg-medi white">
<h4 class="modal-title" id="addGroupModal"><i class="ft-list font-medium-3 mr-2"></i> Προσθήκη Νέας Ομάδας</h4>
</div>
<div class="modal-body mt-1">
<fieldset class="form-group floating-label-form-group row">
<label class="col-md-4 label-control mt-1" for="group_name">Όνομα Ομάδας: </label>
<div class="col-md-5">
<input type="text" id="group_name" class="form-control" name="group_name">
</div>
</fieldset>
<fieldset class="form-group floating-label-form-group row">
<label class="col-md-4 label-control" for="permission_category">Κατηγορία</label>
<div class="col-md-5">
<select id="permission_category" name="permission_category" class="form-control"
data-source="/custom/json/groups.php?permission-category"
data-valueKey="category"
data-displayKey="category">
</select>
</div>
</fieldset>
<fieldset class="form-group floating-label-form-group row">
<label class="col-md-4 label-control" for="permission_category_description">Πρόσβαση</label>
<div class="col-md-5">
<select id="permission_category_description" name="permission_category_description" class="form-control"
data-source="/custom/json/groups.php?permission-description"
data-valueKey="description"
data-displayKey="description">
</select>
</div>
</fieldset>
<div class="table-responsive">
<table class="table table-condensed table-bordered table-sm base-style table-hover full-width settings-groups-permissions">
<thead class="bg-medi text-white text-center">
<tr>
<th>Κατηγορία</th>
<th>Πρόσβαση</th>
<th></th>
</tr>
</thead>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Κλείσιμο</button>
<button type="submit" class="btn btn-medi white" id="savebtn" data-loading-text="Αποθήκευση...">Αποθήκευση</button>
</div>
</form>
</div>
</div>
</div>
<!-- END ADD GROUP MODAL-->
<!-- BEGIN EDIT GROUP MODAL-->
<div class="modal fade text-left" id="editGroupModal" role="dialog" aria-labelledby="editGroupModal" style="display: none;" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<form id="edit-group" action="/custom/json/groups.php?edit" method="post" class="form form-horizontal" autocomplete="off" enctype="multipart/form-data">
<div class="modal-header bg-medi white">
<h4 class="modal-title" id="editGroupModal"><i class="ft-list font-medium-3 mr-2"></i> Επεξεργασία Ομάδας</h4>
</div>
<div class="modal-body mt-1">
<fieldset class="form-group floating-label-form-group row">
<label class="col-md-4 label-control mt-1" for="group_name">Όνομα Ομάδας: </label>
<div class="col-md-5">
<input type="text" id="group_name" class="form-control" name="group_name" disabled>
</div>
</fieldset>
<fieldset class="form-group floating-label-form-group row">
<label class="col-md-4 label-control" for="permission_category_edit">Κατηγορία</label>
<div class="col-md-5">
<select id="permission_category_edit" name="permission_category" class="form-control"
data-source="/custom/json/groups.php?permission-category"
data-valueKey="category"
data-displayKey="category">
</select>
</div>
</fieldset>
<fieldset class="form-group floating-label-form-group row">
<label class="col-md-4 label-control" for="permission_category_description_edit">Πρόσβαση</label>
<div class="col-md-5">
<select id="permission_category_description_edit" name="permission_category_description" class="form-control"
data-source="/custom/json/groups.php?permission-description"
data-valueKey="description"
data-displayKey="description">
</select>
</div>
</fieldset>
<div class="table-responsive">
<table class="table table-condensed table-bordered table-sm base-style table-hover full-width settings-groups-permissions-edit">
<thead class="bg-medi text-white text-center">
<tr>
<th>Κατηγορία</th>
<th>Πρόσβαση</th>
<th></th>
</tr>
</thead>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Κλείσιμο</button>
<button type="submit" class="btn btn-medi white" id="editbtn" data-loading-text="Αποθήκευση...">Αποθήκευση</button>
</div>
</form>
</div>
</div>
</div>
<!-- END EDIT GROUP MODAL-->
Any suggestions ? I can't find where is the issue that causes js to run twice on select populate options.
Thank you in advance
UPDATE: The 2nd select option is doubled on modal show not on form submit.
Because you bind $('select#permission_category').change inside $('#addGroupModal').on('shown.bs.modal' handler so each time your modal show, it will bind $('select#permission_category').change another time. That's why when you open the modal second time, the 2nd select option is doubled and will be tripled on third time...
You can solve it by:
Option 1: Move $('select#permission_category').change to be outside of $('#addGroupModal').on('shown.bs.modal' handler.
Option 2: Remove $('select#permission_category') change handler using .off() when closing modal or before bind it in $('#addGroupModal').on('shown.bs.modal' handler.
Option 3: Create all options first then use .html() instead of .append() to set the html contents of select (this still bind change multiple time but the options is not multipled)

Page get reloaded on form submit with backbone js

I am trying to do a form submit with backbone.js, and when I click submit, it refreshes form. I have added my js code here. Is there any source from where i can get some detailed example with backbone js and have proper explained backbone js. I am new to backbone js and trying to learn it.
$(document).ready(function () {
Models.morderfaq = Backbone.Model.extend({
action: "ae-morder_faq-sync",
defaults: {
}
});
Collections.morderfaqs = Backbone.Collection.extend({
model: morderfaq,
el: '#save_faq_form',
action: 'ae-fetch-morder_faq',
initialize: function () {
}
});
Views.morderfaq_view = Backbone.View.extend({
el: '#save_faq_form',
events: {
"submit #save_faq_form": "syncChange"
},
initialize: function (options) {
_.bindAll(this, 'syncChange');
this.model = new morderfaq();
},
syncChange: function (event) {
event.preventDefault();
var self = this;
console.log('clicked');
self.$el.find('input,textarea,select').each(function () {
self.model.set($(this).attr('name'), $(this).val());
});
}
});
new Views.morderfaq_view();
});
Html code
<form class="post et-form" id="save_faq_form" novalidate="novalidate">
<div class="form-group clearfix">
<div class="input-group">
<label for="" class="input-label">1. send me
</label>
<textarea name="morder_faq_491" class="input-item input-full" id="morder_faq_491" value="" placeholder="Enter Text...">
</textarea>
</div>
</div>
<div class="form-group">
<button class="btn-save btn-submit" type="submit">SEND</button>
<input type="hidden" class="input-item save_faq_nonce" name="_wpnonce" value="fd75e383ec">
</div>
</form>

Ajax script not working on Form Submit?

I have an issue, I am loading a partial page however I dont want the form on this page to redirect when I click the save button.
Not sure if I am using the script the correct way, I want to Post to the controller when I click submit but I want to be redirected back to the same page I was on (AdminPanel/AdminProfile) and not redirected to a different controller/view (Account/Manage).
AdminProfile View:
<div id="tab-2" class="tab-pane">
#{Html.RenderPartial("~/Views/Account/Manage.cshtml");
}
</div>
Not sure if my script should go in this view or stay in the partial view?
Controller:
public ActionResult Manage(LocalPasswordModel model)
{
//....
return Json(new { redirectTo = Url.Action("AdminProfile", "AdminPanel") });
}
Partialview with script:
#model LocalPasswordModel
#{
ViewBag.Title = "Change Password";
}
<section class="hgroup">
<div class="panel-body">
<ul class="breadcrumb pull-right top-right">
<li>You're logged in as <strong>#User.Identity.Name</strong></li>
</ul>
<ul class="message-success">#ViewBag.StatusMessage</ul>
#using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { id = "SavePassword", #class = "form-horizontal" }))
{
<div class="social_sign">
<h3>Change your password.</h3>
</div>
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<div class="form-group">
<label class="col-sm-2 control-label">Old Password</label>
<div class="col-sm-10">
#Html.PasswordFor(m => m.OldPassword, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">New Password</label>
<div class="col-sm-10">
#Html.PasswordFor(m => m.NewPassword, new { #class = "form-control"})
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Confirm Password</label>
<div class="col-sm-10">
#Html.PasswordFor(m => m.ConfirmPassword, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-sm-12 col">
<input type="submit" class="btn btn-primary pull-right" value="Change password" />
</div>
</div>
}
</div>
</section>
Script in the view above:
#section Scripts {
<script>
$('#SavePassword').submit(function ()
{
if ($(this).valid())
{
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result)
{
if (result.redirectTo)
{
window.location.href = result.redirectTo;
}
else
{
$(".tab-2").html(result);
}
},
error: function ()
{
}
});
}
})
</script>
#Scripts.Render("~/bundles/jqueryval")
}
Nothing seems to happen all I get is an empty page with {"redirectTo":"/AdminPanel/AdminProfile"} in it. Which is the url: http://localhost:57239/Account/Manage
you should change your code like these:
<script>
$('#SavePassword').submit(function ()
{
if ($(this).valid())
{
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result)
{
if (result.redirectTo)
{
window.location.href = result.redirectTo;
}
else
{
$(".tab-2").html(result);
}
},
error: function ()
{
}
});
}
return false;
})
</script>
You have already attached the AJAX call, but forgot to prevent the default submission event. So, use event.preventDefault():
$('#SavePassword').submit(function (e) {
e.preventDefault();
// Rest of your code.
if ($(this).valid())

How to call a function again and again using knockout

I have this knockout code.
self.newPatient = ko.asyncCommand({
execute: function(complete) {
var isValid=$('#addPatientForm').parsley( 'validate' );
if(isValid){
var patientJson=ko.toJSON(self.patient());
formdata.append("json",patientJson);
//self.enableButton(false);
var imagepath= $.ajax({
url: projectUrl+"newPatient",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
formdata = new FormData();
imagepath=res;
var length=self.patients().length;
var patient=self.patient();
// self.enableButton(true);
}
});
}
},
canExecute: function(isExecuting) {
return !isExecuting && isDirty() && isValid();
}
});
This is my html inputfields
<div class="control-group">
<label class="control-label" for="inputIcon">Username :</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-hand-right"></i></span>
<input class="span8" type="text" data-bind="value: username" name="username" data-required="true" data-trigger="change" data-remote="${pageContext.request.contextPath}/isUserNameExists" data-remote-method="GET">
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="inputIcon">Password :</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-hand-right"></i></span>
<input class="span8" type="password" data-bind="value: password" name="password" data-required="true" data-trigger="change">
</div>
</div>
</div>
and this is my button
<button class="btn btn-primary"
data-bind="command: $root.newPatient, activity: $root.newPatient.isExecuting">
<i class="icon-ok icon-white"></i> Save
</button>
when I press the save button then execute: function(complete){.....} is called and inside this function
var isValid=$('#addPatientForm').parsley( 'validate' );
is called which checks form validity and if the form is invalid then isValid is false and hence the ajax is not called.
I want to call
var isValid=$('#addPatientForm').parsley( 'validate' );
if(isValid){.....}
when any of the input field is changed .So can any body please suggest me how to do?
You could write your own bindingHandler:
ko.bindingHandlers.parsley = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var isValid = valueAccessor();
var $form = $(element).closest('form');
$(element).change(function() {
isValid($form.parsley('validate'));
});
}
};
And in your ViewModel:
self.isValid = ko.observable(false);
And then:
<form ...>
<input data-bind="parsley: isValid, ..." />
</form>
See http://jsfiddle.net/sjroesink/ksqXx/
Edit
Without being able to reproduce your error, or an actual line where the error occurs, I cannot help you.
Try using Chrome's Developer tools to see where the error occurs:
You could use the subscribe function of your observable to run code:
username.subscribe(function () { isValid=$('#addPatientForm').parsley( 'validate' ); }
password.subscribe(function () { isValid=$('#addPatientForm').parsley( 'validate' ); }
Update after your comment:
Here is what I would do:
<div id='koRoot'>
<input type='text' data-bind='value: username' />
<input type='text' data-bind='enable: enableButton,value: password' />
<input type='button' data-bind='command: newPatient' value='Go!' />
</div>
...
And the js:
var callNewPatient = function () {
if (self.awaitingValidation()) self.newPatient.execute();
}
this.username.subscribe(callNewPatient);
this.password.subscribe(callNewPatient);
this.newPatient = ko.asyncCommand({
execute: function (complete) {
self.isValid(self.username() === 'me' && self.password() === 'pass');
if (self.isValid()) {
self.awaitingValidation(false);
alert("Valid!");
} else {
self.awaitingValidation(true);
}
},
canExecute: function (isExecuting) {
return self.isValid();
}
});
http://jsfiddle.net/nyothecat/LkaEJ/1/

Emberjs: Resolve form data from child views

I have a OutputsFormView which should have a save and cancel handler for click events on the buttons. When the save button is clicked it should collect all values from the child views and send it to the controller which then persists it.
outputs.js
App.OutputsCreateRoute = Ember.Route.extend({
model: function() {
return App.Output.createRecord();
},
renderTemplate: function() {
return this.render('outputs/form', {
controller: 'outputsCreate'
});
}
});
App.OutputsCreateController = Ember.Controller.extend({
save: function(model) {
// outputs empty values for title, receiver, value
console.log(model);
}
});
App.OutputsFormView = Ember.View.extend({
tagName: 'form',
classNames: ['form', 'form-horizontal'],
save: function(e) {
this.get('controller').send('save', {
title: this.get('title'),
receiver: this.get('receiver'),
value: this.get('value')
});
},
cancel: function(e) {
console.log('canceling');
}
});
template
<script type="text/x-handlebars" data-template-name="outputs/form">
{{#view App.OutputsFormView}}
<legend class="text-right">create a new output</legend>
<fieldset>
<div class="control-group">
<label class="control-label" for="title">Title</label>
<div class="controls">
{{view Ember.TextField valueBinding="view.title" placeholder="Lovely Afternoon Pizza"}}
</div>
</div>
<div class="control-group">
<label class="control-label" for="receiver">Receiver</label>
<div class="controls">
{{view Ember.TextField valueBinding="view.receiver" placeholder="The Goverment"}}
</div>
</div>
<div class="control-group">
<label class="control-label" for="value">Receiver</label>
<div class="controls">
{{view App.ValueView valueBinding="view.value"}}
</div>
</div>
<div class="control-group pull-right">
<div class="controls">
<button type="button" {{action "save"}} class="btn">save</button>
<button type="button" {{action "cancel"}} class="btn btn-red">cancel</button>
</div>
</div>
</fieldset>
{{/view}}
</script>
For some reason I cannot get the values of the child form views and unfortunately I have no idea what I have forgotten...
Bodo
The solution is that each a valueBinding is available in the controller:
App.OutputsCreateController = Ember.Controller.extend({
save: function(model) {
var output = this.get('model');
output.set('title', this.get('title'));
output.set('receiver', this.get('receiver'));
output.set('value', this.get('value'));
output.save();
}
});
This is better than resolving the values out of the view directly. But if you want to do this you can give your view a name:
{{view viewName="blabla"}}
and then access it through the parent view with:
this.get('blabla');
However I think the value binding method should be preferred

Categories