extract text from dojo xhrPost - dojo

I have a function in which I am doing a dojo.xhrPost(). Now the returning data is wrapped in an unwanted <div> which is framework specific and cannot be removed. How can I strip away the div element. Here is my code.
function sendForm() {
var resultNode = dojo.create("li");
dojo.xhrPost({
url: "${sectionaddurl}",
form: dojo.byId("sectionform"),
load: function(newContent) {
dojo.style(resultNode,"display","block");
resultNode.innerHTML = newContent;
},
error: function() {
resultNode.innerHTML = "Your form could not be sent.";
}
});
$("#sectionform")[0].reset();
dojo.place(resultNode, "existing_coursesection", "first");
}
In jquery we would do $("#some_ID").text(); where the id will be the div obtained via ajax.
Will dojo allow me to manipulate the request data which is like <div id="unwanted_div">containing my text</div>
any ideas?

I am not sure these are the "best" ways to go at it but they shoud work
1) Have the data be interpreted as XML instead of plain text:
dojo.require('dojox.xml.parser');
dojo.xhrPost({
//...
handleAs: 'xml',
//...
load: function(response_div){
//content should be xml now
result.innerHTML = dojox.xml.parser.textContent(response_div);
}
//...
})
2) Convert it to html and then process it
//create a thworwaway div with the respnse
var d = dojo.create('div', {innerHTML: response});
result.innerHTML = d.firstChild.innerHTML;
2.1) Use dojo.query instead of .firstChild if you need smore sofistication.

