How to add delete button and making it work in nativescript

1.8k views Asked by At

I'm trying to add a delete button and making it work, i'm splitting up the problems in two.

In my xml file I have this:

<Page loaded="onPageLoaded">
 <GridLayout rows="auto, *">
  <StackLayout orientation="horizontal" row="0">
   <TextField width="200" text="{{ task }}" hint="Enter a task" id="task" />
     <Button cssClass="test" text="Add" tap="add"></Button>
     <Button cssClass="test" text="Refresh" tap="refresh"></Button>
  </StackLayout>
    <ListView items="{{ tasks }}" row="1">
     <ListView.itemTemplate>
       <Label text="{{ name }}" />
       <Button cssClass="test" text="X" tap="delbutton"></Button> 
   </ListView.itemTemplate>
  </ListView>
 </GridLayout>
</Page>

The first problem is the delbutton, which is the delete button, if i add it like that it will replace my view with a bunch of X's. I cant seem to understand why.

The second problem i'm having trouble with is how to make it work so that it loops through and deletes the item i want to delete, what im cyrrently doing is getting data form a backend server with json that looks like this:

exports.onPageLoaded = function(args) {
    page = args.object;
    pageData.set("task", "");
    pageData.set("tasks", tasks);
    page.bindingContext = pageData;
    var result;
    http.request({
        url: "http://192.168.1.68:3000/posts.json",
        method: "GET",
        headers: { "Content-Type": "application/json" },
    }).then(function (response) {
        result = response.content.toJSON();
        for (var i in result) {
            tasks.push({ name: result[i].name });
        }
    }, function (e) {
        console.log("Error occurred " + e);
    });
};
exports.delbutton = function() {
    console.log("REM")
};

Thanks for your help and time.

1

There are 1 answers

1
Emil Oberg On BEST ANSWER

The first problem (that only the X is showing) is due to the fact that a ListView item wants exactly one (1) child. You have two (a Label and a Button). Fortunately one item might be a so what you want to do is to enclose your two elements in a StackLayout, like this:

<Page loaded="onPageLoaded">
<GridLayout rows="auto, *">
    <StackLayout orientation="horizontal" row="0">
        <TextField width="200" text="{{ task }}" hint="Enter a task" id="task" />
        <Button cssClass="test" text="Add" tap="add"></Button>
        <Button cssClass="test" text="Refresh" tap="refresh"></Button>
    </StackLayout>
    <ListView items="{{ tasks }}" row="1">
        <ListView.itemTemplate>
            <StackLayout orientation="horizontal">
                <Label text="{{ name }}" />
                <Label text="{{ hello }}" />
                <Button cssClass="test" text="X" tap="delbutton"></Button>
            </StackLayout>
        </ListView.itemTemplate>
    </ListView>
</GridLayout>
</Page>

As for the second part of removing items from the ListView. I don't know if your pageData is an observable object as the declaration is not part of your pasted code, but I'm guessing it is. Anyways, I've created an example of how to populate data using observables (which is the NativeScript way of building ui:s, see previous link) and how to remove an item from the ListView.

I've added comments in the code to explain what I'm doing.

var Observable = require('data/observable');
var ObservableArray = require('data/observable-array');

/**
 * Creating an observable object,
 * see documentation: https://docs.nativescript.org/bindings.html
 * 
 * Populate that observable object with an (empty) observable array.
 * This way we can modify the array (e.g. remove an item) and 
 * the UI will reflect those changes (and remove if from the ui
 * as well).
 * 
 * Observable objects are one of NativeScripts most fundamental parts
 * for building user interfaces as they will allow us to
 * change an object and that change gets propagated to the ui
 * without us doing anything.
 *
 */

var contextArr = new ObservableArray.ObservableArray();
var contextObj = new Observable.Observable({
    tasks: contextArr
});


exports.onPageLoaded = function(args) {
    var page = args.object;
    page.bindingContext = contextObj;
    /**
     * Simulating adding data to array after http request has returned json.
     * Also adding an ID to each item so that we can refer to that when we're
     * removing it.
     */
    contextArr.push({name: 'First Item', id: contextArr.length});
    contextArr.push({name: 'Second Item', id: contextArr.length});
    contextArr.push({name: 'Third Item', id: contextArr.length});
};

exports.delbutton = function(args) {
    /**
     * Getting the "bindingContext" of the tapped item.
     * The bindingContext will contain e.g: {name: 'First Item', id: 0}
     */
    var btn = args.object;
    var tappedItemData = btn.bindingContext;

    /**
     * Iterate through our array and if the tapped item id
     * is the same as the id of the id of the current iteration
     * then remove it.
     */
    contextArr.some(function (item, index) {
        if(item.id === tappedItemData.id) {
            contextArr.splice(index, 1);
            return false;
        }
    });

};