Knockout Validation & Proper way to clear controls - asp.net-mvc-3

I have the following code and it works fine, EXCEPT when you clear the property after you have inserted an item. The error shows up right away.
ko.validation.configure({
insertMessages: false,
decorateElement: true,
errorElementClass: 'error'
});
FirstName: ko.observable().extend({
required: true
}),
and I have add method in the knockout viewmodel
addItem: function () {
if (!viewModel.isValid()) {
viewModel.errors.showAllMessages();
return false;
} else {
//DO SOMETHING
this.SomeCollection.push(newInterviewee);
this.FirstName(null);
}
},
I have the following in the HTML:
<div>
<label>First Name</label>
<input data-bind="value: FirstName, validationElement: FirstName, valueUpdate: 'keyup'" class="input" type="text">
</div>
<div>
<div>
<input data-bind="click: addItem" class="button" type="button">
</div>
The problem is that after I call this.FirstName(null). The error shows up right away! I want the error to show up only when they press the button even after the property is cleared

Here is the solution that is provided by Steve Greatrex: https://github.com/Knockout-Contrib/Knockout-Validation/issues/210

We had the same issue on our project. We solved this by forcing isValid to true.
addItem: function () {
if (!viewModel.isValid()) {
viewModel.errors.showAllMessages();
return false;
} else {
//DO SOMETHING
this.SomeCollection.push(newInterviewee);
this.FirstName(null);
viewModel.isValid(true);
}
},
To be able to do this, you need to overwrite ko.validation's definition for the isValid computed as follows:
observable.isValid = ko.computed({
read: function() {
return observable.__valid__();
},
write: observable.__valid__
}
);

Related

How do I display instant messages, when insecure is removed, with Meteor.methods and Meteor.call?