I prefer handle as JSON format :) , dojo have more utilities to access and to iterate the response.
dojo.xhrGet({
url : url,
handleAs : "json",
failOk : true, //Indicates whether a request should be allowed to fail
//(and therefore no console error message in the event of a failure)
timeout : 20000,
content: {//params},
load: function(){ // something },
preventCache: true,
error: function(error, ioargs) {
console.info("error function", ioargs);
var message = "";
console.info(ioargs.xhr.status, error);
//error process
},
handle: function(response, ioargs) {
var message = "";
console.info(ioargs.xhr.status, error);
switch (ioargs.xhr.status) {
case 200:
message = "Good request.";
break;
case 404:
message = "The page you requested was not found.";
break;
case 0:
message = "A network error occurred. Check that you are connected to the internet.";
break;
default:
message = "An unknown error occurred";
}
}
});

Related

How to hide error message in vue js after validation is true?

Actually my problem I am checking when a particular value is valid through v-on:input. If, the value is invalid I get the response as "invalid data" and i display the same. But, when the value becomes valid, the "invalid data" is not hiding. How to I able to do so.
My code is
methods: {
checkLimit: function () {
var vm = this;
data = {};
if (this.no != '') data['no'] = this.no;
$.ajax({
url: "doc/checkNumber",
method: "POST",
data: data,
dataType: "JSON",
success: function (e) {
if (e.status == true) {
}
else{
console.log(e.msg);
vm.error = e.msg;
}
},
});
},
}
So if status is false, I am showing as
<input type="text" class="form-control" v-model="orno" required=""
v-on:input="checkLimit" maxlength="3"><p>{{error}}</p>
But when Status is true the error message is still present. How can I update based on the change?
You should set the error to '' when the e.status is true. Like this
success: function (e) {
if (e.status == true) {
vm.error = '';
} else {
console.log(e.msg);
vm.error = e.msg;
}
},
Simple: in checkLimit do vm.error=null on success. Then in the template do <p v-if="error">{{error}}</p>.
Since in vue all data is reactive p will disappear when error is falsy.
EDIT: if you want to keep the p and toggle the message do as suggested in the other comment (no v-if).

How do I operate the m.withAttr tutorials code?

A contrived example of bi-directional data binding
var user = {
model: function(name) {
this.name = m.prop(name);
},
controller: function() {
return {user: new user.model("John Doe")};
},
view: function(controller) {
m.render("body", [
m("input", {onchange: m.withAttr("value", controller.user.name), value: controller.user.name()})
]);
}
};
https://lhorie.github.io/mithril/mithril.withAttr.html
I tried the above code does not work nothing.
It was the first to try to append the following.
m.mount(document.body, user);
Uncaught SyntaxError: Unexpected token n
Then I tried to append the following.
var users = m.prop([]);
var error = m.prop("");
m.request({method: "GET", url: "/users/index.php"})
.then(users, error);
▼/users/index.php
<?php
echo '[{name: "John"}, {name: "Mary"}]';
Uncaught SyntaxError: Unexpected token n
How do I operate the m.withAttr tutorials code?
Try returning m('body', [...]) from your controller.
view: function (ctrl) {
return m("body", [
...
]);
}
render should not be used inside of Mithril components (render is only used to mount Mithril components on existing DOM nodes).
The example is difficult to operate because it's contrived, it's not meant to be working out-of-the-box. Here's a slightly modified, working version:
http://jsfiddle.net/ciscoheat/8dwenn02/2/
var user = {
model: function(name) {
this.name = m.prop(name);
},
controller: function() {
return {user: new user.model("John Doe")};
},
view: function(controller) {
return [
m("input", {
oninput: m.withAttr("value", controller.user.name),
value: controller.user.name()
}),
m("h1", controller.user.name())
];
}
};
m.mount(document.body, user);
Changes made:
m.mount injects html inside the element specified as first parameter, so rendering a body element in view will make a body inside a body.
Changed the input field event to oninput for instant feedback, and added a h1 to display the model, so you can see it changing when the input field changes.
Using m.request
Another example how to make an ajax request that displays the retrieved data, as per your modifications:
http://jsfiddle.net/ciscoheat/3senfh9c/
var userList = {
controller: function() {
var users = m.prop([]);
var error = m.prop("");
m.request({
method: "GET",
url: "http://jsonplaceholder.typicode.com/users",
}).then(users, error);
return { users: users, error: error };
},
view: function(controller) {
return [
controller.users().map(function(u) {
return m("div", u.name)
}),
controller.error() ? m(".error", {style: "color:red"}, "Error: " + controller.error()) : null
];
}
};
m.mount(document.body, userList);
The Unexpected token n error can happen if the requested url doesn't return valid JSON, so you need to fix the JSON data in /users/index.php to make it work with your own code. There are no quotes around the name field.

How we get and post api in Titanium alloy?

How can we get and post api in Titanium alloy?
I am having the api of userDetails, I just want that how can i code to get the data from api.
function getUserDetails(){
}
Thanks in advance.
As you mentioned, you are using Titanium alloy.
So another approach be to extend the Alloy's Model and Collection ( which are based on backbone.js concept ).
There are already some implementation at RestAPI Sync Adapter also proper description/usage at Titanium RestApi sync.
I also provide the description and methodology used, in-case link gets broken:
Create a Model : Alloy Models are extensions of Backbone.js Models, so when you're defining specific information about your data, you do it by implementing certain methods common to all Backbone Models, therefor overriding the parent methods. Here we will override the url() method of backbone to allow our custom url endpoint.
Path :/app/models/node.js
exports.definition = {
config: {
adapter: {
type: "rest",
collection_name: "node"
}
},
extendCollection: function(Collection) {
_.extend(Collection.prototype, {
url: function() {
return "http://www.example.com/ws/node";
},
});
return Collection;
}
};
Configure a REST sync adapter : The main purpose of a sync adapter is to override Backbone's default sync method with something that fetches your data. In our example, we'll run through a few integrity checks before calling a function to fetch our data using a Ti.Network.createHTTPClient() call. This will create an object that we can attach headers and handlers to and eventually open and send an xml http request to our server so we can then fetch the data and apply it to our collection.
Path :/app/assets/alloy/sync/rest.js (you may have to create alloy/sync folders first)
// Override the Backbone.sync method with our own sync
functionmodule.exports.sync = function (method, model, opts)
{
var methodMap = {
'create': 'POST',
'read': 'GET',
'update': 'PUT',
'delete': 'DELETE'
};
var type = methodMap[method];
var params = _.extend(
{}, opts);
params.type = type;
//set default headers
params.headers = params.headers || {};
// We need to ensure that we have a base url.
if (!params.url)
{
params.url = model.url();
if (!params.url)
{
Ti.API.error("[REST API] ERROR: NO BASE URL");
return;
}
}
//json data transfers
params.headers['Content-Type'] = 'application/json';
switch (method)
{
case 'delete':
case 'create':
case 'update':
throw "Not Implemented";
break;
case 'read':
fetchData(params, function (_response)
{
if (_response.success)
{
var data = JSON.parse(_response.responseText);
params.success(data, _response.responseText);
}
else
{
params.error(JSON.parse(_response.responseText), _response.responseText);
Ti.API.error('[REST API] ERROR: ' + _response.responseText);
}
});
break;
}
};
function fetchData(_options, _callback)
{
var xhr = Ti.Network.createHTTPClient(
{
timeout: 5000
});
//Prepare the request
xhr.open(_options.type, _options.url);
xhr.onload = function (e)
{
_callback(
{
success: true,
responseText: this.responseText || null,
responseData: this.responseData || null
});
};
//Handle error
xhr.onerror = function (e)
{
_callback(
{
'success': false,
'responseText': e.error
});
Ti.API.error('[REST API] fetchData ERROR: ' + xhr.responseText);
};
for (var header in _options.headers)
{
xhr.setRequestHeader(header, _options.headers[header]);
}
if (_options.beforeSend)
{
_options.beforeSend(xhr);
}
xhr.send(_options.data || null);
}
//we need underscore
var _ = require("alloy/underscore")._;
Setup your View for Model-view binding : Titanium has a feature called Model-View binding, which allows you to create repeatable objects in part of a view for each model in a collection. In our example we'll use a TableView element with the dataCollection property set to node, which is the name of our model, and we'll create a TableViewRow element inside. The row based element will magically repeat for every item in the collection.
Path :/app/views/index.xml
<Alloy>
<Collection src="node">
<Window class="container">
<TableView id="nodeTable" dataCollection="node">
<TableViewRow title="{title}" color="black" />
</TableView>
</Window>
</Alloy>
Finally Controller : Binding the Model to the View requires almost no code at the controller level, the only thing we have to do here is load our collection and initiate a fetch command and the data will be ready to be bound to the view.
Path :/app/controllers/index.js
$.index.open();
var node = Alloy.Collections.node;
node.fetch();
Further reading :
Alloy Models
Sync Adapters
Hope it is helpful.
this is the solution for your problem:-
var request = Titanium.Network.createHTTPClient();
var done=false;
request.onload = function() {
try {
if (this.readyState == 4 && !done) {
done=true;
if(this.status===200){
var content = JSON.parse(this.responseText);
}else{
alert('error code' + this.status);
}
}
} catch (err) {
Titanium.API.error(err);
Titanium.UI.createAlertDialog({
message : err,
title : "Remote Server Error"
});
}
};
request.onerror = function(e) {
Ti.API.info(e.error);
};
request.open("POST", "http://test.com");
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
request.send({ test: 'test'});
if you don't get your answer please let me know.
Thanks

this.store.create wont fire inside ajax call

I simply am trying to update local storage but inside the Ext.Ajax.request I cant call this.store.create(). How do I call the this.store.create function inside the success: area of the Ajax call. Many thanks for your help.
login: function(params) {
params.record.set(params.data);
var errors = params.record.validate();
if (errors.isValid()) {
var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
myMask.show();
//now check if this login exists
Ext.Ajax.request({
url: '../../ajax/login.php',
method: 'GET',
params: params.data,
form: 'loginForm',
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
myMask.hide();
//success they exist show the page
if(obj.success == 1){
//this doesn't work below
this.store.create(params.data);
this.index();
}
else{
Ext.Msg.alert('Incorrect Login');
}
},
failure: function(response, opts) {
alert('server-side failure with status code ' + response.status);
myMask.hide();
}
});
}
else {
params.form.showErrors(errors);
}
},
In Javascript, 'this' keyword changes its meaning with the context it appears in.
When used in a method of an object, 'this' refers to the object the method immediately belong to. In your case, it refers to the argument you passed to Ext.Ajax.request.
To work around this, you need to keep an reference of the upper level 'this' in order to access its 'store' property in an inner context. Specifically, it looks like this:
var me = this,
....;
Ext.Ajax.Request({
...
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
myMask.hide();
//success they exist show the page
if(obj.success == 1){
me.store.create(params.data);
this.index();
}
else{
Ext.Msg.alert('Incorrect Login');
}
},
});

dojox.grid.DataGrid populated from Servlet

I'd like to hava a Dojo dojox.grid.DataGrid with its data from a servlet.
Problem: The data returned from the servlet does not get displayed, just the message "Sorry, an error has occured".
If I just place the JSON string into the HTML, it works. ARRRRGGH.
Can anyone please help me!
Thanks
Jeff Porter
Servlet code...
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
res.setContentType("json");
PrintWriter pw = new PrintWriter(res.getOutputStream());
if (response != null) pw.println("[{'batchId':'2001','batchRef':'146'}]");
pw.close();
}
HtmL code...
<div id="gridDD" dojoType="dojox.grid.DataGrid"
jsId="gridDD" style="height: 600x; width: 100%;"
store="ddInfo" structure="layoutHtmlTableDDDeltaSets">
</div>
var rawdataDDInfo = ""; // empty at start
ddInfo = new dojo.data.ItemFileWriteStore({
data: {
identifier: 'batchId',
label: 'batchId',
items: rawdataDDInfo
}
});
<script>
function doSelectBatchsAfterDate() {
var xhrArgs = {
url: "../secure/jsonServlet",
handleAs: "json",
preventCache: true,
load: function(data) {
var xx =dojo.toJson(data);
var ddInfoX = new dojo.data.ItemFileWriteStore({data: xx});
dijit.byId('gridDD').setStore(ddInfoX);
},
error: function(error) {
alert("error:" + error);
}
}
//Call the asynchronous xhrGet
var deferred = dojo.xhrGet(xhrArgs);
}
</script>
<img src="go.gif" onclick="doSelectBatchsAfterDate();"/>
When you create the dojo.data.ItemFileWriteStore using the JSON data returned from server. You just provide the items, you still needs to specify the metadata. The correct code should be as below.
var ddInfoX = new dojo.data.ItemFileWriteStore({
data: {
identifier: 'batchId',
label: 'batchId',
items: xx
}
});
And you don't need the dojo.toJson function which converts the JSON object to a JSON string. The dojo.data.ItemFileWriteStore requires a JSON object as the parameter, not a JSON string.