I am taking coding courses online, so I can build my app sometime next year...
Can you help me with this instant message code please?
a. I am supposed to display an alert message when the user is not logged in.
b. Display the usename in the header.
c. Display the username with his instant message.
Since insecure is removed, I have to use Meteor.methods and meteor.call. I cannot use Sessions. I keep getting weird errors...
Here is the javascript code I have tried based on the course module, but I get errors that don't make sense to me...
Messages = new Mongo.Collection("messages");
if (Meteor.isClient) {
// this will configure the sign up field so it
// they only need a username
Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY',
});
Template.messageForm.events({
// this event listener is triggered when they click on
// the post! button on the message form template
'click .js-save-message': function (event) {
var messageText = $('#message-text-input').val();
// notice how tihs has changed since the lsat time
// now we read the username from the Meteor.user()
var messageNickname = "Anon";
if (Meteor.user()) {
messageNickname = Meteor.user().username;
}
var message = {
messageText: messageText,
nickname: messageNickname,
createdOn: new Date()
};
// HERE is where you come in ....
// call a meteor method
// on the server here instead of
if (Meteor.isServer) {
Meteor.methods({ // defines a method, adds extra security layer to app
insertMessage: function () {
var doc, user, euser;
doc = Message.findOne();
if (!doc) {
return;
} // no logged in user, give up
// now I have a doc and possibly a user
user = Meteor.user().profile;
eusers = insertMessage.findOne({ docid: doc._id });
if (!eusers) {
eusers = {
docid: doc._id,
users: {},
};
}
user.lastEdit = new Date();
eusers.users[this.userId] = user;
insertMessage.upsert({ _id: eusers._id }, eusers);
}
}
)
}
// comment out this code, which won't work as we removed insecure...
//Messages.insert(message); // the insecure way of doing it
// ... put code here that calls the
Meteor.call('insertMesage', message, function (err, res) {
if (!res) {
alert('You need to log in!');
}
});
Template.header.helpers({
// HERE is another one for you - can you
// complete the template helper for the 'header' template
// called 'nickname' that
// returns the nickname from the Session variable?, if they have set it
nickname: function () {
if (Meteor.user()) {
return Meteor.user().username;
}
},
});
Template.messageList.helpers({
// this helper provides the list of messages for the
// messageList template
messages: function () {
return Messages.find({}, { sort: { createdOn: -1 } })
}
});
},
});
}
Here is the html file
<body>
{{>header}}
{{>nicknameForm}}
{{>messageList}}
{{>messageForm}}
</body>
<template name="header">
<h1>Welcome to M-Instant {{nickname}}</h1>
</template>
<template name="messageList">
{{#each messages}}
{{>messageItem}}
{{/each}}
</template>
<template name="messageItem">
<h3>{{nickname}} - {{messageText}}</h3>
</template>
<template name="nicknameForm">
<div class="form-group">
<label for="nickname-input">Nickname:</label>
<input type="text" class="form-control" id="nickname-input"
placeholder="Type message here...">
<button type="submit" class="btn btn-default js-set-nickname">Set my
nickname!</button>
</div>
</template>
<template name="messageForm">
<div class="form-group">
<label for="message-text-input">Message:</label>
<input type="text" class="form-control" id="message-text-input"
placeholder="Type message here...">
<button type="submit" class="btn btn-primary js-save-message">Post!
</button>
</div>
</template>
Here is the Methods file
Meteor.methods({
'insertMessage':function(message){
console.log("If you manage to call the method, you'll see this
message in the server console");
if (!Meteor.user()){
return;
}
else {
return Messages.insert(message);
}
}
})

How to get value from radio button dynamically

i am creating a form for searching a client, using either id or email both are set to be unique. Application made on Codeignitor.
I have created a form with two radio buttons, one for search with ID and another for search with mail+dob.
Depending on the radio button selected, corresponding input fields shown.
In controller, it choose the model function based on the radio button value.
This is I coded, i need to pass the value of radio button to Controller.php file
Form(only included the radio button)
$(document).ready(function() {
$("#usingdob").hide();
$("#usingmail").hide();
$("input:radio").click(function() {
if ($(this).val() == "id") {
$("#usingId").show();
$("#usingdob").hide();
$("#usingmail").hide();
} else {
$("#usingId").hide();
$("#usingdob").show();
$("#usingmail").show();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-md-4">
<label class="radio-inline">
<input type="radio" name="optradio" value="id" checked>Using ID </label></div>
<div class="col-md-4">
<label class="radio-inline">
<input type="radio" name="optradio" value="mail">Using DOB</label>
</div>
I expected to get the radio button value correctlyenter image description here
JS:
$('input[name="optradio"]').click(function(){
var optradio = $(this).val();
//or
var optradio = $("input[name='optradio']:checked").val();
if(optradio == 'id'){
//do your hide/show stuff
}else{
//do your hide/show stuff
}
});
//on search button press call this function
function passToController(){
var optradio = $("input[name='optradio']:checked").val();
$.ajax({
beforeSend: function () {
},
complete: function () {
},
type: "POST",
url: "<?php echo site_url('controller/cmethod'); ?>",
data: ({optradio : optradio}),
success: function (data) {
}
});
}
Try this
<script type="text/javascript">
$( document ).ready(function() {
$("#usingdob, #usingmail").hide();
$('input[name="radio"]').click(function() {
if($(this).val() == "id") {
$("#usingId").show();
$("#usingdob, #usingmail").hide();
} else {
$("#usingId").hide();
$("#usingdob, #usingmail").show();
}
});
});
</script>
One thing I noticed is that you have 'mail' as a value in the DOB option. Another is that there seems to be 3 options and yet you only have 2 radios?
I adjusted the mail value to dob and created dummy divs to test the code. It seems to work.
$(document).ready(function() {
$("#usingdob").hide();
$("#usingmail").hide();
$("input:radio").click(function() {
console.log($(this).val());
if ($(this).val() == "id") {
$("#usingId").show();
$("#usingdob").hide();
$("#usingmail").hide();
} else {
$("#usingId").hide();
$("#usingdob").show();
$("#usingmail").show();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-md-4">
<label class="radio-inline">
<input type="radio" name="optradio" value="id" checked>Using ID </label></div>
<div class="col-md-4">
<label class="radio-inline">
<input type="radio" name="optradio" value="dob">Using DOB</label>
</div>
<div id="usingId">
Using Id div
</div>
<div id="usingdob">
Using dob div
</div>
<div id="usingmail">
Using mail div
</div>
As far as passing the value to the controller goes, ideally the inputs should be in a form. When you submit the form, the selected value can be passed to the php.
<?php
if (isset($_POST['submit'])) {
if(isset($_POST['optradio']))
{
Radio selection is :".$_POST['optradio']; // Radio selection
}
?>
If you want to get currently checked radio button value Try below line which will return current radio button value
var radioValue = $("input[name='gender']:checked").val();
if(radioValue)
{
alert("Your are a - " + radioValue);
}

Ajax submit and replace submit button with checkmark after success

First, I'm not having luck with ajax submitting at all in cakephp 1.3 environment. Once I successfully submit, I'm hoping user stays on page and submit button hidden or replaced with a checkmark. I've tried a few things... controller without $action and then .click function instead of on submit. I'm also not versed in debugging js to see where it might be wrong so any suggestions are welcome.
Maybe "update_a" is the $action within my dashboard controller
"function applications($action) {" instead?
dashboard controller
function update_a($action) {
...
switch ($action) {
case 'save':
if (!empty($this->data)) {
// update fields in database table matching model
$this->data['Model']['submitted'] = $_POST['submitted'];
$this->data['Model']['locked'] = $_POST['locked'];
if ($this->Model->save($this->data)) {
// save form fields to other models
$this->OtherModel->saveField('form_status_id',$_POST['form_status_id']);
$this->OtherModel->saveField('form_status',$_POST['form_status']);
}
}
}
break;
default:
//$this->redirect("admin/index");
$this->render("dashboard/applications");
break;
} //case
} // end function
html
<body>
<form id='update_a' action='save'>
<div class='form-group'>
<input type='hidden' class='hidden' name='locked' id='locked' value='1'>
<input type='hidden' class='hidden' name='form_status' id='form_status' value='Locked'>
<input type='hidden' class='hidden' name='form_status_id' id='form_status_id' value='3'>
<input type='hidden' class='hidden' name='submitted' id='submitted' value='<?php echo date("Y-m-d G:i:s") ?>'>
</div>
<div class='text-center'>
<input name='submit' type='button' class='btn btn-default' value='Submit Form A'>
</div>
</form>
</body>
<script>
$(document).ready(function () {
$('#update_a').on('submit', function (e) {
//$('#update_a').click(function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '/dashboard/update_a',
data: $('#update_a').serialize(),
success: function () {
alert('Form A has been submitted and locked for editing');
$('#update_a').hide();
},
error : function() {
alert("Error");
}
});
return false;
});
});
</script>

Meteor: Error: {{#each}} currently only accepts arrays, cursors or falsey values

I keep getting this error message when I click on the send button. Im trying to create a Instant Messenger app where online users can chat one on one. I am a beginner and I would really appreciate any help. Here is my error message, again it appears in the console once I click the Send button.
Exception from Tracker recompute function: meteor.js:862 Error:
{{#each}} currently only accepts arrays, cursors or falsey values.
at badSequenceError (observe-sequence.js:148)
at observe-sequence.js:113
at Object.Tracker.nonreactive (tracker.js:597)
at observe-sequence.js:90
at Tracker.Computation._compute (tracker.js:331)
at Tracker.Computation._recompute (tracker.js:350)
at Object.Tracker._runFlush (tracker.js:489)
at onGlobalMessage (meteor.js:347)
Here is my HTML
<template name="chat_page">
<h2>Type in the box below to send a message!</h2>
<div class="row">
<div class="col-md-12">
<div class="well well-lg">
{{#each messages}}
{{> chat_message}}
{{/each}}
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<form class="js-send-chat">
<input class="input" type="text" name="chat" placeholder="type a message here...">
<input type="submit" value="Send">
</form>
</div>
</div>
</template>
<!-- simple template that displays a message -->
<template name="chat_message">
<div class = "container">
<div class = "row">
<img src="/{{profile.avatar}}" class="avatar_img">
{{username}} said: {{text}}
</div>
</div>
<br>
</template>
Client Side
Template.chat_page.helpers({
messages: function () {
var chat = Chats.findOne({ _id: Session.get("chatId") });
return chat.messages;
},
other_user: function () {
return "";
}
});
Template.chat_page.events({
'submit .js-send-chat': function (event) {
console.log(event);
event.preventDefault();
var chat = Chats.findOne({ _id: Session.get("chatId") });
if (chat) {
var msgs = chat.messages;
if (! msgs) {
msgs = [];
}
msgs.push({ text: event.target.chat.value });
event.target.chat.value = "";
chat.messages = msgs;
Chats.update({ _id: chat._id }, { $set : { messages: chat } });
Meteor.call("sendMessage", chat);
}
}
});
Parts of the server side
Meteor.publish("chats", function () {
return Chats.find();
});
Meteor.publish("userStatus", function () {
return Meteor.users.find({ "status.online": true });
});
Meteor.publish("userData", function () {
if (this.userId) {
return Meteor.users.find({ _id: this.userId },{ fields: { 'other': 1, 'things': 1 } });
} else {
this.ready();
}
return Meteor.users.find({ "status.online": true });
});
Meteor.publish("users", function () {
return Meteor.users.find({ "status.online": true });
});
Chats.allow({
insert: function () { return true; },
update: function () { return true; },
remove: function () { return true; }
});
Meteor.methods({
sendMessage: function (chat) {
Chats.insert({
chat: chat,
createdAt: new Date(),
username: Meteor.user().profile.username,
avatar: Meteor.user().profile.avatar,
});
}
});
Chances are your subscriptions aren't ready. This means that Chats.findOne() will return nothing, meaning that Chats.findOne().messages will be undefined.
Try the following:
{{ #if Template.subscriptionsReady }}
{{#each messages}}
{{/each}}
{{/else}}
Alternatively, use a find() on chats, then {{#each}} on the messages within that chat. For example:
Template['Chat'].helpers({
chats: function () {
return Chats.find(Session.get('chatId')); // _id is unique, so this should only ever have one result.
}
});
Then in template:
{{#each chats}}
{{#each messages}}
{{>chat_message}}
{{/each}}
{{/each}}
I think there might be a logical error in this line
Chats.update({ _id : chat._id }, { $set : { messages : chat } });
You are setting the value of the field messages to chat. But chat is an object. So in your helper when you are returning Chats.findOne().messages to the {{#each}} block, you are actually returning an object which is not a valid value to be sent to an {{#each}} block and hence the error.
I think what you mean to do is
Chats.update({ _id : chat._id }, { $set : { messages : msgs } });

php jquery, validate remote , array

I have some problems to run the following code, the js:
$(document).ready(function(){
$.validator.addMethod("name", function(value, element) {
return $("#identiPIC_selected_0").val() !== '' && $("#identiPIC_selected_1").val() !== '' ;
}, "Required!");
$("#signin").validate({
groups:{
name : 'identiPIC_selected[]'
},
rules: {
'identiPIC_selected[]': {
required: true,
remote: {
url:"check3.php",
type:"post",
cache: false,
async:false,
data: {
'identiPIC_selected[0]': function() {
return $.trim($("#identiPIC_selected_0").val());
},
'identiPIC_selected[1]': function() {
return $.trim($("#identiPIC_selected_1").val());
}
}
}
}
}
});
});
the php is the following:
<?php
$captcha = $_POST['identiPIC_selected'];
$identiPIC[0] = "Apple";
$identiPIC[1] = "Flower";
if($captcha === $identiPIC){
echo "true";
} else {
echo "false";
}
?>
and the html:
<form id="signin" action="check3.php" method="POST">
<select id="identiPIC_selected_0" name="identiPIC_selected[]">
<option value="">Click to identify</option>
<option>Apple</option>
<option>Cat</option>
<option>Clock</option>
<option>Flower</option>
<option>Fork</option>
</select>
<select id="identiPIC_selected_1" name="identiPIC_selected[]">
<option value="">Click to identify</option>
<option>Apple</option>
<option>Cat</option>
<option>Clock</option>
<option>Flower</option>
<option>Fork</option>
</select>
<input type="submit" id="save" name="save" value="Save"/>
</form>
This code works well when, except when the user selects the second "select" option wrong, presses submit and then fixes his mistake and then he presses submit it just doesnt submit anymore, so what i mean is for example:
User selects: Apple + Cat and click on save button, displays error,
User fixes the problem: Apple + Flower and click on save button, it doesnt submit, even all the picks are good.
I added this :
$("#identiPIC_selected_0").change(function () {
$("#identiPIC_selected_0").removeData("previousValue");
});
$("#identiPIC_selected_1").change(function () {
$("#identiPIC_selected_1").removeData("previousValue");
});
but it doesnt seem to do anything for me.
Anyone any ideas?
Thanks!!!
ok... after different tries i think i found the solution, this seems to work:
$('#signin').submit(function(){
$("#identiPIC_selected_0").removeData('previousValue');
$("#identiPIC_selected_1").removeData('previousValue');
})

Resources